aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/dock.c11
-rw-r--r--drivers/acpi/ec.c36
-rw-r--r--drivers/acpi/executer/exconfig.c3
-rw-r--r--drivers/acpi/namespace/nsnames.c34
-rw-r--r--drivers/acpi/pci_link.c12
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/acpi/processor_idle.c1
-rw-r--r--drivers/acpi/processor_perflib.c2
-rw-r--r--drivers/acpi/resources/rscalc.c3
-rw-r--r--drivers/acpi/utilities/utalloc.c8
-rw-r--r--drivers/acpi/utilities/utdelete.c13
-rw-r--r--drivers/acpi/utilities/utobject.c13
-rw-r--r--drivers/acpi/wmi.c2
-rw-r--r--drivers/ata/pata_at32.c4
-rw-r--r--drivers/block/cciss.c748
-rw-r--r--drivers/block/cciss.h2
-rw-r--r--drivers/block/cciss_scsi.c195
-rw-r--r--drivers/block/xen-blkfront.c4
-rw-r--r--drivers/bluetooth/Kconfig10
-rw-r--r--drivers/bluetooth/bcm203x.c9
-rw-r--r--drivers/bluetooth/bfusb.c10
-rw-r--r--drivers/bluetooth/bpa10x.c10
-rw-r--r--drivers/bluetooth/bt3c_cs.c2
-rw-r--r--drivers/bluetooth/btusb.c441
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/bluetooth/hci_usb.c10
-rw-r--r--drivers/bluetooth/hci_vhci.c2
-rw-r--r--drivers/cdrom/cdrom.c7
-rw-r--r--drivers/cdrom/gdrom.c7
-rw-r--r--drivers/cdrom/viocd.c7
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/agp/agp.h3
-rw-r--r--drivers/char/agp/ali-agp.c10
-rw-r--r--drivers/char/agp/amd-k7-agp.c10
-rw-r--r--drivers/char/agp/amd64-agp.c51
-rw-r--r--drivers/char/agp/ati-agp.c7
-rw-r--r--drivers/char/agp/backend.c28
-rw-r--r--drivers/char/agp/generic.c41
-rw-r--r--drivers/char/agp/intel-agp.c83
-rw-r--r--drivers/char/agp/isoch.c37
-rw-r--r--drivers/char/agp/sis-agp.c17
-rw-r--r--drivers/char/agp/sworks-agp.c25
-rw-r--r--drivers/char/agp/uninorth-agp.c32
-rw-r--r--drivers/char/amiserial.c2
-rw-r--r--drivers/char/ds1620.c2
-rw-r--r--drivers/char/hvc_console.c5
-rw-r--r--drivers/char/hw_random/ixp4xx-rng.c2
-rw-r--r--drivers/char/hw_random/via-rng.c8
-rw-r--r--drivers/char/pcmcia/ipwireless/tty.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c4
-rw-r--r--drivers/char/random.c1
-rw-r--r--drivers/char/rtc.c1
-rw-r--r--drivers/char/synclink.c4
-rw-r--r--drivers/char/synclink_gt.c6
-rw-r--r--drivers/char/synclinkmp.c4
-rw-r--r--drivers/char/tty_io.c74
-rw-r--r--drivers/char/viocons.c1171
-rw-r--r--drivers/char/vt.c82
-rw-r--r--drivers/char/vt_ioctl.c4
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c1
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c20
-rw-r--r--drivers/cpuidle/governors/ladder.c26
-rw-r--r--drivers/cpuidle/governors/menu.c42
-rw-r--r--drivers/cpuidle/sysfs.c29
-rw-r--r--drivers/crypto/ixp4xx_crypto.c4
-rw-r--r--drivers/crypto/padlock-aes.c28
-rw-r--r--drivers/crypto/padlock-sha.c9
-rw-r--r--drivers/crypto/talitos.c54
-rw-r--r--drivers/dma/ioat_dma.c2
-rw-r--r--drivers/dma/iop-adma.c2
-rw-r--r--drivers/dma/mv_xor.c2
-rw-r--r--drivers/firewire/Kconfig4
-rw-r--r--drivers/firewire/fw-cdev.c29
-rw-r--r--drivers/firmware/memmap.c61
-rw-r--r--drivers/hid/usbhid/hid-quirks.c12
-rw-r--r--drivers/hwmon/Kconfig32
-rw-r--r--drivers/hwmon/Makefile2
-rw-r--r--drivers/hwmon/abituguru3.c134
-rw-r--r--drivers/hwmon/ad7414.c268
-rw-r--r--drivers/hwmon/adcxx.c329
-rw-r--r--drivers/hwmon/applesmc.c20
-rw-r--r--drivers/hwmon/coretemp.c5
-rw-r--r--drivers/hwmon/dme1737.c292
-rw-r--r--drivers/hwmon/f71882fg.c6
-rw-r--r--drivers/hwmon/hwmon-vid.c166
-rw-r--r--drivers/hwmon/i5k_amb.c28
-rw-r--r--drivers/hwmon/ibmaem.c27
-rw-r--r--drivers/hwmon/it87.c45
-rw-r--r--drivers/hwmon/lm75.c114
-rw-r--r--drivers/hwmon/thmc50.c28
-rw-r--r--drivers/hwmon/w83627hf.c101
-rw-r--r--drivers/hwmon/w83791d.c27
-rw-r--r--drivers/i2c/Kconfig14
-rw-r--r--drivers/i2c/algos/Kconfig11
-rw-r--r--drivers/i2c/busses/i2c-acorn.c2
-rw-r--r--drivers/i2c/busses/i2c-amd756-s4882.c9
-rw-r--r--drivers/i2c/busses/i2c-at91.c6
-rw-r--r--drivers/i2c/busses/i2c-davinci.c5
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c4
-rw-r--r--drivers/i2c/busses/i2c-nforce2-s4985.c5
-rw-r--r--drivers/i2c/busses/i2c-pnx.c2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c6
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c4
-rw-r--r--drivers/i2c/chips/at24.c8
-rw-r--r--drivers/i2c/chips/isp1301_omap.c6
-rw-r--r--drivers/i2c/chips/menelaus.c5
-rw-r--r--drivers/i2c/i2c-core.c11
-rw-r--r--drivers/i2c/i2c-dev.c4
-rw-r--r--drivers/ide/arm/ide_arm.c3
-rw-r--r--drivers/ide/ide-cd.c20
-rw-r--r--drivers/ide/pci/aec62xx.c2
-rw-r--r--drivers/ide/pci/cy82c693.c2
-rw-r--r--drivers/ide/pci/hpt366.c2
-rw-r--r--drivers/ide/pci/it821x.c2
-rw-r--r--drivers/ide/pci/pdc202xx_new.c2
-rw-r--r--drivers/ide/pci/scc_pata.c2
-rw-r--r--drivers/ide/pci/sgiioc4.c4
-rw-r--r--drivers/ide/pci/siimage.c2
-rw-r--r--drivers/ide/pci/sis5513.c2
-rw-r--r--drivers/ide/pci/tc86c001.c2
-rw-r--r--drivers/ide/pci/via82cxxx.c2
-rw-r--r--drivers/ieee1394/nodemgr.c63
-rw-r--r--drivers/ieee1394/nodemgr.h2
-rw-r--r--drivers/ieee1394/sbp2.c25
-rw-r--r--drivers/infiniband/core/cma.c37
-rw-r--r--drivers/infiniband/core/mad_rmpp.c2
-rw-r--r--drivers/infiniband/core/ucma.c14
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c6
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c28
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.h7
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c25
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h9
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qes.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c48
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c60
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c5
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba7220.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c12
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c6
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c33
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c19
-rw-r--r--drivers/input/evdev.c63
-rw-r--r--drivers/input/joystick/xpad.c1
-rw-r--r--drivers/input/keyboard/aaed2000_kbd.c4
-rw-r--r--drivers/input/keyboard/corgikbd.c8
-rw-r--r--drivers/input/keyboard/gpio_keys.c4
-rw-r--r--drivers/input/keyboard/jornada720_kbd.c4
-rw-r--r--drivers/input/keyboard/omap-keypad.c11
-rw-r--r--drivers/input/keyboard/pxa27x_keypad.c5
-rw-r--r--drivers/input/keyboard/spitzkbd.c8
-rw-r--r--drivers/input/keyboard/tosakbd.c4
-rw-r--r--drivers/input/misc/cobalt_btns.c3
-rw-r--r--drivers/input/misc/ixp4xx-beeper.c2
-rw-r--r--drivers/input/mouse/Kconfig23
-rw-r--r--drivers/input/mouse/Makefile1
-rw-r--r--drivers/input/mouse/bcm5974.c681
-rw-r--r--drivers/input/mouse/gpio_mouse.c1
-rw-r--r--drivers/input/mouse/rpcmouse.c2
-rw-r--r--drivers/input/serio/i8042-sparcio.h22
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h7
-rw-r--r--drivers/input/serio/rpckbd.c2
-rw-r--r--drivers/input/serio/xilinx_ps2.c4
-rw-r--r--drivers/input/tablet/gtco.c1
-rw-r--r--drivers/input/touchscreen/Kconfig21
-rw-r--r--drivers/input/touchscreen/corgi_ts.c8
-rw-r--r--drivers/input/touchscreen/h3600_ts_input.c4
-rw-r--r--drivers/input/touchscreen/jornada720_ts.c4
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c2
-rw-r--r--drivers/input/touchscreen/wm9705.c1
-rw-r--r--drivers/input/touchscreen/wm9712.c1
-rw-r--r--drivers/input/touchscreen/wm9713.c1
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c1
-rw-r--r--drivers/leds/leds-ams-delta.c2
-rw-r--r--drivers/leds/leds-cm-x270.c4
-rw-r--r--drivers/leds/leds-corgi.c7
-rw-r--r--drivers/leds/leds-fsg.c2
-rw-r--r--drivers/leds/leds-h1940.c6
-rw-r--r--drivers/leds/leds-locomo.c2
-rw-r--r--drivers/leds/leds-s3c24xx.c6
-rw-r--r--drivers/leds/leds-spitz.c6
-rw-r--r--drivers/lguest/page_tables.c25
-rw-r--r--drivers/md/md.c33
-rw-r--r--drivers/md/raid10.c9
-rw-r--r--drivers/md/raid5.c32
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c7
-rw-r--r--drivers/media/dvb/frontends/Kconfig3
-rw-r--r--drivers/media/video/Kconfig2
-rw-r--r--drivers/media/video/arv.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c1
-rw-r--r--drivers/media/video/gspca/conex.c4
-rw-r--r--drivers/media/video/gspca/etoms.c137
-rw-r--r--drivers/media/video/gspca/gspca.c12
-rw-r--r--drivers/media/video/gspca/gspca.h5
-rw-r--r--drivers/media/video/gspca/ov519.c476
-rw-r--r--drivers/media/video/gspca/pac7311.c54
-rw-r--r--drivers/media/video/gspca/sonixb.c2
-rw-r--r--drivers/media/video/gspca/sonixj.c287
-rw-r--r--drivers/media/video/gspca/spca505.c12
-rw-r--r--drivers/media/video/gspca/spca506.c12
-rw-r--r--drivers/media/video/gspca/spca508.c18
-rw-r--r--drivers/media/video/gspca/spca561.c42
-rw-r--r--drivers/media/video/gspca/vc032x.c4
-rw-r--r--drivers/media/video/gspca/zc3xx.c6
-rw-r--r--drivers/media/video/pxa_camera.c62
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c2
-rw-r--r--drivers/media/video/soc_camera.c26
-rw-r--r--drivers/media/video/soc_camera_platform.c2
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c33
-rw-r--r--drivers/media/video/uvc/uvc_driver.c26
-rw-r--r--drivers/media/video/uvc/uvc_video.c33
-rw-r--r--drivers/media/video/v4l2-dev.c4
-rw-r--r--drivers/media/video/vino.c1
-rw-r--r--drivers/mfd/Kconfig21
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/mcp-sa11x0.c6
-rw-r--r--drivers/mfd/t7l66xb.c419
-rw-r--r--drivers/mfd/tc6387xb.c181
-rw-r--r--drivers/mfd/tc6393xb.c159
-rw-r--r--drivers/mfd/ucb1x00-core.c2
-rw-r--r--drivers/mfd/ucb1x00-ts.c2
-rw-r--r--drivers/misc/Kconfig4
-rw-r--r--drivers/misc/acer-wmi.c19
-rw-r--r--drivers/misc/sgi-gru/grutables.h2
-rw-r--r--drivers/mmc/host/Kconfig6
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/at91_mci.c6
-rw-r--r--drivers/mmc/host/atmel-mci.c2
-rw-r--r--drivers/mmc/host/imxmmc.c4
-rw-r--r--drivers/mmc/host/omap.c15
-rw-r--r--drivers/mmc/host/pxamci.c4
-rw-r--r--drivers/mmc/host/s3cmci.c21
-rw-r--r--drivers/mmc/host/sdricoh_cs.c1
-rw-r--r--drivers/mmc/host/tmio_mmc.c691
-rw-r--r--drivers/mmc/host/tmio_mmc.h194
-rw-r--r--drivers/mtd/maps/autcpu12-nvram.c4
-rw-r--r--drivers/mtd/maps/cdb89712.c2
-rw-r--r--drivers/mtd/maps/ceiva.c2
-rw-r--r--drivers/mtd/maps/h720x-flash.c2
-rw-r--r--drivers/mtd/maps/integrator-flash.c2
-rw-r--r--drivers/mtd/maps/ipaq-flash.c4
-rw-r--r--drivers/mtd/maps/ixp2000.c2
-rw-r--r--drivers/mtd/maps/omap_nor.c4
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c2
-rw-r--r--drivers/mtd/maps/sa1100-flash.c2
-rw-r--r--drivers/mtd/nand/Kconfig7
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/ams-delta.c6
-rw-r--r--drivers/mtd/nand/atmel_nand.c4
-rw-r--r--drivers/mtd/nand/autcpu12.c4
-rw-r--r--drivers/mtd/nand/cmx270_nand.c4
-rw-r--r--drivers/mtd/nand/edb7312.c2
-rw-r--r--drivers/mtd/nand/h1910.c6
-rw-r--r--drivers/mtd/nand/orion_nand.c4
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c4
-rw-r--r--drivers/mtd/nand/sharpsl.c2
-rw-r--r--drivers/mtd/nand/tmio_nand.c556
-rw-r--r--drivers/mtd/nand/ts7250.c2
-rw-r--r--drivers/net/3c523.c4
-rw-r--r--drivers/net/3c527.c9
-rw-r--r--drivers/net/3c59x.c14
-rw-r--r--drivers/net/8390.c13
-rw-r--r--drivers/net/8390p.c19
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/acenic.c1
-rw-r--r--drivers/net/arm/am79c961a.c2
-rw-r--r--drivers/net/arm/at91_ether.c6
-rw-r--r--drivers/net/arm/ep93xx_eth.c4
-rw-r--r--drivers/net/arm/ixp4xx_eth.c10
-rw-r--r--drivers/net/atl1e/atl1e_ethtool.c2
-rw-r--r--drivers/net/atl1e/atl1e_main.c4
-rw-r--r--drivers/net/atlx/atl1.c19
-rw-r--r--drivers/net/atp.c9
-rw-r--r--drivers/net/au1000_eth.c2
-rw-r--r--drivers/net/ax88796.c4
-rw-r--r--drivers/net/bnx2.c47
-rw-r--r--drivers/net/bnx2x.h87
-rw-r--r--drivers/net/bnx2x_fw_defs.h160
-rw-r--r--drivers/net/bnx2x_hsi.h16
-rw-r--r--drivers/net/bnx2x_init.h26
-rw-r--r--drivers/net/bnx2x_init_values.h533
-rw-r--r--drivers/net/bnx2x_link.c1259
-rw-r--r--drivers/net/bnx2x_link.h11
-rw-r--r--drivers/net/bnx2x_main.c1215
-rw-r--r--drivers/net/bnx2x_reg.h210
-rw-r--r--drivers/net/bonding/bond_3ad.c1
-rw-r--r--drivers/net/bonding/bond_main.c394
-rw-r--r--drivers/net/bonding/bond_sysfs.c3
-rw-r--r--drivers/net/cpmac.c1
-rw-r--r--drivers/net/cs89x0.c2
-rw-r--r--drivers/net/de620.c7
-rw-r--r--drivers/net/dm9000.c5
-rw-r--r--drivers/net/e1000e/defines.h2
-rw-r--r--drivers/net/e1000e/e1000.h32
-rw-r--r--drivers/net/e1000e/ethtool.c46
-rw-r--r--drivers/net/e1000e/netdev.c427
-rw-r--r--drivers/net/e1000e/param.c56
-rw-r--r--drivers/net/eepro.c8
-rw-r--r--drivers/net/eth16i.c1
-rw-r--r--drivers/net/forcedeth.c110
-rw-r--r--drivers/net/fs_enet/mac-fcc.c2
-rw-r--r--drivers/net/gianfar.c10
-rw-r--r--drivers/net/gianfar_sysfs.c1
-rw-r--r--drivers/net/hamradio/mkiss.c2
-rw-r--r--drivers/net/igb/e1000_82575.c72
-rw-r--r--drivers/net/igb/e1000_82575.h1
-rw-r--r--drivers/net/igb/e1000_defines.h1
-rw-r--r--drivers/net/igb/e1000_hw.h1
-rw-r--r--drivers/net/igb/e1000_mac.c84
-rw-r--r--drivers/net/igb/e1000_mac.h5
-rw-r--r--drivers/net/igb/e1000_regs.h3
-rw-r--r--drivers/net/igb/igb_main.c30
-rw-r--r--drivers/net/ipg.h2
-rw-r--r--drivers/net/irda/ep7211-sir.c2
-rw-r--r--drivers/net/irda/pxaficp_ir.c4
-rw-r--r--drivers/net/irda/sa1100_ir.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c1
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c4
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h1
-rw-r--r--drivers/net/ixp2000/ixp2400-msf.c4
-rw-r--r--drivers/net/ixp2000/ixpdev.c1
-rw-r--r--drivers/net/loopback.c67
-rw-r--r--drivers/net/lp486e.c2
-rw-r--r--drivers/net/macb.c4
-rw-r--r--drivers/net/meth.c2
-rw-r--r--drivers/net/myri10ge/myri10ge.c7
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp.h52
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp_gen_header.h2
-rw-r--r--drivers/net/ne.c4
-rw-r--r--drivers/net/netx-eth.c11
-rw-r--r--drivers/net/netxen/netxen_nic.h48
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c9
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c35
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h10
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c162
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h13
-rw-r--r--drivers/net/netxen/netxen_nic_init.c33
-rw-r--r--drivers/net/netxen/netxen_nic_main.c275
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c16
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h6
-rw-r--r--drivers/net/ni5010.c1
-rw-r--r--drivers/net/ni52.c2
-rw-r--r--drivers/net/ppp_mppe.c1
-rw-r--r--drivers/net/pppol2tp.c1
-rw-r--r--drivers/net/qla3xxx.c23
-rw-r--r--drivers/net/qla3xxx.h105
-rw-r--r--drivers/net/r6040.c1
-rw-r--r--drivers/net/sh_eth.c70
-rw-r--r--drivers/net/sh_eth.h22
-rw-r--r--drivers/net/sky2.c111
-rw-r--r--drivers/net/sky2.h2
-rw-r--r--drivers/net/smc911x.h2
-rw-r--r--drivers/net/smc91x.h6
-rw-r--r--drivers/net/sun3_82586.c7
-rw-r--r--drivers/net/tehuti.h1
-rw-r--r--drivers/net/tg3.c101
-rw-r--r--drivers/net/tg3.h6
-rw-r--r--drivers/net/tlan.c8
-rw-r--r--drivers/net/tun.c105
-rw-r--r--drivers/net/typhoon.c1
-rw-r--r--drivers/net/usb/Kconfig21
-rw-r--r--drivers/net/usb/hso.c53
-rw-r--r--drivers/net/usb/pegasus.c21
-rw-r--r--drivers/net/via-velocity.c301
-rw-r--r--drivers/net/via-velocity.h50
-rw-r--r--drivers/net/wan/Kconfig15
-rw-r--r--drivers/net/wan/Makefile11
-rw-r--r--drivers/net/wan/cosa.c293
-rw-r--r--drivers/net/wan/dscc4.c1
-rw-r--r--drivers/net/wan/farsync.c5
-rw-r--r--drivers/net/wan/farsync.h6
-rw-r--r--drivers/net/wan/hdlc.c25
-rw-r--r--drivers/net/wan/hdlc_cisco.c29
-rw-r--r--drivers/net/wan/hdlc_fr.c19
-rw-r--r--drivers/net/wan/hdlc_ppp.c15
-rw-r--r--drivers/net/wan/hdlc_raw.c15
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c17
-rw-r--r--drivers/net/wan/hdlc_x25.c17
-rw-r--r--drivers/net/wan/hostess_sv11.c382
-rw-r--r--drivers/net/wan/lmc/lmc.h11
-rw-r--r--drivers/net/wan/lmc/lmc_debug.c7
-rw-r--r--drivers/net/wan/lmc/lmc_debug.h6
-rw-r--r--drivers/net/wan/lmc/lmc_ioctl.h2
-rw-r--r--drivers/net/wan/lmc/lmc_main.c672
-rw-r--r--drivers/net/wan/lmc/lmc_media.c66
-rw-r--r--drivers/net/wan/lmc/lmc_proto.c146
-rw-r--r--drivers/net/wan/lmc/lmc_proto.h14
-rw-r--r--drivers/net/wan/lmc/lmc_var.h360
-rw-r--r--drivers/net/wan/pc300.h228
-rw-r--r--drivers/net/wan/pc300_drv.c146
-rw-r--r--drivers/net/wan/sealevel.c361
-rw-r--r--drivers/net/wan/syncppp.c9
-rw-r--r--drivers/net/wan/z85230.c193
-rw-r--r--drivers/net/wan/z85230.h10
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/ath5k/base.c11
-rw-r--r--drivers/net/wireless/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath9k/Makefile11
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h1021
-rw-r--r--drivers/net/wireless/ath9k/beacon.c979
-rw-r--r--drivers/net/wireless/ath9k/core.c1923
-rw-r--r--drivers/net/wireless/ath9k/core.h1072
-rw-r--r--drivers/net/wireless/ath9k/hw.c8575
-rw-r--r--drivers/net/wireless/ath9k/hw.h969
-rw-r--r--drivers/net/wireless/ath9k/initvals.h3146
-rw-r--r--drivers/net/wireless/ath9k/main.c1470
-rw-r--r--drivers/net/wireless/ath9k/phy.c436
-rw-r--r--drivers/net/wireless/ath9k/phy.h543
-rw-r--r--drivers/net/wireless/ath9k/rc.c2126
-rw-r--r--drivers/net/wireless/ath9k/rc.h316
-rw-r--r--drivers/net/wireless/ath9k/recv.c1318
-rw-r--r--drivers/net/wireless/ath9k/reg.h1385
-rw-r--r--drivers/net/wireless/ath9k/regd.c1026
-rw-r--r--drivers/net/wireless/ath9k/regd.h412
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h1915
-rw-r--r--drivers/net/wireless/ath9k/xmit.c2871
-rw-r--r--drivers/net/wireless/b43/main.c3
-rw-r--r--drivers/net/wireless/ipw2100.c1
-rw-r--r--drivers/net/wireless/ipw2200.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c7
-rw-r--r--drivers/net/wireless/orinoco.c7
-rw-r--r--drivers/net/wireless/p54/p54.h1
-rw-r--r--drivers/net/wireless/p54/p54common.c69
-rw-r--r--drivers/net/wireless/p54/p54common.h18
-rw-r--r--drivers/net/wireless/p54/p54usb.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c54
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c1
-rw-r--r--drivers/net/wireless/rtl8187_dev.c1
-rw-r--r--drivers/net/wireless/wavelan.c3
-rw-r--r--drivers/net/wireless/wavelan_cs.c6
-rw-r--r--drivers/net/xen-netfront.c2
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c38
-rw-r--r--drivers/pci/msi.c5
-rw-r--r--drivers/pci/pci.c3
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c7
-rw-r--r--drivers/pci/probe.c57
-rw-r--r--drivers/pci/quirks.c7
-rw-r--r--drivers/pci/setup-bus.c35
-rw-r--r--drivers/pcmcia/at91_cf.c6
-rw-r--r--drivers/pcmcia/omap_cf.c6
-rw-r--r--drivers/pcmcia/pxa2xx_base.c6
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c2
-rw-r--r--drivers/pcmcia/pxa2xx_lubbock.c6
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c6
-rw-r--r--drivers/pcmcia/pxa2xx_palmtx.c53
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c2
-rw-r--r--drivers/pcmcia/sa1100_assabet.c4
-rw-r--r--drivers/pcmcia/sa1100_badge4.c4
-rw-r--r--drivers/pcmcia/sa1100_cerf.c4
-rw-r--r--drivers/pcmcia/sa1100_h3600.c4
-rw-r--r--drivers/pcmcia/sa1100_jornada720.c2
-rw-r--r--drivers/pcmcia/sa1100_neponset.c4
-rw-r--r--drivers/pcmcia/sa1100_shannon.c4
-rw-r--r--drivers/pcmcia/sa1100_simpad.c4
-rw-r--r--drivers/pcmcia/sa1111_generic.c2
-rw-r--r--drivers/pcmcia/sa11xx_base.c2
-rw-r--r--drivers/pcmcia/soc_common.c4
-rw-r--r--drivers/power/palmtx_battery.c2
-rw-r--r--drivers/power/tosa_battery.c2
-rw-r--r--drivers/rtc/rtc-at91rm9200.c2
-rw-r--r--drivers/rtc/rtc-at91sam9.c4
-rw-r--r--drivers/rtc/rtc-dev.c12
-rw-r--r--drivers/rtc/rtc-ep93xx.c2
-rw-r--r--drivers/rtc/rtc-isl1208.c2
-rw-r--r--drivers/rtc/rtc-s3c.c2
-rw-r--r--drivers/rtc/rtc-sa1100.c4
-rw-r--r--drivers/sbus/sbus.c2
-rw-r--r--drivers/scsi/arm/acornscsi-io.S2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_hp_sw.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c2
-rw-r--r--drivers/serial/21285.c2
-rw-r--r--drivers/serial/Kconfig1
-rw-r--r--drivers/serial/atmel_serial.c6
-rw-r--r--drivers/serial/clps711x.c2
-rw-r--r--drivers/serial/imx.c4
-rw-r--r--drivers/serial/netx-serial.c4
-rw-r--r--drivers/serial/pxa.c4
-rw-r--r--drivers/serial/s3c2400.c4
-rw-r--r--drivers/serial/s3c2410.c4
-rw-r--r--drivers/serial/s3c2412.c4
-rw-r--r--drivers/serial/s3c2440.c4
-rw-r--r--drivers/serial/sa1100.c2
-rw-r--r--drivers/serial/samsung.c4
-rw-r--r--drivers/serial/serial_ks8695.c4
-rw-r--r--drivers/serial/sunhv.c2
-rw-r--r--drivers/serial/sunsab.c2
-rw-r--r--drivers/serial/sunsu.c2
-rw-r--r--drivers/serial/sunzilog.c2
-rw-r--r--drivers/spi/atmel_spi.c6
-rw-r--r--drivers/spi/omap2_mcspi.c4
-rw-r--r--drivers/spi/omap_uwire.c6
-rw-r--r--drivers/spi/pxa2xx_spi.c11
-rw-r--r--drivers/spi/spi.c40
-rw-r--r--drivers/spi/spi_imx.c7
-rw-r--r--drivers/spi/spi_s3c24xx.c6
-rw-r--r--drivers/spi/spi_s3c24xx_gpio.c6
-rw-r--r--drivers/ssb/main.c8
-rw-r--r--drivers/usb/Kconfig6
-rw-r--r--drivers/usb/atm/cxacru.c2
-rw-r--r--drivers/usb/class/cdc-acm.c86
-rw-r--r--drivers/usb/class/cdc-acm.h3
-rw-r--r--drivers/usb/core/driver.c5
-rw-r--r--drivers/usb/core/message.c2
-rw-r--r--drivers/usb/gadget/Kconfig10
-rw-r--r--drivers/usb/gadget/at91_udc.c9
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c4
-rw-r--r--drivers/usb/gadget/dummy_hcd.c5
-rw-r--r--drivers/usb/gadget/f_acm.c196
-rw-r--r--drivers/usb/gadget/f_ecm.c2
-rw-r--r--drivers/usb/gadget/f_rndis.c2
-rw-r--r--drivers/usb/gadget/f_serial.c2
-rw-r--r--drivers/usb/gadget/f_subset.c2
-rw-r--r--drivers/usb/gadget/gadget_chips.h6
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.h2
-rw-r--r--drivers/usb/gadget/omap_udc.c9
-rw-r--r--drivers/usb/gadget/pxa25x_udc.c2
-rw-r--r--drivers/usb/gadget/pxa25x_udc.h2
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c6
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c9
-rw-r--r--drivers/usb/gadget/u_serial.c290
-rw-r--r--drivers/usb/gadget/u_serial.h12
-rw-r--r--drivers/usb/host/ehci-orion.c2
-rw-r--r--drivers/usb/host/ehci-q.c2
-rw-r--r--drivers/usb/host/isp1760-hcd.c53
-rw-r--r--drivers/usb/host/isp1760-hcd.h5
-rw-r--r--drivers/usb/host/ohci-at91.c7
-rw-r--r--drivers/usb/host/ohci-ep93xx.c3
-rw-r--r--drivers/usb/host/ohci-hcd.c23
-rw-r--r--drivers/usb/host/ohci-hub.c11
-rw-r--r--drivers/usb/host/ohci-lh7a404.c2
-rw-r--r--drivers/usb/host/ohci-omap.c15
-rw-r--r--drivers/usb/host/ohci-pci.c132
-rw-r--r--drivers/usb/host/ohci-pnx4008.c9
-rw-r--r--drivers/usb/host/ohci-pxa27x.c9
-rw-r--r--drivers/usb/host/ohci-q.c6
-rw-r--r--drivers/usb/host/ohci-s3c2410.c4
-rw-r--r--drivers/usb/host/ohci-sa1111.c6
-rw-r--r--drivers/usb/host/ohci.h11
-rw-r--r--drivers/usb/host/r8a66597-hcd.c49
-rw-r--r--drivers/usb/misc/Kconfig10
-rw-r--r--drivers/usb/misc/Makefile1
-rw-r--r--drivers/usb/misc/auerswald.c2152
-rw-r--r--drivers/usb/misc/isight_firmware.c4
-rw-r--r--drivers/usb/musb/Kconfig176
-rw-r--r--drivers/usb/musb/Makefile86
-rw-r--r--drivers/usb/musb/cppi_dma.c1540
-rw-r--r--drivers/usb/musb/cppi_dma.h133
-rw-r--r--drivers/usb/musb/davinci.c462
-rw-r--r--drivers/usb/musb/davinci.h100
-rw-r--r--drivers/usb/musb/musb_core.c2261
-rw-r--r--drivers/usb/musb/musb_core.h507
-rw-r--r--drivers/usb/musb/musb_debug.h66
-rw-r--r--drivers/usb/musb/musb_dma.h172
-rw-r--r--drivers/usb/musb/musb_gadget.c2031
-rw-r--r--drivers/usb/musb/musb_gadget.h108
-rw-r--r--drivers/usb/musb/musb_gadget_ep0.c981
-rw-r--r--drivers/usb/musb/musb_host.c2170
-rw-r--r--drivers/usb/musb/musb_host.h110
-rw-r--r--drivers/usb/musb/musb_io.h115
-rw-r--r--drivers/usb/musb/musb_procfs.c830
-rw-r--r--drivers/usb/musb/musb_regs.h300
-rw-r--r--drivers/usb/musb/musb_virthub.c425
-rw-r--r--drivers/usb/musb/musbhsdma.c433
-rw-r--r--drivers/usb/musb/omap2430.c324
-rw-r--r--drivers/usb/musb/omap2430.h56
-rw-r--r--drivers/usb/musb/tusb6010.c1151
-rw-r--r--drivers/usb/musb/tusb6010.h233
-rw-r--r--drivers/usb/musb/tusb6010_omap.c719
-rw-r--r--drivers/usb/serial/Kconfig7
-rw-r--r--drivers/usb/serial/ftdi_sio.c6
-rw-r--r--drivers/usb/serial/ftdi_sio.h7
-rw-r--r--drivers/usb/serial/option.c44
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h4
-rw-r--r--drivers/usb/serial/sierra.c170
-rw-r--r--drivers/usb/serial/usb-serial.c7
-rw-r--r--drivers/usb/storage/Kconfig12
-rw-r--r--drivers/usb/storage/Makefile1
-rw-r--r--drivers/usb/storage/sierra_ms.c207
-rw-r--r--drivers/usb/storage/sierra_ms.h4
-rw-r--r--drivers/usb/storage/transport.c17
-rw-r--r--drivers/usb/storage/unusual_devs.h40
-rw-r--r--drivers/usb/storage/usb.c3
-rw-r--r--drivers/video/acornfb.c4
-rw-r--r--drivers/video/am200epd.c2
-rw-r--r--drivers/video/atmel_lcdfb.c19
-rw-r--r--drivers/video/aty/radeon_accel.c8
-rw-r--r--drivers/video/backlight/omap1_bl.c6
-rw-r--r--drivers/video/clps711xfb.c4
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/console/fbcon.h2
-rw-r--r--drivers/video/cyber2000fb.c2
-rw-r--r--drivers/video/epson1355fb.c2
-rw-r--r--drivers/video/fsl-diu-fb.c32
-rw-r--r--drivers/video/imxfb.c4
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c21
-rw-r--r--drivers/video/matrox/matroxfb_maven.c97
-rw-r--r--drivers/video/omap/blizzard.c6
-rw-r--r--drivers/video/omap/dispc.c6
-rw-r--r--drivers/video/omap/hwa742.c6
-rw-r--r--drivers/video/omap/lcd_h3.c4
-rw-r--r--drivers/video/omap/lcd_h4.c2
-rw-r--r--drivers/video/omap/lcd_inn1510.c4
-rw-r--r--drivers/video/omap/lcd_inn1610.c4
-rw-r--r--drivers/video/omap/lcd_osk.c6
-rw-r--r--drivers/video/omap/lcd_palmte.c4
-rw-r--r--drivers/video/omap/lcd_palmtt.c4
-rw-r--r--drivers/video/omap/lcd_palmz71.c2
-rw-r--r--drivers/video/omap/lcd_sx1.c8
-rw-r--r--drivers/video/omap/lcdc.c4
-rw-r--r--drivers/video/omap/omapfb_main.c5
-rw-r--r--drivers/video/omap/rfbi.c2
-rw-r--r--drivers/video/omap/sossi.c4
-rw-r--r--drivers/video/pnx4008/dum.h2
-rw-r--r--drivers/video/pnx4008/sdum.c2
-rw-r--r--drivers/video/pxafb.c78
-rw-r--r--drivers/video/s3c2410fb.c6
-rw-r--r--drivers/video/sa1100fb.c6
-rw-r--r--drivers/watchdog/Kconfig21
-rw-r--r--drivers/watchdog/Makefile9
-rw-r--r--drivers/watchdog/acquirewdt.c130
-rw-r--r--drivers/watchdog/advantechwdt.c162
-rw-r--r--drivers/watchdog/alim1535_wdt.c189
-rw-r--r--drivers/watchdog/alim7101_wdt.c228
-rw-r--r--drivers/watchdog/ar7_wdt.c8
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c43
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c111
-rw-r--r--drivers/watchdog/bfin_wdt.c147
-rw-r--r--drivers/watchdog/booke_wdt.c44
-rw-r--r--drivers/watchdog/cpu5wdt.c144
-rw-r--r--drivers/watchdog/davinci_wdt.c22
-rw-r--r--drivers/watchdog/ep93xx_wdt.c30
-rw-r--r--drivers/watchdog/eurotechwdt.c95
-rw-r--r--drivers/watchdog/geodewdt.c96
-rw-r--r--drivers/watchdog/hpwdt.c6
-rw-r--r--drivers/watchdog/i6300esb.c366
-rw-r--r--drivers/watchdog/iTCO_vendor.h15
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c62
-rw-r--r--drivers/watchdog/iTCO_wdt.c310
-rw-r--r--drivers/watchdog/ib700wdt.c123
-rw-r--r--drivers/watchdog/ibmasr.c151
-rw-r--r--drivers/watchdog/indydog.c114
-rw-r--r--drivers/watchdog/iop_wdt.c64
-rw-r--r--drivers/watchdog/it8712f_wdt.c6
-rw-r--r--drivers/watchdog/ixp2000_wdt.c63
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c69
-rw-r--r--drivers/watchdog/ks8695_wdt.c122
-rw-r--r--drivers/watchdog/machzwd.c108
-rw-r--r--drivers/watchdog/mixcomwd.c133
-rw-r--r--drivers/watchdog/mpc5200_wdt.c24
-rw-r--r--drivers/watchdog/mpc83xx_wdt.c230
-rw-r--r--drivers/watchdog/mpc8xx_wdt.c37
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c316
-rw-r--r--drivers/watchdog/mpcore_wdt.c73
-rw-r--r--drivers/watchdog/mtx-1_wdt.c111
-rw-r--r--drivers/watchdog/mv64x60_wdt.c21
-rw-r--r--drivers/watchdog/omap_wdt.c45
-rw-r--r--drivers/watchdog/pc87413_wdt.c249
-rw-r--r--drivers/watchdog/pcwd.c193
-rw-r--r--drivers/watchdog/pcwd_pci.c161
-rw-r--r--drivers/watchdog/pcwd_usb.c168
-rw-r--r--drivers/watchdog/pnx4008_wdt.c31
-rw-r--r--drivers/watchdog/rm9k_wdt.c34
-rw-r--r--drivers/watchdog/s3c2410_wdt.c19
-rw-r--r--drivers/watchdog/sa1100_wdt.c50
-rw-r--r--drivers/watchdog/sb_wdog.c92
-rw-r--r--drivers/watchdog/sbc60xxwdt.c223
-rw-r--r--drivers/watchdog/sbc7240_wdt.c70
-rw-r--r--drivers/watchdog/sbc8360.c46
-rw-r--r--drivers/watchdog/sbc_epx_c3.c22
-rw-r--r--drivers/watchdog/sc1200wdt.c39
-rw-r--r--drivers/watchdog/sc520_wdt.c162
-rw-r--r--drivers/watchdog/scx200_wdt.c65
-rw-r--r--drivers/watchdog/shwdt.c139
-rw-r--r--drivers/watchdog/smsc37b787_wdt.c448
-rw-r--r--drivers/watchdog/softdog.c87
-rw-r--r--drivers/watchdog/txx9wdt.c37
-rw-r--r--drivers/watchdog/w83627hf_wdt.c190
-rw-r--r--drivers/watchdog/w83697hf_wdt.c189
-rw-r--r--drivers/watchdog/w83877f_wdt.c199
-rw-r--r--drivers/watchdog/w83977f_wdt.c239
-rw-r--r--drivers/watchdog/wafer5823wdt.c132
-rw-r--r--drivers/watchdog/wd501p.h2
-rw-r--r--drivers/watchdog/wdrtas.c105
-rw-r--r--drivers/watchdog/wdt.c4
-rw-r--r--drivers/watchdog/wdt285.c33
-rw-r--r--drivers/watchdog/wdt977.c162
-rw-r--r--drivers/watchdog/wdt_pci.c8
705 files changed, 64679 insertions, 15241 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index a280ab3d0833..2735bde73475 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/
57obj-$(CONFIG_PARIDE) += block/paride/ 57obj-$(CONFIG_PARIDE) += block/paride/
58obj-$(CONFIG_TC) += tc/ 58obj-$(CONFIG_TC) += tc/
59obj-$(CONFIG_USB) += usb/ 59obj-$(CONFIG_USB) += usb/
60obj-$(CONFIG_USB_MUSB_HDRC) += usb/musb/
60obj-$(CONFIG_PCI) += usb/ 61obj-$(CONFIG_PCI) += usb/
61obj-$(CONFIG_USB_GADGET) += usb/gadget/ 62obj-$(CONFIG_USB_GADGET) += usb/gadget/
62obj-$(CONFIG_SERIO) += input/serio/ 63obj-$(CONFIG_SERIO) += input/serio/
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index bb7c51f712bd..7d2edf143f16 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -563,9 +563,6 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
563 */ 563 */
564static int handle_eject_request(struct dock_station *ds, u32 event) 564static int handle_eject_request(struct dock_station *ds, u32 event)
565{ 565{
566 if (!dock_present(ds))
567 return -ENODEV;
568
569 if (dock_in_progress(ds)) 566 if (dock_in_progress(ds))
570 return -EBUSY; 567 return -EBUSY;
571 568
@@ -573,8 +570,16 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
573 * here we need to generate the undock 570 * here we need to generate the undock
574 * event prior to actually doing the undock 571 * event prior to actually doing the undock
575 * so that the device struct still exists. 572 * so that the device struct still exists.
573 * Also, even send the dock event if the
574 * device is not present anymore
576 */ 575 */
577 dock_event(ds, event, UNDOCK_EVENT); 576 dock_event(ds, event, UNDOCK_EVENT);
577
578 if (!dock_present(ds)) {
579 complete_undock(ds);
580 return -ENODEV;
581 }
582
578 hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); 583 hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
579 undock(ds); 584 undock(ds);
580 eject_dock(ds); 585 eject_dock(ds);
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 5622aee996b2..13593f9f2197 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -110,6 +110,31 @@ static struct acpi_ec {
110 u8 handlers_installed; 110 u8 handlers_installed;
111} *boot_ec, *first_ec; 111} *boot_ec, *first_ec;
112 112
113/*
114 * Some Asus system have exchanged ECDT data/command IO addresses.
115 */
116static int print_ecdt_error(const struct dmi_system_id *id)
117{
118 printk(KERN_NOTICE PREFIX "%s detected - "
119 "ECDT has exchanged control/data I/O address\n",
120 id->ident);
121 return 0;
122}
123
124static struct dmi_system_id __cpuinitdata ec_dmi_table[] = {
125 {
126 print_ecdt_error, "Asus L4R", {
127 DMI_MATCH(DMI_BIOS_VERSION, "1008.006"),
128 DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),
129 DMI_MATCH(DMI_BOARD_NAME, "L4R") }, NULL},
130 {
131 print_ecdt_error, "Asus M6R", {
132 DMI_MATCH(DMI_BIOS_VERSION, "0207"),
133 DMI_MATCH(DMI_PRODUCT_NAME, "M6R"),
134 DMI_MATCH(DMI_BOARD_NAME, "M6R") }, NULL},
135 {},
136};
137
113/* -------------------------------------------------------------------------- 138/* --------------------------------------------------------------------------
114 Transaction Management 139 Transaction Management
115 -------------------------------------------------------------------------- */ 140 -------------------------------------------------------------------------- */
@@ -196,6 +221,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
196 return 0; 221 return 0;
197 msleep(1); 222 msleep(1);
198 } 223 }
224 if (acpi_ec_check_status(ec,event))
225 return 0;
199 } 226 }
200 pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", 227 pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
201 acpi_ec_read_status(ec), 228 acpi_ec_read_status(ec),
@@ -911,6 +938,15 @@ int __init acpi_ec_ecdt_probe(void)
911 pr_info(PREFIX "EC description table is found, configuring boot EC\n"); 938 pr_info(PREFIX "EC description table is found, configuring boot EC\n");
912 boot_ec->command_addr = ecdt_ptr->control.address; 939 boot_ec->command_addr = ecdt_ptr->control.address;
913 boot_ec->data_addr = ecdt_ptr->data.address; 940 boot_ec->data_addr = ecdt_ptr->data.address;
941 if (dmi_check_system(ec_dmi_table)) {
942 /*
943 * If the board falls into ec_dmi_table, it means
944 * that ECDT table gives the incorrect command/status
945 * & data I/O address. Just fix it.
946 */
947 boot_ec->data_addr = ecdt_ptr->control.address;
948 boot_ec->command_addr = ecdt_ptr->data.address;
949 }
914 boot_ec->gpe = ecdt_ptr->gpe; 950 boot_ec->gpe = ecdt_ptr->gpe;
915 boot_ec->handle = ACPI_ROOT_OBJECT; 951 boot_ec->handle = ACPI_ROOT_OBJECT;
916 acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); 952 acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 2a32c843cb4a..8892b9824fae 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -479,5 +479,8 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
479 479
480 acpi_tb_set_table_loaded_flag(table_index, FALSE); 480 acpi_tb_set_table_loaded_flag(table_index, FALSE);
481 481
482 /* Table unloaded, remove a reference to the ddb_handle object */
483
484 acpi_ut_remove_reference(ddb_handle);
482 return_ACPI_STATUS(AE_OK); 485 return_ACPI_STATUS(AE_OK);
483} 486}
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index 549db42f16cf..bd5773878009 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -56,13 +56,14 @@ ACPI_MODULE_NAME("nsnames")
56 * Size - Size of the pathname 56 * Size - Size of the pathname
57 * *name_buffer - Where to return the pathname 57 * *name_buffer - Where to return the pathname
58 * 58 *
59 * RETURN: Places the pathname into the name_buffer, in external format 59 * RETURN: Status
60 * Places the pathname into the name_buffer, in external format
60 * (name segments separated by path separators) 61 * (name segments separated by path separators)
61 * 62 *
62 * DESCRIPTION: Generate a full pathaname 63 * DESCRIPTION: Generate a full pathaname
63 * 64 *
64 ******************************************************************************/ 65 ******************************************************************************/
65void 66acpi_status
66acpi_ns_build_external_path(struct acpi_namespace_node *node, 67acpi_ns_build_external_path(struct acpi_namespace_node *node,
67 acpi_size size, char *name_buffer) 68 acpi_size size, char *name_buffer)
68{ 69{
@@ -77,7 +78,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
77 if (index < ACPI_NAME_SIZE) { 78 if (index < ACPI_NAME_SIZE) {
78 name_buffer[0] = AML_ROOT_PREFIX; 79 name_buffer[0] = AML_ROOT_PREFIX;
79 name_buffer[1] = 0; 80 name_buffer[1] = 0;
80 return; 81 return (AE_OK);
81 } 82 }
82 83
83 /* Store terminator byte, then build name backwards */ 84 /* Store terminator byte, then build name backwards */
@@ -105,11 +106,13 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
105 106
106 if (index != 0) { 107 if (index != 0) {
107 ACPI_ERROR((AE_INFO, 108 ACPI_ERROR((AE_INFO,
108 "Could not construct pathname; index=%X, size=%X, Path=%s", 109 "Could not construct external pathname; index=%X, size=%X, Path=%s",
109 (u32) index, (u32) size, &name_buffer[size])); 110 (u32) index, (u32) size, &name_buffer[size]));
111
112 return (AE_BAD_PARAMETER);
110 } 113 }
111 114
112 return; 115 return (AE_OK);
113} 116}
114 117
115#ifdef ACPI_DEBUG_OUTPUT 118#ifdef ACPI_DEBUG_OUTPUT
@@ -129,6 +132,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
129 132
130char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) 133char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
131{ 134{
135 acpi_status status;
132 char *name_buffer; 136 char *name_buffer;
133 acpi_size size; 137 acpi_size size;
134 138
@@ -138,8 +142,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
138 142
139 size = acpi_ns_get_pathname_length(node); 143 size = acpi_ns_get_pathname_length(node);
140 if (!size) { 144 if (!size) {
141 ACPI_ERROR((AE_INFO, "Invalid node failure")); 145 return (NULL);
142 return_PTR(NULL);
143 } 146 }
144 147
145 /* Allocate a buffer to be returned to caller */ 148 /* Allocate a buffer to be returned to caller */
@@ -152,7 +155,11 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
152 155
153 /* Build the path in the allocated buffer */ 156 /* Build the path in the allocated buffer */
154 157
155 acpi_ns_build_external_path(node, size, name_buffer); 158 status = acpi_ns_build_external_path(node, size, name_buffer);
159 if (ACPI_FAILURE(status)) {
160 return (NULL);
161 }
162
156 return_PTR(name_buffer); 163 return_PTR(name_buffer);
157} 164}
158#endif 165#endif
@@ -186,7 +193,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
186 while (next_node && (next_node != acpi_gbl_root_node)) { 193 while (next_node && (next_node != acpi_gbl_root_node)) {
187 if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) { 194 if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) {
188 ACPI_ERROR((AE_INFO, 195 ACPI_ERROR((AE_INFO,
189 "Invalid NS Node (%p) while traversing path", 196 "Invalid Namespace Node (%p) while traversing namespace",
190 next_node)); 197 next_node));
191 return 0; 198 return 0;
192 } 199 }
@@ -234,8 +241,7 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
234 241
235 required_size = acpi_ns_get_pathname_length(node); 242 required_size = acpi_ns_get_pathname_length(node);
236 if (!required_size) { 243 if (!required_size) {
237 ACPI_ERROR((AE_INFO, "Invalid node failure")); 244 return_ACPI_STATUS(AE_BAD_PARAMETER);
238 return_ACPI_STATUS(AE_ERROR);
239 } 245 }
240 246
241 /* Validate/Allocate/Clear caller buffer */ 247 /* Validate/Allocate/Clear caller buffer */
@@ -247,7 +253,11 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
247 253
248 /* Build the path in the caller buffer */ 254 /* Build the path in the caller buffer */
249 255
250 acpi_ns_build_external_path(node, required_size, buffer->pointer); 256 status =
257 acpi_ns_build_external_path(node, required_size, buffer->pointer);
258 if (ACPI_FAILURE(status)) {
259 return_ACPI_STATUS(status);
260 }
251 261
252 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n", 262 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
253 (char *)buffer->pointer, (u32) required_size)); 263 (char *)buffer->pointer, (u32) required_size));
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 89f3b2abfdc7..cf47805a7448 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -849,7 +849,7 @@ static int __init acpi_irq_penalty_update(char *str, int used)
849 if (irq < 0) 849 if (irq < 0)
850 continue; 850 continue;
851 851
852 if (irq >= ACPI_MAX_IRQS) 852 if (irq >= ARRAY_SIZE(acpi_irq_penalty))
853 continue; 853 continue;
854 854
855 if (used) 855 if (used)
@@ -872,10 +872,12 @@ static int __init acpi_irq_penalty_update(char *str, int used)
872 */ 872 */
873void acpi_penalize_isa_irq(int irq, int active) 873void acpi_penalize_isa_irq(int irq, int active)
874{ 874{
875 if (active) 875 if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
876 acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED; 876 if (active)
877 else 877 acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
878 acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; 878 else
879 acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
880 }
879} 881}
880 882
881/* 883/*
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e36422a7122c..d3f0a62efcc1 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -123,7 +123,7 @@ struct acpi_processor_errata errata __read_mostly;
123static int set_no_mwait(const struct dmi_system_id *id) 123static int set_no_mwait(const struct dmi_system_id *id)
124{ 124{
125 printk(KERN_NOTICE PREFIX "%s detected - " 125 printk(KERN_NOTICE PREFIX "%s detected - "
126 "disable mwait for CPU C-stetes\n", id->ident); 126 "disabling mwait for CPU C-states\n", id->ident);
127 idle_nomwait = 1; 127 idle_nomwait = 1;
128 return 0; 128 return 0;
129} 129}
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 283c08f5f4d4..cf5b1b7b684f 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -41,7 +41,6 @@
41#include <linux/pm_qos_params.h> 41#include <linux/pm_qos_params.h>
42#include <linux/clockchips.h> 42#include <linux/clockchips.h>
43#include <linux/cpuidle.h> 43#include <linux/cpuidle.h>
44#include <linux/cpuidle.h>
45 44
46/* 45/*
47 * Include the apic definitions for x86 to have the APIC timer related defines 46 * Include the apic definitions for x86 to have the APIC timer related defines
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 0133af49cf06..80e32093e977 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -70,7 +70,7 @@ static DEFINE_MUTEX(performance_mutex);
70 * 0 -> cpufreq low level drivers initialized -> consider _PPC values 70 * 0 -> cpufreq low level drivers initialized -> consider _PPC values
71 * 1 -> ignore _PPC totally -> forced by user through boot param 71 * 1 -> ignore _PPC totally -> forced by user through boot param
72 */ 72 */
73static unsigned int ignore_ppc = -1; 73static int ignore_ppc = -1;
74module_param(ignore_ppc, uint, 0644); 74module_param(ignore_ppc, uint, 0644);
75MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ 75MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
76 "limited by BIOS, this should help"); 76 "limited by BIOS, this should help");
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index f61ebc679e66..d9063ea414e3 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -587,6 +587,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
587 } else { 587 } else {
588 temp_size_needed += 588 temp_size_needed +=
589 acpi_ns_get_pathname_length((*sub_object_list)->reference.node); 589 acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
590 if (!temp_size_needed) {
591 return_ACPI_STATUS(AE_BAD_PARAMETER);
592 }
590 } 593 }
591 } else { 594 } else {
592 /* 595 /*
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index e7bf34a7b1d2..7dcb67e0b215 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -242,10 +242,12 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
242{ 242{
243 acpi_status status = AE_OK; 243 acpi_status status = AE_OK;
244 244
245 if (!required_length) { 245 /* Parameter validation */
246 WARN_ON(1); 246
247 return AE_ERROR; 247 if (!buffer || !required_length) {
248 return (AE_BAD_PARAMETER);
248 } 249 }
250
249 switch (buffer->length) { 251 switch (buffer->length) {
250 case ACPI_NO_BUFFER: 252 case ACPI_NO_BUFFER:
251 253
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index c5c791a575c9..42609d3a8aa9 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -135,6 +135,10 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
135 obj_pointer = object->package.elements; 135 obj_pointer = object->package.elements;
136 break; 136 break;
137 137
138 /*
139 * These objects have a possible list of notify handlers.
140 * Device object also may have a GPE block.
141 */
138 case ACPI_TYPE_DEVICE: 142 case ACPI_TYPE_DEVICE:
139 143
140 if (object->device.gpe_block) { 144 if (object->device.gpe_block) {
@@ -142,9 +146,14 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
142 gpe_block); 146 gpe_block);
143 } 147 }
144 148
145 /* Walk the handler list for this device */ 149 /*lint -fallthrough */
150
151 case ACPI_TYPE_PROCESSOR:
152 case ACPI_TYPE_THERMAL:
153
154 /* Walk the notify handler list for this object */
146 155
147 handler_desc = object->device.handler; 156 handler_desc = object->common_notify.handler;
148 while (handler_desc) { 157 while (handler_desc) {
149 next_desc = handler_desc->address_space.next; 158 next_desc = handler_desc->address_space.next;
150 acpi_ut_remove_reference(handler_desc); 159 acpi_ut_remove_reference(handler_desc);
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index e25484495e65..916eff399eb3 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -425,6 +425,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
425 acpi_size * obj_length) 425 acpi_size * obj_length)
426{ 426{
427 acpi_size length; 427 acpi_size length;
428 acpi_size size;
428 acpi_status status = AE_OK; 429 acpi_status status = AE_OK;
429 430
430 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object); 431 ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
@@ -484,10 +485,14 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
484 * Get the actual length of the full pathname to this object. 485 * Get the actual length of the full pathname to this object.
485 * The reference will be converted to the pathname to the object 486 * The reference will be converted to the pathname to the object
486 */ 487 */
487 length += 488 size =
488 ACPI_ROUND_UP_TO_NATIVE_WORD 489 acpi_ns_get_pathname_length(internal_object->
489 (acpi_ns_get_pathname_length 490 reference.node);
490 (internal_object->reference.node)); 491 if (!size) {
492 return_ACPI_STATUS(AE_BAD_PARAMETER);
493 }
494
495 length += ACPI_ROUND_UP_TO_NATIVE_WORD(size);
491 break; 496 break;
492 497
493 default: 498 default:
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c
index c33b1c6e93b1..cfe2c833474d 100644
--- a/drivers/acpi/wmi.c
+++ b/drivers/acpi/wmi.c
@@ -347,7 +347,7 @@ struct acpi_buffer *out)
347 strcpy(method, "WQ"); 347 strcpy(method, "WQ");
348 strncat(method, block->object_id, 2); 348 strncat(method, block->object_id, 2);
349 349
350 status = acpi_evaluate_object(handle, method, NULL, out); 350 status = acpi_evaluate_object(handle, method, &input, out);
351 351
352 /* 352 /*
353 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if 353 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c
index 82fb6e273169..ab61095093b9 100644
--- a/drivers/ata/pata_at32.c
+++ b/drivers/ata/pata_at32.c
@@ -24,8 +24,8 @@
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/io.h> 25#include <linux/io.h>
26 26
27#include <asm/arch/board.h> 27#include <mach/board.h>
28#include <asm/arch/smc.h> 28#include <mach/smc.h>
29 29
30#define DRV_NAME "pata_at32" 30#define DRV_NAME "pata_at32"
31#define DRV_VERSION "0.0.3" 31#define DRV_VERSION "0.0.3"
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 0ce0c279aabf..b73116ef9236 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -159,7 +159,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
159static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); 159static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
160 160
161static int cciss_revalidate(struct gendisk *disk); 161static int cciss_revalidate(struct gendisk *disk);
162static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); 162static int rebuild_lun_table(ctlr_info_t *h, int first_time);
163static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, 163static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
164 int clear_all); 164 int clear_all);
165 165
@@ -171,7 +171,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
171 int withirq, sector_t total_size, 171 int withirq, sector_t total_size,
172 unsigned int block_size, InquiryData_struct *inq_buff, 172 unsigned int block_size, InquiryData_struct *inq_buff,
173 drive_info_struct *drv); 173 drive_info_struct *drv);
174static void cciss_getgeometry(int cntl_num);
175static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, 174static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *,
176 __u32); 175 __u32);
177static void start_io(ctlr_info_t *h); 176static void start_io(ctlr_info_t *h);
@@ -929,8 +928,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
929 return 0; 928 return 0;
930 } 929 }
931 930
931 case CCISS_DEREGDISK:
932 case CCISS_REGNEWD:
932 case CCISS_REVALIDVOLS: 933 case CCISS_REVALIDVOLS:
933 return rebuild_lun_table(host, NULL); 934 return rebuild_lun_table(host, 0);
934 935
935 case CCISS_GETLUNINFO:{ 936 case CCISS_GETLUNINFO:{
936 LogvolInfo_struct luninfo; 937 LogvolInfo_struct luninfo;
@@ -943,12 +944,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
943 return -EFAULT; 944 return -EFAULT;
944 return 0; 945 return 0;
945 } 946 }
946 case CCISS_DEREGDISK:
947 return rebuild_lun_table(host, disk);
948
949 case CCISS_REGNEWD:
950 return rebuild_lun_table(host, NULL);
951
952 case CCISS_PASSTHRU: 947 case CCISS_PASSTHRU:
953 { 948 {
954 IOCTL_Command_struct iocommand; 949 IOCTL_Command_struct iocommand;
@@ -1134,7 +1129,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
1134 if (ioc->Request.Type.Direction == XFER_WRITE) { 1129 if (ioc->Request.Type.Direction == XFER_WRITE) {
1135 if (copy_from_user 1130 if (copy_from_user
1136 (buff[sg_used], data_ptr, sz)) { 1131 (buff[sg_used], data_ptr, sz)) {
1137 status = -ENOMEM; 1132 status = -EFAULT;
1138 goto cleanup1; 1133 goto cleanup1;
1139 } 1134 }
1140 } else { 1135 } else {
@@ -1330,15 +1325,84 @@ static void cciss_softirq_done(struct request *rq)
1330 spin_unlock_irqrestore(&h->lock, flags); 1325 spin_unlock_irqrestore(&h->lock, flags);
1331} 1326}
1332 1327
1328/* This function gets the serial number of a logical drive via
1329 * inquiry page 0x83. Serial no. is 16 bytes. If the serial
1330 * number cannot be had, for whatever reason, 16 bytes of 0xff
1331 * are returned instead.
1332 */
1333static void cciss_get_serial_no(int ctlr, int logvol, int withirq,
1334 unsigned char *serial_no, int buflen)
1335{
1336#define PAGE_83_INQ_BYTES 64
1337 int rc;
1338 unsigned char *buf;
1339
1340 if (buflen > 16)
1341 buflen = 16;
1342 memset(serial_no, 0xff, buflen);
1343 buf = kzalloc(PAGE_83_INQ_BYTES, GFP_KERNEL);
1344 if (!buf)
1345 return;
1346 memset(serial_no, 0, buflen);
1347 if (withirq)
1348 rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf,
1349 PAGE_83_INQ_BYTES, 1, logvol, 0x83, TYPE_CMD);
1350 else
1351 rc = sendcmd(CISS_INQUIRY, ctlr, buf,
1352 PAGE_83_INQ_BYTES, 1, logvol, 0x83, NULL, TYPE_CMD);
1353 if (rc == IO_OK)
1354 memcpy(serial_no, &buf[8], buflen);
1355 kfree(buf);
1356 return;
1357}
1358
1359static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
1360 int drv_index)
1361{
1362 disk->queue = blk_init_queue(do_cciss_request, &h->lock);
1363 sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index);
1364 disk->major = h->major;
1365 disk->first_minor = drv_index << NWD_SHIFT;
1366 disk->fops = &cciss_fops;
1367 disk->private_data = &h->drv[drv_index];
1368
1369 /* Set up queue information */
1370 blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
1371
1372 /* This is a hardware imposed limit. */
1373 blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES);
1374
1375 /* This is a limit in the driver and could be eliminated. */
1376 blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES);
1377
1378 blk_queue_max_sectors(disk->queue, h->cciss_max_sectors);
1379
1380 blk_queue_softirq_done(disk->queue, cciss_softirq_done);
1381
1382 disk->queue->queuedata = h;
1383
1384 blk_queue_hardsect_size(disk->queue,
1385 h->drv[drv_index].block_size);
1386
1387 /* Make sure all queue data is written out before */
1388 /* setting h->drv[drv_index].queue, as setting this */
1389 /* allows the interrupt handler to start the queue */
1390 wmb();
1391 h->drv[drv_index].queue = disk->queue;
1392 add_disk(disk);
1393}
1394
1333/* This function will check the usage_count of the drive to be updated/added. 1395/* This function will check the usage_count of the drive to be updated/added.
1334 * If the usage_count is zero then the drive information will be updated and 1396 * If the usage_count is zero and it is a heretofore unknown drive, or,
1335 * the disk will be re-registered with the kernel. If not then it will be 1397 * the drive's capacity, geometry, or serial number has changed,
1336 * left alone for the next reboot. The exception to this is disk 0 which 1398 * then the drive information will be updated and the disk will be
1337 * will always be left registered with the kernel since it is also the 1399 * re-registered with the kernel. If these conditions don't hold,
1338 * controller node. Any changes to disk 0 will show up on the next 1400 * then it will be left alone for the next reboot. The exception to this
1339 * reboot. 1401 * is disk 0 which will always be left registered with the kernel since it
1402 * is also the controller node. Any changes to disk 0 will show up on
1403 * the next reboot.
1340 */ 1404 */
1341static void cciss_update_drive_info(int ctlr, int drv_index) 1405static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
1342{ 1406{
1343 ctlr_info_t *h = hba[ctlr]; 1407 ctlr_info_t *h = hba[ctlr];
1344 struct gendisk *disk; 1408 struct gendisk *disk;
@@ -1347,16 +1411,81 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
1347 sector_t total_size; 1411 sector_t total_size;
1348 unsigned long flags = 0; 1412 unsigned long flags = 0;
1349 int ret = 0; 1413 int ret = 0;
1414 drive_info_struct *drvinfo;
1415 int was_only_controller_node;
1416
1417 /* Get information about the disk and modify the driver structure */
1418 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
1419 drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL);
1420 if (inq_buff == NULL || drvinfo == NULL)
1421 goto mem_msg;
1422
1423 /* See if we're trying to update the "controller node"
1424 * this will happen the when the first logical drive gets
1425 * created by ACU.
1426 */
1427 was_only_controller_node = (drv_index == 0 &&
1428 h->drv[0].raid_level == -1);
1350 1429
1351 /* if the disk already exists then deregister it before proceeding */ 1430 /* testing to see if 16-byte CDBs are already being used */
1352 if (h->drv[drv_index].raid_level != -1) { 1431 if (h->cciss_read == CCISS_READ_16) {
1432 cciss_read_capacity_16(h->ctlr, drv_index, 1,
1433 &total_size, &block_size);
1434
1435 } else {
1436 cciss_read_capacity(ctlr, drv_index, 1,
1437 &total_size, &block_size);
1438
1439 /* if read_capacity returns all F's this volume is >2TB */
1440 /* in size so we switch to 16-byte CDB's for all */
1441 /* read/write ops */
1442 if (total_size == 0xFFFFFFFFULL) {
1443 cciss_read_capacity_16(ctlr, drv_index, 1,
1444 &total_size, &block_size);
1445 h->cciss_read = CCISS_READ_16;
1446 h->cciss_write = CCISS_WRITE_16;
1447 } else {
1448 h->cciss_read = CCISS_READ_10;
1449 h->cciss_write = CCISS_WRITE_10;
1450 }
1451 }
1452
1453 cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
1454 inq_buff, drvinfo);
1455 drvinfo->block_size = block_size;
1456 drvinfo->nr_blocks = total_size + 1;
1457
1458 cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
1459 sizeof(drvinfo->serial_no));
1460
1461 /* Is it the same disk we already know, and nothing's changed? */
1462 if (h->drv[drv_index].raid_level != -1 &&
1463 ((memcmp(drvinfo->serial_no,
1464 h->drv[drv_index].serial_no, 16) == 0) &&
1465 drvinfo->block_size == h->drv[drv_index].block_size &&
1466 drvinfo->nr_blocks == h->drv[drv_index].nr_blocks &&
1467 drvinfo->heads == h->drv[drv_index].heads &&
1468 drvinfo->sectors == h->drv[drv_index].sectors &&
1469 drvinfo->cylinders == h->drv[drv_index].cylinders))
1470 /* The disk is unchanged, nothing to update */
1471 goto freeret;
1472
1473 /* If we get here it's not the same disk, or something's changed,
1474 * so we need to * deregister it, and re-register it, if it's not
1475 * in use.
1476 * If the disk already exists then deregister it before proceeding
1477 * (unless it's the first disk (for the controller node).
1478 */
1479 if (h->drv[drv_index].raid_level != -1 && drv_index != 0) {
1480 printk(KERN_WARNING "disk %d has changed.\n", drv_index);
1353 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); 1481 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1354 h->drv[drv_index].busy_configuring = 1; 1482 h->drv[drv_index].busy_configuring = 1;
1355 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); 1483 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1356 1484
1357 /* deregister_disk sets h->drv[drv_index].queue = NULL */ 1485 /* deregister_disk sets h->drv[drv_index].queue = NULL
1358 /* which keeps the interrupt handler from starting */ 1486 * which keeps the interrupt handler from starting
1359 /* the queue. */ 1487 * the queue.
1488 */
1360 ret = deregister_disk(h->gendisk[drv_index], 1489 ret = deregister_disk(h->gendisk[drv_index],
1361 &h->drv[drv_index], 0); 1490 &h->drv[drv_index], 0);
1362 h->drv[drv_index].busy_configuring = 0; 1491 h->drv[drv_index].busy_configuring = 0;
@@ -1364,81 +1493,37 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
1364 1493
1365 /* If the disk is in use return */ 1494 /* If the disk is in use return */
1366 if (ret) 1495 if (ret)
1367 return; 1496 goto freeret;
1368 1497
1369 /* Get information about the disk and modify the driver structure */ 1498 /* Save the new information from cciss_geometry_inquiry
1370 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); 1499 * and serial number inquiry.
1371 if (inq_buff == NULL) 1500 */
1372 goto mem_msg; 1501 h->drv[drv_index].block_size = drvinfo->block_size;
1373 1502 h->drv[drv_index].nr_blocks = drvinfo->nr_blocks;
1374 /* testing to see if 16-byte CDBs are already being used */ 1503 h->drv[drv_index].heads = drvinfo->heads;
1375 if (h->cciss_read == CCISS_READ_16) { 1504 h->drv[drv_index].sectors = drvinfo->sectors;
1376 cciss_read_capacity_16(h->ctlr, drv_index, 1, 1505 h->drv[drv_index].cylinders = drvinfo->cylinders;
1377 &total_size, &block_size); 1506 h->drv[drv_index].raid_level = drvinfo->raid_level;
1378 goto geo_inq; 1507 memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16);
1379 }
1380
1381 cciss_read_capacity(ctlr, drv_index, 1,
1382 &total_size, &block_size);
1383
1384 /* if read_capacity returns all F's this volume is >2TB in size */
1385 /* so we switch to 16-byte CDB's for all read/write ops */
1386 if (total_size == 0xFFFFFFFFULL) {
1387 cciss_read_capacity_16(ctlr, drv_index, 1,
1388 &total_size, &block_size);
1389 h->cciss_read = CCISS_READ_16;
1390 h->cciss_write = CCISS_WRITE_16;
1391 } else {
1392 h->cciss_read = CCISS_READ_10;
1393 h->cciss_write = CCISS_WRITE_10;
1394 }
1395geo_inq:
1396 cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
1397 inq_buff, &h->drv[drv_index]);
1398 1508
1399 ++h->num_luns; 1509 ++h->num_luns;
1400 disk = h->gendisk[drv_index]; 1510 disk = h->gendisk[drv_index];
1401 set_capacity(disk, h->drv[drv_index].nr_blocks); 1511 set_capacity(disk, h->drv[drv_index].nr_blocks);
1402 1512
1403 /* if it's the controller it's already added */ 1513 /* If it's not disk 0 (drv_index != 0)
1404 if (drv_index) { 1514 * or if it was disk 0, but there was previously
1405 disk->queue = blk_init_queue(do_cciss_request, &h->lock); 1515 * no actual corresponding configured logical drive
1406 sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); 1516 * (raid_leve == -1) then we want to update the
1407 disk->major = h->major; 1517 * logical drive's information.
1408 disk->first_minor = drv_index << NWD_SHIFT; 1518 */
1409 disk->fops = &cciss_fops; 1519 if (drv_index || first_time)
1410 disk->private_data = &h->drv[drv_index]; 1520 cciss_add_disk(h, disk, drv_index);
1411
1412 /* Set up queue information */
1413 blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask);
1414
1415 /* This is a hardware imposed limit. */
1416 blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES);
1417
1418 /* This is a limit in the driver and could be eliminated. */
1419 blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES);
1420
1421 blk_queue_max_sectors(disk->queue, h->cciss_max_sectors);
1422
1423 blk_queue_softirq_done(disk->queue, cciss_softirq_done);
1424
1425 disk->queue->queuedata = hba[ctlr];
1426
1427 blk_queue_hardsect_size(disk->queue,
1428 hba[ctlr]->drv[drv_index].block_size);
1429
1430 /* Make sure all queue data is written out before */
1431 /* setting h->drv[drv_index].queue, as setting this */
1432 /* allows the interrupt handler to start the queue */
1433 wmb();
1434 h->drv[drv_index].queue = disk->queue;
1435 add_disk(disk);
1436 }
1437 1521
1438 freeret: 1522freeret:
1439 kfree(inq_buff); 1523 kfree(inq_buff);
1524 kfree(drvinfo);
1440 return; 1525 return;
1441 mem_msg: 1526mem_msg:
1442 printk(KERN_ERR "cciss: out of memory\n"); 1527 printk(KERN_ERR "cciss: out of memory\n");
1443 goto freeret; 1528 goto freeret;
1444} 1529}
@@ -1448,21 +1533,91 @@ geo_inq:
1448 * where new drives will be added. If the index to be returned is greater 1533 * where new drives will be added. If the index to be returned is greater
1449 * than the highest_lun index for the controller then highest_lun is set 1534 * than the highest_lun index for the controller then highest_lun is set
1450 * to this new index. If there are no available indexes then -1 is returned. 1535 * to this new index. If there are no available indexes then -1 is returned.
1536 * "controller_node" is used to know if this is a real logical drive, or just
1537 * the controller node, which determines if this counts towards highest_lun.
1451 */ 1538 */
1452static int cciss_find_free_drive_index(int ctlr) 1539static int cciss_find_free_drive_index(int ctlr, int controller_node)
1453{ 1540{
1454 int i; 1541 int i;
1455 1542
1456 for (i = 0; i < CISS_MAX_LUN; i++) { 1543 for (i = 0; i < CISS_MAX_LUN; i++) {
1457 if (hba[ctlr]->drv[i].raid_level == -1) { 1544 if (hba[ctlr]->drv[i].raid_level == -1) {
1458 if (i > hba[ctlr]->highest_lun) 1545 if (i > hba[ctlr]->highest_lun)
1459 hba[ctlr]->highest_lun = i; 1546 if (!controller_node)
1547 hba[ctlr]->highest_lun = i;
1460 return i; 1548 return i;
1461 } 1549 }
1462 } 1550 }
1463 return -1; 1551 return -1;
1464} 1552}
1465 1553
1554/* cciss_add_gendisk finds a free hba[]->drv structure
1555 * and allocates a gendisk if needed, and sets the lunid
1556 * in the drvinfo structure. It returns the index into
1557 * the ->drv[] array, or -1 if none are free.
1558 * is_controller_node indicates whether highest_lun should
1559 * count this disk, or if it's only being added to provide
1560 * a means to talk to the controller in case no logical
1561 * drives have yet been configured.
1562 */
1563static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
1564{
1565 int drv_index;
1566
1567 drv_index = cciss_find_free_drive_index(h->ctlr, controller_node);
1568 if (drv_index == -1)
1569 return -1;
1570 /*Check if the gendisk needs to be allocated */
1571 if (!h->gendisk[drv_index]) {
1572 h->gendisk[drv_index] =
1573 alloc_disk(1 << NWD_SHIFT);
1574 if (!h->gendisk[drv_index]) {
1575 printk(KERN_ERR "cciss%d: could not "
1576 "allocate a new disk %d\n",
1577 h->ctlr, drv_index);
1578 return -1;
1579 }
1580 }
1581 h->drv[drv_index].LunID = lunid;
1582
1583 /* Don't need to mark this busy because nobody */
1584 /* else knows about this disk yet to contend */
1585 /* for access to it. */
1586 h->drv[drv_index].busy_configuring = 0;
1587 wmb();
1588 return drv_index;
1589}
1590
1591/* This is for the special case of a controller which
1592 * has no logical drives. In this case, we still need
1593 * to register a disk so the controller can be accessed
1594 * by the Array Config Utility.
1595 */
1596static void cciss_add_controller_node(ctlr_info_t *h)
1597{
1598 struct gendisk *disk;
1599 int drv_index;
1600
1601 if (h->gendisk[0] != NULL) /* already did this? Then bail. */
1602 return;
1603
1604 drv_index = cciss_add_gendisk(h, 0, 1);
1605 if (drv_index == -1) {
1606 printk(KERN_WARNING "cciss%d: could not "
1607 "add disk 0.\n", h->ctlr);
1608 return;
1609 }
1610 h->drv[drv_index].block_size = 512;
1611 h->drv[drv_index].nr_blocks = 0;
1612 h->drv[drv_index].heads = 0;
1613 h->drv[drv_index].sectors = 0;
1614 h->drv[drv_index].cylinders = 0;
1615 h->drv[drv_index].raid_level = -1;
1616 memset(h->drv[drv_index].serial_no, 0, 16);
1617 disk = h->gendisk[drv_index];
1618 cciss_add_disk(h, disk, drv_index);
1619}
1620
1466/* This function will add and remove logical drives from the Logical 1621/* This function will add and remove logical drives from the Logical
1467 * drive array of the controller and maintain persistency of ordering 1622 * drive array of the controller and maintain persistency of ordering
1468 * so that mount points are preserved until the next reboot. This allows 1623 * so that mount points are preserved until the next reboot. This allows
@@ -1470,15 +1625,12 @@ static int cciss_find_free_drive_index(int ctlr)
1470 * without a re-ordering of those drives. 1625 * without a re-ordering of those drives.
1471 * INPUT 1626 * INPUT
1472 * h = The controller to perform the operations on 1627 * h = The controller to perform the operations on
1473 * del_disk = The disk to remove if specified. If the value given
1474 * is NULL then no disk is removed.
1475 */ 1628 */
1476static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) 1629static int rebuild_lun_table(ctlr_info_t *h, int first_time)
1477{ 1630{
1478 int ctlr = h->ctlr; 1631 int ctlr = h->ctlr;
1479 int num_luns; 1632 int num_luns;
1480 ReportLunData_struct *ld_buff = NULL; 1633 ReportLunData_struct *ld_buff = NULL;
1481 drive_info_struct *drv = NULL;
1482 int return_code; 1634 int return_code;
1483 int listlength = 0; 1635 int listlength = 0;
1484 int i; 1636 int i;
@@ -1487,6 +1639,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
1487 __u32 lunid = 0; 1639 __u32 lunid = 0;
1488 unsigned long flags; 1640 unsigned long flags;
1489 1641
1642 if (!capable(CAP_SYS_RAWIO))
1643 return -EPERM;
1644
1490 /* Set busy_configuring flag for this operation */ 1645 /* Set busy_configuring flag for this operation */
1491 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); 1646 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1492 if (h->busy_configuring) { 1647 if (h->busy_configuring) {
@@ -1494,100 +1649,100 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
1494 return -EBUSY; 1649 return -EBUSY;
1495 } 1650 }
1496 h->busy_configuring = 1; 1651 h->busy_configuring = 1;
1652 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1497 1653
1498 /* if del_disk is NULL then we are being called to add a new disk 1654 ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
1499 * and update the logical drive table. If it is not NULL then 1655 if (ld_buff == NULL)
1500 * we will check if the disk is in use or not. 1656 goto mem_msg;
1501 */
1502 if (del_disk != NULL) {
1503 drv = get_drv(del_disk);
1504 drv->busy_configuring = 1;
1505 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1506 return_code = deregister_disk(del_disk, drv, 1);
1507 drv->busy_configuring = 0;
1508 h->busy_configuring = 0;
1509 return return_code;
1510 } else {
1511 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1512 if (!capable(CAP_SYS_RAWIO))
1513 return -EPERM;
1514 1657
1515 ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); 1658 return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
1516 if (ld_buff == NULL) 1659 sizeof(ReportLunData_struct), 0,
1517 goto mem_msg; 1660 0, 0, TYPE_CMD);
1518
1519 return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
1520 sizeof(ReportLunData_struct), 0,
1521 0, 0, TYPE_CMD);
1522
1523 if (return_code == IO_OK) {
1524 listlength =
1525 be32_to_cpu(*(__be32 *) ld_buff->LUNListLength);
1526 } else { /* reading number of logical volumes failed */
1527 printk(KERN_WARNING "cciss: report logical volume"
1528 " command failed\n");
1529 listlength = 0;
1530 goto freeret;
1531 }
1532 1661
1533 num_luns = listlength / 8; /* 8 bytes per entry */ 1662 if (return_code == IO_OK)
1534 if (num_luns > CISS_MAX_LUN) { 1663 listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength);
1535 num_luns = CISS_MAX_LUN; 1664 else { /* reading number of logical volumes failed */
1536 printk(KERN_WARNING "cciss: more luns configured" 1665 printk(KERN_WARNING "cciss: report logical volume"
1537 " on controller than can be handled by" 1666 " command failed\n");
1538 " this driver.\n"); 1667 listlength = 0;
1668 goto freeret;
1669 }
1670
1671 num_luns = listlength / 8; /* 8 bytes per entry */
1672 if (num_luns > CISS_MAX_LUN) {
1673 num_luns = CISS_MAX_LUN;
1674 printk(KERN_WARNING "cciss: more luns configured"
1675 " on controller than can be handled by"
1676 " this driver.\n");
1677 }
1678
1679 if (num_luns == 0)
1680 cciss_add_controller_node(h);
1681
1682 /* Compare controller drive array to driver's drive array
1683 * to see if any drives are missing on the controller due
1684 * to action of Array Config Utility (user deletes drive)
1685 * and deregister logical drives which have disappeared.
1686 */
1687 for (i = 0; i <= h->highest_lun; i++) {
1688 int j;
1689 drv_found = 0;
1690 for (j = 0; j < num_luns; j++) {
1691 memcpy(&lunid, &ld_buff->LUN[j][0], 4);
1692 lunid = le32_to_cpu(lunid);
1693 if (h->drv[i].LunID == lunid) {
1694 drv_found = 1;
1695 break;
1696 }
1539 } 1697 }
1698 if (!drv_found) {
1699 /* Deregister it from the OS, it's gone. */
1700 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1701 h->drv[i].busy_configuring = 1;
1702 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1703 return_code = deregister_disk(h->gendisk[i],
1704 &h->drv[i], 1);
1705 h->drv[i].busy_configuring = 0;
1706 }
1707 }
1708
1709 /* Compare controller drive array to driver's drive array.
1710 * Check for updates in the drive information and any new drives
1711 * on the controller due to ACU adding logical drives, or changing
1712 * a logical drive's size, etc. Reregister any new/changed drives
1713 */
1714 for (i = 0; i < num_luns; i++) {
1715 int j;
1540 1716
1541 /* Compare controller drive array to drivers drive array. 1717 drv_found = 0;
1542 * Check for updates in the drive information and any new drives 1718
1543 * on the controller. 1719 memcpy(&lunid, &ld_buff->LUN[i][0], 4);
1720 lunid = le32_to_cpu(lunid);
1721
1722 /* Find if the LUN is already in the drive array
1723 * of the driver. If so then update its info
1724 * if not in use. If it does not exist then find
1725 * the first free index and add it.
1544 */ 1726 */
1545 for (i = 0; i < num_luns; i++) { 1727 for (j = 0; j <= h->highest_lun; j++) {
1546 int j; 1728 if (h->drv[j].raid_level != -1 &&
1547 1729 h->drv[j].LunID == lunid) {
1548 drv_found = 0; 1730 drv_index = j;
1549 1731 drv_found = 1;
1550 lunid = (0xff & 1732 break;
1551 (unsigned int)(ld_buff->LUN[i][3])) << 24;
1552 lunid |= (0xff &
1553 (unsigned int)(ld_buff->LUN[i][2])) << 16;
1554 lunid |= (0xff &
1555 (unsigned int)(ld_buff->LUN[i][1])) << 8;
1556 lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
1557
1558 /* Find if the LUN is already in the drive array
1559 * of the controller. If so then update its info
1560 * if not is use. If it does not exist then find
1561 * the first free index and add it.
1562 */
1563 for (j = 0; j <= h->highest_lun; j++) {
1564 if (h->drv[j].LunID == lunid) {
1565 drv_index = j;
1566 drv_found = 1;
1567 }
1568 } 1733 }
1734 }
1569 1735
1570 /* check if the drive was found already in the array */ 1736 /* check if the drive was found already in the array */
1571 if (!drv_found) { 1737 if (!drv_found) {
1572 drv_index = cciss_find_free_drive_index(ctlr); 1738 drv_index = cciss_add_gendisk(h, lunid, 0);
1573 if (drv_index == -1) 1739 if (drv_index == -1)
1574 goto freeret; 1740 goto freeret;
1575 1741 }
1576 /*Check if the gendisk needs to be allocated */ 1742 cciss_update_drive_info(ctlr, drv_index, first_time);
1577 if (!h->gendisk[drv_index]){ 1743 } /* end for */
1578 h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT);
1579 if (!h->gendisk[drv_index]){
1580 printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index);
1581 goto mem_msg;
1582 }
1583 }
1584 }
1585 h->drv[drv_index].LunID = lunid;
1586 cciss_update_drive_info(ctlr, drv_index);
1587 } /* end for */
1588 } /* end else */
1589 1744
1590 freeret: 1745freeret:
1591 kfree(ld_buff); 1746 kfree(ld_buff);
1592 h->busy_configuring = 0; 1747 h->busy_configuring = 0;
1593 /* We return -1 here to tell the ACU that we have registered/updated 1748 /* We return -1 here to tell the ACU that we have registered/updated
@@ -1595,8 +1750,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
1595 * additional times. 1750 * additional times.
1596 */ 1751 */
1597 return -1; 1752 return -1;
1598 mem_msg: 1753mem_msg:
1599 printk(KERN_ERR "cciss: out of memory\n"); 1754 printk(KERN_ERR "cciss: out of memory\n");
1755 h->busy_configuring = 0;
1600 goto freeret; 1756 goto freeret;
1601} 1757}
1602 1758
@@ -1652,15 +1808,15 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
1652 * other than disk 0 we will call put_disk. We do not 1808 * other than disk 0 we will call put_disk. We do not
1653 * do this for disk 0 as we need it to be able to 1809 * do this for disk 0 as we need it to be able to
1654 * configure the controller. 1810 * configure the controller.
1655 */ 1811 */
1656 if (clear_all){ 1812 if (clear_all){
1657 /* This isn't pretty, but we need to find the 1813 /* This isn't pretty, but we need to find the
1658 * disk in our array and NULL our the pointer. 1814 * disk in our array and NULL our the pointer.
1659 * This is so that we will call alloc_disk if 1815 * This is so that we will call alloc_disk if
1660 * this index is used again later. 1816 * this index is used again later.
1661 */ 1817 */
1662 for (i=0; i < CISS_MAX_LUN; i++){ 1818 for (i=0; i < CISS_MAX_LUN; i++){
1663 if(h->gendisk[i] == disk){ 1819 if (h->gendisk[i] == disk) {
1664 h->gendisk[i] = NULL; 1820 h->gendisk[i] = NULL;
1665 break; 1821 break;
1666 } 1822 }
@@ -1688,7 +1844,7 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
1688 if (drv == h->drv + h->highest_lun) { 1844 if (drv == h->drv + h->highest_lun) {
1689 /* if so, find the new hightest lun */ 1845 /* if so, find the new hightest lun */
1690 int i, newhighest = -1; 1846 int i, newhighest = -1;
1691 for (i = 0; i < h->highest_lun; i++) { 1847 for (i = 0; i <= h->highest_lun; i++) {
1692 /* if the disk has size > 0, it is available */ 1848 /* if the disk has size > 0, it is available */
1693 if (h->drv[i].heads) 1849 if (h->drv[i].heads)
1694 newhighest = i; 1850 newhighest = i;
@@ -3199,136 +3355,9 @@ err_out_free_res:
3199 return err; 3355 return err;
3200} 3356}
3201 3357
3202/* 3358/* Function to find the first free pointer into our hba[] array
3203 * Gets information about the local volumes attached to the controller. 3359 * Returns -1 if no free entries are left.
3204 */ 3360 */
3205static void cciss_getgeometry(int cntl_num)
3206{
3207 ReportLunData_struct *ld_buff;
3208 InquiryData_struct *inq_buff;
3209 int return_code;
3210 int i;
3211 int listlength = 0;
3212 __u32 lunid = 0;
3213 unsigned block_size;
3214 sector_t total_size;
3215
3216 ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
3217 if (ld_buff == NULL) {
3218 printk(KERN_ERR "cciss: out of memory\n");
3219 return;
3220 }
3221 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
3222 if (inq_buff == NULL) {
3223 printk(KERN_ERR "cciss: out of memory\n");
3224 kfree(ld_buff);
3225 return;
3226 }
3227 /* Get the firmware version */
3228 return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
3229 sizeof(InquiryData_struct), 0, 0, 0, NULL,
3230 TYPE_CMD);
3231 if (return_code == IO_OK) {
3232 hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
3233 hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33];
3234 hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34];
3235 hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35];
3236 } else { /* send command failed */
3237
3238 printk(KERN_WARNING "cciss: unable to determine firmware"
3239 " version of controller\n");
3240 }
3241 /* Get the number of logical volumes */
3242 return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff,
3243 sizeof(ReportLunData_struct), 0, 0, 0, NULL,
3244 TYPE_CMD);
3245
3246 if (return_code == IO_OK) {
3247#ifdef CCISS_DEBUG
3248 printk("LUN Data\n--------------------------\n");
3249#endif /* CCISS_DEBUG */
3250
3251 listlength |=
3252 (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
3253 listlength |=
3254 (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
3255 listlength |=
3256 (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;
3257 listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
3258 } else { /* reading number of logical volumes failed */
3259
3260 printk(KERN_WARNING "cciss: report logical volume"
3261 " command failed\n");
3262 listlength = 0;
3263 }
3264 hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry
3265 if (hba[cntl_num]->num_luns > CISS_MAX_LUN) {
3266 printk(KERN_ERR
3267 "ciss: only %d number of logical volumes supported\n",
3268 CISS_MAX_LUN);
3269 hba[cntl_num]->num_luns = CISS_MAX_LUN;
3270 }
3271#ifdef CCISS_DEBUG
3272 printk(KERN_DEBUG "Length = %x %x %x %x = %d\n",
3273 ld_buff->LUNListLength[0], ld_buff->LUNListLength[1],
3274 ld_buff->LUNListLength[2], ld_buff->LUNListLength[3],
3275 hba[cntl_num]->num_luns);
3276#endif /* CCISS_DEBUG */
3277
3278 hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1;
3279 for (i = 0; i < CISS_MAX_LUN; i++) {
3280 if (i < hba[cntl_num]->num_luns) {
3281 lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3]))
3282 << 24;
3283 lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2]))
3284 << 16;
3285 lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1]))
3286 << 8;
3287 lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
3288
3289 hba[cntl_num]->drv[i].LunID = lunid;
3290
3291#ifdef CCISS_DEBUG
3292 printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i,
3293 ld_buff->LUN[i][0], ld_buff->LUN[i][1],
3294 ld_buff->LUN[i][2], ld_buff->LUN[i][3],
3295 hba[cntl_num]->drv[i].LunID);
3296#endif /* CCISS_DEBUG */
3297
3298 /* testing to see if 16-byte CDBs are already being used */
3299 if(hba[cntl_num]->cciss_read == CCISS_READ_16) {
3300 cciss_read_capacity_16(cntl_num, i, 0,
3301 &total_size, &block_size);
3302 goto geo_inq;
3303 }
3304 cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size);
3305
3306 /* If read_capacity returns all F's the logical is >2TB */
3307 /* so we switch to 16-byte CDBs for all read/write ops */
3308 if(total_size == 0xFFFFFFFFULL) {
3309 cciss_read_capacity_16(cntl_num, i, 0,
3310 &total_size, &block_size);
3311 hba[cntl_num]->cciss_read = CCISS_READ_16;
3312 hba[cntl_num]->cciss_write = CCISS_WRITE_16;
3313 } else {
3314 hba[cntl_num]->cciss_read = CCISS_READ_10;
3315 hba[cntl_num]->cciss_write = CCISS_WRITE_10;
3316 }
3317geo_inq:
3318 cciss_geometry_inquiry(cntl_num, i, 0, total_size,
3319 block_size, inq_buff,
3320 &hba[cntl_num]->drv[i]);
3321 } else {
3322 /* initialize raid_level to indicate a free space */
3323 hba[cntl_num]->drv[i].raid_level = -1;
3324 }
3325 }
3326 kfree(ld_buff);
3327 kfree(inq_buff);
3328}
3329
3330/* Function to find the first free pointer into our hba[] array */
3331/* Returns -1 if no free entries are left. */
3332static int alloc_cciss_hba(void) 3361static int alloc_cciss_hba(void)
3333{ 3362{
3334 int i; 3363 int i;
@@ -3340,11 +3369,6 @@ static int alloc_cciss_hba(void)
3340 p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); 3369 p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
3341 if (!p) 3370 if (!p)
3342 goto Enomem; 3371 goto Enomem;
3343 p->gendisk[0] = alloc_disk(1 << NWD_SHIFT);
3344 if (!p->gendisk[0]) {
3345 kfree(p);
3346 goto Enomem;
3347 }
3348 hba[i] = p; 3372 hba[i] = p;
3349 return i; 3373 return i;
3350 } 3374 }
@@ -3472,11 +3496,13 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3472 ((hba[i]->nr_cmds + BITS_PER_LONG - 3496 ((hba[i]->nr_cmds + BITS_PER_LONG -
3473 1) / BITS_PER_LONG) * sizeof(unsigned long)); 3497 1) / BITS_PER_LONG) * sizeof(unsigned long));
3474 3498
3475#ifdef CCISS_DEBUG 3499 hba[i]->num_luns = 0;
3476 printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); 3500 hba[i]->highest_lun = -1;
3477#endif /* CCISS_DEBUG */ 3501 for (j = 0; j < CISS_MAX_LUN; j++) {
3478 3502 hba[i]->drv[j].raid_level = -1;
3479 cciss_getgeometry(i); 3503 hba[i]->drv[j].queue = NULL;
3504 hba[i]->gendisk[j] = NULL;
3505 }
3480 3506
3481 cciss_scsi_setup(i); 3507 cciss_scsi_setup(i);
3482 3508
@@ -3489,76 +3515,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3489 3515
3490 hba[i]->busy_initializing = 0; 3516 hba[i]->busy_initializing = 0;
3491 3517
3492 do { 3518 rebuild_lun_table(hba[i], 1);
3493 drive_info_struct *drv = &(hba[i]->drv[j]);
3494 struct gendisk *disk = hba[i]->gendisk[j];
3495 struct request_queue *q;
3496
3497 /* Check if the disk was allocated already */
3498 if (!disk){
3499 hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT);
3500 disk = hba[i]->gendisk[j];
3501 }
3502
3503 /* Check that the disk was able to be allocated */
3504 if (!disk) {
3505 printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j);
3506 goto clean4;
3507 }
3508
3509 q = blk_init_queue(do_cciss_request, &hba[i]->lock);
3510 if (!q) {
3511 printk(KERN_ERR
3512 "cciss: unable to allocate queue for disk %d\n",
3513 j);
3514 goto clean4;
3515 }
3516 drv->queue = q;
3517
3518 blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
3519
3520 /* This is a hardware imposed limit. */
3521 blk_queue_max_hw_segments(q, MAXSGENTRIES);
3522
3523 /* This is a limit in the driver and could be eliminated. */
3524 blk_queue_max_phys_segments(q, MAXSGENTRIES);
3525
3526 blk_queue_max_sectors(q, hba[i]->cciss_max_sectors);
3527
3528 blk_queue_softirq_done(q, cciss_softirq_done);
3529
3530 q->queuedata = hba[i];
3531 sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
3532 disk->major = hba[i]->major;
3533 disk->first_minor = j << NWD_SHIFT;
3534 disk->fops = &cciss_fops;
3535 disk->queue = q;
3536 disk->private_data = drv;
3537 disk->driverfs_dev = &pdev->dev;
3538 /* we must register the controller even if no disks exist */
3539 /* this is for the online array utilities */
3540 if (!drv->heads && j)
3541 continue;
3542 blk_queue_hardsect_size(q, drv->block_size);
3543 set_capacity(disk, drv->nr_blocks);
3544 j++;
3545 } while (j <= hba[i]->highest_lun);
3546
3547 /* Make sure all queue data is written out before */
3548 /* interrupt handler, triggered by add_disk, */
3549 /* is allowed to start them. */
3550 wmb();
3551
3552 for (j = 0; j <= hba[i]->highest_lun; j++)
3553 add_disk(hba[i]->gendisk[j]);
3554
3555 /* we must register the controller even if no disks exist */
3556 if (hba[i]->highest_lun == -1)
3557 add_disk(hba[i]->gendisk[0]);
3558
3559 return 1; 3519 return 1;
3560 3520
3561 clean4: 3521clean4:
3562#ifdef CONFIG_CISS_SCSI_TAPE 3522#ifdef CONFIG_CISS_SCSI_TAPE
3563 kfree(hba[i]->scsi_rejects.complete); 3523 kfree(hba[i]->scsi_rejects.complete);
3564#endif 3524#endif
@@ -3573,9 +3533,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3573 hba[i]->errinfo_pool, 3533 hba[i]->errinfo_pool,
3574 hba[i]->errinfo_pool_dhandle); 3534 hba[i]->errinfo_pool_dhandle);
3575 free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); 3535 free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]);
3576 clean2: 3536clean2:
3577 unregister_blkdev(hba[i]->major, hba[i]->devname); 3537 unregister_blkdev(hba[i]->major, hba[i]->devname);
3578 clean1: 3538clean1:
3579 hba[i]->busy_initializing = 0; 3539 hba[i]->busy_initializing = 0;
3580 /* cleanup any queues that may have been initialized */ 3540 /* cleanup any queues that may have been initialized */
3581 for (j=0; j <= hba[i]->highest_lun; j++){ 3541 for (j=0; j <= hba[i]->highest_lun; j++){
@@ -3654,7 +3614,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
3654 } 3614 }
3655 } 3615 }
3656 3616
3617#ifdef CONFIG_CISS_SCSI_TAPE
3657 cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ 3618 cciss_unregister_scsi(i); /* unhook from SCSI subsystem */
3619#endif
3658 3620
3659 cciss_shutdown(pdev); 3621 cciss_shutdown(pdev);
3660 3622
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index b70988dd33ec..24a7efa993ab 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -39,6 +39,8 @@ typedef struct _drive_info_struct
39 *to prevent it from being opened or it's queue 39 *to prevent it from being opened or it's queue
40 *from being started. 40 *from being started.
41 */ 41 */
42 __u8 serial_no[16]; /* from inquiry page 0x83, */
43 /* not necc. null terminated. */
42} drive_info_struct; 44} drive_info_struct;
43 45
44#ifdef CONFIG_CISS_SCSI_TAPE 46#ifdef CONFIG_CISS_SCSI_TAPE
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index e4bf9a11ca0d..e1233aabda77 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -358,23 +358,68 @@ find_bus_target_lun(int ctlr, int *bus, int *target, int *lun)
358 } 358 }
359 return (!found); 359 return (!found);
360} 360}
361struct scsi2map {
362 char scsi3addr[8];
363 int bus, target, lun;
364};
361 365
362static int 366static int
363cciss_scsi_add_entry(int ctlr, int hostno, 367cciss_scsi_add_entry(int ctlr, int hostno,
364 unsigned char *scsi3addr, int devtype) 368 unsigned char *scsi3addr, int devtype,
369 struct scsi2map *added, int *nadded)
365{ 370{
366 /* assumes hba[ctlr]->scsi_ctlr->lock is held */ 371 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
367 int n = ccissscsi[ctlr].ndevices; 372 int n = ccissscsi[ctlr].ndevices;
368 struct cciss_scsi_dev_t *sd; 373 struct cciss_scsi_dev_t *sd;
374 int i, bus, target, lun;
375 unsigned char addr1[8], addr2[8];
369 376
370 if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { 377 if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
371 printk("cciss%d: Too many devices, " 378 printk("cciss%d: Too many devices, "
372 "some will be inaccessible.\n", ctlr); 379 "some will be inaccessible.\n", ctlr);
373 return -1; 380 return -1;
374 } 381 }
382
383 bus = target = -1;
384 lun = 0;
385 /* Is this device a non-zero lun of a multi-lun device */
386 /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */
387 if (scsi3addr[4] != 0) {
388 /* Search through our list and find the device which */
389 /* has the same 8 byte LUN address, excepting byte 4. */
390 /* Assign the same bus and target for this new LUN. */
391 /* Use the logical unit number from the firmware. */
392 memcpy(addr1, scsi3addr, 8);
393 addr1[4] = 0;
394 for (i = 0; i < n; i++) {
395 sd = &ccissscsi[ctlr].dev[i];
396 memcpy(addr2, sd->scsi3addr, 8);
397 addr2[4] = 0;
398 /* differ only in byte 4? */
399 if (memcmp(addr1, addr2, 8) == 0) {
400 bus = sd->bus;
401 target = sd->target;
402 lun = scsi3addr[4];
403 break;
404 }
405 }
406 }
407
375 sd = &ccissscsi[ctlr].dev[n]; 408 sd = &ccissscsi[ctlr].dev[n];
376 if (find_bus_target_lun(ctlr, &sd->bus, &sd->target, &sd->lun) != 0) 409 if (lun == 0) {
377 return -1; 410 if (find_bus_target_lun(ctlr,
411 &sd->bus, &sd->target, &sd->lun) != 0)
412 return -1;
413 } else {
414 sd->bus = bus;
415 sd->target = target;
416 sd->lun = lun;
417 }
418 added[*nadded].bus = sd->bus;
419 added[*nadded].target = sd->target;
420 added[*nadded].lun = sd->lun;
421 (*nadded)++;
422
378 memcpy(&sd->scsi3addr[0], scsi3addr, 8); 423 memcpy(&sd->scsi3addr[0], scsi3addr, 8);
379 sd->devtype = devtype; 424 sd->devtype = devtype;
380 ccissscsi[ctlr].ndevices++; 425 ccissscsi[ctlr].ndevices++;
@@ -390,7 +435,8 @@ cciss_scsi_add_entry(int ctlr, int hostno,
390} 435}
391 436
392static void 437static void
393cciss_scsi_remove_entry(int ctlr, int hostno, int entry) 438cciss_scsi_remove_entry(int ctlr, int hostno, int entry,
439 struct scsi2map *removed, int *nremoved)
394{ 440{
395 /* assumes hba[ctlr]->scsi_ctlr->lock is held */ 441 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
396 int i; 442 int i;
@@ -398,6 +444,10 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry)
398 444
399 if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; 445 if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return;
400 sd = ccissscsi[ctlr].dev[entry]; 446 sd = ccissscsi[ctlr].dev[entry];
447 removed[*nremoved].bus = sd.bus;
448 removed[*nremoved].target = sd.target;
449 removed[*nremoved].lun = sd.lun;
450 (*nremoved)++;
401 for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) 451 for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++)
402 ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; 452 ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1];
403 ccissscsi[ctlr].ndevices--; 453 ccissscsi[ctlr].ndevices--;
@@ -417,6 +467,26 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry)
417 (a)[1] == (b)[1] && \ 467 (a)[1] == (b)[1] && \
418 (a)[0] == (b)[0]) 468 (a)[0] == (b)[0])
419 469
470static void fixup_botched_add(int ctlr, char *scsi3addr)
471{
472 /* called when scsi_add_device fails in order to re-adjust */
473 /* ccissscsi[] to match the mid layer's view. */
474 unsigned long flags;
475 int i, j;
476 CPQ_TAPE_LOCK(ctlr, flags);
477 for (i = 0; i < ccissscsi[ctlr].ndevices; i++) {
478 if (memcmp(scsi3addr,
479 ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) {
480 for (j = i; j < ccissscsi[ctlr].ndevices-1; j++)
481 ccissscsi[ctlr].dev[j] =
482 ccissscsi[ctlr].dev[j+1];
483 ccissscsi[ctlr].ndevices--;
484 break;
485 }
486 }
487 CPQ_TAPE_UNLOCK(ctlr, flags);
488}
489
420static int 490static int
421adjust_cciss_scsi_table(int ctlr, int hostno, 491adjust_cciss_scsi_table(int ctlr, int hostno,
422 struct cciss_scsi_dev_t sd[], int nsds) 492 struct cciss_scsi_dev_t sd[], int nsds)
@@ -429,13 +499,33 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
429 int i,j, found, changes=0; 499 int i,j, found, changes=0;
430 struct cciss_scsi_dev_t *csd; 500 struct cciss_scsi_dev_t *csd;
431 unsigned long flags; 501 unsigned long flags;
502 struct scsi2map *added, *removed;
503 int nadded, nremoved;
504 struct Scsi_Host *sh = NULL;
505
506 added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA,
507 GFP_KERNEL);
508 removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA,
509 GFP_KERNEL);
510
511 if (!added || !removed) {
512 printk(KERN_WARNING "cciss%d: Out of memory in "
513 "adjust_cciss_scsi_table\n", ctlr);
514 goto free_and_out;
515 }
432 516
433 CPQ_TAPE_LOCK(ctlr, flags); 517 CPQ_TAPE_LOCK(ctlr, flags);
434 518
519 if (hostno != -1) /* if it's not the first time... */
520 sh = ((struct cciss_scsi_adapter_data_t *)
521 hba[ctlr]->scsi_ctlr)->scsi_host;
522
435 /* find any devices in ccissscsi[] that are not in 523 /* find any devices in ccissscsi[] that are not in
436 sd[] and remove them from ccissscsi[] */ 524 sd[] and remove them from ccissscsi[] */
437 525
438 i = 0; 526 i = 0;
527 nremoved = 0;
528 nadded = 0;
439 while(i<ccissscsi[ctlr].ndevices) { 529 while(i<ccissscsi[ctlr].ndevices) {
440 csd = &ccissscsi[ctlr].dev[i]; 530 csd = &ccissscsi[ctlr].dev[i];
441 found=0; 531 found=0;
@@ -455,8 +545,9 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
455 /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", 545 /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
456 ctlr, scsi_device_type(csd->devtype), hostno, 546 ctlr, scsi_device_type(csd->devtype), hostno,
457 csd->bus, csd->target, csd->lun); */ 547 csd->bus, csd->target, csd->lun); */
458 cciss_scsi_remove_entry(ctlr, hostno, i); 548 cciss_scsi_remove_entry(ctlr, hostno, i,
459 /* note, i not incremented */ 549 removed, &nremoved);
550 /* remove ^^^, hence i not incremented */
460 } 551 }
461 else if (found == 1) { /* device is different kind */ 552 else if (found == 1) { /* device is different kind */
462 changes++; 553 changes++;
@@ -464,8 +555,15 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
464 "(device type now %s).\n", 555 "(device type now %s).\n",
465 ctlr, hostno, csd->bus, csd->target, csd->lun, 556 ctlr, hostno, csd->bus, csd->target, csd->lun,
466 scsi_device_type(csd->devtype)); 557 scsi_device_type(csd->devtype));
558 cciss_scsi_remove_entry(ctlr, hostno, i,
559 removed, &nremoved);
560 /* remove ^^^, hence i not incremented */
561 if (cciss_scsi_add_entry(ctlr, hostno,
562 &sd[j].scsi3addr[0], sd[j].devtype,
563 added, &nadded) != 0)
564 /* we just removed one, so add can't fail. */
565 BUG();
467 csd->devtype = sd[j].devtype; 566 csd->devtype = sd[j].devtype;
468 i++; /* so just move along. */
469 } else /* device is same as it ever was, */ 567 } else /* device is same as it ever was, */
470 i++; /* so just move along. */ 568 i++; /* so just move along. */
471 } 569 }
@@ -489,7 +587,9 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
489 if (!found) { 587 if (!found) {
490 changes++; 588 changes++;
491 if (cciss_scsi_add_entry(ctlr, hostno, 589 if (cciss_scsi_add_entry(ctlr, hostno,
492 &sd[i].scsi3addr[0], sd[i].devtype) != 0) 590
591 &sd[i].scsi3addr[0], sd[i].devtype,
592 added, &nadded) != 0)
493 break; 593 break;
494 } else if (found == 1) { 594 } else if (found == 1) {
495 /* should never happen... */ 595 /* should never happen... */
@@ -501,9 +601,50 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
501 } 601 }
502 CPQ_TAPE_UNLOCK(ctlr, flags); 602 CPQ_TAPE_UNLOCK(ctlr, flags);
503 603
504 if (!changes) 604 /* Don't notify scsi mid layer of any changes the first time through */
505 printk("cciss%d: No device changes detected.\n", ctlr); 605 /* (or if there are no changes) scsi_scan_host will do it later the */
606 /* first time through. */
607 if (hostno == -1 || !changes)
608 goto free_and_out;
609
610 /* Notify scsi mid layer of any removed devices */
611 for (i = 0; i < nremoved; i++) {
612 struct scsi_device *sdev =
613 scsi_device_lookup(sh, removed[i].bus,
614 removed[i].target, removed[i].lun);
615 if (sdev != NULL) {
616 scsi_remove_device(sdev);
617 scsi_device_put(sdev);
618 } else {
619 /* We don't expect to get here. */
620 /* future cmds to this device will get selection */
621 /* timeout as if the device was gone. */
622 printk(KERN_WARNING "cciss%d: didn't find "
623 "c%db%dt%dl%d\n for removal.",
624 ctlr, hostno, removed[i].bus,
625 removed[i].target, removed[i].lun);
626 }
627 }
628
629 /* Notify scsi mid layer of any added devices */
630 for (i = 0; i < nadded; i++) {
631 int rc;
632 rc = scsi_add_device(sh, added[i].bus,
633 added[i].target, added[i].lun);
634 if (rc == 0)
635 continue;
636 printk(KERN_WARNING "cciss%d: scsi_add_device "
637 "c%db%dt%dl%d failed, device not added.\n",
638 ctlr, hostno,
639 added[i].bus, added[i].target, added[i].lun);
640 /* now we have to remove it from ccissscsi, */
641 /* since it didn't get added to scsi mid layer */
642 fixup_botched_add(ctlr, added[i].scsi3addr);
643 }
506 644
645free_and_out:
646 kfree(added);
647 kfree(removed);
507 return 0; 648 return 0;
508} 649}
509 650
@@ -1355,32 +1496,6 @@ cciss_unregister_scsi(int ctlr)
1355} 1496}
1356 1497
1357static int 1498static int
1358cciss_register_scsi(int ctlr)
1359{
1360 unsigned long flags;
1361
1362 CPQ_TAPE_LOCK(ctlr, flags);
1363
1364 /* Since this is really a block driver, the SCSI core may not be
1365 initialized at init time, in which case, calling scsi_register_host
1366 would hang. Instead, we do it later, via /proc filesystem
1367 and rc scripts, when we know SCSI core is good to go. */
1368
1369 /* Only register if SCSI devices are detected. */
1370 if (ccissscsi[ctlr].ndevices != 0) {
1371 ((struct cciss_scsi_adapter_data_t *)
1372 hba[ctlr]->scsi_ctlr)->registered = 1;
1373 CPQ_TAPE_UNLOCK(ctlr, flags);
1374 return cciss_scsi_detect(ctlr);
1375 }
1376 CPQ_TAPE_UNLOCK(ctlr, flags);
1377 printk(KERN_INFO
1378 "cciss%d: No appropriate SCSI device detected, "
1379 "SCSI subsystem not engaged.\n", ctlr);
1380 return 0;
1381}
1382
1383static int
1384cciss_engage_scsi(int ctlr) 1499cciss_engage_scsi(int ctlr)
1385{ 1500{
1386 struct cciss_scsi_adapter_data_t *sa; 1501 struct cciss_scsi_adapter_data_t *sa;
@@ -1391,15 +1506,15 @@ cciss_engage_scsi(int ctlr)
1391 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; 1506 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
1392 stk = &sa->cmd_stack; 1507 stk = &sa->cmd_stack;
1393 1508
1394 if (((struct cciss_scsi_adapter_data_t *) 1509 if (sa->registered) {
1395 hba[ctlr]->scsi_ctlr)->registered) {
1396 printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); 1510 printk("cciss%d: SCSI subsystem already engaged.\n", ctlr);
1397 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); 1511 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1398 return ENXIO; 1512 return ENXIO;
1399 } 1513 }
1514 sa->registered = 1;
1400 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); 1515 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1401 cciss_update_non_disk_devices(ctlr, -1); 1516 cciss_update_non_disk_devices(ctlr, -1);
1402 cciss_register_scsi(ctlr); 1517 cciss_scsi_detect(ctlr);
1403 return 0; 1518 return 0;
1404} 1519}
1405 1520
@@ -1493,7 +1608,5 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
1493/* If no tape support, then these become defined out of existence */ 1608/* If no tape support, then these become defined out of existence */
1494 1609
1495#define cciss_scsi_setup(cntl_num) 1610#define cciss_scsi_setup(cntl_num)
1496#define cciss_unregister_scsi(ctlr)
1497#define cciss_register_scsi(ctlr)
1498 1611
1499#endif /* CONFIG_CISS_SCSI_TAPE */ 1612#endif /* CONFIG_CISS_SCSI_TAPE */
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 9ae05c584234..3ca643cafccd 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -154,8 +154,8 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
154 return 0; 154 return 0;
155} 155}
156 156
157int blkif_ioctl(struct inode *inode, struct file *filep, 157static int blkif_ioctl(struct inode *inode, struct file *filep,
158 unsigned command, unsigned long argument) 158 unsigned command, unsigned long argument)
159{ 159{
160 struct blkfront_info *info = 160 struct blkfront_info *info =
161 inode->i_bdev->bd_disk->private_data; 161 inode->i_bdev->bd_disk->private_data;
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index a235ca787465..7cb4029a5375 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -3,8 +3,8 @@ menu "Bluetooth device drivers"
3 depends on BT 3 depends on BT
4 4
5config BT_HCIUSB 5config BT_HCIUSB
6 tristate "HCI USB driver" 6 tristate "HCI USB driver (old version)"
7 depends on USB 7 depends on USB && BT_HCIBTUSB=n
8 help 8 help
9 Bluetooth HCI USB driver. 9 Bluetooth HCI USB driver.
10 This driver is required if you want to use Bluetooth devices with 10 This driver is required if you want to use Bluetooth devices with
@@ -23,15 +23,13 @@ config BT_HCIUSB_SCO
23 Say Y here to compile support for SCO over HCI USB. 23 Say Y here to compile support for SCO over HCI USB.
24 24
25config BT_HCIBTUSB 25config BT_HCIBTUSB
26 tristate "HCI USB driver (alternate version)" 26 tristate "HCI USB driver"
27 depends on USB && EXPERIMENTAL && BT_HCIUSB=n 27 depends on USB
28 help 28 help
29 Bluetooth HCI USB driver. 29 Bluetooth HCI USB driver.
30 This driver is required if you want to use Bluetooth devices with 30 This driver is required if you want to use Bluetooth devices with
31 USB interface. 31 USB interface.
32 32
33 This driver is still experimental and has no SCO support.
34
35 Say Y here to compile support for Bluetooth USB devices into the 33 Say Y here to compile support for Bluetooth USB devices into the
36 kernel or say M to compile it as module (btusb). 34 kernel or say M to compile it as module (btusb).
37 35
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 8919ccf8274b..ee40201c7278 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -42,9 +42,7 @@
42#define BT_DBG(D...) 42#define BT_DBG(D...)
43#endif 43#endif
44 44
45#define VERSION "1.1" 45#define VERSION "1.2"
46
47static int ignore = 0;
48 46
49static struct usb_device_id bcm203x_table[] = { 47static struct usb_device_id bcm203x_table[] = {
50 /* Broadcom Blutonium (BCM2033) */ 48 /* Broadcom Blutonium (BCM2033) */
@@ -175,7 +173,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
175 173
176 BT_DBG("intf %p id %p", intf, id); 174 BT_DBG("intf %p id %p", intf, id);
177 175
178 if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0)) 176 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
179 return -ENODEV; 177 return -ENODEV;
180 178
181 data = kzalloc(sizeof(*data), GFP_KERNEL); 179 data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -300,9 +298,6 @@ static void __exit bcm203x_exit(void)
300module_init(bcm203x_init); 298module_init(bcm203x_init);
301module_exit(bcm203x_exit); 299module_exit(bcm203x_exit);
302 300
303module_param(ignore, bool, 0644);
304MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
305
306MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 301MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
307MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION); 302MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);
308MODULE_VERSION(VERSION); 303MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 0c211adbc063..90a094634630 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -43,9 +43,7 @@
43#define BT_DBG(D...) 43#define BT_DBG(D...)
44#endif 44#endif
45 45
46#define VERSION "1.1" 46#define VERSION "1.2"
47
48static int ignore = 0;
49 47
50static struct usb_driver bfusb_driver; 48static struct usb_driver bfusb_driver;
51 49
@@ -656,9 +654,6 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
656 654
657 BT_DBG("intf %p id %p", intf, id); 655 BT_DBG("intf %p id %p", intf, id);
658 656
659 if (ignore)
660 return -ENODEV;
661
662 /* Check number of endpoints */ 657 /* Check number of endpoints */
663 if (intf->cur_altsetting->desc.bNumEndpoints < 2) 658 if (intf->cur_altsetting->desc.bNumEndpoints < 2)
664 return -EIO; 659 return -EIO;
@@ -795,9 +790,6 @@ static void __exit bfusb_exit(void)
795module_init(bfusb_init); 790module_init(bfusb_init);
796module_exit(bfusb_exit); 791module_exit(bfusb_exit);
797 792
798module_param(ignore, bool, 0644);
799MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
800
801MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 793MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
802MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION); 794MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
803MODULE_VERSION(VERSION); 795MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 3b28658f5a1f..1e55a658e6ce 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -40,9 +40,7 @@
40#define BT_DBG(D...) 40#define BT_DBG(D...)
41#endif 41#endif
42 42
43#define VERSION "0.9" 43#define VERSION "0.10"
44
45static int ignore = 0;
46 44
47static struct usb_device_id bpa10x_table[] = { 45static struct usb_device_id bpa10x_table[] = {
48 /* Tektronix BPA 100/105 (Digianswer) */ 46 /* Tektronix BPA 100/105 (Digianswer) */
@@ -460,9 +458,6 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
460 458
461 BT_DBG("intf %p id %p", intf, id); 459 BT_DBG("intf %p id %p", intf, id);
462 460
463 if (ignore)
464 return -ENODEV;
465
466 if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 461 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
467 return -ENODEV; 462 return -ENODEV;
468 463
@@ -546,9 +541,6 @@ static void __exit bpa10x_exit(void)
546module_init(bpa10x_init); 541module_init(bpa10x_init);
547module_exit(bpa10x_exit); 542module_exit(bpa10x_exit);
548 543
549module_param(ignore, bool, 0644);
550MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
551
552MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 544MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
553MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION); 545MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION);
554MODULE_VERSION(VERSION); 546MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 593b7c595038..27058477cc8b 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -60,7 +60,7 @@
60/* ======================== Module parameters ======================== */ 60/* ======================== Module parameters ======================== */
61 61
62 62
63MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>"); 63MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
64MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card"); 64MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
65MODULE_LICENSE("GPL"); 65MODULE_LICENSE("GPL");
66MODULE_FIRMWARE("BT3CPCC.bin"); 66MODULE_FIRMWARE("BT3CPCC.bin");
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 12e108914f19..6a010681ecf3 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * Generic Bluetooth USB driver 3 * Generic Bluetooth USB driver
4 * 4 *
5 * Copyright (C) 2005-2007 Marcel Holtmann <marcel@holtmann.org> 5 * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
6 * 6 *
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -41,27 +41,135 @@
41#define BT_DBG(D...) 41#define BT_DBG(D...)
42#endif 42#endif
43 43
44#define VERSION "0.1" 44#define VERSION "0.3"
45
46static int ignore_dga;
47static int ignore_csr;
48static int ignore_sniffer;
49static int disable_scofix;
50static int force_scofix;
51static int reset;
52
53static struct usb_driver btusb_driver;
54
55#define BTUSB_IGNORE 0x01
56#define BTUSB_RESET 0x02
57#define BTUSB_DIGIANSWER 0x04
58#define BTUSB_CSR 0x08
59#define BTUSB_SNIFFER 0x10
60#define BTUSB_BCM92035 0x20
61#define BTUSB_BROKEN_ISOC 0x40
62#define BTUSB_WRONG_SCO_MTU 0x80
45 63
46static struct usb_device_id btusb_table[] = { 64static struct usb_device_id btusb_table[] = {
47 /* Generic Bluetooth USB device */ 65 /* Generic Bluetooth USB device */
48 { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, 66 { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
49 67
68 /* AVM BlueFRITZ! USB v2.0 */
69 { USB_DEVICE(0x057c, 0x3800) },
70
71 /* Bluetooth Ultraport Module from IBM */
72 { USB_DEVICE(0x04bf, 0x030a) },
73
74 /* ALPS Modules with non-standard id */
75 { USB_DEVICE(0x044e, 0x3001) },
76 { USB_DEVICE(0x044e, 0x3002) },
77
78 /* Ericsson with non-standard id */
79 { USB_DEVICE(0x0bdb, 0x1002) },
80
81 /* Canyon CN-BTU1 with HID interfaces */
82 { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_RESET },
83
50 { } /* Terminating entry */ 84 { } /* Terminating entry */
51}; 85};
52 86
53MODULE_DEVICE_TABLE(usb, btusb_table); 87MODULE_DEVICE_TABLE(usb, btusb_table);
54 88
55static struct usb_device_id blacklist_table[] = { 89static struct usb_device_id blacklist_table[] = {
90 /* CSR BlueCore devices */
91 { USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
92
93 /* Broadcom BCM2033 without firmware */
94 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
95
96 /* Broadcom BCM2035 */
97 { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
98 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
99
100 /* Broadcom BCM2045 */
101 { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
102 { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
103
104 /* Broadcom BCM2046 */
105 { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET },
106
107 /* IBM/Lenovo ThinkPad with Broadcom chip */
108 { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
109 { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
110
111 /* Targus ACB10US */
112 { USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET },
113
114 /* ANYCOM Bluetooth USB-200 and USB-250 */
115 { USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET },
116
117 /* HP laptop with Broadcom chip */
118 { USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
119
120 /* Dell laptop with Broadcom chip */
121 { USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
122
123 /* Dell Wireless 370 */
124 { USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
125
126 /* Dell Wireless 410 */
127 { USB_DEVICE(0x413c, 0x8152), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
128
129 /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
130 { USB_DEVICE(0x045e, 0x009c), .driver_info = BTUSB_RESET },
131
132 /* Kensington Bluetooth USB adapter */
133 { USB_DEVICE(0x047d, 0x105d), .driver_info = BTUSB_RESET },
134 { USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
135
136 /* ISSC Bluetooth Adapter v3.1 */
137 { USB_DEVICE(0x1131, 0x1001), .driver_info = BTUSB_RESET },
138
139 /* RTX Telecom based adapters with buggy SCO support */
140 { USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC },
141 { USB_DEVICE(0x0400, 0x080a), .driver_info = BTUSB_BROKEN_ISOC },
142
143 /* CONWISE Technology based adapters with buggy SCO support */
144 { USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC },
145
146 /* Belkin F8T012 and F8T013 devices */
147 { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
148 { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
149
150 /* Digianswer devices */
151 { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER },
152 { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
153
154 /* CSR BlueCore Bluetooth Sniffer */
155 { USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
156
157 /* Frontline ComProbe Bluetooth Sniffer */
158 { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
159
56 { } /* Terminating entry */ 160 { } /* Terminating entry */
57}; 161};
58 162
163#define BTUSB_MAX_ISOC_FRAMES 10
164
59#define BTUSB_INTR_RUNNING 0 165#define BTUSB_INTR_RUNNING 0
60#define BTUSB_BULK_RUNNING 1 166#define BTUSB_BULK_RUNNING 1
167#define BTUSB_ISOC_RUNNING 2
61 168
62struct btusb_data { 169struct btusb_data {
63 struct hci_dev *hdev; 170 struct hci_dev *hdev;
64 struct usb_device *udev; 171 struct usb_device *udev;
172 struct usb_interface *isoc;
65 173
66 spinlock_t lock; 174 spinlock_t lock;
67 175
@@ -72,10 +180,15 @@ struct btusb_data {
72 struct usb_anchor tx_anchor; 180 struct usb_anchor tx_anchor;
73 struct usb_anchor intr_anchor; 181 struct usb_anchor intr_anchor;
74 struct usb_anchor bulk_anchor; 182 struct usb_anchor bulk_anchor;
183 struct usb_anchor isoc_anchor;
75 184
76 struct usb_endpoint_descriptor *intr_ep; 185 struct usb_endpoint_descriptor *intr_ep;
77 struct usb_endpoint_descriptor *bulk_tx_ep; 186 struct usb_endpoint_descriptor *bulk_tx_ep;
78 struct usb_endpoint_descriptor *bulk_rx_ep; 187 struct usb_endpoint_descriptor *bulk_rx_ep;
188 struct usb_endpoint_descriptor *isoc_tx_ep;
189 struct usb_endpoint_descriptor *isoc_rx_ep;
190
191 int isoc_altsetting;
79}; 192};
80 193
81static void btusb_intr_complete(struct urb *urb) 194static void btusb_intr_complete(struct urb *urb)
@@ -91,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb)
91 return; 204 return;
92 205
93 if (urb->status == 0) { 206 if (urb->status == 0) {
207 hdev->stat.byte_rx += urb->actual_length;
208
94 if (hci_recv_fragment(hdev, HCI_EVENT_PKT, 209 if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
95 urb->transfer_buffer, 210 urb->transfer_buffer,
96 urb->actual_length) < 0) { 211 urb->actual_length) < 0) {
@@ -112,7 +227,7 @@ static void btusb_intr_complete(struct urb *urb)
112 } 227 }
113} 228}
114 229
115static inline int btusb_submit_intr_urb(struct hci_dev *hdev) 230static int btusb_submit_intr_urb(struct hci_dev *hdev)
116{ 231{
117 struct btusb_data *data = hdev->driver_data; 232 struct btusb_data *data = hdev->driver_data;
118 struct urb *urb; 233 struct urb *urb;
@@ -122,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
122 237
123 BT_DBG("%s", hdev->name); 238 BT_DBG("%s", hdev->name);
124 239
240 if (!data->intr_ep)
241 return -ENODEV;
242
125 urb = usb_alloc_urb(0, GFP_ATOMIC); 243 urb = usb_alloc_urb(0, GFP_ATOMIC);
126 if (!urb) 244 if (!urb)
127 return -ENOMEM; 245 return -ENOMEM;
@@ -170,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb)
170 return; 288 return;
171 289
172 if (urb->status == 0) { 290 if (urb->status == 0) {
291 hdev->stat.byte_rx += urb->actual_length;
292
173 if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT, 293 if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
174 urb->transfer_buffer, 294 urb->transfer_buffer,
175 urb->actual_length) < 0) { 295 urb->actual_length) < 0) {
@@ -191,7 +311,7 @@ static void btusb_bulk_complete(struct urb *urb)
191 } 311 }
192} 312}
193 313
194static inline int btusb_submit_bulk_urb(struct hci_dev *hdev) 314static int btusb_submit_bulk_urb(struct hci_dev *hdev)
195{ 315{
196 struct btusb_data *data = hdev->driver_data; 316 struct btusb_data *data = hdev->driver_data;
197 struct urb *urb; 317 struct urb *urb;
@@ -201,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
201 321
202 BT_DBG("%s", hdev->name); 322 BT_DBG("%s", hdev->name);
203 323
324 if (!data->bulk_rx_ep)
325 return -ENODEV;
326
204 urb = usb_alloc_urb(0, GFP_KERNEL); 327 urb = usb_alloc_urb(0, GFP_KERNEL);
205 if (!urb) 328 if (!urb)
206 return -ENOMEM; 329 return -ENOMEM;
@@ -235,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
235 return err; 358 return err;
236} 359}
237 360
361static void btusb_isoc_complete(struct urb *urb)
362{
363 struct hci_dev *hdev = urb->context;
364 struct btusb_data *data = hdev->driver_data;
365 int i, err;
366
367 BT_DBG("%s urb %p status %d count %d", hdev->name,
368 urb, urb->status, urb->actual_length);
369
370 if (!test_bit(HCI_RUNNING, &hdev->flags))
371 return;
372
373 if (urb->status == 0) {
374 for (i = 0; i < urb->number_of_packets; i++) {
375 unsigned int offset = urb->iso_frame_desc[i].offset;
376 unsigned int length = urb->iso_frame_desc[i].actual_length;
377
378 if (urb->iso_frame_desc[i].status)
379 continue;
380
381 hdev->stat.byte_rx += length;
382
383 if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
384 urb->transfer_buffer + offset,
385 length) < 0) {
386 BT_ERR("%s corrupted SCO packet", hdev->name);
387 hdev->stat.err_rx++;
388 }
389 }
390 }
391
392 if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
393 return;
394
395 usb_anchor_urb(urb, &data->isoc_anchor);
396
397 err = usb_submit_urb(urb, GFP_ATOMIC);
398 if (err < 0) {
399 BT_ERR("%s urb %p failed to resubmit (%d)",
400 hdev->name, urb, -err);
401 usb_unanchor_urb(urb);
402 }
403}
404
405static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
406{
407 int i, offset = 0;
408
409 BT_DBG("len %d mtu %d", len, mtu);
410
411 for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
412 i++, offset += mtu, len -= mtu) {
413 urb->iso_frame_desc[i].offset = offset;
414 urb->iso_frame_desc[i].length = mtu;
415 }
416
417 if (len && i < BTUSB_MAX_ISOC_FRAMES) {
418 urb->iso_frame_desc[i].offset = offset;
419 urb->iso_frame_desc[i].length = len;
420 i++;
421 }
422
423 urb->number_of_packets = i;
424}
425
426static int btusb_submit_isoc_urb(struct hci_dev *hdev)
427{
428 struct btusb_data *data = hdev->driver_data;
429 struct urb *urb;
430 unsigned char *buf;
431 unsigned int pipe;
432 int err, size;
433
434 BT_DBG("%s", hdev->name);
435
436 if (!data->isoc_rx_ep)
437 return -ENODEV;
438
439 urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL);
440 if (!urb)
441 return -ENOMEM;
442
443 size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
444 BTUSB_MAX_ISOC_FRAMES;
445
446 buf = kmalloc(size, GFP_KERNEL);
447 if (!buf) {
448 usb_free_urb(urb);
449 return -ENOMEM;
450 }
451
452 pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
453
454 urb->dev = data->udev;
455 urb->pipe = pipe;
456 urb->context = hdev;
457 urb->complete = btusb_isoc_complete;
458 urb->interval = data->isoc_rx_ep->bInterval;
459
460 urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
461 urb->transfer_buffer = buf;
462 urb->transfer_buffer_length = size;
463
464 __fill_isoc_descriptor(urb, size,
465 le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
466
467 usb_anchor_urb(urb, &data->isoc_anchor);
468
469 err = usb_submit_urb(urb, GFP_KERNEL);
470 if (err < 0) {
471 BT_ERR("%s urb %p submission failed (%d)",
472 hdev->name, urb, -err);
473 usb_unanchor_urb(urb);
474 kfree(buf);
475 }
476
477 usb_free_urb(urb);
478
479 return err;
480}
481
238static void btusb_tx_complete(struct urb *urb) 482static void btusb_tx_complete(struct urb *urb)
239{ 483{
240 struct sk_buff *skb = urb->context; 484 struct sk_buff *skb = urb->context;
@@ -288,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev)
288 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) 532 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
289 return 0; 533 return 0;
290 534
535 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
536 usb_kill_anchored_urbs(&data->intr_anchor);
537
291 clear_bit(BTUSB_BULK_RUNNING, &data->flags); 538 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
292 usb_kill_anchored_urbs(&data->bulk_anchor); 539 usb_kill_anchored_urbs(&data->bulk_anchor);
293 540
@@ -349,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb)
349 break; 596 break;
350 597
351 case HCI_ACLDATA_PKT: 598 case HCI_ACLDATA_PKT:
599 if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1)
600 return -ENODEV;
601
352 urb = usb_alloc_urb(0, GFP_ATOMIC); 602 urb = usb_alloc_urb(0, GFP_ATOMIC);
353 if (!urb) 603 if (!urb)
354 return -ENOMEM; 604 return -ENOMEM;
@@ -363,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb)
363 break; 613 break;
364 614
365 case HCI_SCODATA_PKT: 615 case HCI_SCODATA_PKT:
616 if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
617 return -ENODEV;
618
619 urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
620 if (!urb)
621 return -ENOMEM;
622
623 pipe = usb_sndisocpipe(data->udev,
624 data->isoc_tx_ep->bEndpointAddress);
625
626 urb->dev = data->udev;
627 urb->pipe = pipe;
628 urb->context = skb;
629 urb->complete = btusb_tx_complete;
630 urb->interval = data->isoc_tx_ep->bInterval;
631
632 urb->transfer_flags = URB_ISO_ASAP;
633 urb->transfer_buffer = skb->data;
634 urb->transfer_buffer_length = skb->len;
635
636 __fill_isoc_descriptor(urb, skb->len,
637 le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
638
366 hdev->stat.sco_tx++; 639 hdev->stat.sco_tx++;
367 kfree_skb(skb); 640 break;
368 return 0;
369 641
370 default: 642 default:
371 return -EILSEQ; 643 return -EILSEQ;
@@ -404,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
404 schedule_work(&data->work); 676 schedule_work(&data->work);
405} 677}
406 678
679static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
680{
681 struct btusb_data *data = hdev->driver_data;
682 struct usb_interface *intf = data->isoc;
683 struct usb_endpoint_descriptor *ep_desc;
684 int i, err;
685
686 if (!data->isoc)
687 return -ENODEV;
688
689 err = usb_set_interface(data->udev, 1, altsetting);
690 if (err < 0) {
691 BT_ERR("%s setting interface failed (%d)", hdev->name, -err);
692 return err;
693 }
694
695 data->isoc_altsetting = altsetting;
696
697 data->isoc_tx_ep = NULL;
698 data->isoc_rx_ep = NULL;
699
700 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
701 ep_desc = &intf->cur_altsetting->endpoint[i].desc;
702
703 if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
704 data->isoc_tx_ep = ep_desc;
705 continue;
706 }
707
708 if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
709 data->isoc_rx_ep = ep_desc;
710 continue;
711 }
712 }
713
714 if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
715 BT_ERR("%s invalid SCO descriptors", hdev->name);
716 return -ENODEV;
717 }
718
719 return 0;
720}
721
407static void btusb_work(struct work_struct *work) 722static void btusb_work(struct work_struct *work)
408{ 723{
409 struct btusb_data *data = container_of(work, struct btusb_data, work); 724 struct btusb_data *data = container_of(work, struct btusb_data, work);
410 struct hci_dev *hdev = data->hdev; 725 struct hci_dev *hdev = data->hdev;
411 726
412 if (hdev->conn_hash.acl_num == 0) { 727 if (hdev->conn_hash.acl_num > 0) {
728 if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
729 if (btusb_submit_bulk_urb(hdev) < 0)
730 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
731 else
732 btusb_submit_bulk_urb(hdev);
733 }
734 } else {
413 clear_bit(BTUSB_BULK_RUNNING, &data->flags); 735 clear_bit(BTUSB_BULK_RUNNING, &data->flags);
414 usb_kill_anchored_urbs(&data->bulk_anchor); 736 usb_kill_anchored_urbs(&data->bulk_anchor);
415 return;
416 } 737 }
417 738
418 if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) { 739 if (hdev->conn_hash.sco_num > 0) {
419 if (btusb_submit_bulk_urb(hdev) < 0) 740 if (data->isoc_altsetting != 2) {
420 clear_bit(BTUSB_BULK_RUNNING, &data->flags); 741 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
421 else 742 usb_kill_anchored_urbs(&data->isoc_anchor);
422 btusb_submit_bulk_urb(hdev); 743
744 if (__set_isoc_interface(hdev, 2) < 0)
745 return;
746 }
747
748 if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
749 if (btusb_submit_isoc_urb(hdev) < 0)
750 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
751 else
752 btusb_submit_isoc_urb(hdev);
753 }
754 } else {
755 clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
756 usb_kill_anchored_urbs(&data->isoc_anchor);
757
758 __set_isoc_interface(hdev, 0);
423 } 759 }
424} 760}
425 761
@@ -433,6 +769,7 @@ static int btusb_probe(struct usb_interface *intf,
433 769
434 BT_DBG("intf %p id %p", intf, id); 770 BT_DBG("intf %p id %p", intf, id);
435 771
772 /* interface numbers are hardcoded in the spec */
436 if (intf->cur_altsetting->desc.bInterfaceNumber != 0) 773 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
437 return -ENODEV; 774 return -ENODEV;
438 775
@@ -443,6 +780,18 @@ static int btusb_probe(struct usb_interface *intf,
443 id = match; 780 id = match;
444 } 781 }
445 782
783 if (id->driver_info == BTUSB_IGNORE)
784 return -ENODEV;
785
786 if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
787 return -ENODEV;
788
789 if (ignore_csr && id->driver_info & BTUSB_CSR)
790 return -ENODEV;
791
792 if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
793 return -ENODEV;
794
446 data = kzalloc(sizeof(*data), GFP_KERNEL); 795 data = kzalloc(sizeof(*data), GFP_KERNEL);
447 if (!data) 796 if (!data)
448 return -ENOMEM; 797 return -ENOMEM;
@@ -480,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf,
480 init_usb_anchor(&data->tx_anchor); 829 init_usb_anchor(&data->tx_anchor);
481 init_usb_anchor(&data->intr_anchor); 830 init_usb_anchor(&data->intr_anchor);
482 init_usb_anchor(&data->bulk_anchor); 831 init_usb_anchor(&data->bulk_anchor);
832 init_usb_anchor(&data->isoc_anchor);
483 833
484 hdev = hci_alloc_dev(); 834 hdev = hci_alloc_dev();
485 if (!hdev) { 835 if (!hdev) {
@@ -503,7 +853,49 @@ static int btusb_probe(struct usb_interface *intf,
503 853
504 hdev->owner = THIS_MODULE; 854 hdev->owner = THIS_MODULE;
505 855
506 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); 856 /* interface numbers are hardcoded in the spec */
857 data->isoc = usb_ifnum_to_if(data->udev, 1);
858
859 if (reset || id->driver_info & BTUSB_RESET)
860 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
861
862 if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
863 if (!disable_scofix)
864 set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
865 }
866
867 if (id->driver_info & BTUSB_BROKEN_ISOC)
868 data->isoc = NULL;
869
870 if (id->driver_info & BTUSB_SNIFFER) {
871 struct usb_device *udev = data->udev;
872
873 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
874 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
875
876 data->isoc = NULL;
877 }
878
879 if (id->driver_info & BTUSB_BCM92035) {
880 unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
881 struct sk_buff *skb;
882
883 skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
884 if (skb) {
885 memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
886 skb_queue_tail(&hdev->driver_init, skb);
887 }
888 }
889
890 if (data->isoc) {
891 err = usb_driver_claim_interface(&btusb_driver,
892 data->isoc, NULL);
893 if (err < 0) {
894 hci_free_dev(hdev);
895 kfree(data);
896 return err;
897 }
898 }
507 899
508 err = hci_register_dev(hdev); 900 err = hci_register_dev(hdev);
509 if (err < 0) { 901 if (err < 0) {
@@ -529,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf)
529 921
530 hdev = data->hdev; 922 hdev = data->hdev;
531 923
924 if (data->isoc)
925 usb_driver_release_interface(&btusb_driver, data->isoc);
926
532 usb_set_intfdata(intf, NULL); 927 usb_set_intfdata(intf, NULL);
533 928
534 hci_unregister_dev(hdev); 929 hci_unregister_dev(hdev);
@@ -558,6 +953,24 @@ static void __exit btusb_exit(void)
558module_init(btusb_init); 953module_init(btusb_init);
559module_exit(btusb_exit); 954module_exit(btusb_exit);
560 955
956module_param(ignore_dga, bool, 0644);
957MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
958
959module_param(ignore_csr, bool, 0644);
960MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
961
962module_param(ignore_sniffer, bool, 0644);
963MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
964
965module_param(disable_scofix, bool, 0644);
966MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
967
968module_param(force_scofix, bool, 0644);
969MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
970
971module_param(reset, bool, 0644);
972MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
973
561MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); 974MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
562MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION); 975MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION);
563MODULE_VERSION(VERSION); 976MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 69df187d74ce..8dfcf77cb717 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -577,7 +577,7 @@ module_exit(hci_uart_exit);
577module_param(reset, bool, 0644); 577module_param(reset, bool, 0644);
578MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); 578MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
579 579
580MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>"); 580MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
581MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION); 581MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
582MODULE_VERSION(VERSION); 582MODULE_VERSION(VERSION);
583MODULE_LICENSE("GPL"); 583MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index c33bb59ed1fa..3c453924f838 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -62,7 +62,6 @@
62#define URB_ZERO_PACKET 0 62#define URB_ZERO_PACKET 0
63#endif 63#endif
64 64
65static int ignore;
66static int ignore_dga; 65static int ignore_dga;
67static int ignore_csr; 66static int ignore_csr;
68static int ignore_sniffer; 67static int ignore_sniffer;
@@ -74,7 +73,7 @@ static int reset;
74static int isoc = 2; 73static int isoc = 2;
75#endif 74#endif
76 75
77#define VERSION "2.9" 76#define VERSION "2.10"
78 77
79static struct usb_driver hci_usb_driver; 78static struct usb_driver hci_usb_driver;
80 79
@@ -801,7 +800,7 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
801 id = match; 800 id = match;
802 } 801 }
803 802
804 if (ignore || id->driver_info & HCI_IGNORE) 803 if (id->driver_info & HCI_IGNORE)
805 return -ENODEV; 804 return -ENODEV;
806 805
807 if (ignore_dga && id->driver_info & HCI_DIGIANSWER) 806 if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
@@ -1108,9 +1107,6 @@ static void __exit hci_usb_exit(void)
1108module_init(hci_usb_init); 1107module_init(hci_usb_init);
1109module_exit(hci_usb_exit); 1108module_exit(hci_usb_exit);
1110 1109
1111module_param(ignore, bool, 0644);
1112MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1113
1114module_param(ignore_dga, bool, 0644); 1110module_param(ignore_dga, bool, 0644);
1115MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001"); 1111MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
1116 1112
@@ -1134,7 +1130,7 @@ module_param(isoc, int, 0644);
1134MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support"); 1130MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
1135#endif 1131#endif
1136 1132
1137MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>"); 1133MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
1138MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION); 1134MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
1139MODULE_VERSION(VERSION); 1135MODULE_VERSION(VERSION);
1140MODULE_LICENSE("GPL"); 1136MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index d97700aa54a9..7320a71b6368 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -377,7 +377,7 @@ module_exit(vhci_exit);
377module_param(minor, int, 0444); 377module_param(minor, int, 0444);
378MODULE_PARM_DESC(minor, "Miscellaneous minor device number"); 378MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
379 379
380MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>"); 380MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
381MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); 381MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
382MODULE_VERSION(VERSION); 382MODULE_VERSION(VERSION);
383MODULE_LICENSE("GPL"); 383MODULE_LICENSE("GPL");
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index d9d1b65d206c..74031de517e6 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -408,7 +408,6 @@ int register_cdrom(struct cdrom_device_info *cdi)
408 ENSURE(get_last_session, CDC_MULTI_SESSION); 408 ENSURE(get_last_session, CDC_MULTI_SESSION);
409 ENSURE(get_mcn, CDC_MCN); 409 ENSURE(get_mcn, CDC_MCN);
410 ENSURE(reset, CDC_RESET); 410 ENSURE(reset, CDC_RESET);
411 ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
412 ENSURE(generic_packet, CDC_GENERIC_PACKET); 411 ENSURE(generic_packet, CDC_GENERIC_PACKET);
413 cdi->mc_flags = 0; 412 cdi->mc_flags = 0;
414 cdo->n_minors = 0; 413 cdo->n_minors = 0;
@@ -2506,8 +2505,6 @@ static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi,
2506 2505
2507 /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/ 2506 /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
2508 2507
2509 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2510 return -ENOSYS;
2511 if (copy_from_user(&q, argp, sizeof(q))) 2508 if (copy_from_user(&q, argp, sizeof(q)))
2512 return -EFAULT; 2509 return -EFAULT;
2513 2510
@@ -2538,8 +2535,6 @@ static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi,
2538 2535
2539 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */ 2536 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
2540 2537
2541 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2542 return -ENOSYS;
2543 if (copy_from_user(&header, argp, sizeof(header))) 2538 if (copy_from_user(&header, argp, sizeof(header)))
2544 return -EFAULT; 2539 return -EFAULT;
2545 2540
@@ -2562,8 +2557,6 @@ static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi,
2562 2557
2563 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */ 2558 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
2564 2559
2565 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2566 return -ENOSYS;
2567 if (copy_from_user(&entry, argp, sizeof(entry))) 2560 if (copy_from_user(&entry, argp, sizeof(entry)))
2568 return -EFAULT; 2561 return -EFAULT;
2569 2562
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 1e0455bd6df9..1231d95aa695 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -471,6 +471,12 @@ cleanup_sense_final:
471 return err; 471 return err;
472} 472}
473 473
474static int gdrom_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
475 void *arg)
476{
477 return -EINVAL;
478}
479
474static struct cdrom_device_ops gdrom_ops = { 480static struct cdrom_device_ops gdrom_ops = {
475 .open = gdrom_open, 481 .open = gdrom_open,
476 .release = gdrom_release, 482 .release = gdrom_release,
@@ -478,6 +484,7 @@ static struct cdrom_device_ops gdrom_ops = {
478 .media_changed = gdrom_mediachanged, 484 .media_changed = gdrom_mediachanged,
479 .get_last_session = gdrom_get_last_session, 485 .get_last_session = gdrom_get_last_session,
480 .reset = gdrom_hardreset, 486 .reset = gdrom_hardreset,
487 .audio_ioctl = gdrom_audio_ioctl,
481 .capability = CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | 488 .capability = CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
482 CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R, 489 CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R,
483 .n_minors = 1, 490 .n_minors = 1,
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 9d0dfe6e0d63..031e0e1a1a3b 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -550,12 +550,19 @@ return_complete:
550 } 550 }
551} 551}
552 552
553static int viocd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
554 void *arg)
555{
556 return -EINVAL;
557}
558
553static struct cdrom_device_ops viocd_dops = { 559static struct cdrom_device_ops viocd_dops = {
554 .open = viocd_open, 560 .open = viocd_open,
555 .release = viocd_release, 561 .release = viocd_release,
556 .media_changed = viocd_media_changed, 562 .media_changed = viocd_media_changed,
557 .lock_door = viocd_lock_door, 563 .lock_door = viocd_lock_door,
558 .generic_packet = viocd_packet, 564 .generic_packet = viocd_packet,
565 .audio_ioctl = viocd_audio_ioctl,
559 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM 566 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
560}; 567};
561 568
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index d0ac944e1696..caff85149b9d 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -8,7 +8,7 @@ config VT
8 bool "Virtual terminal" if EMBEDDED 8 bool "Virtual terminal" if EMBEDDED
9 depends on !S390 9 depends on !S390
10 select INPUT 10 select INPUT
11 default y if !VIOCONS 11 default y
12 ---help--- 12 ---help---
13 If you say Y here, you will get support for terminal devices with 13 If you say Y here, you will get support for terminal devices with
14 display and keyboard devices. These are called "virtual" because you 14 display and keyboard devices. These are called "virtual" because you
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 8a161c30e1dc..6850f6da7576 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -55,7 +55,6 @@ obj-$(CONFIG_RAW_DRIVER) += raw.o
55obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o 55obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
56obj-$(CONFIG_MSPEC) += mspec.o 56obj-$(CONFIG_MSPEC) += mspec.o
57obj-$(CONFIG_MMTIMER) += mmtimer.o 57obj-$(CONFIG_MMTIMER) += mmtimer.o
58obj-$(CONFIG_VIOCONS) += viocons.o
59obj-$(CONFIG_VIOTAPE) += viotape.o 58obj-$(CONFIG_VIOTAPE) += viotape.o
60obj-$(CONFIG_HVCS) += hvcs.o 59obj-$(CONFIG_HVCS) += hvcs.o
61obj-$(CONFIG_IBM_BSR) += bsr.o 60obj-$(CONFIG_IBM_BSR) += bsr.o
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 81e14bea54bd..4bada0e8b812 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -148,6 +148,9 @@ struct agp_bridge_data {
148 char minor_version; 148 char minor_version;
149 struct list_head list; 149 struct list_head list;
150 u32 apbase_config; 150 u32 apbase_config;
151 /* list of agp_memory mapped to the aperture */
152 struct list_head mapped_list;
153 spinlock_t mapped_lock;
151}; 154};
152 155
153#define KB(x) ((x) * 1024) 156#define KB(x) ((x) * 1024)
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 1ffb381130c3..31dcd9142d54 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -110,7 +110,8 @@ static int ali_configure(void)
110 110
111 nlvm_addr+= agp_bridge->gart_bus_addr; 111 nlvm_addr+= agp_bridge->gart_bus_addr;
112 nlvm_addr|=(agp_bridge->gart_bus_addr>>12); 112 nlvm_addr|=(agp_bridge->gart_bus_addr>>12);
113 printk(KERN_INFO PFX "nlvm top &base = %8x\n",nlvm_addr); 113 dev_info(&agp_bridge->dev->dev, "nlvm top &base = %8x\n",
114 nlvm_addr);
114 } 115 }
115#endif 116#endif
116 117
@@ -315,8 +316,8 @@ static int __devinit agp_ali_probe(struct pci_dev *pdev,
315 goto found; 316 goto found;
316 } 317 }
317 318
318 printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x)\n", 319 dev_err(&pdev->dev, "unsupported ALi chipset [%04x/%04x])\n",
319 pdev->device); 320 pdev->vendor, pdev->device);
320 return -ENODEV; 321 return -ENODEV;
321 322
322 323
@@ -361,8 +362,7 @@ found:
361 bridge->driver = &ali_generic_bridge; 362 bridge->driver = &ali_generic_bridge;
362 } 363 }
363 364
364 printk(KERN_INFO PFX "Detected ALi %s chipset\n", 365 dev_info(&pdev->dev, "ALi %s chipset\n", devs[j].chipset_name);
365 devs[j].chipset_name);
366 366
367 /* Fill in the mode register */ 367 /* Fill in the mode register */
368 pci_read_config_dword(pdev, 368 pci_read_config_dword(pdev,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 39a0718bc616..e280531843be 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -419,8 +419,8 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
419 return -ENODEV; 419 return -ENODEV;
420 420
421 j = ent - agp_amdk7_pci_table; 421 j = ent - agp_amdk7_pci_table;
422 printk(KERN_INFO PFX "Detected AMD %s chipset\n", 422 dev_info(&pdev->dev, "AMD %s chipset\n",
423 amd_agp_device_ids[j].chipset_name); 423 amd_agp_device_ids[j].chipset_name);
424 424
425 bridge = agp_alloc_bridge(); 425 bridge = agp_alloc_bridge();
426 if (!bridge) 426 if (!bridge)
@@ -442,7 +442,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
442 while (!cap_ptr) { 442 while (!cap_ptr) {
443 gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard); 443 gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard);
444 if (!gfxcard) { 444 if (!gfxcard) {
445 printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n"); 445 dev_info(&pdev->dev, "no AGP VGA controller\n");
446 return -ENODEV; 446 return -ENODEV;
447 } 447 }
448 cap_ptr = pci_find_capability(gfxcard, PCI_CAP_ID_AGP); 448 cap_ptr = pci_find_capability(gfxcard, PCI_CAP_ID_AGP);
@@ -453,7 +453,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
453 (if necessary at all). */ 453 (if necessary at all). */
454 if (gfxcard->vendor == PCI_VENDOR_ID_NVIDIA) { 454 if (gfxcard->vendor == PCI_VENDOR_ID_NVIDIA) {
455 agp_bridge->flags |= AGP_ERRATA_1X; 455 agp_bridge->flags |= AGP_ERRATA_1X;
456 printk (KERN_INFO PFX "AMD 751 chipset with NVidia GeForce detected. Forcing to 1X due to errata.\n"); 456 dev_info(&pdev->dev, "AMD 751 chipset with NVidia GeForce; forcing 1X due to errata\n");
457 } 457 }
458 pci_dev_put(gfxcard); 458 pci_dev_put(gfxcard);
459 } 459 }
@@ -469,7 +469,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
469 agp_bridge->flags = AGP_ERRATA_FASTWRITES; 469 agp_bridge->flags = AGP_ERRATA_FASTWRITES;
470 agp_bridge->flags |= AGP_ERRATA_SBA; 470 agp_bridge->flags |= AGP_ERRATA_SBA;
471 agp_bridge->flags |= AGP_ERRATA_1X; 471 agp_bridge->flags |= AGP_ERRATA_1X;
472 printk (KERN_INFO PFX "AMD 761 chipset with errata detected - disabling AGP fast writes & SBA and forcing to 1X.\n"); 472 dev_info(&pdev->dev, "AMD 761 chipset with errata; disabling AGP fast writes & SBA and forcing to 1X\n");
473 } 473 }
474 } 474 }
475 475
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 481ffe87c716..7495c522d8e4 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -34,6 +34,7 @@
34 34
35static struct resource *aperture_resource; 35static struct resource *aperture_resource;
36static int __initdata agp_try_unsupported = 1; 36static int __initdata agp_try_unsupported = 1;
37static int agp_bridges_found;
37 38
38static void amd64_tlbflush(struct agp_memory *temp) 39static void amd64_tlbflush(struct agp_memory *temp)
39{ 40{
@@ -293,12 +294,13 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
293 * so let double check that order, and lets trust the AMD NB settings 294 * so let double check that order, and lets trust the AMD NB settings
294 */ 295 */
295 if (order >=0 && aper + (32ULL<<(20 + order)) > 0x100000000ULL) { 296 if (order >=0 && aper + (32ULL<<(20 + order)) > 0x100000000ULL) {
296 printk(KERN_INFO "Aperture size %u MB is not right, using settings from NB\n", 297 dev_info(&agp->dev, "aperture size %u MB is not right, using settings from NB\n",
297 32 << order); 298 32 << order);
298 order = nb_order; 299 order = nb_order;
299 } 300 }
300 301
301 printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order); 302 dev_info(&agp->dev, "aperture from AGP @ %Lx size %u MB\n",
303 aper, 32 << order);
302 if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order)) 304 if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order))
303 return -1; 305 return -1;
304 306
@@ -319,10 +321,10 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr)
319 for (i = 0; i < num_k8_northbridges; i++) { 321 for (i = 0; i < num_k8_northbridges; i++) {
320 struct pci_dev *dev = k8_northbridges[i]; 322 struct pci_dev *dev = k8_northbridges[i];
321 if (fix_northbridge(dev, pdev, cap_ptr) < 0) { 323 if (fix_northbridge(dev, pdev, cap_ptr) < 0) {
322 printk(KERN_ERR PFX "No usable aperture found.\n"); 324 dev_err(&dev->dev, "no usable aperture found\n");
323#ifdef __x86_64__ 325#ifdef __x86_64__
324 /* should port this to i386 */ 326 /* should port this to i386 */
325 printk(KERN_ERR PFX "Consider rebooting with iommu=memaper=2 to get a good aperture.\n"); 327 dev_err(&dev->dev, "consider rebooting with iommu=memaper=2 to get a good aperture\n");
326#endif 328#endif
327 return -1; 329 return -1;
328 } 330 }
@@ -345,14 +347,14 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data
345 default: revstring="??"; break; 347 default: revstring="??"; break;
346 } 348 }
347 349
348 printk (KERN_INFO PFX "Detected AMD 8151 AGP Bridge rev %s\n", revstring); 350 dev_info(&pdev->dev, "AMD 8151 AGP Bridge rev %s\n", revstring);
349 351
350 /* 352 /*
351 * Work around errata. 353 * Work around errata.
352 * Chips before B2 stepping incorrectly reporting v3.5 354 * Chips before B2 stepping incorrectly reporting v3.5
353 */ 355 */
354 if (pdev->revision < 0x13) { 356 if (pdev->revision < 0x13) {
355 printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n"); 357 dev_info(&pdev->dev, "correcting AGP revision (reports 3.5, is really 3.0)\n");
356 bridge->major_version = 3; 358 bridge->major_version = 3;
357 bridge->minor_version = 0; 359 bridge->minor_version = 0;
358 } 360 }
@@ -375,11 +377,11 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
375 struct pci_dev *dev1; 377 struct pci_dev *dev1;
376 int i; 378 int i;
377 unsigned size = amd64_fetch_size(); 379 unsigned size = amd64_fetch_size();
378 printk(KERN_INFO "Setting up ULi AGP.\n"); 380
381 dev_info(&pdev->dev, "setting up ULi AGP\n");
379 dev1 = pci_get_slot (pdev->bus,PCI_DEVFN(0,0)); 382 dev1 = pci_get_slot (pdev->bus,PCI_DEVFN(0,0));
380 if (dev1 == NULL) { 383 if (dev1 == NULL) {
381 printk(KERN_INFO PFX "Detected a ULi chipset, " 384 dev_info(&pdev->dev, "can't find ULi secondary device\n");
382 "but could not fine the secondary device.\n");
383 return -ENODEV; 385 return -ENODEV;
384 } 386 }
385 387
@@ -388,7 +390,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
388 break; 390 break;
389 391
390 if (i == ARRAY_SIZE(uli_sizes)) { 392 if (i == ARRAY_SIZE(uli_sizes)) {
391 printk(KERN_INFO PFX "No ULi size found for %d\n", size); 393 dev_info(&pdev->dev, "no ULi size found for %d\n", size);
392 return -ENODEV; 394 return -ENODEV;
393 } 395 }
394 396
@@ -433,13 +435,11 @@ static int nforce3_agp_init(struct pci_dev *pdev)
433 int i; 435 int i;
434 unsigned size = amd64_fetch_size(); 436 unsigned size = amd64_fetch_size();
435 437
436 printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n"); 438 dev_info(&pdev->dev, "setting up Nforce3 AGP\n");
437 439
438 dev1 = pci_get_slot(pdev->bus, PCI_DEVFN(11, 0)); 440 dev1 = pci_get_slot(pdev->bus, PCI_DEVFN(11, 0));
439 if (dev1 == NULL) { 441 if (dev1 == NULL) {
440 printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " 442 dev_info(&pdev->dev, "can't find Nforce3 secondary device\n");
441 "nForce3 chipset, but could not find "
442 "the secondary device.\n");
443 return -ENODEV; 443 return -ENODEV;
444 } 444 }
445 445
@@ -448,7 +448,7 @@ static int nforce3_agp_init(struct pci_dev *pdev)
448 break; 448 break;
449 449
450 if (i == ARRAY_SIZE(nforce3_sizes)) { 450 if (i == ARRAY_SIZE(nforce3_sizes)) {
451 printk(KERN_INFO PFX "No NForce3 size found for %d\n", size); 451 dev_info(&pdev->dev, "no NForce3 size found for %d\n", size);
452 return -ENODEV; 452 return -ENODEV;
453 } 453 }
454 454
@@ -462,7 +462,7 @@ static int nforce3_agp_init(struct pci_dev *pdev)
462 462
463 /* if x86-64 aperture base is beyond 4G, exit here */ 463 /* if x86-64 aperture base is beyond 4G, exit here */
464 if ( (apbase & 0x7fff) >> (32 - 25) ) { 464 if ( (apbase & 0x7fff) >> (32 - 25) ) {
465 printk(KERN_INFO PFX "aperture base > 4G\n"); 465 dev_info(&pdev->dev, "aperture base > 4G\n");
466 return -ENODEV; 466 return -ENODEV;
467 } 467 }
468 468
@@ -489,6 +489,7 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev,
489{ 489{
490 struct agp_bridge_data *bridge; 490 struct agp_bridge_data *bridge;
491 u8 cap_ptr; 491 u8 cap_ptr;
492 int err;
492 493
493 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); 494 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
494 if (!cap_ptr) 495 if (!cap_ptr)
@@ -504,7 +505,8 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev,
504 pdev->device == PCI_DEVICE_ID_AMD_8151_0) { 505 pdev->device == PCI_DEVICE_ID_AMD_8151_0) {
505 amd8151_init(pdev, bridge); 506 amd8151_init(pdev, bridge);
506 } else { 507 } else {
507 printk(KERN_INFO PFX "Detected AGP bridge %x\n", pdev->devfn); 508 dev_info(&pdev->dev, "AGP bridge [%04x/%04x]\n",
509 pdev->vendor, pdev->device);
508 } 510 }
509 511
510 bridge->driver = &amd_8151_driver; 512 bridge->driver = &amd_8151_driver;
@@ -536,7 +538,12 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev,
536 } 538 }
537 539
538 pci_set_drvdata(pdev, bridge); 540 pci_set_drvdata(pdev, bridge);
539 return agp_add_bridge(bridge); 541 err = agp_add_bridge(bridge);
542 if (err < 0)
543 return err;
544
545 agp_bridges_found++;
546 return 0;
540} 547}
541 548
542static void __devexit agp_amd64_remove(struct pci_dev *pdev) 549static void __devexit agp_amd64_remove(struct pci_dev *pdev)
@@ -713,7 +720,11 @@ int __init agp_amd64_init(void)
713 720
714 if (agp_off) 721 if (agp_off)
715 return -EINVAL; 722 return -EINVAL;
716 if (pci_register_driver(&agp_amd64_pci_driver) < 0) { 723 err = pci_register_driver(&agp_amd64_pci_driver);
724 if (err < 0)
725 return err;
726
727 if (agp_bridges_found == 0) {
717 struct pci_dev *dev; 728 struct pci_dev *dev;
718 if (!agp_try_unsupported && !agp_try_unsupported_boot) { 729 if (!agp_try_unsupported && !agp_try_unsupported_boot) {
719 printk(KERN_INFO PFX "No supported AGP bridge found.\n"); 730 printk(KERN_INFO PFX "No supported AGP bridge found.\n");
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 3a4566c0d84f..6ecbcafb34b1 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -486,8 +486,8 @@ static int __devinit agp_ati_probe(struct pci_dev *pdev,
486 goto found; 486 goto found;
487 } 487 }
488 488
489 printk(KERN_ERR PFX 489 dev_err(&pdev->dev, "unsupported Ati chipset [%04x/%04x])\n",
490 "Unsupported Ati chipset (device id: %04x)\n", pdev->device); 490 pdev->vendor, pdev->device);
491 return -ENODEV; 491 return -ENODEV;
492 492
493found: 493found:
@@ -500,8 +500,7 @@ found:
500 500
501 bridge->driver = &ati_generic_bridge; 501 bridge->driver = &ati_generic_bridge;
502 502
503 printk(KERN_INFO PFX "Detected Ati %s chipset\n", 503 dev_info(&pdev->dev, "Ati %s chipset\n", devs[j].chipset_name);
504 devs[j].chipset_name);
505 504
506 /* Fill in the mode register */ 505 /* Fill in the mode register */
507 pci_read_config_dword(pdev, 506 pci_read_config_dword(pdev,
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 1ec87104e68c..3a3cc03d401c 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -144,7 +144,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
144 void *addr = bridge->driver->agp_alloc_page(bridge); 144 void *addr = bridge->driver->agp_alloc_page(bridge);
145 145
146 if (!addr) { 146 if (!addr) {
147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); 147 dev_err(&bridge->dev->dev,
148 "can't get memory for scratch page\n");
148 return -ENOMEM; 149 return -ENOMEM;
149 } 150 }
150 151
@@ -155,13 +156,13 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
155 156
156 size_value = bridge->driver->fetch_size(); 157 size_value = bridge->driver->fetch_size();
157 if (size_value == 0) { 158 if (size_value == 0) {
158 printk(KERN_ERR PFX "unable to determine aperture size.\n"); 159 dev_err(&bridge->dev->dev, "can't determine aperture size\n");
159 rc = -EINVAL; 160 rc = -EINVAL;
160 goto err_out; 161 goto err_out;
161 } 162 }
162 if (bridge->driver->create_gatt_table(bridge)) { 163 if (bridge->driver->create_gatt_table(bridge)) {
163 printk(KERN_ERR PFX 164 dev_err(&bridge->dev->dev,
164 "unable to get memory for graphics translation table.\n"); 165 "can't get memory for graphics translation table\n");
165 rc = -ENOMEM; 166 rc = -ENOMEM;
166 goto err_out; 167 goto err_out;
167 } 168 }
@@ -169,7 +170,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
169 170
170 bridge->key_list = vmalloc(PAGE_SIZE * 4); 171 bridge->key_list = vmalloc(PAGE_SIZE * 4);
171 if (bridge->key_list == NULL) { 172 if (bridge->key_list == NULL) {
172 printk(KERN_ERR PFX "error allocating memory for key lists.\n"); 173 dev_err(&bridge->dev->dev,
174 "can't allocate memory for key lists\n");
173 rc = -ENOMEM; 175 rc = -ENOMEM;
174 goto err_out; 176 goto err_out;
175 } 177 }
@@ -179,10 +181,12 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
179 memset(bridge->key_list, 0, PAGE_SIZE * 4); 181 memset(bridge->key_list, 0, PAGE_SIZE * 4);
180 182
181 if (bridge->driver->configure()) { 183 if (bridge->driver->configure()) {
182 printk(KERN_ERR PFX "error configuring host chipset.\n"); 184 dev_err(&bridge->dev->dev, "error configuring host chipset\n");
183 rc = -EINVAL; 185 rc = -EINVAL;
184 goto err_out; 186 goto err_out;
185 } 187 }
188 INIT_LIST_HEAD(&bridge->mapped_list);
189 spin_lock_init(&bridge->mapped_lock);
186 190
187 return 0; 191 return 0;
188 192
@@ -269,25 +273,27 @@ int agp_add_bridge(struct agp_bridge_data *bridge)
269 273
270 /* Grab reference on the chipset driver. */ 274 /* Grab reference on the chipset driver. */
271 if (!try_module_get(bridge->driver->owner)) { 275 if (!try_module_get(bridge->driver->owner)) {
272 printk (KERN_INFO PFX "Couldn't lock chipset driver.\n"); 276 dev_info(&bridge->dev->dev, "can't lock chipset driver\n");
273 return -EINVAL; 277 return -EINVAL;
274 } 278 }
275 279
276 error = agp_backend_initialize(bridge); 280 error = agp_backend_initialize(bridge);
277 if (error) { 281 if (error) {
278 printk (KERN_INFO PFX "agp_backend_initialize() failed.\n"); 282 dev_info(&bridge->dev->dev,
283 "agp_backend_initialize() failed\n");
279 goto err_out; 284 goto err_out;
280 } 285 }
281 286
282 if (list_empty(&agp_bridges)) { 287 if (list_empty(&agp_bridges)) {
283 error = agp_frontend_initialize(); 288 error = agp_frontend_initialize();
284 if (error) { 289 if (error) {
285 printk (KERN_INFO PFX "agp_frontend_initialize() failed.\n"); 290 dev_info(&bridge->dev->dev,
291 "agp_frontend_initialize() failed\n");
286 goto frontend_err; 292 goto frontend_err;
287 } 293 }
288 294
289 printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n", 295 dev_info(&bridge->dev->dev, "AGP aperture is %dM @ 0x%lx\n",
290 bridge->driver->fetch_size(), bridge->gart_bus_addr); 296 bridge->driver->fetch_size(), bridge->gart_bus_addr);
291 297
292 } 298 }
293 299
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index eaa1a355bb32..118dbde25dc7 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -429,6 +429,10 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
429 429
430 curr->is_bound = true; 430 curr->is_bound = true;
431 curr->pg_start = pg_start; 431 curr->pg_start = pg_start;
432 spin_lock(&agp_bridge->mapped_lock);
433 list_add(&curr->mapped_list, &agp_bridge->mapped_list);
434 spin_unlock(&agp_bridge->mapped_lock);
435
432 return 0; 436 return 0;
433} 437}
434EXPORT_SYMBOL(agp_bind_memory); 438EXPORT_SYMBOL(agp_bind_memory);
@@ -461,10 +465,34 @@ int agp_unbind_memory(struct agp_memory *curr)
461 465
462 curr->is_bound = false; 466 curr->is_bound = false;
463 curr->pg_start = 0; 467 curr->pg_start = 0;
468 spin_lock(&curr->bridge->mapped_lock);
469 list_del(&curr->mapped_list);
470 spin_unlock(&curr->bridge->mapped_lock);
464 return 0; 471 return 0;
465} 472}
466EXPORT_SYMBOL(agp_unbind_memory); 473EXPORT_SYMBOL(agp_unbind_memory);
467 474
475/**
476 * agp_rebind_emmory - Rewrite the entire GATT, useful on resume
477 */
478int agp_rebind_memory(void)
479{
480 struct agp_memory *curr;
481 int ret_val = 0;
482
483 spin_lock(&agp_bridge->mapped_lock);
484 list_for_each_entry(curr, &agp_bridge->mapped_list, mapped_list) {
485 ret_val = curr->bridge->driver->insert_memory(curr,
486 curr->pg_start,
487 curr->type);
488 if (ret_val != 0)
489 break;
490 }
491 spin_unlock(&agp_bridge->mapped_lock);
492 return ret_val;
493}
494EXPORT_SYMBOL(agp_rebind_memory);
495
468/* End - Routines for handling swapping of agp_memory into the GATT */ 496/* End - Routines for handling swapping of agp_memory into the GATT */
469 497
470 498
@@ -771,8 +799,8 @@ void agp_device_command(u32 bridge_agpstat, bool agp_v3)
771 if (!agp) 799 if (!agp)
772 continue; 800 continue;
773 801
774 printk(KERN_INFO PFX "Putting AGP V%d device at %s into %dx mode\n", 802 dev_info(&device->dev, "putting AGP V%d device into %dx mode\n",
775 agp_v3 ? 3 : 2, pci_name(device), mode); 803 agp_v3 ? 3 : 2, mode);
776 pci_write_config_dword(device, agp + PCI_AGP_COMMAND, bridge_agpstat); 804 pci_write_config_dword(device, agp + PCI_AGP_COMMAND, bridge_agpstat);
777 } 805 }
778} 806}
@@ -800,10 +828,8 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
800 828
801 get_agp_version(agp_bridge); 829 get_agp_version(agp_bridge);
802 830
803 printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n", 831 dev_info(&agp_bridge->dev->dev, "AGP %d.%d bridge\n",
804 agp_bridge->major_version, 832 agp_bridge->major_version, agp_bridge->minor_version);
805 agp_bridge->minor_version,
806 pci_name(agp_bridge->dev));
807 833
808 pci_read_config_dword(agp_bridge->dev, 834 pci_read_config_dword(agp_bridge->dev,
809 agp_bridge->capndx + PCI_AGP_STATUS, &bridge_agpstat); 835 agp_bridge->capndx + PCI_AGP_STATUS, &bridge_agpstat);
@@ -832,8 +858,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
832 pci_write_config_dword(bridge->dev, 858 pci_write_config_dword(bridge->dev,
833 bridge->capndx+AGPCTRL, temp); 859 bridge->capndx+AGPCTRL, temp);
834 860
835 printk(KERN_INFO PFX "Device is in legacy mode," 861 dev_info(&bridge->dev->dev, "bridge is in legacy mode, falling back to 2.x\n");
836 " falling back to 2.x\n");
837 } 862 }
838 } 863 }
839 864
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index df702642ab8f..016fdf0623a4 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -32,8 +32,8 @@
32#define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2 32#define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2
33#define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0 33#define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0
34#define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 34#define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2
35#define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40 35#define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40
36#define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42 36#define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42
37#define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00 37#define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00
38#define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02 38#define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02
39#define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10 39#define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10
@@ -55,7 +55,7 @@
55 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ 55 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
56 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ 56 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
57 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \ 57 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \
58 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB) 58 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
59 59
60#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ 60#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
61 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ 61 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
@@ -161,7 +161,7 @@ static int intel_i810_fetch_size(void)
161 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); 161 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
162 162
163 if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { 163 if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
164 printk(KERN_WARNING PFX "i810 is disabled\n"); 164 dev_warn(&agp_bridge->dev->dev, "i810 is disabled\n");
165 return 0; 165 return 0;
166 } 166 }
167 if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { 167 if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
@@ -193,7 +193,8 @@ static int intel_i810_configure(void)
193 193
194 intel_private.registers = ioremap(temp, 128 * 4096); 194 intel_private.registers = ioremap(temp, 128 * 4096);
195 if (!intel_private.registers) { 195 if (!intel_private.registers) {
196 printk(KERN_ERR PFX "Unable to remap memory.\n"); 196 dev_err(&intel_private.pcidev->dev,
197 "can't remap memory\n");
197 return -ENOMEM; 198 return -ENOMEM;
198 } 199 }
199 } 200 }
@@ -201,7 +202,8 @@ static int intel_i810_configure(void)
201 if ((readl(intel_private.registers+I810_DRAM_CTL) 202 if ((readl(intel_private.registers+I810_DRAM_CTL)
202 & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { 203 & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
203 /* This will need to be dynamically assigned */ 204 /* This will need to be dynamically assigned */
204 printk(KERN_INFO PFX "detected 4MB dedicated video ram.\n"); 205 dev_info(&intel_private.pcidev->dev,
206 "detected 4MB dedicated video ram\n");
205 intel_private.num_dcache_entries = 1024; 207 intel_private.num_dcache_entries = 1024;
206 } 208 }
207 pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp); 209 pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp);
@@ -500,8 +502,8 @@ static void intel_i830_init_gtt_entries(void)
500 size = 1024 + 512; 502 size = 1024 + 512;
501 break; 503 break;
502 default: 504 default:
503 printk(KERN_INFO PFX "Unknown page table size, " 505 dev_info(&intel_private.pcidev->dev,
504 "assuming 512KB\n"); 506 "unknown page table size, assuming 512KB\n");
505 size = 512; 507 size = 512;
506 } 508 }
507 size += 4; /* add in BIOS popup space */ 509 size += 4; /* add in BIOS popup space */
@@ -515,8 +517,8 @@ static void intel_i830_init_gtt_entries(void)
515 size = 2048; 517 size = 2048;
516 break; 518 break;
517 default: 519 default:
518 printk(KERN_INFO PFX "Unknown page table size 0x%x, " 520 dev_info(&agp_bridge->dev->dev,
519 "assuming 512KB\n", 521 "unknown page table size 0x%x, assuming 512KB\n",
520 (gmch_ctrl & G33_PGETBL_SIZE_MASK)); 522 (gmch_ctrl & G33_PGETBL_SIZE_MASK));
521 size = 512; 523 size = 512;
522 } 524 }
@@ -627,11 +629,11 @@ static void intel_i830_init_gtt_entries(void)
627 } 629 }
628 } 630 }
629 if (gtt_entries > 0) 631 if (gtt_entries > 0)
630 printk(KERN_INFO PFX "Detected %dK %s memory.\n", 632 dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n",
631 gtt_entries / KB(1), local ? "local" : "stolen"); 633 gtt_entries / KB(1), local ? "local" : "stolen");
632 else 634 else
633 printk(KERN_INFO PFX 635 dev_info(&agp_bridge->dev->dev,
634 "No pre-allocated video memory detected.\n"); 636 "no pre-allocated video memory detected\n");
635 gtt_entries /= KB(4); 637 gtt_entries /= KB(4);
636 638
637 intel_private.gtt_entries = gtt_entries; 639 intel_private.gtt_entries = gtt_entries;
@@ -801,10 +803,12 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start,
801 num_entries = A_SIZE_FIX(temp)->num_entries; 803 num_entries = A_SIZE_FIX(temp)->num_entries;
802 804
803 if (pg_start < intel_private.gtt_entries) { 805 if (pg_start < intel_private.gtt_entries) {
804 printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", 806 dev_printk(KERN_DEBUG, &intel_private.pcidev->dev,
805 pg_start, intel_private.gtt_entries); 807 "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n",
808 pg_start, intel_private.gtt_entries);
806 809
807 printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n"); 810 dev_info(&intel_private.pcidev->dev,
811 "trying to insert into local/stolen memory\n");
808 goto out_err; 812 goto out_err;
809 } 813 }
810 814
@@ -851,7 +855,8 @@ static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start,
851 return 0; 855 return 0;
852 856
853 if (pg_start < intel_private.gtt_entries) { 857 if (pg_start < intel_private.gtt_entries) {
854 printk(KERN_INFO PFX "Trying to disable local/stolen memory\n"); 858 dev_info(&intel_private.pcidev->dev,
859 "trying to disable local/stolen memory\n");
855 return -EINVAL; 860 return -EINVAL;
856 } 861 }
857 862
@@ -957,7 +962,7 @@ static void intel_i9xx_setup_flush(void)
957 if (intel_private.ifp_resource.start) { 962 if (intel_private.ifp_resource.start) {
958 intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); 963 intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE);
959 if (!intel_private.i9xx_flush_page) 964 if (!intel_private.i9xx_flush_page)
960 printk(KERN_INFO "unable to ioremap flush page - no chipset flushing"); 965 dev_info(&intel_private.pcidev->dev, "can't ioremap flush page - no chipset flushing");
961 } 966 }
962} 967}
963 968
@@ -1028,10 +1033,12 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
1028 num_entries = A_SIZE_FIX(temp)->num_entries; 1033 num_entries = A_SIZE_FIX(temp)->num_entries;
1029 1034
1030 if (pg_start < intel_private.gtt_entries) { 1035 if (pg_start < intel_private.gtt_entries) {
1031 printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", 1036 dev_printk(KERN_DEBUG, &intel_private.pcidev->dev,
1032 pg_start, intel_private.gtt_entries); 1037 "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n",
1038 pg_start, intel_private.gtt_entries);
1033 1039
1034 printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n"); 1040 dev_info(&intel_private.pcidev->dev,
1041 "trying to insert into local/stolen memory\n");
1035 goto out_err; 1042 goto out_err;
1036 } 1043 }
1037 1044
@@ -1078,7 +1085,8 @@ static int intel_i915_remove_entries(struct agp_memory *mem, off_t pg_start,
1078 return 0; 1085 return 0;
1079 1086
1080 if (pg_start < intel_private.gtt_entries) { 1087 if (pg_start < intel_private.gtt_entries) {
1081 printk(KERN_INFO PFX "Trying to disable local/stolen memory\n"); 1088 dev_info(&intel_private.pcidev->dev,
1089 "trying to disable local/stolen memory\n");
1082 return -EINVAL; 1090 return -EINVAL;
1083 } 1091 }
1084 1092
@@ -1182,7 +1190,7 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
1182static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) 1190static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
1183{ 1191{
1184 switch (agp_bridge->dev->device) { 1192 switch (agp_bridge->dev->device) {
1185 case PCI_DEVICE_ID_INTEL_IGD_HB: 1193 case PCI_DEVICE_ID_INTEL_GM45_HB:
1186 case PCI_DEVICE_ID_INTEL_IGD_E_HB: 1194 case PCI_DEVICE_ID_INTEL_IGD_E_HB:
1187 case PCI_DEVICE_ID_INTEL_Q45_HB: 1195 case PCI_DEVICE_ID_INTEL_Q45_HB:
1188 case PCI_DEVICE_ID_INTEL_G45_HB: 1196 case PCI_DEVICE_ID_INTEL_G45_HB:
@@ -1379,7 +1387,7 @@ static int intel_815_configure(void)
1379 /* the Intel 815 chipset spec. says that bits 29-31 in the 1387 /* the Intel 815 chipset spec. says that bits 29-31 in the
1380 * ATTBASE register are reserved -> try not to write them */ 1388 * ATTBASE register are reserved -> try not to write them */
1381 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) { 1389 if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
1382 printk(KERN_EMERG PFX "gatt bus addr too high"); 1390 dev_emerg(&agp_bridge->dev->dev, "gatt bus addr too high");
1383 return -EINVAL; 1391 return -EINVAL;
1384 } 1392 }
1385 1393
@@ -2117,8 +2125,8 @@ static const struct intel_driver_description {
2117 NULL, &intel_g33_driver }, 2125 NULL, &intel_g33_driver },
2118 { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", 2126 { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
2119 NULL, &intel_g33_driver }, 2127 NULL, &intel_g33_driver },
2120 { PCI_DEVICE_ID_INTEL_IGD_HB, PCI_DEVICE_ID_INTEL_IGD_IG, 0, 2128 { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
2121 "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, 2129 "Mobile Intel? GM45 Express", NULL, &intel_i965_driver },
2122 { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0, 2130 { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
2123 "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, 2131 "Intel Integrated Graphics Device", NULL, &intel_i965_driver },
2124 { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0, 2132 { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0,
@@ -2163,8 +2171,8 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2163 2171
2164 if (intel_agp_chipsets[i].name == NULL) { 2172 if (intel_agp_chipsets[i].name == NULL) {
2165 if (cap_ptr) 2173 if (cap_ptr)
2166 printk(KERN_WARNING PFX "Unsupported Intel chipset" 2174 dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n",
2167 "(device id: %04x)\n", pdev->device); 2175 pdev->vendor, pdev->device);
2168 agp_put_bridge(bridge); 2176 agp_put_bridge(bridge);
2169 return -ENODEV; 2177 return -ENODEV;
2170 } 2178 }
@@ -2172,9 +2180,8 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2172 if (bridge->driver == NULL) { 2180 if (bridge->driver == NULL) {
2173 /* bridge has no AGP and no IGD detected */ 2181 /* bridge has no AGP and no IGD detected */
2174 if (cap_ptr) 2182 if (cap_ptr)
2175 printk(KERN_WARNING PFX "Failed to find bridge device " 2183 dev_warn(&pdev->dev, "can't find bridge device (chip_id: %04x)\n",
2176 "(chip_id: %04x)\n", 2184 intel_agp_chipsets[i].gmch_chip_id);
2177 intel_agp_chipsets[i].gmch_chip_id);
2178 agp_put_bridge(bridge); 2185 agp_put_bridge(bridge);
2179 return -ENODEV; 2186 return -ENODEV;
2180 } 2187 }
@@ -2183,8 +2190,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2183 bridge->capndx = cap_ptr; 2190 bridge->capndx = cap_ptr;
2184 bridge->dev_private_data = &intel_private; 2191 bridge->dev_private_data = &intel_private;
2185 2192
2186 printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", 2193 dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
2187 intel_agp_chipsets[i].name);
2188 2194
2189 /* 2195 /*
2190 * The following fixes the case where the BIOS has "forgotten" to 2196 * The following fixes the case where the BIOS has "forgotten" to
@@ -2194,7 +2200,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2194 r = &pdev->resource[0]; 2200 r = &pdev->resource[0];
2195 if (!r->start && r->end) { 2201 if (!r->start && r->end) {
2196 if (pci_assign_resource(pdev, 0)) { 2202 if (pci_assign_resource(pdev, 0)) {
2197 printk(KERN_ERR PFX "could not assign resource 0\n"); 2203 dev_err(&pdev->dev, "can't assign resource 0\n");
2198 agp_put_bridge(bridge); 2204 agp_put_bridge(bridge);
2199 return -ENODEV; 2205 return -ENODEV;
2200 } 2206 }
@@ -2206,7 +2212,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
2206 * 20030610 - hamish@zot.org 2212 * 20030610 - hamish@zot.org
2207 */ 2213 */
2208 if (pci_enable_device(pdev)) { 2214 if (pci_enable_device(pdev)) {
2209 printk(KERN_ERR PFX "Unable to Enable PCI device\n"); 2215 dev_err(&pdev->dev, "can't enable PCI device\n");
2210 agp_put_bridge(bridge); 2216 agp_put_bridge(bridge);
2211 return -ENODEV; 2217 return -ENODEV;
2212 } 2218 }
@@ -2238,6 +2244,7 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
2238static int agp_intel_resume(struct pci_dev *pdev) 2244static int agp_intel_resume(struct pci_dev *pdev)
2239{ 2245{
2240 struct agp_bridge_data *bridge = pci_get_drvdata(pdev); 2246 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
2247 int ret_val;
2241 2248
2242 pci_restore_state(pdev); 2249 pci_restore_state(pdev);
2243 2250
@@ -2265,6 +2272,10 @@ static int agp_intel_resume(struct pci_dev *pdev)
2265 else if (bridge->driver == &intel_i965_driver) 2272 else if (bridge->driver == &intel_i965_driver)
2266 intel_i915_configure(); 2273 intel_i915_configure();
2267 2274
2275 ret_val = agp_rebind_memory();
2276 if (ret_val != 0)
2277 return ret_val;
2278
2268 return 0; 2279 return 0;
2269} 2280}
2270#endif 2281#endif
@@ -2315,7 +2326,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
2315 ID(PCI_DEVICE_ID_INTEL_G33_HB), 2326 ID(PCI_DEVICE_ID_INTEL_G33_HB),
2316 ID(PCI_DEVICE_ID_INTEL_Q35_HB), 2327 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
2317 ID(PCI_DEVICE_ID_INTEL_Q33_HB), 2328 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
2318 ID(PCI_DEVICE_ID_INTEL_IGD_HB), 2329 ID(PCI_DEVICE_ID_INTEL_GM45_HB),
2319 ID(PCI_DEVICE_ID_INTEL_IGD_E_HB), 2330 ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
2320 ID(PCI_DEVICE_ID_INTEL_Q45_HB), 2331 ID(PCI_DEVICE_ID_INTEL_Q45_HB),
2321 ID(PCI_DEVICE_ID_INTEL_G45_HB), 2332 ID(PCI_DEVICE_ID_INTEL_G45_HB),
diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c
index 3f9ccde62377..c73385cc4b8a 100644
--- a/drivers/char/agp/isoch.c
+++ b/drivers/char/agp/isoch.c
@@ -153,7 +153,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge,
153 153
154 /* Check if this configuration has any chance of working */ 154 /* Check if this configuration has any chance of working */
155 if (tot_bw > target.maxbw) { 155 if (tot_bw > target.maxbw) {
156 printk(KERN_ERR PFX "isochronous bandwidth required " 156 dev_err(&td->dev, "isochronous bandwidth required "
157 "by AGP 3.0 devices exceeds that which is supported by " 157 "by AGP 3.0 devices exceeds that which is supported by "
158 "the AGP 3.0 bridge!\n"); 158 "the AGP 3.0 bridge!\n");
159 ret = -ENODEV; 159 ret = -ENODEV;
@@ -188,7 +188,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge,
188 /* Exit if the minimal ISOCH_N allocation among the masters is more 188 /* Exit if the minimal ISOCH_N allocation among the masters is more
189 * than the target can handle. */ 189 * than the target can handle. */
190 if (tot_n > target.n) { 190 if (tot_n > target.n) {
191 printk(KERN_ERR PFX "number of isochronous " 191 dev_err(&td->dev, "number of isochronous "
192 "transactions per period required by AGP 3.0 devices " 192 "transactions per period required by AGP 3.0 devices "
193 "exceeds that which is supported by the AGP 3.0 " 193 "exceeds that which is supported by the AGP 3.0 "
194 "bridge!\n"); 194 "bridge!\n");
@@ -229,7 +229,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge,
229 /* Exit if the minimal RQ needs of the masters exceeds what the target 229 /* Exit if the minimal RQ needs of the masters exceeds what the target
230 * can provide. */ 230 * can provide. */
231 if (tot_rq > rq_isoch) { 231 if (tot_rq > rq_isoch) {
232 printk(KERN_ERR PFX "number of request queue slots " 232 dev_err(&td->dev, "number of request queue slots "
233 "required by the isochronous bandwidth requested by " 233 "required by the isochronous bandwidth requested by "
234 "AGP 3.0 devices exceeds the number provided by the " 234 "AGP 3.0 devices exceeds the number provided by the "
235 "AGP 3.0 bridge!\n"); 235 "AGP 3.0 bridge!\n");
@@ -359,8 +359,9 @@ int agp_3_5_enable(struct agp_bridge_data *bridge)
359 case 0x0001: /* Unclassified device */ 359 case 0x0001: /* Unclassified device */
360 /* Don't know what this is, but log it for investigation. */ 360 /* Don't know what this is, but log it for investigation. */
361 if (mcapndx != 0) { 361 if (mcapndx != 0) {
362 printk (KERN_INFO PFX "Wacky, found unclassified AGP device. %x:%x\n", 362 dev_info(&td->dev, "wacky, found unclassified AGP device %s [%04x/%04x]\n",
363 dev->vendor, dev->device); 363 pci_name(dev),
364 dev->vendor, dev->device);
364 } 365 }
365 continue; 366 continue;
366 367
@@ -407,17 +408,18 @@ int agp_3_5_enable(struct agp_bridge_data *bridge)
407 } 408 }
408 409
409 if (mcapndx == 0) { 410 if (mcapndx == 0) {
410 printk(KERN_ERR PFX "woah! Non-AGP device " 411 dev_err(&td->dev, "woah! Non-AGP device %s on "
411 "found on the secondary bus of an AGP 3.5 bridge!\n"); 412 "secondary bus of AGP 3.5 bridge!\n",
413 pci_name(dev));
412 ret = -ENODEV; 414 ret = -ENODEV;
413 goto free_and_exit; 415 goto free_and_exit;
414 } 416 }
415 417
416 mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf; 418 mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
417 if (mmajor < 3) { 419 if (mmajor < 3) {
418 printk(KERN_ERR PFX "woah! AGP 2.0 device " 420 dev_err(&td->dev, "woah! AGP 2.0 device %s on "
419 "found on the secondary bus of an AGP 3.5 " 421 "secondary bus of AGP 3.5 bridge operating "
420 "bridge operating with AGP 3.0 electricals!\n"); 422 "with AGP 3.0 electricals!\n", pci_name(dev));
421 ret = -ENODEV; 423 ret = -ENODEV;
422 goto free_and_exit; 424 goto free_and_exit;
423 } 425 }
@@ -427,10 +429,10 @@ int agp_3_5_enable(struct agp_bridge_data *bridge)
427 pci_read_config_dword(dev, cur->capndx+AGPSTAT, &mstatus); 429 pci_read_config_dword(dev, cur->capndx+AGPSTAT, &mstatus);
428 430
429 if (((mstatus >> 3) & 0x1) == 0) { 431 if (((mstatus >> 3) & 0x1) == 0) {
430 printk(KERN_ERR PFX "woah! AGP 3.x device " 432 dev_err(&td->dev, "woah! AGP 3.x device %s not "
431 "not operating in AGP 3.x mode found on the " 433 "operating in AGP 3.x mode on secondary bus "
432 "secondary bus of an AGP 3.5 bridge operating " 434 "of AGP 3.5 bridge operating with AGP 3.0 "
433 "with AGP 3.0 electricals!\n"); 435 "electricals!\n", pci_name(dev));
434 ret = -ENODEV; 436 ret = -ENODEV;
435 goto free_and_exit; 437 goto free_and_exit;
436 } 438 }
@@ -444,9 +446,9 @@ int agp_3_5_enable(struct agp_bridge_data *bridge)
444 if (isoch) { 446 if (isoch) {
445 ret = agp_3_5_isochronous_node_enable(bridge, dev_list, ndevs); 447 ret = agp_3_5_isochronous_node_enable(bridge, dev_list, ndevs);
446 if (ret) { 448 if (ret) {
447 printk(KERN_INFO PFX "Something bad happened setting " 449 dev_info(&td->dev, "something bad happened setting "
448 "up isochronous xfers. Falling back to " 450 "up isochronous xfers; falling back to "
449 "non-isochronous xfer mode.\n"); 451 "non-isochronous xfer mode\n");
450 } else { 452 } else {
451 goto free_and_exit; 453 goto free_and_exit;
452 } 454 }
@@ -466,4 +468,3 @@ free_and_exit:
466get_out: 468get_out:
467 return ret; 469 return ret;
468} 470}
469
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index b6791846809f..2587ef96a960 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -79,10 +79,8 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode)
79 u32 command; 79 u32 command;
80 int rate; 80 int rate;
81 81
82 printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n", 82 dev_info(&agp_bridge->dev->dev, "AGP %d.%d bridge\n",
83 agp_bridge->major_version, 83 agp_bridge->major_version, agp_bridge->minor_version);
84 agp_bridge->minor_version,
85 pci_name(agp_bridge->dev));
86 84
87 pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + PCI_AGP_STATUS, &command); 85 pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + PCI_AGP_STATUS, &command);
88 command = agp_collect_device_status(bridge, mode, command); 86 command = agp_collect_device_status(bridge, mode, command);
@@ -94,8 +92,8 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode)
94 if (!agp) 92 if (!agp)
95 continue; 93 continue;
96 94
97 printk(KERN_INFO PFX "Putting AGP V3 device at %s into %dx mode\n", 95 dev_info(&agp_bridge->dev->dev, "putting AGP V3 device at %s into %dx mode\n",
98 pci_name(device), rate); 96 pci_name(device), rate);
99 97
100 pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command); 98 pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command);
101 99
@@ -105,7 +103,7 @@ static void sis_delayed_enable(struct agp_bridge_data *bridge, u32 mode)
105 * cannot be configured 103 * cannot be configured
106 */ 104 */
107 if (device->device == bridge->dev->device) { 105 if (device->device == bridge->dev->device) {
108 printk(KERN_INFO PFX "SiS delay workaround: giving bridge time to recover.\n"); 106 dev_info(&agp_bridge->dev->dev, "SiS delay workaround: giving bridge time to recover\n");
109 msleep(10); 107 msleep(10);
110 } 108 }
111 } 109 }
@@ -190,7 +188,8 @@ static int __devinit agp_sis_probe(struct pci_dev *pdev,
190 return -ENODEV; 188 return -ENODEV;
191 189
192 190
193 printk(KERN_INFO PFX "Detected SiS chipset - id:%i\n", pdev->device); 191 dev_info(&pdev->dev, "SiS chipset [%04x/%04x]\n",
192 pdev->vendor, pdev->device);
194 bridge = agp_alloc_bridge(); 193 bridge = agp_alloc_bridge();
195 if (!bridge) 194 if (!bridge)
196 return -ENOMEM; 195 return -ENOMEM;
@@ -242,7 +241,7 @@ static struct pci_device_id agp_sis_pci_table[] = {
242 .class = (PCI_CLASS_BRIDGE_HOST << 8), 241 .class = (PCI_CLASS_BRIDGE_HOST << 8),
243 .class_mask = ~0, 242 .class_mask = ~0,
244 .vendor = PCI_VENDOR_ID_SI, 243 .vendor = PCI_VENDOR_ID_SI,
245 .device = PCI_DEVICE_ID_SI_5591_AGP, 244 .device = PCI_DEVICE_ID_SI_5591,
246 .subvendor = PCI_ANY_ID, 245 .subvendor = PCI_ANY_ID,
247 .subdevice = PCI_ANY_ID, 246 .subdevice = PCI_ANY_ID,
248 }, 247 },
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 0e054c134490..2fb27fe4c10c 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -241,7 +241,8 @@ static void serverworks_tlbflush(struct agp_memory *temp)
241 while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) { 241 while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) {
242 cpu_relax(); 242 cpu_relax();
243 if (time_after(jiffies, timeout)) { 243 if (time_after(jiffies, timeout)) {
244 printk(KERN_ERR PFX "TLB post flush took more than 3 seconds\n"); 244 dev_err(&serverworks_private.svrwrks_dev->dev,
245 "TLB post flush took more than 3 seconds\n");
245 break; 246 break;
246 } 247 }
247 } 248 }
@@ -251,7 +252,8 @@ static void serverworks_tlbflush(struct agp_memory *temp)
251 while (readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) { 252 while (readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) {
252 cpu_relax(); 253 cpu_relax();
253 if (time_after(jiffies, timeout)) { 254 if (time_after(jiffies, timeout)) {
254 printk(KERN_ERR PFX "TLB Dir flush took more than 3 seconds\n"); 255 dev_err(&serverworks_private.svrwrks_dev->dev,
256 "TLB Dir flush took more than 3 seconds\n");
255 break; 257 break;
256 } 258 }
257 } 259 }
@@ -271,7 +273,7 @@ static int serverworks_configure(void)
271 temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); 273 temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
272 serverworks_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); 274 serverworks_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
273 if (!serverworks_private.registers) { 275 if (!serverworks_private.registers) {
274 printk (KERN_ERR PFX "Unable to ioremap() memory.\n"); 276 dev_err(&agp_bridge->dev->dev, "can't ioremap(%#x)\n", temp);
275 return -ENOMEM; 277 return -ENOMEM;
276 } 278 }
277 279
@@ -451,7 +453,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
451 453
452 switch (pdev->device) { 454 switch (pdev->device) {
453 case 0x0006: 455 case 0x0006:
454 printk (KERN_ERR PFX "ServerWorks CNB20HE is unsupported due to lack of documentation.\n"); 456 dev_err(&pdev->dev, "ServerWorks CNB20HE is unsupported due to lack of documentation\n");
455 return -ENODEV; 457 return -ENODEV;
456 458
457 case PCI_DEVICE_ID_SERVERWORKS_HE: 459 case PCI_DEVICE_ID_SERVERWORKS_HE:
@@ -461,8 +463,8 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
461 463
462 default: 464 default:
463 if (cap_ptr) 465 if (cap_ptr)
464 printk(KERN_ERR PFX "Unsupported Serverworks chipset " 466 dev_err(&pdev->dev, "unsupported Serverworks chipset "
465 "(device id: %04x)\n", pdev->device); 467 "[%04x/%04x]\n", pdev->vendor, pdev->device);
466 return -ENODEV; 468 return -ENODEV;
467 } 469 }
468 470
@@ -470,8 +472,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
470 bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number, 472 bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
471 PCI_DEVFN(0, 1)); 473 PCI_DEVFN(0, 1));
472 if (!bridge_dev) { 474 if (!bridge_dev) {
473 printk(KERN_INFO PFX "Detected a Serverworks chipset " 475 dev_info(&pdev->dev, "can't find secondary device\n");
474 "but could not find the secondary device.\n");
475 return -ENODEV; 476 return -ENODEV;
476 } 477 }
477 478
@@ -482,8 +483,8 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
482 if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) { 483 if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
483 pci_read_config_dword(pdev, SVWRKS_APSIZE + 4, &temp2); 484 pci_read_config_dword(pdev, SVWRKS_APSIZE + 4, &temp2);
484 if (temp2 != 0) { 485 if (temp2 != 0) {
485 printk(KERN_INFO PFX "Detected 64 bit aperture address, " 486 dev_info(&pdev->dev, "64 bit aperture address, "
486 "but top bits are not zero. Disabling agp\n"); 487 "but top bits are not zero; disabling AGP\n");
487 return -ENODEV; 488 return -ENODEV;
488 } 489 }
489 serverworks_private.mm_addr_ofs = 0x18; 490 serverworks_private.mm_addr_ofs = 0x18;
@@ -495,8 +496,8 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
495 pci_read_config_dword(pdev, 496 pci_read_config_dword(pdev,
496 serverworks_private.mm_addr_ofs + 4, &temp2); 497 serverworks_private.mm_addr_ofs + 4, &temp2);
497 if (temp2 != 0) { 498 if (temp2 != 0) {
498 printk(KERN_INFO PFX "Detected 64 bit MMIO address, " 499 dev_info(&pdev->dev, "64 bit MMIO address, but top "
499 "but top bits are not zero. Disabling agp\n"); 500 "bits are not zero; disabling AGP\n");
500 return -ENODEV; 501 return -ENODEV;
501 } 502 }
502 } 503 }
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index d2fa3cfca02a..eef72709ec53 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -46,8 +46,8 @@ static int uninorth_fetch_size(void)
46 break; 46 break;
47 47
48 if (i == agp_bridge->driver->num_aperture_sizes) { 48 if (i == agp_bridge->driver->num_aperture_sizes) {
49 printk(KERN_ERR PFX "Invalid aperture size, using" 49 dev_err(&agp_bridge->dev->dev, "invalid aperture size, "
50 " default\n"); 50 "using default\n");
51 size = 0; 51 size = 0;
52 aperture = NULL; 52 aperture = NULL;
53 } 53 }
@@ -108,8 +108,8 @@ static int uninorth_configure(void)
108 108
109 current_size = A_SIZE_32(agp_bridge->current_size); 109 current_size = A_SIZE_32(agp_bridge->current_size);
110 110
111 printk(KERN_INFO PFX "configuring for size idx: %d\n", 111 dev_info(&agp_bridge->dev->dev, "configuring for size idx: %d\n",
112 current_size->size_value); 112 current_size->size_value);
113 113
114 /* aperture size and gatt addr */ 114 /* aperture size and gatt addr */
115 pci_write_config_dword(agp_bridge->dev, 115 pci_write_config_dword(agp_bridge->dev,
@@ -197,8 +197,9 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
197 gp = (u32 *) &agp_bridge->gatt_table[pg_start]; 197 gp = (u32 *) &agp_bridge->gatt_table[pg_start];
198 for (i = 0; i < mem->page_count; ++i) { 198 for (i = 0; i < mem->page_count; ++i) {
199 if (gp[i]) { 199 if (gp[i]) {
200 printk("u3_insert_memory: entry 0x%x occupied (%x)\n", 200 dev_info(&agp_bridge->dev->dev,
201 i, gp[i]); 201 "u3_insert_memory: entry 0x%x occupied (%x)\n",
202 i, gp[i]);
202 return -EBUSY; 203 return -EBUSY;
203 } 204 }
204 } 205 }
@@ -276,8 +277,8 @@ static void uninorth_agp_enable(struct agp_bridge_data *bridge, u32 mode)
276 &scratch); 277 &scratch);
277 } while ((scratch & PCI_AGP_COMMAND_AGP) == 0 && ++timeout < 1000); 278 } while ((scratch & PCI_AGP_COMMAND_AGP) == 0 && ++timeout < 1000);
278 if ((scratch & PCI_AGP_COMMAND_AGP) == 0) 279 if ((scratch & PCI_AGP_COMMAND_AGP) == 0)
279 printk(KERN_ERR PFX "failed to write UniNorth AGP" 280 dev_err(&bridge->dev->dev, "can't write UniNorth AGP "
280 " command register\n"); 281 "command register\n");
281 282
282 if (uninorth_rev >= 0x30) { 283 if (uninorth_rev >= 0x30) {
283 /* This is an AGP V3 */ 284 /* This is an AGP V3 */
@@ -330,8 +331,8 @@ static int agp_uninorth_suspend(struct pci_dev *pdev)
330 pci_read_config_dword(device, agp + PCI_AGP_COMMAND, &cmd); 331 pci_read_config_dword(device, agp + PCI_AGP_COMMAND, &cmd);
331 if (!(cmd & PCI_AGP_COMMAND_AGP)) 332 if (!(cmd & PCI_AGP_COMMAND_AGP))
332 continue; 333 continue;
333 printk("uninorth-agp: disabling AGP on device %s\n", 334 dev_info(&pdev->dev, "disabling AGP on device %s\n",
334 pci_name(device)); 335 pci_name(device));
335 cmd &= ~PCI_AGP_COMMAND_AGP; 336 cmd &= ~PCI_AGP_COMMAND_AGP;
336 pci_write_config_dword(device, agp + PCI_AGP_COMMAND, cmd); 337 pci_write_config_dword(device, agp + PCI_AGP_COMMAND, cmd);
337 } 338 }
@@ -341,8 +342,7 @@ static int agp_uninorth_suspend(struct pci_dev *pdev)
341 pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd); 342 pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd);
342 bridge->dev_private_data = (void *)(long)cmd; 343 bridge->dev_private_data = (void *)(long)cmd;
343 if (cmd & PCI_AGP_COMMAND_AGP) { 344 if (cmd & PCI_AGP_COMMAND_AGP) {
344 printk("uninorth-agp: disabling AGP on bridge %s\n", 345 dev_info(&pdev->dev, "disabling AGP on bridge\n");
345 pci_name(pdev));
346 cmd &= ~PCI_AGP_COMMAND_AGP; 346 cmd &= ~PCI_AGP_COMMAND_AGP;
347 pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, cmd); 347 pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, cmd);
348 } 348 }
@@ -591,14 +591,14 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
591 /* probe for known chipsets */ 591 /* probe for known chipsets */
592 for (j = 0; devs[j].chipset_name != NULL; ++j) { 592 for (j = 0; devs[j].chipset_name != NULL; ++j) {
593 if (pdev->device == devs[j].device_id) { 593 if (pdev->device == devs[j].device_id) {
594 printk(KERN_INFO PFX "Detected Apple %s chipset\n", 594 dev_info(&pdev->dev, "Apple %s chipset\n",
595 devs[j].chipset_name); 595 devs[j].chipset_name);
596 goto found; 596 goto found;
597 } 597 }
598 } 598 }
599 599
600 printk(KERN_ERR PFX "Unsupported Apple chipset (device id: %04x).\n", 600 dev_err(&pdev->dev, "unsupported Apple chipset [%04x/%04x]\n",
601 pdev->device); 601 pdev->vendor, pdev->device);
602 return -ENODEV; 602 return -ENODEV;
603 603
604 found: 604 found:
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 3530ff417a51..6e763e3f5a81 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1254,7 +1254,7 @@ static int rs_break(struct tty_struct *tty, int break_state)
1254 unsigned long flags; 1254 unsigned long flags;
1255 1255
1256 if (serial_paranoia_check(info, tty->name, "rs_break")) 1256 if (serial_paranoia_check(info, tty->name, "rs_break"))
1257 return; 1257 return -EINVAL;
1258 1258
1259 local_irq_save(flags); 1259 local_irq_save(flags);
1260 if (break_state == -1) 1260 if (break_state == -1)
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 34275c6f1da2..74e9cd81b5b2 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -10,7 +10,7 @@
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/smp_lock.h> 11#include <linux/smp_lock.h>
12 12
13#include <asm/hardware.h> 13#include <mach/hardware.h>
14#include <asm/mach-types.h> 14#include <asm/mach-types.h>
15#include <asm/uaccess.h> 15#include <asm/uaccess.h>
16#include <asm/therm.h> 16#include <asm/therm.h>
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 02aac104842d..fd64137b1ab9 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -322,11 +322,10 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
322 322
323 hp->tty = tty; 323 hp->tty = tty;
324 324
325 if (hp->ops->notifier_add)
326 rc = hp->ops->notifier_add(hp, hp->data);
327
328 spin_unlock_irqrestore(&hp->lock, flags); 325 spin_unlock_irqrestore(&hp->lock, flags);
329 326
327 if (hp->ops->notifier_add)
328 rc = hp->ops->notifier_add(hp, hp->data);
330 329
331 /* 330 /*
332 * If the notifier fails we return an error. The tty layer 331 * If the notifier fails we return an error. The tty layer
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c
index bab43ca32ac1..263567f5f392 100644
--- a/drivers/char/hw_random/ixp4xx-rng.c
+++ b/drivers/char/hw_random/ixp4xx-rng.c
@@ -23,7 +23,7 @@
23#include <linux/hw_random.h> 23#include <linux/hw_random.h>
24 24
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/hardware.h> 26#include <mach/hardware.h>
27 27
28 28
29static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer) 29static int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer)
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c
index f7feae4ebb5e..128202e18fc9 100644
--- a/drivers/char/hw_random/via-rng.c
+++ b/drivers/char/hw_random/via-rng.c
@@ -31,6 +31,7 @@
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/msr.h> 32#include <asm/msr.h>
33#include <asm/cpufeature.h> 33#include <asm/cpufeature.h>
34#include <asm/i387.h>
34 35
35 36
36#define PFX KBUILD_MODNAME ": " 37#define PFX KBUILD_MODNAME ": "
@@ -67,16 +68,23 @@ enum {
67 * Another possible performance boost may come from simply buffering 68 * Another possible performance boost may come from simply buffering
68 * until we have 4 bytes, thus returning a u32 at a time, 69 * until we have 4 bytes, thus returning a u32 at a time,
69 * instead of the current u8-at-a-time. 70 * instead of the current u8-at-a-time.
71 *
72 * Padlock instructions can generate a spurious DNA fault, so
73 * we have to call them in the context of irq_ts_save/restore()
70 */ 74 */
71 75
72static inline u32 xstore(u32 *addr, u32 edx_in) 76static inline u32 xstore(u32 *addr, u32 edx_in)
73{ 77{
74 u32 eax_out; 78 u32 eax_out;
79 int ts_state;
80
81 ts_state = irq_ts_save();
75 82
76 asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */" 83 asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */"
77 :"=m"(*addr), "=a"(eax_out) 84 :"=m"(*addr), "=a"(eax_out)
78 :"D"(addr), "d"(edx_in)); 85 :"D"(addr), "d"(edx_in));
79 86
87 irq_ts_restore(ts_state);
80 return eax_out; 88 return eax_out;
81} 89}
82 90
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c
index b1414507997c..3a23e7694d55 100644
--- a/drivers/char/pcmcia/ipwireless/tty.c
+++ b/drivers/char/pcmcia/ipwireless/tty.c
@@ -29,7 +29,6 @@
29#include <linux/tty_driver.h> 29#include <linux/tty_driver.h>
30#include <linux/tty_flip.h> 30#include <linux/tty_flip.h>
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <linux/version.h>
33 32
34#include "tty.h" 33#include "tty.h"
35#include "network.h" 34#include "network.h"
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index d1fceabe3aef..c240562c218b 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -232,7 +232,6 @@ typedef struct _mgslpc_info {
232 232
233 /* SPPP/Cisco HDLC device parts */ 233 /* SPPP/Cisco HDLC device parts */
234 int netcount; 234 int netcount;
235 int dosyncppp;
236 spinlock_t netlock; 235 spinlock_t netlock;
237 236
238#if SYNCLINK_GENERIC_HDLC 237#if SYNCLINK_GENERIC_HDLC
@@ -459,13 +458,11 @@ static int ttymajor=0;
459 458
460static int debug_level = 0; 459static int debug_level = 0;
461static int maxframe[MAX_DEVICE_COUNT] = {0,}; 460static int maxframe[MAX_DEVICE_COUNT] = {0,};
462static int dosyncppp[MAX_DEVICE_COUNT] = {1,1,1,1};
463 461
464module_param(break_on_load, bool, 0); 462module_param(break_on_load, bool, 0);
465module_param(ttymajor, int, 0); 463module_param(ttymajor, int, 0);
466module_param(debug_level, int, 0); 464module_param(debug_level, int, 0);
467module_param_array(maxframe, int, NULL, 0); 465module_param_array(maxframe, int, NULL, 0);
468module_param_array(dosyncppp, int, NULL, 0);
469 466
470MODULE_LICENSE("GPL"); 467MODULE_LICENSE("GPL");
471 468
@@ -2915,7 +2912,6 @@ static void mgslpc_add_device(MGSLPC_INFO *info)
2915 if (info->line < MAX_DEVICE_COUNT) { 2912 if (info->line < MAX_DEVICE_COUNT) {
2916 if (maxframe[info->line]) 2913 if (maxframe[info->line])
2917 info->max_frame_size = maxframe[info->line]; 2914 info->max_frame_size = maxframe[info->line];
2918 info->dosyncppp = dosyncppp[info->line];
2919 } 2915 }
2920 2916
2921 mgslpc_device_count++; 2917 mgslpc_device_count++;
diff --git a/drivers/char/random.c b/drivers/char/random.c
index e0d0e371909c..1838aa3d24fe 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1571,6 +1571,7 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
1571 1571
1572 return half_md4_transform(hash, keyptr->secret); 1572 return half_md4_transform(hash, keyptr->secret);
1573} 1573}
1574EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
1574 1575
1575#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1576#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1576u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, 1577u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index d9799e2bcfbf..f53d4d00faf0 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -78,7 +78,6 @@
78#include <linux/wait.h> 78#include <linux/wait.h>
79#include <linux/bcd.h> 79#include <linux/bcd.h>
80#include <linux/delay.h> 80#include <linux/delay.h>
81#include <linux/smp_lock.h>
82#include <linux/uaccess.h> 81#include <linux/uaccess.h>
83 82
84#include <asm/current.h> 83#include <asm/current.h>
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ef6706f09061..500f5176b6ba 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -304,7 +304,6 @@ struct mgsl_struct {
304 304
305 /* generic HDLC device parts */ 305 /* generic HDLC device parts */
306 int netcount; 306 int netcount;
307 int dosyncppp;
308 spinlock_t netlock; 307 spinlock_t netlock;
309 308
310#if SYNCLINK_GENERIC_HDLC 309#if SYNCLINK_GENERIC_HDLC
@@ -868,7 +867,6 @@ static int irq[MAX_ISA_DEVICES];
868static int dma[MAX_ISA_DEVICES]; 867static int dma[MAX_ISA_DEVICES];
869static int debug_level; 868static int debug_level;
870static int maxframe[MAX_TOTAL_DEVICES]; 869static int maxframe[MAX_TOTAL_DEVICES];
871static int dosyncppp[MAX_TOTAL_DEVICES];
872static int txdmabufs[MAX_TOTAL_DEVICES]; 870static int txdmabufs[MAX_TOTAL_DEVICES];
873static int txholdbufs[MAX_TOTAL_DEVICES]; 871static int txholdbufs[MAX_TOTAL_DEVICES];
874 872
@@ -879,7 +877,6 @@ module_param_array(irq, int, NULL, 0);
879module_param_array(dma, int, NULL, 0); 877module_param_array(dma, int, NULL, 0);
880module_param(debug_level, int, 0); 878module_param(debug_level, int, 0);
881module_param_array(maxframe, int, NULL, 0); 879module_param_array(maxframe, int, NULL, 0);
882module_param_array(dosyncppp, int, NULL, 0);
883module_param_array(txdmabufs, int, NULL, 0); 880module_param_array(txdmabufs, int, NULL, 0);
884module_param_array(txholdbufs, int, NULL, 0); 881module_param_array(txholdbufs, int, NULL, 0);
885 882
@@ -4258,7 +4255,6 @@ static void mgsl_add_device( struct mgsl_struct *info )
4258 if (info->line < MAX_TOTAL_DEVICES) { 4255 if (info->line < MAX_TOTAL_DEVICES) {
4259 if (maxframe[info->line]) 4256 if (maxframe[info->line])
4260 info->max_frame_size = maxframe[info->line]; 4257 info->max_frame_size = maxframe[info->line];
4261 info->dosyncppp = dosyncppp[info->line];
4262 4258
4263 if (txdmabufs[info->line]) { 4259 if (txdmabufs[info->line]) {
4264 info->num_tx_dma_buffers = txdmabufs[info->line]; 4260 info->num_tx_dma_buffers = txdmabufs[info->line];
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 3e9058993e41..08911ed66494 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -47,7 +47,6 @@
47 47
48 48
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/version.h>
51#include <linux/errno.h> 50#include <linux/errno.h>
52#include <linux/signal.h> 51#include <linux/signal.h>
53#include <linux/sched.h> 52#include <linux/sched.h>
@@ -128,17 +127,14 @@ static int slgt_device_count;
128static int ttymajor; 127static int ttymajor;
129static int debug_level; 128static int debug_level;
130static int maxframe[MAX_DEVICES]; 129static int maxframe[MAX_DEVICES];
131static int dosyncppp[MAX_DEVICES];
132 130
133module_param(ttymajor, int, 0); 131module_param(ttymajor, int, 0);
134module_param(debug_level, int, 0); 132module_param(debug_level, int, 0);
135module_param_array(maxframe, int, NULL, 0); 133module_param_array(maxframe, int, NULL, 0);
136module_param_array(dosyncppp, int, NULL, 0);
137 134
138MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned"); 135MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned");
139MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail"); 136MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail");
140MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)"); 137MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)");
141MODULE_PARM_DESC(dosyncppp, "Enable synchronous net device, 0=disable 1=enable");
142 138
143/* 139/*
144 * tty support and callbacks 140 * tty support and callbacks
@@ -349,7 +345,6 @@ struct slgt_info {
349 /* SPPP/Cisco HDLC device parts */ 345 /* SPPP/Cisco HDLC device parts */
350 346
351 int netcount; 347 int netcount;
352 int dosyncppp;
353 spinlock_t netlock; 348 spinlock_t netlock;
354#if SYNCLINK_GENERIC_HDLC 349#if SYNCLINK_GENERIC_HDLC
355 struct net_device *netdev; 350 struct net_device *netdev;
@@ -3405,7 +3400,6 @@ static void add_device(struct slgt_info *info)
3405 if (info->line < MAX_DEVICES) { 3400 if (info->line < MAX_DEVICES) {
3406 if (maxframe[info->line]) 3401 if (maxframe[info->line])
3407 info->max_frame_size = maxframe[info->line]; 3402 info->max_frame_size = maxframe[info->line];
3408 info->dosyncppp = dosyncppp[info->line];
3409 } 3403 }
3410 3404
3411 slgt_device_count++; 3405 slgt_device_count++;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index c0490cbd0db2..6bdb44f7bec2 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -270,7 +270,6 @@ typedef struct _synclinkmp_info {
270 270
271 /* SPPP/Cisco HDLC device parts */ 271 /* SPPP/Cisco HDLC device parts */
272 int netcount; 272 int netcount;
273 int dosyncppp;
274 spinlock_t netlock; 273 spinlock_t netlock;
275 274
276#if SYNCLINK_GENERIC_HDLC 275#if SYNCLINK_GENERIC_HDLC
@@ -469,13 +468,11 @@ static int ttymajor = 0;
469 */ 468 */
470static int debug_level = 0; 469static int debug_level = 0;
471static int maxframe[MAX_DEVICES] = {0,}; 470static int maxframe[MAX_DEVICES] = {0,};
472static int dosyncppp[MAX_DEVICES] = {0,};
473 471
474module_param(break_on_load, bool, 0); 472module_param(break_on_load, bool, 0);
475module_param(ttymajor, int, 0); 473module_param(ttymajor, int, 0);
476module_param(debug_level, int, 0); 474module_param(debug_level, int, 0);
477module_param_array(maxframe, int, NULL, 0); 475module_param_array(maxframe, int, NULL, 0);
478module_param_array(dosyncppp, int, NULL, 0);
479 476
480static char *driver_name = "SyncLink MultiPort driver"; 477static char *driver_name = "SyncLink MultiPort driver";
481static char *driver_version = "$Revision: 4.38 $"; 478static char *driver_version = "$Revision: 4.38 $";
@@ -3752,7 +3749,6 @@ static void add_device(SLMP_INFO *info)
3752 if (info->line < MAX_DEVICES) { 3749 if (info->line < MAX_DEVICES) {
3753 if (maxframe[info->line]) 3750 if (maxframe[info->line])
3754 info->max_frame_size = maxframe[info->line]; 3751 info->max_frame_size = maxframe[info->line];
3755 info->dosyncppp = dosyncppp[info->line];
3756 } 3752 }
3757 3753
3758 synclinkmp_device_count++; 3754 synclinkmp_device_count++;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e1b46bc7e43c..a27160ba21d7 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1161,8 +1161,8 @@ void disassociate_ctty(int on_exit)
1161 tty = get_current_tty(); 1161 tty = get_current_tty();
1162 if (tty) { 1162 if (tty) {
1163 tty_pgrp = get_pid(tty->pgrp); 1163 tty_pgrp = get_pid(tty->pgrp);
1164 mutex_unlock(&tty_mutex);
1165 lock_kernel(); 1164 lock_kernel();
1165 mutex_unlock(&tty_mutex);
1166 /* XXX: here we race, there is nothing protecting tty */ 1166 /* XXX: here we race, there is nothing protecting tty */
1167 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) 1167 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
1168 tty_vhangup(tty); 1168 tty_vhangup(tty);
@@ -2496,45 +2496,25 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
2496} 2496}
2497 2497
2498/** 2498/**
2499 * tiocswinsz - implement window size set ioctl 2499 * tty_do_resize - resize event
2500 * @tty; tty 2500 * @tty: tty being resized
2501 * @arg: user buffer for result 2501 * @real_tty: real tty (if using a pty/tty pair)
2502 * @rows: rows (character)
2503 * @cols: cols (character)
2502 * 2504 *
2503 * Copies the user idea of the window size to the kernel. Traditionally 2505 * Update the termios variables and send the neccessary signals to
2504 * this is just advisory information but for the Linux console it 2506 * peform a terminal resize correctly
2505 * actually has driver level meaning and triggers a VC resize.
2506 *
2507 * Locking:
2508 * Called function use the console_sem is used to ensure we do
2509 * not try and resize the console twice at once.
2510 * The tty->termios_mutex is used to ensure we don't double
2511 * resize and get confused. Lock order - tty->termios_mutex before
2512 * console sem
2513 */ 2507 */
2514 2508
2515static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, 2509int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
2516 struct winsize __user *arg) 2510 struct winsize *ws)
2517{ 2511{
2518 struct winsize tmp_ws;
2519 struct pid *pgrp, *rpgrp; 2512 struct pid *pgrp, *rpgrp;
2520 unsigned long flags; 2513 unsigned long flags;
2521 2514
2522 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2523 return -EFAULT;
2524
2525 mutex_lock(&tty->termios_mutex); 2515 mutex_lock(&tty->termios_mutex);
2526 if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg))) 2516 if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
2527 goto done; 2517 goto done;
2528
2529#ifdef CONFIG_VT
2530 if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) {
2531 if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col,
2532 tmp_ws.ws_row)) {
2533 mutex_unlock(&tty->termios_mutex);
2534 return -ENXIO;
2535 }
2536 }
2537#endif
2538 /* Get the PID values and reference them so we can 2518 /* Get the PID values and reference them so we can
2539 avoid holding the tty ctrl lock while sending signals */ 2519 avoid holding the tty ctrl lock while sending signals */
2540 spin_lock_irqsave(&tty->ctrl_lock, flags); 2520 spin_lock_irqsave(&tty->ctrl_lock, flags);
@@ -2550,14 +2530,42 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
2550 put_pid(pgrp); 2530 put_pid(pgrp);
2551 put_pid(rpgrp); 2531 put_pid(rpgrp);
2552 2532
2553 tty->winsize = tmp_ws; 2533 tty->winsize = *ws;
2554 real_tty->winsize = tmp_ws; 2534 real_tty->winsize = *ws;
2555done: 2535done:
2556 mutex_unlock(&tty->termios_mutex); 2536 mutex_unlock(&tty->termios_mutex);
2557 return 0; 2537 return 0;
2558} 2538}
2559 2539
2560/** 2540/**
2541 * tiocswinsz - implement window size set ioctl
2542 * @tty; tty
2543 * @arg: user buffer for result
2544 *
2545 * Copies the user idea of the window size to the kernel. Traditionally
2546 * this is just advisory information but for the Linux console it
2547 * actually has driver level meaning and triggers a VC resize.
2548 *
2549 * Locking:
2550 * Driver dependant. The default do_resize method takes the
2551 * tty termios mutex and ctrl_lock. The console takes its own lock
2552 * then calls into the default method.
2553 */
2554
2555static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
2556 struct winsize __user *arg)
2557{
2558 struct winsize tmp_ws;
2559 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2560 return -EFAULT;
2561
2562 if (tty->ops->resize)
2563 return tty->ops->resize(tty, real_tty, &tmp_ws);
2564 else
2565 return tty_do_resize(tty, real_tty, &tmp_ws);
2566}
2567
2568/**
2561 * tioccons - allow admin to move logical console 2569 * tioccons - allow admin to move logical console
2562 * @file: the file to become console 2570 * @file: the file to become console
2563 * 2571 *
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
deleted file mode 100644
index 65fb848e1cce..000000000000
--- a/drivers/char/viocons.c
+++ /dev/null
@@ -1,1171 +0,0 @@
1/* -*- linux-c -*-
2 *
3 * drivers/char/viocons.c
4 *
5 * iSeries Virtual Terminal
6 *
7 * Authors: Dave Boutcher <boutcher@us.ibm.com>
8 * Ryan Arnold <ryanarn@us.ibm.com>
9 * Colin Devilbiss <devilbis@us.ibm.com>
10 * Stephen Rothwell
11 *
12 * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) anyu later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */
28#include <linux/kernel.h>
29#include <linux/proc_fs.h>
30#include <linux/errno.h>
31#include <linux/vmalloc.h>
32#include <linux/mm.h>
33#include <linux/console.h>
34#include <linux/module.h>
35#include <asm/uaccess.h>
36#include <linux/init.h>
37#include <linux/wait.h>
38#include <linux/spinlock.h>
39#include <asm/ioctls.h>
40#include <linux/kd.h>
41#include <linux/tty.h>
42#include <linux/tty_flip.h>
43#include <linux/sysrq.h>
44
45#include <asm/firmware.h>
46#include <asm/iseries/vio.h>
47#include <asm/iseries/hv_lp_event.h>
48#include <asm/iseries/hv_call_event.h>
49#include <asm/iseries/hv_lp_config.h>
50#include <asm/iseries/hv_call.h>
51
52#ifdef CONFIG_VT
53#error You must turn off CONFIG_VT to use CONFIG_VIOCONS
54#endif
55
56#define VIOTTY_MAGIC (0x0DCB)
57#define VTTY_PORTS 10
58
59#define VIOCONS_KERN_WARN KERN_WARNING "viocons: "
60#define VIOCONS_KERN_INFO KERN_INFO "viocons: "
61
62static DEFINE_SPINLOCK(consolelock);
63static DEFINE_SPINLOCK(consoleloglock);
64
65static int vio_sysrq_pressed;
66
67#define VIOCHAR_NUM_BUF 16
68
69/*
70 * Our port information. We store a pointer to one entry in the
71 * tty_driver_data
72 */
73static struct port_info {
74 int magic;
75 struct tty_struct *tty;
76 HvLpIndex lp;
77 u8 vcons;
78 u64 seq; /* sequence number of last HV send */
79 u64 ack; /* last ack from HV */
80/*
81 * When we get writes faster than we can send it to the partition,
82 * buffer the data here. Note that used is a bit map of used buffers.
83 * It had better have enough bits to hold VIOCHAR_NUM_BUF the bitops assume
84 * it is a multiple of unsigned long
85 */
86 unsigned long used;
87 u8 *buffer[VIOCHAR_NUM_BUF];
88 int bufferBytes[VIOCHAR_NUM_BUF];
89 int curbuf;
90 int bufferOverflow;
91 int overflowMessage;
92} port_info[VTTY_PORTS];
93
94#define viochar_is_console(pi) ((pi) == &port_info[0])
95#define viochar_port(pi) ((pi) - &port_info[0])
96
97static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp);
98
99static struct tty_driver *viotty_driver;
100
101static void hvlog(char *fmt, ...)
102{
103 int i;
104 unsigned long flags;
105 va_list args;
106 static char buf[256];
107
108 spin_lock_irqsave(&consoleloglock, flags);
109 va_start(args, fmt);
110 i = vscnprintf(buf, sizeof(buf) - 1, fmt, args);
111 va_end(args);
112 buf[i++] = '\r';
113 HvCall_writeLogBuffer(buf, i);
114 spin_unlock_irqrestore(&consoleloglock, flags);
115}
116
117static void hvlogOutput(const char *buf, int count)
118{
119 unsigned long flags;
120 int begin;
121 int index;
122 static const char cr = '\r';
123
124 begin = 0;
125 spin_lock_irqsave(&consoleloglock, flags);
126 for (index = 0; index < count; index++) {
127 if (buf[index] == '\n') {
128 /*
129 * Start right after the last '\n' or at the zeroth
130 * array position and output the number of characters
131 * including the newline.
132 */
133 HvCall_writeLogBuffer(&buf[begin], index - begin + 1);
134 begin = index + 1;
135 HvCall_writeLogBuffer(&cr, 1);
136 }
137 }
138 if ((index - begin) > 0)
139 HvCall_writeLogBuffer(&buf[begin], index - begin);
140 spin_unlock_irqrestore(&consoleloglock, flags);
141}
142
143/*
144 * Make sure we're pointing to a valid port_info structure. Shamelessly
145 * plagerized from serial.c
146 */
147static inline int viotty_paranoia_check(struct port_info *pi,
148 char *name, const char *routine)
149{
150 static const char *bad_pi_addr = VIOCONS_KERN_WARN
151 "warning: bad address for port_info struct (%s) in %s\n";
152 static const char *badmagic = VIOCONS_KERN_WARN
153 "warning: bad magic number for port_info struct (%s) in %s\n";
154
155 if ((pi < &port_info[0]) || (viochar_port(pi) > VTTY_PORTS)) {
156 printk(bad_pi_addr, name, routine);
157 return 1;
158 }
159 if (pi->magic != VIOTTY_MAGIC) {
160 printk(badmagic, name, routine);
161 return 1;
162 }
163 return 0;
164}
165
166/*
167 * Add data to our pending-send buffers.
168 *
169 * NOTE: Don't use printk in here because it gets nastily recursive.
170 * hvlog can be used to log to the hypervisor buffer
171 */
172static int buffer_add(struct port_info *pi, const char *buf, size_t len)
173{
174 size_t bleft;
175 size_t curlen;
176 const char *curbuf;
177 int nextbuf;
178
179 curbuf = buf;
180 bleft = len;
181 while (bleft > 0) {
182 /*
183 * If there is no space left in the current buffer, we have
184 * filled everything up, so return. If we filled the previous
185 * buffer we would already have moved to the next one.
186 */
187 if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) {
188 hvlog ("\n\rviocons: No overflow buffer available for memcpy().\n");
189 pi->bufferOverflow++;
190 pi->overflowMessage = 1;
191 break;
192 }
193
194 /*
195 * Turn on the "used" bit for this buffer. If it's already on,
196 * that's fine.
197 */
198 set_bit(pi->curbuf, &pi->used);
199
200 /*
201 * See if this buffer has been allocated. If not, allocate it.
202 */
203 if (pi->buffer[pi->curbuf] == NULL) {
204 pi->buffer[pi->curbuf] =
205 kmalloc(VIOCHAR_MAX_DATA, GFP_ATOMIC);
206 if (pi->buffer[pi->curbuf] == NULL) {
207 hvlog("\n\rviocons: kmalloc failed allocating spaces for buffer %d.",
208 pi->curbuf);
209 break;
210 }
211 }
212
213 /* Figure out how much we can copy into this buffer. */
214 if (bleft < (VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf]))
215 curlen = bleft;
216 else
217 curlen = VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf];
218
219 /* Copy the data into the buffer. */
220 memcpy(pi->buffer[pi->curbuf] + pi->bufferBytes[pi->curbuf],
221 curbuf, curlen);
222
223 pi->bufferBytes[pi->curbuf] += curlen;
224 curbuf += curlen;
225 bleft -= curlen;
226
227 /*
228 * Now see if we've filled this buffer. If not then
229 * we'll try to use it again later. If we've filled it
230 * up then we'll advance the curbuf to the next in the
231 * circular queue.
232 */
233 if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) {
234 nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF;
235 /*
236 * Move to the next buffer if it hasn't been used yet
237 */
238 if (test_bit(nextbuf, &pi->used) == 0)
239 pi->curbuf = nextbuf;
240 }
241 }
242 return len - bleft;
243}
244
245/*
246 * Send pending data
247 *
248 * NOTE: Don't use printk in here because it gets nastily recursive.
249 * hvlog can be used to log to the hypervisor buffer
250 */
251static void send_buffers(struct port_info *pi)
252{
253 HvLpEvent_Rc hvrc;
254 int nextbuf;
255 struct viocharlpevent *viochar;
256 unsigned long flags;
257
258 spin_lock_irqsave(&consolelock, flags);
259
260 viochar = (struct viocharlpevent *)
261 vio_get_event_buffer(viomajorsubtype_chario);
262
263 /* Make sure we got a buffer */
264 if (viochar == NULL) {
265 hvlog("\n\rviocons: Can't get viochar buffer in sendBuffers().");
266 spin_unlock_irqrestore(&consolelock, flags);
267 return;
268 }
269
270 if (pi->used == 0) {
271 hvlog("\n\rviocons: in sendbuffers(), but no buffers used.\n");
272 vio_free_event_buffer(viomajorsubtype_chario, viochar);
273 spin_unlock_irqrestore(&consolelock, flags);
274 return;
275 }
276
277 /*
278 * curbuf points to the buffer we're filling. We want to
279 * start sending AFTER this one.
280 */
281 nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF;
282
283 /*
284 * Loop until we find a buffer with the used bit on
285 */
286 while (test_bit(nextbuf, &pi->used) == 0)
287 nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF;
288
289 initDataEvent(viochar, pi->lp);
290
291 /*
292 * While we have buffers with data, and our send window
293 * is open, send them
294 */
295 while ((test_bit(nextbuf, &pi->used)) &&
296 ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
297 viochar->len = pi->bufferBytes[nextbuf];
298 viochar->event.xCorrelationToken = pi->seq++;
299 viochar->event.xSizeMinus1 =
300 offsetof(struct viocharlpevent, data) + viochar->len;
301
302 memcpy(viochar->data, pi->buffer[nextbuf], viochar->len);
303
304 hvrc = HvCallEvent_signalLpEvent(&viochar->event);
305 if (hvrc) {
306 /*
307 * MUST unlock the spinlock before doing a printk
308 */
309 vio_free_event_buffer(viomajorsubtype_chario, viochar);
310 spin_unlock_irqrestore(&consolelock, flags);
311
312 printk(VIOCONS_KERN_WARN
313 "error sending event! return code %d\n",
314 (int)hvrc);
315 return;
316 }
317
318 /*
319 * clear the used bit, zero the number of bytes in
320 * this buffer, and move to the next buffer
321 */
322 clear_bit(nextbuf, &pi->used);
323 pi->bufferBytes[nextbuf] = 0;
324 nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF;
325 }
326
327 /*
328 * If we have emptied all the buffers, start at 0 again.
329 * this will re-use any allocated buffers
330 */
331 if (pi->used == 0) {
332 pi->curbuf = 0;
333
334 if (pi->overflowMessage)
335 pi->overflowMessage = 0;
336
337 if (pi->tty) {
338 tty_wakeup(pi->tty);
339 }
340 }
341
342 vio_free_event_buffer(viomajorsubtype_chario, viochar);
343 spin_unlock_irqrestore(&consolelock, flags);
344}
345
346/*
347 * Our internal writer. Gets called both from the console device and
348 * the tty device. the tty pointer will be NULL if called from the console.
349 * Return total number of bytes "written".
350 *
351 * NOTE: Don't use printk in here because it gets nastily recursive. hvlog
352 * can be used to log to the hypervisor buffer
353 */
354static int internal_write(struct port_info *pi, const char *buf, size_t len)
355{
356 HvLpEvent_Rc hvrc;
357 size_t bleft;
358 size_t curlen;
359 const char *curbuf;
360 unsigned long flags;
361 struct viocharlpevent *viochar;
362
363 /*
364 * Write to the hvlog of inbound data are now done prior to
365 * calling internal_write() since internal_write() is only called in
366 * the event that an lp event path is active, which isn't the case for
367 * logging attempts prior to console initialization.
368 *
369 * If there is already data queued for this port, send it prior to
370 * attempting to send any new data.
371 */
372 if (pi->used)
373 send_buffers(pi);
374
375 spin_lock_irqsave(&consolelock, flags);
376
377 viochar = vio_get_event_buffer(viomajorsubtype_chario);
378 if (viochar == NULL) {
379 spin_unlock_irqrestore(&consolelock, flags);
380 hvlog("\n\rviocons: Can't get vio buffer in internal_write().");
381 return -EAGAIN;
382 }
383 initDataEvent(viochar, pi->lp);
384
385 curbuf = buf;
386 bleft = len;
387
388 while ((bleft > 0) && (pi->used == 0) &&
389 ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
390 if (bleft > VIOCHAR_MAX_DATA)
391 curlen = VIOCHAR_MAX_DATA;
392 else
393 curlen = bleft;
394
395 viochar->event.xCorrelationToken = pi->seq++;
396 memcpy(viochar->data, curbuf, curlen);
397 viochar->len = curlen;
398 viochar->event.xSizeMinus1 =
399 offsetof(struct viocharlpevent, data) + curlen;
400
401 hvrc = HvCallEvent_signalLpEvent(&viochar->event);
402 if (hvrc) {
403 hvlog("viocons: error sending event! %d\n", (int)hvrc);
404 goto out;
405 }
406 curbuf += curlen;
407 bleft -= curlen;
408 }
409
410 /* If we didn't send it all, buffer as much of it as we can. */
411 if (bleft > 0)
412 bleft -= buffer_add(pi, curbuf, bleft);
413out:
414 vio_free_event_buffer(viomajorsubtype_chario, viochar);
415 spin_unlock_irqrestore(&consolelock, flags);
416 return len - bleft;
417}
418
419static struct port_info *get_port_data(struct tty_struct *tty)
420{
421 unsigned long flags;
422 struct port_info *pi;
423
424 spin_lock_irqsave(&consolelock, flags);
425 if (tty) {
426 pi = (struct port_info *)tty->driver_data;
427 if (!pi || viotty_paranoia_check(pi, tty->name,
428 "get_port_data")) {
429 pi = NULL;
430 }
431 } else
432 /*
433 * If this is the console device, use the lp from
434 * the first port entry
435 */
436 pi = &port_info[0];
437 spin_unlock_irqrestore(&consolelock, flags);
438 return pi;
439}
440
441/*
442 * Initialize the common fields in a charLpEvent
443 */
444static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp)
445{
446 struct HvLpEvent *hev = &viochar->event;
447
448 memset(viochar, 0, sizeof(struct viocharlpevent));
449
450 hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
451 HV_LP_EVENT_INT;
452 hev->xType = HvLpEvent_Type_VirtualIo;
453 hev->xSubtype = viomajorsubtype_chario | viochardata;
454 hev->xSourceLp = HvLpConfig_getLpIndex();
455 hev->xTargetLp = lp;
456 hev->xSizeMinus1 = sizeof(struct viocharlpevent);
457 hev->xSourceInstanceId = viopath_sourceinst(lp);
458 hev->xTargetInstanceId = viopath_targetinst(lp);
459}
460
461/*
462 * early console device write
463 */
464static void viocons_write_early(struct console *co, const char *s, unsigned count)
465{
466 hvlogOutput(s, count);
467}
468
469/*
470 * console device write
471 */
472static void viocons_write(struct console *co, const char *s, unsigned count)
473{
474 int index;
475 int begin;
476 struct port_info *pi;
477
478 static const char cr = '\r';
479
480 /*
481 * Check port data first because the target LP might be valid but
482 * simply not active, in which case we want to hvlog the output.
483 */
484 pi = get_port_data(NULL);
485 if (pi == NULL) {
486 hvlog("\n\rviocons_write: unable to get port data.");
487 return;
488 }
489
490 hvlogOutput(s, count);
491
492 if (!viopath_isactive(pi->lp))
493 return;
494
495 /*
496 * Any newline character found will cause a
497 * carriage return character to be emitted as well.
498 */
499 begin = 0;
500 for (index = 0; index < count; index++) {
501 if (s[index] == '\n') {
502 /*
503 * Newline found. Print everything up to and
504 * including the newline
505 */
506 internal_write(pi, &s[begin], index - begin + 1);
507 begin = index + 1;
508 /* Emit a carriage return as well */
509 internal_write(pi, &cr, 1);
510 }
511 }
512
513 /* If any characters left to write, write them now */
514 if ((index - begin) > 0)
515 internal_write(pi, &s[begin], index - begin);
516}
517
518/*
519 * Work out the device associate with this console
520 */
521static struct tty_driver *viocons_device(struct console *c, int *index)
522{
523 *index = c->index;
524 return viotty_driver;
525}
526
527/*
528 * console device I/O methods
529 */
530static struct console viocons_early = {
531 .name = "viocons",
532 .write = viocons_write_early,
533 .flags = CON_PRINTBUFFER,
534 .index = -1,
535};
536
537static struct console viocons = {
538 .name = "viocons",
539 .write = viocons_write,
540 .device = viocons_device,
541 .flags = CON_PRINTBUFFER,
542 .index = -1,
543};
544
545/*
546 * TTY Open method
547 */
548static int viotty_open(struct tty_struct *tty, struct file *filp)
549{
550 int port;
551 unsigned long flags;
552 struct port_info *pi;
553
554 port = tty->index;
555
556 if ((port < 0) || (port >= VTTY_PORTS))
557 return -ENODEV;
558
559 spin_lock_irqsave(&consolelock, flags);
560
561 pi = &port_info[port];
562 /* If some other TTY is already connected here, reject the open */
563 if ((pi->tty) && (pi->tty != tty)) {
564 spin_unlock_irqrestore(&consolelock, flags);
565 printk(VIOCONS_KERN_WARN
566 "attempt to open device twice from different ttys\n");
567 return -EBUSY;
568 }
569 tty->driver_data = pi;
570 pi->tty = tty;
571 spin_unlock_irqrestore(&consolelock, flags);
572
573 return 0;
574}
575
576/*
577 * TTY Close method
578 */
579static void viotty_close(struct tty_struct *tty, struct file *filp)
580{
581 unsigned long flags;
582 struct port_info *pi;
583
584 spin_lock_irqsave(&consolelock, flags);
585 pi = (struct port_info *)tty->driver_data;
586
587 if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_close")) {
588 spin_unlock_irqrestore(&consolelock, flags);
589 return;
590 }
591 if (tty->count == 1)
592 pi->tty = NULL;
593 spin_unlock_irqrestore(&consolelock, flags);
594}
595
596/*
597 * TTY Write method
598 */
599static int viotty_write(struct tty_struct *tty, const unsigned char *buf,
600 int count)
601{
602 struct port_info *pi;
603
604 pi = get_port_data(tty);
605 if (pi == NULL) {
606 hvlog("\n\rviotty_write: no port data.");
607 return -ENODEV;
608 }
609
610 if (viochar_is_console(pi))
611 hvlogOutput(buf, count);
612
613 /*
614 * If the path to this LP is closed, don't bother doing anything more.
615 * just dump the data on the floor and return count. For some reason
616 * some user level programs will attempt to probe available tty's and
617 * they'll attempt a viotty_write on an invalid port which maps to an
618 * invalid target lp. If this is the case then ignore the
619 * viotty_write call and, since the viopath isn't active to this
620 * partition, return count.
621 */
622 if (!viopath_isactive(pi->lp))
623 return count;
624
625 return internal_write(pi, buf, count);
626}
627
628/*
629 * TTY put_char method
630 */
631static int viotty_put_char(struct tty_struct *tty, unsigned char ch)
632{
633 struct port_info *pi;
634
635 pi = get_port_data(tty);
636 if (pi == NULL)
637 return 0;
638
639 /* This will append '\r' as well if the char is '\n' */
640 if (viochar_is_console(pi))
641 hvlogOutput(&ch, 1);
642
643 if (viopath_isactive(pi->lp))
644 internal_write(pi, &ch, 1);
645 return 1;
646}
647
648/*
649 * TTY write_room method
650 */
651static int viotty_write_room(struct tty_struct *tty)
652{
653 int i;
654 int room = 0;
655 struct port_info *pi;
656 unsigned long flags;
657
658 spin_lock_irqsave(&consolelock, flags);
659 pi = (struct port_info *)tty->driver_data;
660 if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_write_room")) {
661 spin_unlock_irqrestore(&consolelock, flags);
662 return 0;
663 }
664
665 /* If no buffers are used, return the max size. */
666 if (pi->used == 0) {
667 spin_unlock_irqrestore(&consolelock, flags);
668 return VIOCHAR_MAX_DATA * VIOCHAR_NUM_BUF;
669 }
670
671 /*
672 * We retain the spinlock because we want to get an accurate
673 * count and it can change on us between each operation if we
674 * don't hold the spinlock.
675 */
676 for (i = 0; ((i < VIOCHAR_NUM_BUF) && (room < VIOCHAR_MAX_DATA)); i++)
677 room += (VIOCHAR_MAX_DATA - pi->bufferBytes[i]);
678 spin_unlock_irqrestore(&consolelock, flags);
679
680 if (room > VIOCHAR_MAX_DATA)
681 room = VIOCHAR_MAX_DATA;
682 return room;
683}
684
685/*
686 * TTY chars_in_buffer method
687 */
688static int viotty_chars_in_buffer(struct tty_struct *tty)
689{
690 return 0;
691}
692
693static int viotty_ioctl(struct tty_struct *tty, struct file *file,
694 unsigned int cmd, unsigned long arg)
695{
696 switch (cmd) {
697 /*
698 * the ioctls below read/set the flags usually shown in the leds
699 * don't use them - they will go away without warning
700 */
701 case KDGETLED:
702 case KDGKBLED:
703 return put_user(0, (char *)arg);
704
705 case KDSKBLED:
706 return 0;
707 }
708 /* FIXME: WTF is this being called for ??? */
709 lock_kernel();
710 ret = n_tty_ioctl(tty, file, cmd, arg);
711 unlock_kernel();
712 return ret;
713}
714
715/*
716 * Handle an open charLpEvent. Could be either interrupt or ack
717 */
718static void vioHandleOpenEvent(struct HvLpEvent *event)
719{
720 unsigned long flags;
721 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
722 u8 port = cevent->virtual_device;
723 struct port_info *pi;
724 int reject = 0;
725
726 if (hvlpevent_is_ack(event)) {
727 if (port >= VTTY_PORTS)
728 return;
729
730 spin_lock_irqsave(&consolelock, flags);
731 /* Got the lock, don't cause console output */
732
733 pi = &port_info[port];
734 if (event->xRc == HvLpEvent_Rc_Good) {
735 pi->seq = pi->ack = 0;
736 /*
737 * This line allows connections from the primary
738 * partition but once one is connected from the
739 * primary partition nothing short of a reboot
740 * of linux will allow access from the hosting
741 * partition again without a required iSeries fix.
742 */
743 pi->lp = event->xTargetLp;
744 }
745
746 spin_unlock_irqrestore(&consolelock, flags);
747 if (event->xRc != HvLpEvent_Rc_Good)
748 printk(VIOCONS_KERN_WARN
749 "handle_open_event: event->xRc == (%d).\n",
750 event->xRc);
751
752 if (event->xCorrelationToken != 0) {
753 atomic_t *aptr= (atomic_t *)event->xCorrelationToken;
754 atomic_set(aptr, 1);
755 } else
756 printk(VIOCONS_KERN_WARN
757 "weird...got open ack without atomic\n");
758 return;
759 }
760
761 /* This had better require an ack, otherwise complain */
762 if (!hvlpevent_need_ack(event)) {
763 printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n");
764 return;
765 }
766
767 spin_lock_irqsave(&consolelock, flags);
768 /* Got the lock, don't cause console output */
769
770 /* Make sure this is a good virtual tty */
771 if (port >= VTTY_PORTS) {
772 event->xRc = HvLpEvent_Rc_SubtypeError;
773 cevent->subtype_result_code = viorc_openRejected;
774 /*
775 * Flag state here since we can't printk while holding
776 * a spinlock.
777 */
778 reject = 1;
779 } else {
780 pi = &port_info[port];
781 if ((pi->lp != HvLpIndexInvalid) &&
782 (pi->lp != event->xSourceLp)) {
783 /*
784 * If this is tty is already connected to a different
785 * partition, fail.
786 */
787 event->xRc = HvLpEvent_Rc_SubtypeError;
788 cevent->subtype_result_code = viorc_openRejected;
789 reject = 2;
790 } else {
791 pi->lp = event->xSourceLp;
792 event->xRc = HvLpEvent_Rc_Good;
793 cevent->subtype_result_code = viorc_good;
794 pi->seq = pi->ack = 0;
795 reject = 0;
796 }
797 }
798
799 spin_unlock_irqrestore(&consolelock, flags);
800
801 if (reject == 1)
802 printk(VIOCONS_KERN_WARN "open rejected: bad virtual tty.\n");
803 else if (reject == 2)
804 printk(VIOCONS_KERN_WARN
805 "open rejected: console in exclusive use by another partition.\n");
806
807 /* Return the acknowledgement */
808 HvCallEvent_ackLpEvent(event);
809}
810
811/*
812 * Handle a close charLpEvent. This should ONLY be an Interrupt because the
813 * virtual console should never actually issue a close event to the hypervisor
814 * because the virtual console never goes away. A close event coming from the
815 * hypervisor simply means that there are no client consoles connected to the
816 * virtual console.
817 *
818 * Regardless of the number of connections masqueraded on the other side of
819 * the hypervisor ONLY ONE close event should be called to accompany the ONE
820 * open event that is called. The close event should ONLY be called when NO
821 * MORE connections (masqueraded or not) exist on the other side of the
822 * hypervisor.
823 */
824static void vioHandleCloseEvent(struct HvLpEvent *event)
825{
826 unsigned long flags;
827 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
828 u8 port = cevent->virtual_device;
829
830 if (hvlpevent_is_int(event)) {
831 if (port >= VTTY_PORTS) {
832 printk(VIOCONS_KERN_WARN
833 "close message from invalid virtual device.\n");
834 return;
835 }
836
837 /* For closes, just mark the console partition invalid */
838 spin_lock_irqsave(&consolelock, flags);
839 /* Got the lock, don't cause console output */
840
841 if (port_info[port].lp == event->xSourceLp)
842 port_info[port].lp = HvLpIndexInvalid;
843
844 spin_unlock_irqrestore(&consolelock, flags);
845 printk(VIOCONS_KERN_INFO "close from %d\n", event->xSourceLp);
846 } else
847 printk(VIOCONS_KERN_WARN
848 "got unexpected close acknowlegement\n");
849}
850
851/*
852 * Handle a config charLpEvent. Could be either interrupt or ack
853 */
854static void vioHandleConfig(struct HvLpEvent *event)
855{
856 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
857
858 HvCall_writeLogBuffer(cevent->data, cevent->len);
859
860 if (cevent->data[0] == 0x01)
861 printk(VIOCONS_KERN_INFO "window resized to %d: %d: %d: %d\n",
862 cevent->data[1], cevent->data[2],
863 cevent->data[3], cevent->data[4]);
864 else
865 printk(VIOCONS_KERN_WARN "unknown config event\n");
866}
867
868/*
869 * Handle a data charLpEvent.
870 */
871static void vioHandleData(struct HvLpEvent *event)
872{
873 struct tty_struct *tty;
874 unsigned long flags;
875 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
876 struct port_info *pi;
877 int index;
878 int num_pushed;
879 u8 port = cevent->virtual_device;
880
881 if (port >= VTTY_PORTS) {
882 printk(VIOCONS_KERN_WARN "data on invalid virtual device %d\n",
883 port);
884 return;
885 }
886
887 /*
888 * Hold the spinlock so that we don't take an interrupt that
889 * changes tty between the time we fetch the port_info
890 * pointer and the time we paranoia check.
891 */
892 spin_lock_irqsave(&consolelock, flags);
893 pi = &port_info[port];
894
895 /*
896 * Change 05/01/2003 - Ryan Arnold: If a partition other than
897 * the current exclusive partition tries to send us data
898 * events then just drop them on the floor because we don't
899 * want his stinking data. He isn't authorized to receive
900 * data because he wasn't the first one to get the console,
901 * therefore he shouldn't be allowed to send data either.
902 * This will work without an iSeries fix.
903 */
904 if (pi->lp != event->xSourceLp) {
905 spin_unlock_irqrestore(&consolelock, flags);
906 return;
907 }
908
909 tty = pi->tty;
910 if (tty == NULL) {
911 spin_unlock_irqrestore(&consolelock, flags);
912 printk(VIOCONS_KERN_WARN "no tty for virtual device %d\n",
913 port);
914 return;
915 }
916
917 if (tty->magic != TTY_MAGIC) {
918 spin_unlock_irqrestore(&consolelock, flags);
919 printk(VIOCONS_KERN_WARN "tty bad magic\n");
920 return;
921 }
922
923 /*
924 * Just to be paranoid, make sure the tty points back to this port
925 */
926 pi = (struct port_info *)tty->driver_data;
927 if (!pi || viotty_paranoia_check(pi, tty->name, "vioHandleData")) {
928 spin_unlock_irqrestore(&consolelock, flags);
929 return;
930 }
931 spin_unlock_irqrestore(&consolelock, flags);
932
933 /*
934 * Change 07/21/2003 - Ryan Arnold: functionality added to
935 * support sysrq utilizing ^O as the sysrq key. The sysrq
936 * functionality will only work if built into the kernel and
937 * then only if sysrq is enabled through the proc filesystem.
938 */
939 num_pushed = 0;
940 for (index = 0; index < cevent->len; index++) {
941 /*
942 * Will be optimized away if !CONFIG_MAGIC_SYSRQ:
943 */
944 if (sysrq_on()) {
945 /* 0x0f is the ascii character for ^O */
946 if (cevent->data[index] == '\x0f') {
947 vio_sysrq_pressed = 1;
948 /*
949 * continue because we don't want to add
950 * the sysrq key into the data string.
951 */
952 continue;
953 } else if (vio_sysrq_pressed) {
954 handle_sysrq(cevent->data[index], tty);
955 vio_sysrq_pressed = 0;
956 /*
957 * continue because we don't want to add
958 * the sysrq sequence into the data string.
959 */
960 continue;
961 }
962 }
963 /*
964 * The sysrq sequence isn't included in this check if
965 * sysrq is enabled and compiled into the kernel because
966 * the sequence will never get inserted into the buffer.
967 * Don't attempt to copy more data into the buffer than we
968 * have room for because it would fail without indication.
969 */
970 if(tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL) == 0) {
971 printk(VIOCONS_KERN_WARN "input buffer overflow!\n");
972 break;
973 }
974 num_pushed++;
975 }
976
977 if (num_pushed)
978 tty_flip_buffer_push(tty);
979}
980
981/*
982 * Handle an ack charLpEvent.
983 */
984static void vioHandleAck(struct HvLpEvent *event)
985{
986 struct viocharlpevent *cevent = (struct viocharlpevent *)event;
987 unsigned long flags;
988 u8 port = cevent->virtual_device;
989
990 if (port >= VTTY_PORTS) {
991 printk(VIOCONS_KERN_WARN "data on invalid virtual device\n");
992 return;
993 }
994
995 spin_lock_irqsave(&consolelock, flags);
996 port_info[port].ack = event->xCorrelationToken;
997 spin_unlock_irqrestore(&consolelock, flags);
998
999 if (port_info[port].used)
1000 send_buffers(&port_info[port]);
1001}
1002
1003/*
1004 * Handle charLpEvents and route to the appropriate routine
1005 */
1006static void vioHandleCharEvent(struct HvLpEvent *event)
1007{
1008 int charminor;
1009
1010 if (event == NULL)
1011 return;
1012
1013 charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
1014 switch (charminor) {
1015 case viocharopen:
1016 vioHandleOpenEvent(event);
1017 break;
1018 case viocharclose:
1019 vioHandleCloseEvent(event);
1020 break;
1021 case viochardata:
1022 vioHandleData(event);
1023 break;
1024 case viocharack:
1025 vioHandleAck(event);
1026 break;
1027 case viocharconfig:
1028 vioHandleConfig(event);
1029 break;
1030 default:
1031 if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
1032 event->xRc = HvLpEvent_Rc_InvalidSubtype;
1033 HvCallEvent_ackLpEvent(event);
1034 }
1035 }
1036}
1037
1038/*
1039 * Send an open event
1040 */
1041static int send_open(HvLpIndex remoteLp, void *sem)
1042{
1043 return HvCallEvent_signalLpEventFast(remoteLp,
1044 HvLpEvent_Type_VirtualIo,
1045 viomajorsubtype_chario | viocharopen,
1046 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
1047 viopath_sourceinst(remoteLp),
1048 viopath_targetinst(remoteLp),
1049 (u64)(unsigned long)sem, VIOVERSION << 16,
1050 0, 0, 0, 0);
1051}
1052
1053static const struct tty_operations serial_ops = {
1054 .open = viotty_open,
1055 .close = viotty_close,
1056 .write = viotty_write,
1057 .put_char = viotty_put_char,
1058 .write_room = viotty_write_room,
1059 .chars_in_buffer = viotty_chars_in_buffer,
1060 .ioctl = viotty_ioctl,
1061};
1062
1063static int __init viocons_init2(void)
1064{
1065 atomic_t wait_flag;
1066 int rc;
1067
1068 if (!firmware_has_feature(FW_FEATURE_ISERIES))
1069 return -ENODEV;
1070
1071 /* +2 for fudge */
1072 rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
1073 viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
1074 if (rc)
1075 printk(VIOCONS_KERN_WARN "error opening to primary %d\n", rc);
1076
1077 if (viopath_hostLp == HvLpIndexInvalid)
1078 vio_set_hostlp();
1079
1080 /*
1081 * And if the primary is not the same as the hosting LP, open to the
1082 * hosting lp
1083 */
1084 if ((viopath_hostLp != HvLpIndexInvalid) &&
1085 (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) {
1086 printk(VIOCONS_KERN_INFO "open path to hosting (%d)\n",
1087 viopath_hostLp);
1088 rc = viopath_open(viopath_hostLp, viomajorsubtype_chario,
1089 VIOCHAR_WINDOW + 2); /* +2 for fudge */
1090 if (rc)
1091 printk(VIOCONS_KERN_WARN
1092 "error opening to partition %d: %d\n",
1093 viopath_hostLp, rc);
1094 }
1095
1096 if (vio_setHandler(viomajorsubtype_chario, vioHandleCharEvent) < 0)
1097 printk(VIOCONS_KERN_WARN
1098 "error seting handler for console events!\n");
1099
1100 /*
1101 * First, try to open the console to the hosting lp.
1102 * Wait on a semaphore for the response.
1103 */
1104 atomic_set(&wait_flag, 0);
1105 if ((viopath_isactive(viopath_hostLp)) &&
1106 (send_open(viopath_hostLp, (void *)&wait_flag) == 0)) {
1107 printk(VIOCONS_KERN_INFO "hosting partition %d\n",
1108 viopath_hostLp);
1109 while (atomic_read(&wait_flag) == 0)
1110 mb();
1111 atomic_set(&wait_flag, 0);
1112 }
1113
1114 /*
1115 * If we don't have an active console, try the primary
1116 */
1117 if ((!viopath_isactive(port_info[0].lp)) &&
1118 (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) &&
1119 (send_open(HvLpConfig_getPrimaryLpIndex(), (void *)&wait_flag)
1120 == 0)) {
1121 printk(VIOCONS_KERN_INFO "opening console to primary partition\n");
1122 while (atomic_read(&wait_flag) == 0)
1123 mb();
1124 }
1125
1126 /* Initialize the tty_driver structure */
1127 viotty_driver = alloc_tty_driver(VTTY_PORTS);
1128 viotty_driver->owner = THIS_MODULE;
1129 viotty_driver->driver_name = "vioconsole";
1130 viotty_driver->name = "tty";
1131 viotty_driver->name_base = 1;
1132 viotty_driver->major = TTY_MAJOR;
1133 viotty_driver->minor_start = 1;
1134 viotty_driver->type = TTY_DRIVER_TYPE_CONSOLE;
1135 viotty_driver->subtype = 1;
1136 viotty_driver->init_termios = tty_std_termios;
1137 viotty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
1138 tty_set_operations(viotty_driver, &serial_ops);
1139
1140 if (tty_register_driver(viotty_driver)) {
1141 printk(VIOCONS_KERN_WARN "couldn't register console driver\n");
1142 put_tty_driver(viotty_driver);
1143 viotty_driver = NULL;
1144 }
1145
1146 unregister_console(&viocons_early);
1147 register_console(&viocons);
1148
1149 return 0;
1150}
1151
1152static int __init viocons_init(void)
1153{
1154 int i;
1155
1156 if (!firmware_has_feature(FW_FEATURE_ISERIES))
1157 return -ENODEV;
1158
1159 printk(VIOCONS_KERN_INFO "registering console\n");
1160 for (i = 0; i < VTTY_PORTS; i++) {
1161 port_info[i].lp = HvLpIndexInvalid;
1162 port_info[i].magic = VIOTTY_MAGIC;
1163 }
1164 HvCall_setLogBufferFormatAndCodepage(HvCall_LogBuffer_ASCII, 437);
1165 add_preferred_console("viocons", 0, NULL);
1166 register_console(&viocons_early);
1167 return 0;
1168}
1169
1170console_initcall(viocons_init);
1171module_init(viocons_init2);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1bc00c9d860d..60359c360912 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -803,7 +803,25 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,
803 */ 803 */
804#define VC_RESIZE_MAXCOL (32767) 804#define VC_RESIZE_MAXCOL (32767)
805#define VC_RESIZE_MAXROW (32767) 805#define VC_RESIZE_MAXROW (32767)
806int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) 806
807/**
808 * vc_do_resize - resizing method for the tty
809 * @tty: tty being resized
810 * @real_tty: real tty (different to tty if a pty/tty pair)
811 * @vc: virtual console private data
812 * @cols: columns
813 * @lines: lines
814 *
815 * Resize a virtual console, clipping according to the actual constraints.
816 * If the caller passes a tty structure then update the termios winsize
817 * information and perform any neccessary signal handling.
818 *
819 * Caller must hold the console semaphore. Takes the termios mutex and
820 * ctrl_lock of the tty IFF a tty is passed.
821 */
822
823static int vc_do_resize(struct tty_struct *tty, struct tty_struct *real_tty,
824 struct vc_data *vc, unsigned int cols, unsigned int lines)
807{ 825{
808 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; 826 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
809 unsigned int old_cols, old_rows, old_row_size, old_screen_size; 827 unsigned int old_cols, old_rows, old_row_size, old_screen_size;
@@ -907,24 +925,15 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
907 gotoxy(vc, vc->vc_x, vc->vc_y); 925 gotoxy(vc, vc->vc_x, vc->vc_y);
908 save_cur(vc); 926 save_cur(vc);
909 927
910 if (vc->vc_tty) { 928 if (tty) {
911 struct winsize ws, *cws = &vc->vc_tty->winsize; 929 /* Rewrite the requested winsize data with the actual
912 struct pid *pgrp = NULL; 930 resulting sizes */
913 931 struct winsize ws;
914 memset(&ws, 0, sizeof(ws)); 932 memset(&ws, 0, sizeof(ws));
915 ws.ws_row = vc->vc_rows; 933 ws.ws_row = vc->vc_rows;
916 ws.ws_col = vc->vc_cols; 934 ws.ws_col = vc->vc_cols;
917 ws.ws_ypixel = vc->vc_scan_lines; 935 ws.ws_ypixel = vc->vc_scan_lines;
918 936 tty_do_resize(tty, real_tty, &ws);
919 spin_lock_irq(&vc->vc_tty->ctrl_lock);
920 if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col))
921 pgrp = get_pid(vc->vc_tty->pgrp);
922 spin_unlock_irq(&vc->vc_tty->ctrl_lock);
923 if (pgrp) {
924 kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1);
925 put_pid(pgrp);
926 }
927 *cws = ws;
928 } 937 }
929 938
930 if (CON_IS_VISIBLE(vc)) 939 if (CON_IS_VISIBLE(vc))
@@ -932,14 +941,47 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
932 return err; 941 return err;
933} 942}
934 943
935int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) 944/**
945 * vc_resize - resize a VT
946 * @vc: virtual console
947 * @cols: columns
948 * @rows: rows
949 *
950 * Resize a virtual console as seen from the console end of things. We
951 * use the common vc_do_resize methods to update the structures. The
952 * caller must hold the console sem to protect console internals and
953 * vc->vc_tty
954 */
955
956int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
957{
958 return vc_do_resize(vc->vc_tty, vc->vc_tty, vc, cols, rows);
959}
960
961/**
962 * vt_resize - resize a VT
963 * @tty: tty to resize
964 * @real_tty: tty if a pty/tty pair
965 * @ws: winsize attributes
966 *
967 * Resize a virtual terminal. This is called by the tty layer as we
968 * register our own handler for resizing. The mutual helper does all
969 * the actual work.
970 *
971 * Takes the console sem and the called methods then take the tty
972 * termios_mutex and the tty ctrl_lock in that order.
973 */
974
975int vt_resize(struct tty_struct *tty, struct tty_struct *real_tty,
976 struct winsize *ws)
936{ 977{
937 int rc; 978 struct vc_data *vc = tty->driver_data;
979 int ret;
938 980
939 acquire_console_sem(); 981 acquire_console_sem();
940 rc = vc_resize(vc, cols, lines); 982 ret = vc_do_resize(tty, real_tty, vc, ws->ws_col, ws->ws_row);
941 release_console_sem(); 983 release_console_sem();
942 return rc; 984 return ret;
943} 985}
944 986
945void vc_deallocate(unsigned int currcons) 987void vc_deallocate(unsigned int currcons)
@@ -2907,6 +2949,7 @@ static const struct tty_operations con_ops = {
2907 .start = con_start, 2949 .start = con_start,
2908 .throttle = con_throttle, 2950 .throttle = con_throttle,
2909 .unthrottle = con_unthrottle, 2951 .unthrottle = con_unthrottle,
2952 .resize = vt_resize,
2910}; 2953};
2911 2954
2912int __init vty_init(void) 2955int __init vty_init(void)
@@ -4061,7 +4104,6 @@ EXPORT_SYMBOL(default_blu);
4061EXPORT_SYMBOL(update_region); 4104EXPORT_SYMBOL(update_region);
4062EXPORT_SYMBOL(redraw_screen); 4105EXPORT_SYMBOL(redraw_screen);
4063EXPORT_SYMBOL(vc_resize); 4106EXPORT_SYMBOL(vc_resize);
4064EXPORT_SYMBOL(vc_lock_resize);
4065EXPORT_SYMBOL(fg_console); 4107EXPORT_SYMBOL(fg_console);
4066EXPORT_SYMBOL(console_blank_hook); 4108EXPORT_SYMBOL(console_blank_hook);
4067EXPORT_SYMBOL(console_blanked); 4109EXPORT_SYMBOL(console_blanked);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 3211afd9d57e..c904e9ad4a71 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -947,14 +947,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
947 get_user(cc, &vtsizes->v_cols)) 947 get_user(cc, &vtsizes->v_cols))
948 ret = -EFAULT; 948 ret = -EFAULT;
949 else { 949 else {
950 acquire_console_sem();
950 for (i = 0; i < MAX_NR_CONSOLES; i++) { 951 for (i = 0; i < MAX_NR_CONSOLES; i++) {
951 vc = vc_cons[i].d; 952 vc = vc_cons[i].d;
952 953
953 if (vc) { 954 if (vc) {
954 vc->vc_resize_user = 1; 955 vc->vc_resize_user = 1;
955 vc_lock_resize(vc_cons[i].d, cc, ll); 956 vc_resize(vc_cons[i].d, cc, ll);
956 } 957 }
957 } 958 }
959 release_console_sem();
958 } 960 }
959 break; 961 break;
960 } 962 }
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 8bfee5fb7223..278c9857bcf5 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -74,7 +74,6 @@
74 * currently programmed in the FPGA. 74 * currently programmed in the FPGA.
75 */ 75 */
76 76
77#include <linux/version.h>
78#include <linux/module.h> 77#include <linux/module.h>
79#include <linux/kernel.h> 78#include <linux/kernel.h>
80#include <linux/types.h> 79#include <linux/types.h>
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index fe565ee43757..ac0bbf2d234f 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -333,7 +333,7 @@ static void dbs_check_cpu(int cpu)
333{ 333{
334 unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; 334 unsigned int idle_ticks, up_idle_ticks, down_idle_ticks;
335 unsigned int tmp_idle_ticks, total_idle_ticks; 335 unsigned int tmp_idle_ticks, total_idle_ticks;
336 unsigned int freq_step; 336 unsigned int freq_target;
337 unsigned int freq_down_sampling_rate; 337 unsigned int freq_down_sampling_rate;
338 struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, cpu); 338 struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
339 struct cpufreq_policy *policy; 339 struct cpufreq_policy *policy;
@@ -383,13 +383,13 @@ static void dbs_check_cpu(int cpu)
383 if (this_dbs_info->requested_freq == policy->max) 383 if (this_dbs_info->requested_freq == policy->max)
384 return; 384 return;
385 385
386 freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; 386 freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
387 387
388 /* max freq cannot be less than 100. But who knows.... */ 388 /* max freq cannot be less than 100. But who knows.... */
389 if (unlikely(freq_step == 0)) 389 if (unlikely(freq_target == 0))
390 freq_step = 5; 390 freq_target = 5;
391 391
392 this_dbs_info->requested_freq += freq_step; 392 this_dbs_info->requested_freq += freq_target;
393 if (this_dbs_info->requested_freq > policy->max) 393 if (this_dbs_info->requested_freq > policy->max)
394 this_dbs_info->requested_freq = policy->max; 394 this_dbs_info->requested_freq = policy->max;
395 395
@@ -425,19 +425,19 @@ static void dbs_check_cpu(int cpu)
425 /* 425 /*
426 * if we are already at the lowest speed then break out early 426 * if we are already at the lowest speed then break out early
427 * or if we 'cannot' reduce the speed as the user might want 427 * or if we 'cannot' reduce the speed as the user might want
428 * freq_step to be zero 428 * freq_target to be zero
429 */ 429 */
430 if (this_dbs_info->requested_freq == policy->min 430 if (this_dbs_info->requested_freq == policy->min
431 || dbs_tuners_ins.freq_step == 0) 431 || dbs_tuners_ins.freq_step == 0)
432 return; 432 return;
433 433
434 freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; 434 freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
435 435
436 /* max freq cannot be less than 100. But who knows.... */ 436 /* max freq cannot be less than 100. But who knows.... */
437 if (unlikely(freq_step == 0)) 437 if (unlikely(freq_target == 0))
438 freq_step = 5; 438 freq_target = 5;
439 439
440 this_dbs_info->requested_freq -= freq_step; 440 this_dbs_info->requested_freq -= freq_target;
441 if (this_dbs_info->requested_freq < policy->min) 441 if (this_dbs_info->requested_freq < policy->min)
442 this_dbs_info->requested_freq = policy->min; 442 this_dbs_info->requested_freq = policy->min;
443 443
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
index ba7b9a6b17a1..a4bec3f919aa 100644
--- a/drivers/cpuidle/governors/ladder.c
+++ b/drivers/cpuidle/governors/ladder.c
@@ -67,10 +67,17 @@ static int ladder_select_state(struct cpuidle_device *dev)
67 struct ladder_device *ldev = &__get_cpu_var(ladder_devices); 67 struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
68 struct ladder_device_state *last_state; 68 struct ladder_device_state *last_state;
69 int last_residency, last_idx = ldev->last_state_idx; 69 int last_residency, last_idx = ldev->last_state_idx;
70 int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
70 71
71 if (unlikely(!ldev)) 72 if (unlikely(!ldev))
72 return 0; 73 return 0;
73 74
75 /* Special case when user has set very strict latency requirement */
76 if (unlikely(latency_req == 0)) {
77 ladder_do_selection(ldev, last_idx, 0);
78 return 0;
79 }
80
74 last_state = &ldev->states[last_idx]; 81 last_state = &ldev->states[last_idx];
75 82
76 if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) 83 if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID)
@@ -81,8 +88,7 @@ static int ladder_select_state(struct cpuidle_device *dev)
81 /* consider promotion */ 88 /* consider promotion */
82 if (last_idx < dev->state_count - 1 && 89 if (last_idx < dev->state_count - 1 &&
83 last_residency > last_state->threshold.promotion_time && 90 last_residency > last_state->threshold.promotion_time &&
84 dev->states[last_idx + 1].exit_latency <= 91 dev->states[last_idx + 1].exit_latency <= latency_req) {
85 pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
86 last_state->stats.promotion_count++; 92 last_state->stats.promotion_count++;
87 last_state->stats.demotion_count = 0; 93 last_state->stats.demotion_count = 0;
88 if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) { 94 if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
@@ -92,7 +98,19 @@ static int ladder_select_state(struct cpuidle_device *dev)
92 } 98 }
93 99
94 /* consider demotion */ 100 /* consider demotion */
95 if (last_idx > 0 && 101 if (last_idx > CPUIDLE_DRIVER_STATE_START &&
102 dev->states[last_idx].exit_latency > latency_req) {
103 int i;
104
105 for (i = last_idx - 1; i > CPUIDLE_DRIVER_STATE_START; i--) {
106 if (dev->states[i].exit_latency <= latency_req)
107 break;
108 }
109 ladder_do_selection(ldev, last_idx, i);
110 return i;
111 }
112
113 if (last_idx > CPUIDLE_DRIVER_STATE_START &&
96 last_residency < last_state->threshold.demotion_time) { 114 last_residency < last_state->threshold.demotion_time) {
97 last_state->stats.demotion_count++; 115 last_state->stats.demotion_count++;
98 last_state->stats.promotion_count = 0; 116 last_state->stats.promotion_count = 0;
@@ -117,7 +135,7 @@ static int ladder_enable_device(struct cpuidle_device *dev)
117 struct ladder_device_state *lstate; 135 struct ladder_device_state *lstate;
118 struct cpuidle_state *state; 136 struct cpuidle_state *state;
119 137
120 ldev->last_state_idx = 0; 138 ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
121 139
122 for (i = 0; i < dev->state_count; i++) { 140 for (i = 0; i < dev->state_count; i++) {
123 state = &dev->states[i]; 141 state = &dev->states[i];
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 78d77c5dc35c..8d7cf3f31450 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -34,21 +34,28 @@ static DEFINE_PER_CPU(struct menu_device, menu_devices);
34static int menu_select(struct cpuidle_device *dev) 34static int menu_select(struct cpuidle_device *dev)
35{ 35{
36 struct menu_device *data = &__get_cpu_var(menu_devices); 36 struct menu_device *data = &__get_cpu_var(menu_devices);
37 int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY);
37 int i; 38 int i;
38 39
40 /* Special case when user has set very strict latency requirement */
41 if (unlikely(latency_req == 0)) {
42 data->last_state_idx = 0;
43 return 0;
44 }
45
39 /* determine the expected residency time */ 46 /* determine the expected residency time */
40 data->expected_us = 47 data->expected_us =
41 (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000; 48 (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000;
42 49
43 /* find the deepest idle state that satisfies our constraints */ 50 /* find the deepest idle state that satisfies our constraints */
44 for (i = 1; i < dev->state_count; i++) { 51 for (i = CPUIDLE_DRIVER_STATE_START + 1; i < dev->state_count; i++) {
45 struct cpuidle_state *s = &dev->states[i]; 52 struct cpuidle_state *s = &dev->states[i];
46 53
47 if (s->target_residency > data->expected_us) 54 if (s->target_residency > data->expected_us)
48 break; 55 break;
49 if (s->target_residency > data->predicted_us) 56 if (s->target_residency > data->predicted_us)
50 break; 57 break;
51 if (s->exit_latency > pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) 58 if (s->exit_latency > latency_req)
52 break; 59 break;
53 } 60 }
54 61
@@ -67,9 +74,9 @@ static void menu_reflect(struct cpuidle_device *dev)
67{ 74{
68 struct menu_device *data = &__get_cpu_var(menu_devices); 75 struct menu_device *data = &__get_cpu_var(menu_devices);
69 int last_idx = data->last_state_idx; 76 int last_idx = data->last_state_idx;
70 unsigned int measured_us = 77 unsigned int last_idle_us = cpuidle_get_last_residency(dev);
71 cpuidle_get_last_residency(dev) + data->elapsed_us;
72 struct cpuidle_state *target = &dev->states[last_idx]; 78 struct cpuidle_state *target = &dev->states[last_idx];
79 unsigned int measured_us;
73 80
74 /* 81 /*
75 * Ugh, this idle state doesn't support residency measurements, so we 82 * Ugh, this idle state doesn't support residency measurements, so we
@@ -77,20 +84,27 @@ static void menu_reflect(struct cpuidle_device *dev)
77 * for one full standard timer tick. However, be aware that this 84 * for one full standard timer tick. However, be aware that this
78 * could potentially result in a suboptimal state transition. 85 * could potentially result in a suboptimal state transition.
79 */ 86 */
80 if (!(target->flags & CPUIDLE_FLAG_TIME_VALID)) 87 if (unlikely(!(target->flags & CPUIDLE_FLAG_TIME_VALID)))
81 measured_us = USEC_PER_SEC / HZ; 88 last_idle_us = USEC_PER_SEC / HZ;
89
90 /*
91 * measured_us and elapsed_us are the cumulative idle time, since the
92 * last time we were woken out of idle by an interrupt.
93 */
94 if (data->elapsed_us <= data->elapsed_us + last_idle_us)
95 measured_us = data->elapsed_us + last_idle_us;
96 else
97 measured_us = -1;
98
99 /* Predict time until next break event */
100 data->predicted_us = max(measured_us, data->last_measured_us);
82 101
83 /* Predict time remaining until next break event */ 102 if (last_idle_us + BREAK_FUZZ <
84 if (measured_us + BREAK_FUZZ < data->expected_us - target->exit_latency) { 103 data->expected_us - target->exit_latency) {
85 data->predicted_us = max(measured_us, data->last_measured_us);
86 data->last_measured_us = measured_us; 104 data->last_measured_us = measured_us;
87 data->elapsed_us = 0; 105 data->elapsed_us = 0;
88 } else { 106 } else {
89 if (data->elapsed_us < data->elapsed_us + measured_us) 107 data->elapsed_us = measured_us;
90 data->elapsed_us = measured_us;
91 else
92 data->elapsed_us = -1;
93 data->predicted_us = max(measured_us, data->last_measured_us);
94 } 108 }
95} 109}
96 110
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
index 31a0e0b455b6..97b003839fb6 100644
--- a/drivers/cpuidle/sysfs.c
+++ b/drivers/cpuidle/sysfs.c
@@ -21,8 +21,8 @@ static int __init cpuidle_sysfs_setup(char *unused)
21} 21}
22__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup); 22__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
23 23
24static ssize_t show_available_governors(struct sys_device *dev, 24static ssize_t show_available_governors(struct sysdev_class *class,
25 struct sysdev_attribute *attr, char *buf) 25 char *buf)
26{ 26{
27 ssize_t i = 0; 27 ssize_t i = 0;
28 struct cpuidle_governor *tmp; 28 struct cpuidle_governor *tmp;
@@ -40,8 +40,8 @@ out:
40 return i; 40 return i;
41} 41}
42 42
43static ssize_t show_current_driver(struct sys_device *dev, 43static ssize_t show_current_driver(struct sysdev_class *class,
44 struct sysdev_attribute *attr, char *buf) 44 char *buf)
45{ 45{
46 ssize_t ret; 46 ssize_t ret;
47 47
@@ -55,8 +55,8 @@ static ssize_t show_current_driver(struct sys_device *dev,
55 return ret; 55 return ret;
56} 56}
57 57
58static ssize_t show_current_governor(struct sys_device *dev, 58static ssize_t show_current_governor(struct sysdev_class *class,
59 struct sysdev_attribute *attr, char *buf) 59 char *buf)
60{ 60{
61 ssize_t ret; 61 ssize_t ret;
62 62
@@ -70,9 +70,8 @@ static ssize_t show_current_governor(struct sys_device *dev,
70 return ret; 70 return ret;
71} 71}
72 72
73static ssize_t store_current_governor(struct sys_device *dev, 73static ssize_t store_current_governor(struct sysdev_class *class,
74 struct sysdev_attribute *attr, 74 const char *buf, size_t count)
75 const char *buf, size_t count)
76{ 75{
77 char gov_name[CPUIDLE_NAME_LEN]; 76 char gov_name[CPUIDLE_NAME_LEN];
78 int ret = -EINVAL; 77 int ret = -EINVAL;
@@ -104,8 +103,9 @@ static ssize_t store_current_governor(struct sys_device *dev,
104 return count; 103 return count;
105} 104}
106 105
107static SYSDEV_ATTR(current_driver, 0444, show_current_driver, NULL); 106static SYSDEV_CLASS_ATTR(current_driver, 0444, show_current_driver, NULL);
108static SYSDEV_ATTR(current_governor_ro, 0444, show_current_governor, NULL); 107static SYSDEV_CLASS_ATTR(current_governor_ro, 0444, show_current_governor,
108 NULL);
109 109
110static struct attribute *cpuclass_default_attrs[] = { 110static struct attribute *cpuclass_default_attrs[] = {
111 &attr_current_driver.attr, 111 &attr_current_driver.attr,
@@ -113,9 +113,10 @@ static struct attribute *cpuclass_default_attrs[] = {
113 NULL 113 NULL
114}; 114};
115 115
116static SYSDEV_ATTR(available_governors, 0444, show_available_governors, NULL); 116static SYSDEV_CLASS_ATTR(available_governors, 0444, show_available_governors,
117static SYSDEV_ATTR(current_governor, 0644, show_current_governor, 117 NULL);
118 store_current_governor); 118static SYSDEV_CLASS_ATTR(current_governor, 0644, show_current_governor,
119 store_current_governor);
119 120
120static struct attribute *cpuclass_switch_attrs[] = { 121static struct attribute *cpuclass_switch_attrs[] = {
121 &attr_available_governors.attr, 122 &attr_available_governors.attr,
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 42a107fe9233..2d637e0fbc03 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -27,8 +27,8 @@
27#include <crypto/authenc.h> 27#include <crypto/authenc.h>
28#include <crypto/scatterwalk.h> 28#include <crypto/scatterwalk.h>
29 29
30#include <asm/arch/npe.h> 30#include <mach/npe.h>
31#include <asm/arch/qmgr.h> 31#include <mach/qmgr.h>
32 32
33#define MAX_KEYLEN 32 33#define MAX_KEYLEN 32
34 34
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 54a2a166e566..bf2917d197a0 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -16,6 +16,7 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <asm/byteorder.h> 18#include <asm/byteorder.h>
19#include <asm/i387.h>
19#include "padlock.h" 20#include "padlock.h"
20 21
21/* Control word. */ 22/* Control word. */
@@ -141,6 +142,12 @@ static inline void padlock_reset_key(void)
141 asm volatile ("pushfl; popfl"); 142 asm volatile ("pushfl; popfl");
142} 143}
143 144
145/*
146 * While the padlock instructions don't use FP/SSE registers, they
147 * generate a spurious DNA fault when cr0.ts is '1'. These instructions
148 * should be used only inside the irq_ts_save/restore() context
149 */
150
144static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key, 151static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
145 void *control_word) 152 void *control_word)
146{ 153{
@@ -205,15 +212,23 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
205static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 212static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
206{ 213{
207 struct aes_ctx *ctx = aes_ctx(tfm); 214 struct aes_ctx *ctx = aes_ctx(tfm);
215 int ts_state;
208 padlock_reset_key(); 216 padlock_reset_key();
217
218 ts_state = irq_ts_save();
209 aes_crypt(in, out, ctx->E, &ctx->cword.encrypt); 219 aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
220 irq_ts_restore(ts_state);
210} 221}
211 222
212static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 223static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
213{ 224{
214 struct aes_ctx *ctx = aes_ctx(tfm); 225 struct aes_ctx *ctx = aes_ctx(tfm);
226 int ts_state;
215 padlock_reset_key(); 227 padlock_reset_key();
228
229 ts_state = irq_ts_save();
216 aes_crypt(in, out, ctx->D, &ctx->cword.decrypt); 230 aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
231 irq_ts_restore(ts_state);
217} 232}
218 233
219static struct crypto_alg aes_alg = { 234static struct crypto_alg aes_alg = {
@@ -244,12 +259,14 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
244 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 259 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
245 struct blkcipher_walk walk; 260 struct blkcipher_walk walk;
246 int err; 261 int err;
262 int ts_state;
247 263
248 padlock_reset_key(); 264 padlock_reset_key();
249 265
250 blkcipher_walk_init(&walk, dst, src, nbytes); 266 blkcipher_walk_init(&walk, dst, src, nbytes);
251 err = blkcipher_walk_virt(desc, &walk); 267 err = blkcipher_walk_virt(desc, &walk);
252 268
269 ts_state = irq_ts_save();
253 while ((nbytes = walk.nbytes)) { 270 while ((nbytes = walk.nbytes)) {
254 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr, 271 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
255 ctx->E, &ctx->cword.encrypt, 272 ctx->E, &ctx->cword.encrypt,
@@ -257,6 +274,7 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
257 nbytes &= AES_BLOCK_SIZE - 1; 274 nbytes &= AES_BLOCK_SIZE - 1;
258 err = blkcipher_walk_done(desc, &walk, nbytes); 275 err = blkcipher_walk_done(desc, &walk, nbytes);
259 } 276 }
277 irq_ts_restore(ts_state);
260 278
261 return err; 279 return err;
262} 280}
@@ -268,12 +286,14 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
268 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 286 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
269 struct blkcipher_walk walk; 287 struct blkcipher_walk walk;
270 int err; 288 int err;
289 int ts_state;
271 290
272 padlock_reset_key(); 291 padlock_reset_key();
273 292
274 blkcipher_walk_init(&walk, dst, src, nbytes); 293 blkcipher_walk_init(&walk, dst, src, nbytes);
275 err = blkcipher_walk_virt(desc, &walk); 294 err = blkcipher_walk_virt(desc, &walk);
276 295
296 ts_state = irq_ts_save();
277 while ((nbytes = walk.nbytes)) { 297 while ((nbytes = walk.nbytes)) {
278 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr, 298 padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
279 ctx->D, &ctx->cword.decrypt, 299 ctx->D, &ctx->cword.decrypt,
@@ -281,7 +301,7 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
281 nbytes &= AES_BLOCK_SIZE - 1; 301 nbytes &= AES_BLOCK_SIZE - 1;
282 err = blkcipher_walk_done(desc, &walk, nbytes); 302 err = blkcipher_walk_done(desc, &walk, nbytes);
283 } 303 }
284 304 irq_ts_restore(ts_state);
285 return err; 305 return err;
286} 306}
287 307
@@ -314,12 +334,14 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
314 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 334 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
315 struct blkcipher_walk walk; 335 struct blkcipher_walk walk;
316 int err; 336 int err;
337 int ts_state;
317 338
318 padlock_reset_key(); 339 padlock_reset_key();
319 340
320 blkcipher_walk_init(&walk, dst, src, nbytes); 341 blkcipher_walk_init(&walk, dst, src, nbytes);
321 err = blkcipher_walk_virt(desc, &walk); 342 err = blkcipher_walk_virt(desc, &walk);
322 343
344 ts_state = irq_ts_save();
323 while ((nbytes = walk.nbytes)) { 345 while ((nbytes = walk.nbytes)) {
324 u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr, 346 u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr,
325 walk.dst.virt.addr, ctx->E, 347 walk.dst.virt.addr, ctx->E,
@@ -329,6 +351,7 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
329 nbytes &= AES_BLOCK_SIZE - 1; 351 nbytes &= AES_BLOCK_SIZE - 1;
330 err = blkcipher_walk_done(desc, &walk, nbytes); 352 err = blkcipher_walk_done(desc, &walk, nbytes);
331 } 353 }
354 irq_ts_restore(ts_state);
332 355
333 return err; 356 return err;
334} 357}
@@ -340,12 +363,14 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
340 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm); 363 struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
341 struct blkcipher_walk walk; 364 struct blkcipher_walk walk;
342 int err; 365 int err;
366 int ts_state;
343 367
344 padlock_reset_key(); 368 padlock_reset_key();
345 369
346 blkcipher_walk_init(&walk, dst, src, nbytes); 370 blkcipher_walk_init(&walk, dst, src, nbytes);
347 err = blkcipher_walk_virt(desc, &walk); 371 err = blkcipher_walk_virt(desc, &walk);
348 372
373 ts_state = irq_ts_save();
349 while ((nbytes = walk.nbytes)) { 374 while ((nbytes = walk.nbytes)) {
350 padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr, 375 padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr,
351 ctx->D, walk.iv, &ctx->cword.decrypt, 376 ctx->D, walk.iv, &ctx->cword.decrypt,
@@ -354,6 +379,7 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
354 err = blkcipher_walk_done(desc, &walk, nbytes); 379 err = blkcipher_walk_done(desc, &walk, nbytes);
355 } 380 }
356 381
382 irq_ts_restore(ts_state);
357 return err; 383 return err;
358} 384}
359 385
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
index 40d5680fa013..a7fbadebf623 100644
--- a/drivers/crypto/padlock-sha.c
+++ b/drivers/crypto/padlock-sha.c
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/scatterlist.h> 24#include <linux/scatterlist.h>
25#include <asm/i387.h>
25#include "padlock.h" 26#include "padlock.h"
26 27
27#define SHA1_DEFAULT_FALLBACK "sha1-generic" 28#define SHA1_DEFAULT_FALLBACK "sha1-generic"
@@ -102,6 +103,7 @@ static void padlock_do_sha1(const char *in, char *out, int count)
102 * PadLock microcode needs it that big. */ 103 * PadLock microcode needs it that big. */
103 char buf[128+16]; 104 char buf[128+16];
104 char *result = NEAREST_ALIGNED(buf); 105 char *result = NEAREST_ALIGNED(buf);
106 int ts_state;
105 107
106 ((uint32_t *)result)[0] = SHA1_H0; 108 ((uint32_t *)result)[0] = SHA1_H0;
107 ((uint32_t *)result)[1] = SHA1_H1; 109 ((uint32_t *)result)[1] = SHA1_H1;
@@ -109,9 +111,12 @@ static void padlock_do_sha1(const char *in, char *out, int count)
109 ((uint32_t *)result)[3] = SHA1_H3; 111 ((uint32_t *)result)[3] = SHA1_H3;
110 ((uint32_t *)result)[4] = SHA1_H4; 112 ((uint32_t *)result)[4] = SHA1_H4;
111 113
114 /* prevent taking the spurious DNA fault with padlock. */
115 ts_state = irq_ts_save();
112 asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" /* rep xsha1 */ 116 asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" /* rep xsha1 */
113 : "+S"(in), "+D"(result) 117 : "+S"(in), "+D"(result)
114 : "c"(count), "a"(0)); 118 : "c"(count), "a"(0));
119 irq_ts_restore(ts_state);
115 120
116 padlock_output_block((uint32_t *)result, (uint32_t *)out, 5); 121 padlock_output_block((uint32_t *)result, (uint32_t *)out, 5);
117} 122}
@@ -123,6 +128,7 @@ static void padlock_do_sha256(const char *in, char *out, int count)
123 * PadLock microcode needs it that big. */ 128 * PadLock microcode needs it that big. */
124 char buf[128+16]; 129 char buf[128+16];
125 char *result = NEAREST_ALIGNED(buf); 130 char *result = NEAREST_ALIGNED(buf);
131 int ts_state;
126 132
127 ((uint32_t *)result)[0] = SHA256_H0; 133 ((uint32_t *)result)[0] = SHA256_H0;
128 ((uint32_t *)result)[1] = SHA256_H1; 134 ((uint32_t *)result)[1] = SHA256_H1;
@@ -133,9 +139,12 @@ static void padlock_do_sha256(const char *in, char *out, int count)
133 ((uint32_t *)result)[6] = SHA256_H6; 139 ((uint32_t *)result)[6] = SHA256_H6;
134 ((uint32_t *)result)[7] = SHA256_H7; 140 ((uint32_t *)result)[7] = SHA256_H7;
135 141
142 /* prevent taking the spurious DNA fault with padlock. */
143 ts_state = irq_ts_save();
136 asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" /* rep xsha256 */ 144 asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" /* rep xsha256 */
137 : "+S"(in), "+D"(result) 145 : "+S"(in), "+D"(result)
138 : "c"(count), "a"(0)); 146 : "c"(count), "a"(0));
147 irq_ts_restore(ts_state);
139 148
140 padlock_output_block((uint32_t *)result, (uint32_t *)out, 8); 149 padlock_output_block((uint32_t *)result, (uint32_t *)out, 8);
141} 150}
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 681c15f42083..ee827a7f7c6a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -96,6 +96,9 @@ struct talitos_private {
96 unsigned int exec_units; 96 unsigned int exec_units;
97 unsigned int desc_types; 97 unsigned int desc_types;
98 98
99 /* SEC Compatibility info */
100 unsigned long features;
101
99 /* next channel to be assigned next incoming descriptor */ 102 /* next channel to be assigned next incoming descriptor */
100 atomic_t last_chan; 103 atomic_t last_chan;
101 104
@@ -133,6 +136,9 @@ struct talitos_private {
133 struct hwrng rng; 136 struct hwrng rng;
134}; 137};
135 138
139/* .features flag */
140#define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001
141
136/* 142/*
137 * map virtual single (contiguous) pointer to h/w descriptor pointer 143 * map virtual single (contiguous) pointer to h/w descriptor pointer
138 */ 144 */
@@ -785,7 +791,7 @@ static void ipsec_esp_encrypt_done(struct device *dev,
785 /* copy the generated ICV to dst */ 791 /* copy the generated ICV to dst */
786 if (edesc->dma_len) { 792 if (edesc->dma_len) {
787 icvdata = &edesc->link_tbl[edesc->src_nents + 793 icvdata = &edesc->link_tbl[edesc->src_nents +
788 edesc->dst_nents + 1]; 794 edesc->dst_nents + 2];
789 sg = sg_last(areq->dst, edesc->dst_nents); 795 sg = sg_last(areq->dst, edesc->dst_nents);
790 memcpy((char *)sg_virt(sg) + sg->length - ctx->authsize, 796 memcpy((char *)sg_virt(sg) + sg->length - ctx->authsize,
791 icvdata, ctx->authsize); 797 icvdata, ctx->authsize);
@@ -814,7 +820,7 @@ static void ipsec_esp_decrypt_done(struct device *dev,
814 /* auth check */ 820 /* auth check */
815 if (edesc->dma_len) 821 if (edesc->dma_len)
816 icvdata = &edesc->link_tbl[edesc->src_nents + 822 icvdata = &edesc->link_tbl[edesc->src_nents +
817 edesc->dst_nents + 1]; 823 edesc->dst_nents + 2];
818 else 824 else
819 icvdata = &edesc->link_tbl[0]; 825 icvdata = &edesc->link_tbl[0];
820 826
@@ -921,10 +927,30 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
921 sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen, 927 sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen,
922 &edesc->link_tbl[0]); 928 &edesc->link_tbl[0]);
923 if (sg_count > 1) { 929 if (sg_count > 1) {
930 struct talitos_ptr *link_tbl_ptr =
931 &edesc->link_tbl[sg_count-1];
932 struct scatterlist *sg;
933 struct talitos_private *priv = dev_get_drvdata(dev);
934
924 desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP; 935 desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
925 desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl); 936 desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl);
926 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, 937 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
927 edesc->dma_len, DMA_BIDIRECTIONAL); 938 edesc->dma_len, DMA_BIDIRECTIONAL);
939 /* If necessary for this SEC revision,
940 * add a link table entry for ICV.
941 */
942 if ((priv->features &
943 TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT) &&
944 (edesc->desc.hdr & DESC_HDR_MODE0_ENCRYPT) == 0) {
945 link_tbl_ptr->j_extent = 0;
946 link_tbl_ptr++;
947 link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
948 link_tbl_ptr->len = cpu_to_be16(authsize);
949 sg = sg_last(areq->src, edesc->src_nents ? : 1);
950 link_tbl_ptr->ptr = cpu_to_be32(
951 (char *)sg_dma_address(sg)
952 + sg->length - authsize);
953 }
928 } else { 954 } else {
929 /* Only one segment now, so no link tbl needed */ 955 /* Only one segment now, so no link tbl needed */
930 desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src)); 956 desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src));
@@ -944,12 +970,11 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
944 desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst)); 970 desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst));
945 } else { 971 } else {
946 struct talitos_ptr *link_tbl_ptr = 972 struct talitos_ptr *link_tbl_ptr =
947 &edesc->link_tbl[edesc->src_nents]; 973 &edesc->link_tbl[edesc->src_nents + 1];
948 struct scatterlist *sg;
949 974
950 desc->ptr[5].ptr = cpu_to_be32((struct talitos_ptr *) 975 desc->ptr[5].ptr = cpu_to_be32((struct talitos_ptr *)
951 edesc->dma_link_tbl + 976 edesc->dma_link_tbl +
952 edesc->src_nents); 977 edesc->src_nents + 1);
953 if (areq->src == areq->dst) { 978 if (areq->src == areq->dst) {
954 memcpy(link_tbl_ptr, &edesc->link_tbl[0], 979 memcpy(link_tbl_ptr, &edesc->link_tbl[0],
955 edesc->src_nents * sizeof(struct talitos_ptr)); 980 edesc->src_nents * sizeof(struct talitos_ptr));
@@ -957,14 +982,10 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
957 sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen, 982 sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
958 link_tbl_ptr); 983 link_tbl_ptr);
959 } 984 }
985 /* Add an entry to the link table for ICV data */
960 link_tbl_ptr += sg_count - 1; 986 link_tbl_ptr += sg_count - 1;
961
962 /* handle case where sg_last contains the ICV exclusively */
963 sg = sg_last(areq->dst, edesc->dst_nents);
964 if (sg->length == ctx->authsize)
965 link_tbl_ptr--;
966
967 link_tbl_ptr->j_extent = 0; 987 link_tbl_ptr->j_extent = 0;
988 sg_count++;
968 link_tbl_ptr++; 989 link_tbl_ptr++;
969 link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; 990 link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
970 link_tbl_ptr->len = cpu_to_be16(authsize); 991 link_tbl_ptr->len = cpu_to_be16(authsize);
@@ -973,7 +994,7 @@ static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
973 link_tbl_ptr->ptr = cpu_to_be32((struct talitos_ptr *) 994 link_tbl_ptr->ptr = cpu_to_be32((struct talitos_ptr *)
974 edesc->dma_link_tbl + 995 edesc->dma_link_tbl +
975 edesc->src_nents + 996 edesc->src_nents +
976 edesc->dst_nents + 1); 997 edesc->dst_nents + 2);
977 998
978 desc->ptr[5].j_extent |= DESC_PTR_LNKTBL_JUMP; 999 desc->ptr[5].j_extent |= DESC_PTR_LNKTBL_JUMP;
979 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl, 1000 dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
@@ -1040,12 +1061,12 @@ static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
1040 1061
1041 /* 1062 /*
1042 * allocate space for base edesc plus the link tables, 1063 * allocate space for base edesc plus the link tables,
1043 * allowing for a separate entry for the generated ICV (+ 1), 1064 * allowing for two separate entries for ICV and generated ICV (+ 2),
1044 * and the ICV data itself 1065 * and the ICV data itself
1045 */ 1066 */
1046 alloc_len = sizeof(struct ipsec_esp_edesc); 1067 alloc_len = sizeof(struct ipsec_esp_edesc);
1047 if (src_nents || dst_nents) { 1068 if (src_nents || dst_nents) {
1048 dma_len = (src_nents + dst_nents + 1) * 1069 dma_len = (src_nents + dst_nents + 2) *
1049 sizeof(struct talitos_ptr) + ctx->authsize; 1070 sizeof(struct talitos_ptr) + ctx->authsize;
1050 alloc_len += dma_len; 1071 alloc_len += dma_len;
1051 } else { 1072 } else {
@@ -1104,7 +1125,7 @@ static int aead_authenc_decrypt(struct aead_request *req)
1104 /* stash incoming ICV for later cmp with ICV generated by the h/w */ 1125 /* stash incoming ICV for later cmp with ICV generated by the h/w */
1105 if (edesc->dma_len) 1126 if (edesc->dma_len)
1106 icvdata = &edesc->link_tbl[edesc->src_nents + 1127 icvdata = &edesc->link_tbl[edesc->src_nents +
1107 edesc->dst_nents + 1]; 1128 edesc->dst_nents + 2];
1108 else 1129 else
1109 icvdata = &edesc->link_tbl[0]; 1130 icvdata = &edesc->link_tbl[0];
1110 1131
@@ -1480,6 +1501,9 @@ static int talitos_probe(struct of_device *ofdev,
1480 goto err_out; 1501 goto err_out;
1481 } 1502 }
1482 1503
1504 if (of_device_is_compatible(np, "fsl,sec3.0"))
1505 priv->features |= TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT;
1506
1483 priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, 1507 priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels,
1484 GFP_KERNEL); 1508 GFP_KERNEL);
1485 priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, 1509 priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels,
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index a52156e56886..bc8c6e3470ca 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -551,7 +551,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx)
551 /* write address into NextDescriptor field of last desc in chain */ 551 /* write address into NextDescriptor field of last desc in chain */
552 to_ioat_desc(ioat_chan->used_desc.prev)->hw->next = 552 to_ioat_desc(ioat_chan->used_desc.prev)->hw->next =
553 first->async_tx.phys; 553 first->async_tx.phys;
554 __list_splice(&new_chain, ioat_chan->used_desc.prev); 554 list_splice_tail(&new_chain, &ioat_chan->used_desc);
555 555
556 ioat_chan->dmacount += desc_count; 556 ioat_chan->dmacount += desc_count;
557 ioat_chan->pending += desc_count; 557 ioat_chan->pending += desc_count;
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 85bfeba4d85e..71fba82462cb 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -33,7 +33,7 @@
33#include <linux/memory.h> 33#include <linux/memory.h>
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35 35
36#include <asm/arch/adma.h> 36#include <mach/adma.h>
37 37
38#define to_iop_adma_chan(chan) container_of(chan, struct iop_adma_chan, common) 38#define to_iop_adma_chan(chan) container_of(chan, struct iop_adma_chan, common)
39#define to_iop_adma_device(dev) \ 39#define to_iop_adma_device(dev) \
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index a4e4494663bf..0328da020a10 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -25,7 +25,7 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/memory.h> 27#include <linux/memory.h>
28#include <asm/plat-orion/mv_xor.h> 28#include <plat/mv_xor.h>
29#include "mv_xor.h" 29#include "mv_xor.h"
30 30
31static void mv_xor_issue_pending(struct dma_chan *chan); 31static void mv_xor_issue_pending(struct dma_chan *chan);
diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
index fa6d6abefd4d..450902438208 100644
--- a/drivers/firewire/Kconfig
+++ b/drivers/firewire/Kconfig
@@ -12,8 +12,8 @@ config FIREWIRE
12 This is the "Juju" FireWire stack, a new alternative implementation 12 This is the "Juju" FireWire stack, a new alternative implementation
13 designed for robustness and simplicity. You can build either this 13 designed for robustness and simplicity. You can build either this
14 stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both. 14 stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both.
15 Please read http://wiki.linux1394.org/JujuMigration before you 15 Please read http://ieee1394.wiki.kernel.org/index.php/Juju_Migration
16 enable the new stack. 16 before you enable the new stack.
17 17
18 To compile this driver as a module, say M here: the module will be 18 To compile this driver as a module, say M here: the module will be
19 called firewire-core. 19 called firewire-core.
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index bc81d6fcd2fd..2e6d5848d217 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -369,22 +369,33 @@ complete_transaction(struct fw_card *card, int rcode,
369 struct response *response = data; 369 struct response *response = data;
370 struct client *client = response->client; 370 struct client *client = response->client;
371 unsigned long flags; 371 unsigned long flags;
372 struct fw_cdev_event_response *r = &response->response;
372 373
373 if (length < response->response.length) 374 if (length < r->length)
374 response->response.length = length; 375 r->length = length;
375 if (rcode == RCODE_COMPLETE) 376 if (rcode == RCODE_COMPLETE)
376 memcpy(response->response.data, payload, 377 memcpy(r->data, payload, r->length);
377 response->response.length);
378 378
379 spin_lock_irqsave(&client->lock, flags); 379 spin_lock_irqsave(&client->lock, flags);
380 list_del(&response->resource.link); 380 list_del(&response->resource.link);
381 spin_unlock_irqrestore(&client->lock, flags); 381 spin_unlock_irqrestore(&client->lock, flags);
382 382
383 response->response.type = FW_CDEV_EVENT_RESPONSE; 383 r->type = FW_CDEV_EVENT_RESPONSE;
384 response->response.rcode = rcode; 384 r->rcode = rcode;
385 queue_event(client, &response->event, &response->response, 385
386 sizeof(response->response) + response->response.length, 386 /*
387 NULL, 0); 387 * In the case that sizeof(*r) doesn't align with the position of the
388 * data, and the read is short, preserve an extra copy of the data
389 * to stay compatible with a pre-2.6.27 bug. Since the bug is harmless
390 * for short reads and some apps depended on it, this is both safe
391 * and prudent for compatibility.
392 */
393 if (r->length <= sizeof(*r) - offsetof(typeof(*r), data))
394 queue_event(client, &response->event, r, sizeof(*r),
395 r->data, r->length);
396 else
397 queue_event(client, &response->event, r, sizeof(*r) + r->length,
398 NULL, 0);
388} 399}
389 400
390static int ioctl_send_request(struct client *client, void *buffer) 401static int ioctl_send_request(struct client *client, void *buffer)
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 001622eb86f9..3bf8ee120d42 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -84,20 +84,23 @@ static struct kobj_type memmap_ktype = {
84 */ 84 */
85 85
86/* 86/*
87 * Firmware memory map entries 87 * Firmware memory map entries. No locking is needed because the
88 * firmware_map_add() and firmware_map_add_early() functions are called
89 * in firmware initialisation code in one single thread of execution.
88 */ 90 */
89static LIST_HEAD(map_entries); 91static LIST_HEAD(map_entries);
90 92
91/** 93/**
92 * Common implementation of firmware_map_add() and firmware_map_add_early() 94 * firmware_map_add_entry() - Does the real work to add a firmware memmap entry.
93 * which expects a pre-allocated struct firmware_map_entry.
94 *
95 * @start: Start of the memory range. 95 * @start: Start of the memory range.
96 * @end: End of the memory range (inclusive). 96 * @end: End of the memory range (inclusive).
97 * @type: Type of the memory range. 97 * @type: Type of the memory range.
98 * @entry: Pre-allocated (either kmalloc() or bootmem allocator), uninitialised 98 * @entry: Pre-allocated (either kmalloc() or bootmem allocator), uninitialised
99 * entry. 99 * entry.
100 */ 100 *
101 * Common implementation of firmware_map_add() and firmware_map_add_early()
102 * which expects a pre-allocated struct firmware_map_entry.
103 **/
101static int firmware_map_add_entry(resource_size_t start, resource_size_t end, 104static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
102 const char *type, 105 const char *type,
103 struct firmware_map_entry *entry) 106 struct firmware_map_entry *entry)
@@ -115,33 +118,52 @@ static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
115 return 0; 118 return 0;
116} 119}
117 120
118/* 121/**
119 * See <linux/firmware-map.h> for documentation. 122 * firmware_map_add() - Adds a firmware mapping entry.
120 */ 123 * @start: Start of the memory range.
124 * @end: End of the memory range (inclusive).
125 * @type: Type of the memory range.
126 *
127 * This function uses kmalloc() for memory
128 * allocation. Use firmware_map_add_early() if you want to use the bootmem
129 * allocator.
130 *
131 * That function must be called before late_initcall.
132 *
133 * Returns 0 on success, or -ENOMEM if no memory could be allocated.
134 **/
121int firmware_map_add(resource_size_t start, resource_size_t end, 135int firmware_map_add(resource_size_t start, resource_size_t end,
122 const char *type) 136 const char *type)
123{ 137{
124 struct firmware_map_entry *entry; 138 struct firmware_map_entry *entry;
125 139
126 entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC); 140 entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
127 WARN_ON(!entry);
128 if (!entry) 141 if (!entry)
129 return -ENOMEM; 142 return -ENOMEM;
130 143
131 return firmware_map_add_entry(start, end, type, entry); 144 return firmware_map_add_entry(start, end, type, entry);
132} 145}
133 146
134/* 147/**
135 * See <linux/firmware-map.h> for documentation. 148 * firmware_map_add_early() - Adds a firmware mapping entry.
136 */ 149 * @start: Start of the memory range.
150 * @end: End of the memory range (inclusive).
151 * @type: Type of the memory range.
152 *
153 * Adds a firmware mapping entry. This function uses the bootmem allocator
154 * for memory allocation. Use firmware_map_add() if you want to use kmalloc().
155 *
156 * That function must be called before late_initcall.
157 *
158 * Returns 0 on success, or -ENOMEM if no memory could be allocated.
159 **/
137int __init firmware_map_add_early(resource_size_t start, resource_size_t end, 160int __init firmware_map_add_early(resource_size_t start, resource_size_t end,
138 const char *type) 161 const char *type)
139{ 162{
140 struct firmware_map_entry *entry; 163 struct firmware_map_entry *entry;
141 164
142 entry = alloc_bootmem_low(sizeof(struct firmware_map_entry)); 165 entry = alloc_bootmem_low(sizeof(struct firmware_map_entry));
143 WARN_ON(!entry); 166 if (WARN_ON(!entry))
144 if (!entry)
145 return -ENOMEM; 167 return -ENOMEM;
146 168
147 return firmware_map_add_entry(start, end, type, entry); 169 return firmware_map_add_entry(start, end, type, entry);
@@ -183,7 +205,10 @@ static ssize_t memmap_attr_show(struct kobject *kobj,
183/* 205/*
184 * Initialises stuff and adds the entries in the map_entries list to 206 * Initialises stuff and adds the entries in the map_entries list to
185 * sysfs. Important is that firmware_map_add() and firmware_map_add_early() 207 * sysfs. Important is that firmware_map_add() and firmware_map_add_early()
186 * must be called before late_initcall. 208 * must be called before late_initcall. That's just because that function
209 * is called as late_initcall() function, which means that if you call
210 * firmware_map_add() or firmware_map_add_early() afterwards, the entries
211 * are not added to sysfs.
187 */ 212 */
188static int __init memmap_init(void) 213static int __init memmap_init(void)
189{ 214{
@@ -192,13 +217,13 @@ static int __init memmap_init(void)
192 struct kset *memmap_kset; 217 struct kset *memmap_kset;
193 218
194 memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj); 219 memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
195 WARN_ON(!memmap_kset); 220 if (WARN_ON(!memmap_kset))
196 if (!memmap_kset)
197 return -ENOMEM; 221 return -ENOMEM;
198 222
199 list_for_each_entry(entry, &map_entries, list) { 223 list_for_each_entry(entry, &map_entries, list) {
200 entry->kobj.kset = memmap_kset; 224 entry->kobj.kset = memmap_kset;
201 kobject_add(&entry->kobj, NULL, "%d", i++); 225 if (kobject_add(&entry->kobj, NULL, "%d", i++))
226 kobject_put(&entry->kobj);
202 } 227 }
203 228
204 return 0; 229 return 0;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 61e78a4369b9..b15f88249639 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -654,12 +654,12 @@ static const struct hid_blacklist {
654 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, 654 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
655 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, 655 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
656 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, 656 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
657 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN }, 657 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
658 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, 658 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE},
659 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN }, 659 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
660 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN }, 660 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
661 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, 661 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
662 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN }, 662 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
663 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, 663 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
664 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, 664 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
665 665
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c882fd05cf29..d402e8d813ce 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -57,6 +57,16 @@ config SENSORS_ABITUGURU3
57 This driver can also be built as a module. If so, the module 57 This driver can also be built as a module. If so, the module
58 will be called abituguru3. 58 will be called abituguru3.
59 59
60config SENSORS_AD7414
61 tristate "Analog Devices AD7414"
62 depends on I2C && EXPERIMENTAL
63 help
64 If you say yes here you get support for the Analog Devices
65 AD7414 temperature monitoring chip.
66
67 This driver can also be built as a module. If so, the module
68 will be called ad7414.
69
60config SENSORS_AD7418 70config SENSORS_AD7418
61 tristate "Analog Devices AD7416, AD7417 and AD7418" 71 tristate "Analog Devices AD7416, AD7417 and AD7418"
62 depends on I2C && EXPERIMENTAL 72 depends on I2C && EXPERIMENTAL
@@ -67,6 +77,22 @@ config SENSORS_AD7418
67 This driver can also be built as a module. If so, the module 77 This driver can also be built as a module. If so, the module
68 will be called ad7418. 78 will be called ad7418.
69 79
80config SENSORS_ADCXX
81 tristate "National Semiconductor ADCxxxSxxx"
82 depends on SPI_MASTER && EXPERIMENTAL
83 help
84 If you say yes here you get support for the National Semiconductor
85 ADC<bb><c>S<sss> chip family, where
86 * bb is the resolution in number of bits (8, 10, 12)
87 * c is the number of channels (1, 2, 4, 8)
88 * sss is the maximum conversion speed (021 for 200 kSPS, 051 for 500
89 kSPS and 101 for 1 MSPS)
90
91 Examples : ADC081S101, ADC124S501, ...
92
93 This driver can also be built as a module. If so, the module
94 will be called adcxx.
95
70config SENSORS_ADM1021 96config SENSORS_ADM1021
71 tristate "Analog Devices ADM1021 and compatibles" 97 tristate "Analog Devices ADM1021 and compatibles"
72 depends on I2C 98 depends on I2C
@@ -124,7 +150,7 @@ config SENSORS_ADM1031
124 150
125config SENSORS_ADM9240 151config SENSORS_ADM9240
126 tristate "Analog Devices ADM9240 and compatibles" 152 tristate "Analog Devices ADM9240 and compatibles"
127 depends on I2C && EXPERIMENTAL 153 depends on I2C
128 select HWMON_VID 154 select HWMON_VID
129 help 155 help
130 If you say yes here you get support for Analog Devices ADM9240, 156 If you say yes here you get support for Analog Devices ADM9240,
@@ -575,8 +601,8 @@ config SENSORS_DME1737
575 select HWMON_VID 601 select HWMON_VID
576 help 602 help
577 If you say yes here you get support for the hardware monitoring 603 If you say yes here you get support for the hardware monitoring
578 and fan control features of the SMSC DME1737 (and compatibles 604 and fan control features of the SMSC DME1737, SCH311x, SCH5027, and
579 like the Asus A8000) and SCH311x Super-I/O chips. 605 Asus A8000 Super-I/O chips.
580 606
581 This driver can also be built as a module. If so, the module 607 This driver can also be built as a module. If so, the module
582 will be called dme1737. 608 will be called dme1737.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index d098677e08de..950134ab8426 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -15,7 +15,9 @@ obj-$(CONFIG_SENSORS_W83791D) += w83791d.o
15 15
16obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o 16obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o
17obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o 17obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o
18obj-$(CONFIG_SENSORS_AD7414) += ad7414.o
18obj-$(CONFIG_SENSORS_AD7418) += ad7418.o 19obj-$(CONFIG_SENSORS_AD7418) += ad7418.o
20obj-$(CONFIG_SENSORS_ADCXX) += adcxx.o
19obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o 21obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
20obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o 22obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
21obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o 23obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index f00f497b9ca9..d568c65c1370 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -1,5 +1,8 @@
1/* 1/*
2 abituguru3.c Copyright (c) 2006 Hans de Goede <j.w.r.degoede@hhs.nl> 2 abituguru3.c
3
4 Copyright (c) 2006-2008 Hans de Goede <j.w.r.degoede@hhs.nl>
5 Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk>
3 6
4 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
@@ -116,7 +119,7 @@ struct abituguru3_sensor_info {
116 119
117struct abituguru3_motherboard_info { 120struct abituguru3_motherboard_info {
118 u16 id; 121 u16 id;
119 const char *name; 122 const char *dmi_name;
120 /* + 1 -> end of sensors indicated by a sensor with name == NULL */ 123 /* + 1 -> end of sensors indicated by a sensor with name == NULL */
121 struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; 124 struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
122}; 125};
@@ -161,7 +164,7 @@ struct abituguru3_data {
161 164
162/* Constants */ 165/* Constants */
163static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { 166static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
164 { 0x000C, "unknown", { 167 { 0x000C, NULL /* Unknown, need DMI string */, {
165 { "CPU Core", 0, 0, 10, 1, 0 }, 168 { "CPU Core", 0, 0, 10, 1, 0 },
166 { "DDR", 1, 0, 10, 1, 0 }, 169 { "DDR", 1, 0, 10, 1, 0 },
167 { "DDR VTT", 2, 0, 10, 1, 0 }, 170 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -183,7 +186,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
183 { "AUX1 Fan", 35, 2, 60, 1, 0 }, 186 { "AUX1 Fan", 35, 2, 60, 1, 0 },
184 { NULL, 0, 0, 0, 0, 0 } } 187 { NULL, 0, 0, 0, 0, 0 } }
185 }, 188 },
186 { 0x000D, "Abit AW8", { 189 { 0x000D, NULL /* Abit AW8, need DMI string */, {
187 { "CPU Core", 0, 0, 10, 1, 0 }, 190 { "CPU Core", 0, 0, 10, 1, 0 },
188 { "DDR", 1, 0, 10, 1, 0 }, 191 { "DDR", 1, 0, 10, 1, 0 },
189 { "DDR VTT", 2, 0, 10, 1, 0 }, 192 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -212,7 +215,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
212 { "AUX5 Fan", 39, 2, 60, 1, 0 }, 215 { "AUX5 Fan", 39, 2, 60, 1, 0 },
213 { NULL, 0, 0, 0, 0, 0 } } 216 { NULL, 0, 0, 0, 0, 0 } }
214 }, 217 },
215 { 0x000E, "AL-8", { 218 { 0x000E, NULL /* AL-8, need DMI string */, {
216 { "CPU Core", 0, 0, 10, 1, 0 }, 219 { "CPU Core", 0, 0, 10, 1, 0 },
217 { "DDR", 1, 0, 10, 1, 0 }, 220 { "DDR", 1, 0, 10, 1, 0 },
218 { "DDR VTT", 2, 0, 10, 1, 0 }, 221 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -233,7 +236,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
233 { "SYS Fan", 34, 2, 60, 1, 0 }, 236 { "SYS Fan", 34, 2, 60, 1, 0 },
234 { NULL, 0, 0, 0, 0, 0 } } 237 { NULL, 0, 0, 0, 0, 0 } }
235 }, 238 },
236 { 0x000F, "unknown", { 239 { 0x000F, NULL /* Unknown, need DMI string */, {
237 { "CPU Core", 0, 0, 10, 1, 0 }, 240 { "CPU Core", 0, 0, 10, 1, 0 },
238 { "DDR", 1, 0, 10, 1, 0 }, 241 { "DDR", 1, 0, 10, 1, 0 },
239 { "DDR VTT", 2, 0, 10, 1, 0 }, 242 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -254,7 +257,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
254 { "SYS Fan", 34, 2, 60, 1, 0 }, 257 { "SYS Fan", 34, 2, 60, 1, 0 },
255 { NULL, 0, 0, 0, 0, 0 } } 258 { NULL, 0, 0, 0, 0, 0 } }
256 }, 259 },
257 { 0x0010, "Abit NI8 SLI GR", { 260 { 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, {
258 { "CPU Core", 0, 0, 10, 1, 0 }, 261 { "CPU Core", 0, 0, 10, 1, 0 },
259 { "DDR", 1, 0, 10, 1, 0 }, 262 { "DDR", 1, 0, 10, 1, 0 },
260 { "DDR VTT", 2, 0, 10, 1, 0 }, 263 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -276,7 +279,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
276 { "OTES1 Fan", 36, 2, 60, 1, 0 }, 279 { "OTES1 Fan", 36, 2, 60, 1, 0 },
277 { NULL, 0, 0, 0, 0, 0 } } 280 { NULL, 0, 0, 0, 0, 0 } }
278 }, 281 },
279 { 0x0011, "Abit AT8 32X", { 282 { 0x0011, NULL /* Abit AT8 32X, need DMI string */, {
280 { "CPU Core", 0, 0, 10, 1, 0 }, 283 { "CPU Core", 0, 0, 10, 1, 0 },
281 { "DDR", 1, 0, 20, 1, 0 }, 284 { "DDR", 1, 0, 20, 1, 0 },
282 { "DDR VTT", 2, 0, 10, 1, 0 }, 285 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -302,7 +305,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
302 { "AUX2 Fan", 36, 2, 60, 1, 0 }, 305 { "AUX2 Fan", 36, 2, 60, 1, 0 },
303 { NULL, 0, 0, 0, 0, 0 } } 306 { NULL, 0, 0, 0, 0, 0 } }
304 }, 307 },
305 { 0x0012, "Abit AN8 32X", { 308 { 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
306 { "CPU Core", 0, 0, 10, 1, 0 }, 309 { "CPU Core", 0, 0, 10, 1, 0 },
307 { "DDR", 1, 0, 20, 1, 0 }, 310 { "DDR", 1, 0, 20, 1, 0 },
308 { "DDR VTT", 2, 0, 10, 1, 0 }, 311 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -324,7 +327,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
324 { "AUX1 Fan", 36, 2, 60, 1, 0 }, 327 { "AUX1 Fan", 36, 2, 60, 1, 0 },
325 { NULL, 0, 0, 0, 0, 0 } } 328 { NULL, 0, 0, 0, 0, 0 } }
326 }, 329 },
327 { 0x0013, "Abit AW8D", { 330 { 0x0013, NULL /* Abit AW8D, need DMI string */, {
328 { "CPU Core", 0, 0, 10, 1, 0 }, 331 { "CPU Core", 0, 0, 10, 1, 0 },
329 { "DDR", 1, 0, 10, 1, 0 }, 332 { "DDR", 1, 0, 10, 1, 0 },
330 { "DDR VTT", 2, 0, 10, 1, 0 }, 333 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -353,7 +356,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
353 { "AUX5 Fan", 39, 2, 60, 1, 0 }, 356 { "AUX5 Fan", 39, 2, 60, 1, 0 },
354 { NULL, 0, 0, 0, 0, 0 } } 357 { NULL, 0, 0, 0, 0, 0 } }
355 }, 358 },
356 { 0x0014, "Abit AB9 Pro", { 359 { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, {
357 { "CPU Core", 0, 0, 10, 1, 0 }, 360 { "CPU Core", 0, 0, 10, 1, 0 },
358 { "DDR", 1, 0, 10, 1, 0 }, 361 { "DDR", 1, 0, 10, 1, 0 },
359 { "DDR VTT", 2, 0, 10, 1, 0 }, 362 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -374,7 +377,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
374 { "SYS Fan", 34, 2, 60, 1, 0 }, 377 { "SYS Fan", 34, 2, 60, 1, 0 },
375 { NULL, 0, 0, 0, 0, 0 } } 378 { NULL, 0, 0, 0, 0, 0 } }
376 }, 379 },
377 { 0x0015, "unknown", { 380 { 0x0015, NULL /* Unknown, need DMI string */, {
378 { "CPU Core", 0, 0, 10, 1, 0 }, 381 { "CPU Core", 0, 0, 10, 1, 0 },
379 { "DDR", 1, 0, 20, 1, 0 }, 382 { "DDR", 1, 0, 20, 1, 0 },
380 { "DDR VTT", 2, 0, 10, 1, 0 }, 383 { "DDR VTT", 2, 0, 10, 1, 0 },
@@ -398,7 +401,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
398 { "AUX3 Fan", 36, 2, 60, 1, 0 }, 401 { "AUX3 Fan", 36, 2, 60, 1, 0 },
399 { NULL, 0, 0, 0, 0, 0 } } 402 { NULL, 0, 0, 0, 0, 0 } }
400 }, 403 },
401 { 0x0016, "AW9D-MAX", { 404 { 0x0016, NULL /* AW9D-MAX, need DMI string */, {
402 { "CPU Core", 0, 0, 10, 1, 0 }, 405 { "CPU Core", 0, 0, 10, 1, 0 },
403 { "DDR2", 1, 0, 20, 1, 0 }, 406 { "DDR2", 1, 0, 20, 1, 0 },
404 { "DDR2 VTT", 2, 0, 10, 1, 0 }, 407 { "DDR2 VTT", 2, 0, 10, 1, 0 },
@@ -426,7 +429,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
426 { "OTES1 Fan", 38, 2, 60, 1, 0 }, 429 { "OTES1 Fan", 38, 2, 60, 1, 0 },
427 { NULL, 0, 0, 0, 0, 0 } } 430 { NULL, 0, 0, 0, 0, 0 } }
428 }, 431 },
429 { 0x0017, "unknown", { 432 { 0x0017, NULL /* Unknown, need DMI string */, {
430 { "CPU Core", 0, 0, 10, 1, 0 }, 433 { "CPU Core", 0, 0, 10, 1, 0 },
431 { "DDR2", 1, 0, 20, 1, 0 }, 434 { "DDR2", 1, 0, 20, 1, 0 },
432 { "DDR2 VTT", 2, 0, 10, 1, 0 }, 435 { "DDR2 VTT", 2, 0, 10, 1, 0 },
@@ -451,7 +454,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
451 { "AUX3 FAN", 37, 2, 60, 1, 0 }, 454 { "AUX3 FAN", 37, 2, 60, 1, 0 },
452 { NULL, 0, 0, 0, 0, 0 } } 455 { NULL, 0, 0, 0, 0, 0 } }
453 }, 456 },
454 { 0x0018, "unknown", { 457 { 0x0018, NULL /* Unknown, need DMI string */, {
455 { "CPU Core", 0, 0, 10, 1, 0 }, 458 { "CPU Core", 0, 0, 10, 1, 0 },
456 { "DDR2", 1, 0, 20, 1, 0 }, 459 { "DDR2", 1, 0, 20, 1, 0 },
457 { "DDR2 VTT", 2, 0, 10, 1, 0 }, 460 { "DDR2 VTT", 2, 0, 10, 1, 0 },
@@ -478,7 +481,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
478 { "AUX3 Fan", 36, 2, 60, 1, 0 }, 481 { "AUX3 Fan", 36, 2, 60, 1, 0 },
479 { NULL, 0, 0, 0, 0, 0 } } 482 { NULL, 0, 0, 0, 0, 0 } }
480 }, 483 },
481 { 0x0019, "unknown", { 484 { 0x0019, NULL /* Unknown, need DMI string */, {
482 { "CPU Core", 7, 0, 10, 1, 0 }, 485 { "CPU Core", 7, 0, 10, 1, 0 },
483 { "DDR2", 13, 0, 20, 1, 0 }, 486 { "DDR2", 13, 0, 20, 1, 0 },
484 { "DDR2 VTT", 14, 0, 10, 1, 0 }, 487 { "DDR2 VTT", 14, 0, 10, 1, 0 },
@@ -505,7 +508,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
505 { "AUX3 FAN", 36, 2, 60, 1, 0 }, 508 { "AUX3 FAN", 36, 2, 60, 1, 0 },
506 { NULL, 0, 0, 0, 0, 0 } } 509 { NULL, 0, 0, 0, 0, 0 } }
507 }, 510 },
508 { 0x001A, "Abit IP35 Pro", { 511 { 0x001A, "IP35 Pro(Intel P35-ICH9R)", {
509 { "CPU Core", 0, 0, 10, 1, 0 }, 512 { "CPU Core", 0, 0, 10, 1, 0 },
510 { "DDR2", 1, 0, 20, 1, 0 }, 513 { "DDR2", 1, 0, 20, 1, 0 },
511 { "DDR2 VTT", 2, 0, 10, 1, 0 }, 514 { "DDR2 VTT", 2, 0, 10, 1, 0 },
@@ -533,7 +536,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
533 { "AUX4 Fan", 37, 2, 60, 1, 0 }, 536 { "AUX4 Fan", 37, 2, 60, 1, 0 },
534 { NULL, 0, 0, 0, 0, 0 } } 537 { NULL, 0, 0, 0, 0, 0 } }
535 }, 538 },
536 { 0x001B, "unknown", { 539 { 0x001B, NULL /* Unknown, need DMI string */, {
537 { "CPU Core", 0, 0, 10, 1, 0 }, 540 { "CPU Core", 0, 0, 10, 1, 0 },
538 { "DDR3", 1, 0, 20, 1, 0 }, 541 { "DDR3", 1, 0, 20, 1, 0 },
539 { "DDR3 VTT", 2, 0, 10, 1, 0 }, 542 { "DDR3 VTT", 2, 0, 10, 1, 0 },
@@ -560,7 +563,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
560 { "AUX3 Fan", 36, 2, 60, 1, 0 }, 563 { "AUX3 Fan", 36, 2, 60, 1, 0 },
561 { NULL, 0, 0, 0, 0, 0 } } 564 { NULL, 0, 0, 0, 0, 0 } }
562 }, 565 },
563 { 0x001C, "unknown", { 566 { 0x001C, NULL /* Unknown, need DMI string */, {
564 { "CPU Core", 0, 0, 10, 1, 0 }, 567 { "CPU Core", 0, 0, 10, 1, 0 },
565 { "DDR2", 1, 0, 20, 1, 0 }, 568 { "DDR2", 1, 0, 20, 1, 0 },
566 { "DDR2 VTT", 2, 0, 10, 1, 0 }, 569 { "DDR2 VTT", 2, 0, 10, 1, 0 },
@@ -935,9 +938,18 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
935 goto abituguru3_probe_error; 938 goto abituguru3_probe_error;
936 } 939 }
937 data->sensors = abituguru3_motherboards[i].sensors; 940 data->sensors = abituguru3_motherboards[i].sensors;
941
938 printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " 942 printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard "
939 "ID: %04X (%s)\n", (unsigned int)id, 943 "ID: %04X\n", (unsigned int)id);
940 abituguru3_motherboards[i].name); 944
945#ifdef CONFIG_DMI
946 if (!abituguru3_motherboards[i].dmi_name) {
947 printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
948 "not detected using DMI. Please send the output of "
949 "\"dmidecode\" to the abituguru3 maintainer"
950 "(see MAINTAINERS)\n");
951 }
952#endif
941 953
942 /* Fill the sysfs attr array */ 954 /* Fill the sysfs attr array */
943 sysfs_attr_i = 0; 955 sysfs_attr_i = 0;
@@ -1109,6 +1121,46 @@ static struct platform_driver abituguru3_driver = {
1109 .resume = abituguru3_resume 1121 .resume = abituguru3_resume
1110}; 1122};
1111 1123
1124#ifdef CONFIG_DMI
1125
1126static int __init abituguru3_dmi_detect(void)
1127{
1128 const char *board_vendor, *board_name;
1129 int i, err = (force) ? 1 : -ENODEV;
1130
1131 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1132 if (!board_vendor || strcmp(board_vendor, "http://www.abit.com.tw/"))
1133 return err;
1134
1135 board_name = dmi_get_system_info(DMI_BOARD_NAME);
1136 if (!board_name)
1137 return err;
1138
1139 for (i = 0; abituguru3_motherboards[i].id; i++) {
1140 const char *dmi_name = abituguru3_motherboards[i].dmi_name;
1141 if (dmi_name && !strcmp(dmi_name, board_name))
1142 break;
1143 }
1144
1145 if (!abituguru3_motherboards[i].id)
1146 return 1;
1147
1148 return 0;
1149}
1150
1151#else /* !CONFIG_DMI */
1152
1153static inline int abituguru3_dmi_detect(void)
1154{
1155 return -ENODEV;
1156}
1157
1158#endif /* CONFIG_DMI */
1159
1160/* FIXME: Manual detection should die eventually; we need to collect stable
1161 * DMI model names first before we can rely entirely on CONFIG_DMI.
1162 */
1163
1112static int __init abituguru3_detect(void) 1164static int __init abituguru3_detect(void)
1113{ 1165{
1114 /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or 1166 /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
@@ -1119,7 +1171,7 @@ static int __init abituguru3_detect(void)
1119 if (((data_val == 0x00) || (data_val == 0x08)) && 1171 if (((data_val == 0x00) || (data_val == 0x08)) &&
1120 ((cmd_val == 0xAC) || (cmd_val == 0x05) || 1172 ((cmd_val == 0xAC) || (cmd_val == 0x05) ||
1121 (cmd_val == 0x55))) 1173 (cmd_val == 0x55)))
1122 return ABIT_UGURU3_BASE; 1174 return 0;
1123 1175
1124 ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " 1176 ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
1125 "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); 1177 "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val);
@@ -1127,7 +1179,7 @@ static int __init abituguru3_detect(void)
1127 if (force) { 1179 if (force) {
1128 printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " 1180 printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is "
1129 "present because of \"force\" parameter\n"); 1181 "present because of \"force\" parameter\n");
1130 return ABIT_UGURU3_BASE; 1182 return 0;
1131 } 1183 }
1132 1184
1133 /* No uGuru3 found */ 1185 /* No uGuru3 found */
@@ -1138,27 +1190,29 @@ static struct platform_device *abituguru3_pdev;
1138 1190
1139static int __init abituguru3_init(void) 1191static int __init abituguru3_init(void)
1140{ 1192{
1141 int address, err;
1142 struct resource res = { .flags = IORESOURCE_IO }; 1193 struct resource res = { .flags = IORESOURCE_IO };
1143 1194 int err;
1144#ifdef CONFIG_DMI 1195
1145 const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); 1196 /* Attempt DMI detection first */
1146 1197 err = abituguru3_dmi_detect();
1147 /* safety check, refuse to load on non Abit motherboards */ 1198 if (err < 0)
1148 if (!force && (!board_vendor || 1199 return err;
1149 strcmp(board_vendor, "http://www.abit.com.tw/"))) 1200
1150 return -ENODEV; 1201 /* Fall back to manual detection if there was no exact
1151#endif 1202 * board name match, or force was specified.
1152 1203 */
1153 address = abituguru3_detect(); 1204 if (err > 0) {
1154 if (address < 0) 1205 err = abituguru3_detect();
1155 return address; 1206 if (err)
1207 return err;
1208 }
1156 1209
1157 err = platform_driver_register(&abituguru3_driver); 1210 err = platform_driver_register(&abituguru3_driver);
1158 if (err) 1211 if (err)
1159 goto exit; 1212 goto exit;
1160 1213
1161 abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, address); 1214 abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME,
1215 ABIT_UGURU3_BASE);
1162 if (!abituguru3_pdev) { 1216 if (!abituguru3_pdev) {
1163 printk(KERN_ERR ABIT_UGURU3_NAME 1217 printk(KERN_ERR ABIT_UGURU3_NAME
1164 ": Device allocation failed\n"); 1218 ": Device allocation failed\n");
@@ -1166,8 +1220,8 @@ static int __init abituguru3_init(void)
1166 goto exit_driver_unregister; 1220 goto exit_driver_unregister;
1167 } 1221 }
1168 1222
1169 res.start = address; 1223 res.start = ABIT_UGURU3_BASE;
1170 res.end = address + ABIT_UGURU3_REGION_LENGTH - 1; 1224 res.end = ABIT_UGURU3_BASE + ABIT_UGURU3_REGION_LENGTH - 1;
1171 res.name = ABIT_UGURU3_NAME; 1225 res.name = ABIT_UGURU3_NAME;
1172 1226
1173 err = platform_device_add_resources(abituguru3_pdev, &res, 1); 1227 err = platform_device_add_resources(abituguru3_pdev, &res, 1);
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c
new file mode 100644
index 000000000000..ce8d94fbfd7e
--- /dev/null
+++ b/drivers/hwmon/ad7414.c
@@ -0,0 +1,268 @@
1/*
2 * An hwmon driver for the Analog Devices AD7414
3 *
4 * Copyright 2006 Stefan Roese <sr at denx.de>, DENX Software Engineering
5 *
6 * Copyright (c) 2008 PIKA Technologies
7 * Sean MacLennan <smaclennan@pikatech.com>
8 *
9 * Copyright (c) 2008 Spansion Inc.
10 * Frank Edelhaeuser <frank.edelhaeuser at spansion.com>
11 * (converted to "new style" I2C driver model, removed checkpatch.pl warnings)
12 *
13 * Based on ad7418.c
14 * Copyright 2006 Tower Technologies, Alessandro Zummo <a.zummo at towertech.it>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 */
21
22#include <linux/module.h>
23#include <linux/jiffies.h>
24#include <linux/i2c.h>
25#include <linux/hwmon.h>
26#include <linux/hwmon-sysfs.h>
27#include <linux/err.h>
28#include <linux/mutex.h>
29#include <linux/sysfs.h>
30
31
32/* AD7414 registers */
33#define AD7414_REG_TEMP 0x00
34#define AD7414_REG_CONF 0x01
35#define AD7414_REG_T_HIGH 0x02
36#define AD7414_REG_T_LOW 0x03
37
38static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW };
39
40struct ad7414_data {
41 struct device *hwmon_dev;
42 struct mutex lock; /* atomic read data updates */
43 char valid; /* !=0 if following fields are valid */
44 unsigned long next_update; /* In jiffies */
45 s16 temp_input; /* Register values */
46 s8 temps[ARRAY_SIZE(AD7414_REG_LIMIT)];
47};
48
49/* REG: (0.25C/bit, two's complement) << 6 */
50static inline int ad7414_temp_from_reg(s16 reg)
51{
52 /* use integer division instead of equivalent right shift to
53 * guarantee arithmetic shift and preserve the sign
54 */
55 return ((int)reg / 64) * 250;
56}
57
58static inline int ad7414_read(struct i2c_client *client, u8 reg)
59{
60 if (reg == AD7414_REG_TEMP) {
61 int value = i2c_smbus_read_word_data(client, reg);
62 return (value < 0) ? value : swab16(value);
63 } else
64 return i2c_smbus_read_byte_data(client, reg);
65}
66
67static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
68{
69 return i2c_smbus_write_byte_data(client, reg, value);
70}
71
72struct ad7414_data *ad7414_update_device(struct device *dev)
73{
74 struct i2c_client *client = to_i2c_client(dev);
75 struct ad7414_data *data = i2c_get_clientdata(client);
76
77 mutex_lock(&data->lock);
78
79 if (time_after(jiffies, data->next_update) || !data->valid) {
80 int value, i;
81
82 dev_dbg(&client->dev, "starting ad7414 update\n");
83
84 value = ad7414_read(client, AD7414_REG_TEMP);
85 if (value < 0)
86 dev_dbg(&client->dev, "AD7414_REG_TEMP err %d\n",
87 value);
88 else
89 data->temp_input = value;
90
91 for (i = 0; i < ARRAY_SIZE(AD7414_REG_LIMIT); ++i) {
92 value = ad7414_read(client, AD7414_REG_LIMIT[i]);
93 if (value < 0)
94 dev_dbg(&client->dev, "AD7414 reg %d err %d\n",
95 AD7414_REG_LIMIT[i], value);
96 else
97 data->temps[i] = value;
98 }
99
100 data->next_update = jiffies + HZ + HZ / 2;
101 data->valid = 1;
102 }
103
104 mutex_unlock(&data->lock);
105
106 return data;
107}
108
109static ssize_t show_temp_input(struct device *dev,
110 struct device_attribute *attr, char *buf)
111{
112 struct ad7414_data *data = ad7414_update_device(dev);
113 return sprintf(buf, "%d\n", ad7414_temp_from_reg(data->temp_input));
114}
115static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0);
116
117static ssize_t show_max_min(struct device *dev, struct device_attribute *attr,
118 char *buf)
119{
120 int index = to_sensor_dev_attr(attr)->index;
121 struct ad7414_data *data = ad7414_update_device(dev);
122 return sprintf(buf, "%d\n", data->temps[index] * 1000);
123}
124
125static ssize_t set_max_min(struct device *dev,
126 struct device_attribute *attr,
127 const char *buf, size_t count)
128{
129 struct i2c_client *client = to_i2c_client(dev);
130 struct ad7414_data *data = i2c_get_clientdata(client);
131 int index = to_sensor_dev_attr(attr)->index;
132 u8 reg = AD7414_REG_LIMIT[index];
133 long temp = simple_strtol(buf, NULL, 10);
134
135 temp = SENSORS_LIMIT(temp, -40000, 85000);
136 temp = (temp + (temp < 0 ? -500 : 500)) / 1000;
137
138 mutex_lock(&data->lock);
139 data->temps[index] = temp;
140 ad7414_write(client, reg, temp);
141 mutex_unlock(&data->lock);
142 return count;
143}
144
145static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
146 show_max_min, set_max_min, 0);
147static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
148 show_max_min, set_max_min, 1);
149
150static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
151 char *buf)
152{
153 int bitnr = to_sensor_dev_attr(attr)->index;
154 struct ad7414_data *data = ad7414_update_device(dev);
155 int value = (data->temp_input >> bitnr) & 1;
156 return sprintf(buf, "%d\n", value);
157}
158
159static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3);
160static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4);
161
162static struct attribute *ad7414_attributes[] = {
163 &sensor_dev_attr_temp1_input.dev_attr.attr,
164 &sensor_dev_attr_temp1_max.dev_attr.attr,
165 &sensor_dev_attr_temp1_min.dev_attr.attr,
166 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
167 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
168 NULL
169};
170
171static const struct attribute_group ad7414_group = {
172 .attrs = ad7414_attributes,
173};
174
175static int ad7414_probe(struct i2c_client *client,
176 const struct i2c_device_id *dev_id)
177{
178 struct ad7414_data *data;
179 int conf;
180 int err = 0;
181
182 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
183 I2C_FUNC_SMBUS_READ_WORD_DATA))
184 goto exit;
185
186 data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL);
187 if (!data) {
188 err = -ENOMEM;
189 goto exit;
190 }
191
192 i2c_set_clientdata(client, data);
193 mutex_init(&data->lock);
194
195 dev_info(&client->dev, "chip found\n");
196
197 /* Make sure the chip is powered up. */
198 conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF);
199 if (conf < 0)
200 dev_warn(&client->dev,
201 "ad7414_probe unable to read config register.\n");
202 else {
203 conf &= ~(1 << 7);
204 i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf);
205 }
206
207 /* Register sysfs hooks */
208 err = sysfs_create_group(&client->dev.kobj, &ad7414_group);
209 if (err)
210 goto exit_free;
211
212 data->hwmon_dev = hwmon_device_register(&client->dev);
213 if (IS_ERR(data->hwmon_dev)) {
214 err = PTR_ERR(data->hwmon_dev);
215 goto exit_remove;
216 }
217
218 return 0;
219
220exit_remove:
221 sysfs_remove_group(&client->dev.kobj, &ad7414_group);
222exit_free:
223 kfree(data);
224exit:
225 return err;
226}
227
228static int __devexit ad7414_remove(struct i2c_client *client)
229{
230 struct ad7414_data *data = i2c_get_clientdata(client);
231
232 hwmon_device_unregister(data->hwmon_dev);
233 sysfs_remove_group(&client->dev.kobj, &ad7414_group);
234 kfree(data);
235 return 0;
236}
237
238static const struct i2c_device_id ad7414_id[] = {
239 { "ad7414", 0 },
240 {}
241};
242
243static struct i2c_driver ad7414_driver = {
244 .driver = {
245 .name = "ad7414",
246 },
247 .probe = ad7414_probe,
248 .remove = __devexit_p(ad7414_remove),
249 .id_table = ad7414_id,
250};
251
252static int __init ad7414_init(void)
253{
254 return i2c_add_driver(&ad7414_driver);
255}
256module_init(ad7414_init);
257
258static void __exit ad7414_exit(void)
259{
260 i2c_del_driver(&ad7414_driver);
261}
262module_exit(ad7414_exit);
263
264MODULE_AUTHOR("Stefan Roese <sr at denx.de>, "
265 "Frank Edelhaeuser <frank.edelhaeuser at spansion.com>");
266
267MODULE_DESCRIPTION("AD7414 driver");
268MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c
new file mode 100644
index 000000000000..242294db3db6
--- /dev/null
+++ b/drivers/hwmon/adcxx.c
@@ -0,0 +1,329 @@
1/*
2 * adcxx.c
3 *
4 * The adcxx4s is an AD converter family from National Semiconductor (NS).
5 *
6 * Copyright (c) 2008 Marc Pignat <marc.pignat@hevs.ch>
7 *
8 * The adcxx4s communicates with a host processor via an SPI/Microwire Bus
9 * interface. This driver supports the whole family of devices with name
10 * ADC<bb><c>S<sss>, where
11 * * bb is the resolution in number of bits (8, 10, 12)
12 * * c is the number of channels (1, 2, 4, 8)
13 * * sss is the maximum conversion speed (021 for 200 kSPS, 051 for 500 kSPS
14 * and 101 for 1 MSPS)
15 *
16 * Complete datasheets are available at National's website here:
17 * http://www.national.com/ds/DC/ADC<bb><c>S<sss>.pdf
18 *
19 * Handling of 8, 10 and 12 bits converters are the same, the
20 * unavailable bits are 0 :)
21 *
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License as published by
24 * the Free Software Foundation; either version 2 of the License, or
25 * (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36
37#include <linux/init.h>
38#include <linux/module.h>
39#include <linux/kernel.h>
40#include <linux/device.h>
41#include <linux/err.h>
42#include <linux/sysfs.h>
43#include <linux/hwmon.h>
44#include <linux/hwmon-sysfs.h>
45#include <linux/mutex.h>
46#include <linux/spi/spi.h>
47
48#define DRVNAME "adcxx"
49
50struct adcxx {
51 struct device *hwmon_dev;
52 struct mutex lock;
53 u32 channels;
54 u32 reference; /* in millivolts */
55};
56
57/* sysfs hook function */
58static ssize_t adcxx_read(struct device *dev,
59 struct device_attribute *devattr, char *buf)
60{
61 struct spi_device *spi = to_spi_device(dev);
62 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
63 struct adcxx *adc = dev_get_drvdata(&spi->dev);
64 u8 tx_buf[2] = { attr->index << 3 }; /* other bits are don't care */
65 u8 rx_buf[2];
66 int status;
67 int value;
68
69 if (mutex_lock_interruptible(&adc->lock))
70 return -ERESTARTSYS;
71
72 status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf),
73 rx_buf, sizeof(rx_buf));
74 if (status < 0) {
75 dev_warn(dev, "spi_write_then_read failed with status %d\n",
76 status);
77 goto out;
78 }
79
80 value = (rx_buf[0] << 8) + rx_buf[1];
81 dev_dbg(dev, "raw value = 0x%x\n", value);
82
83 value = value * adc->reference >> 12;
84 status = sprintf(buf, "%d\n", value);
85out:
86 mutex_unlock(&adc->lock);
87 return status;
88}
89
90static ssize_t adcxx_show_min(struct device *dev,
91 struct device_attribute *devattr, char *buf)
92{
93 /* The minimum reference is 0 for this chip family */
94 return sprintf(buf, "0\n");
95}
96
97static ssize_t adcxx_show_max(struct device *dev,
98 struct device_attribute *devattr, char *buf)
99{
100 struct spi_device *spi = to_spi_device(dev);
101 struct adcxx *adc = dev_get_drvdata(&spi->dev);
102 u32 reference;
103
104 if (mutex_lock_interruptible(&adc->lock))
105 return -ERESTARTSYS;
106
107 reference = adc->reference;
108
109 mutex_unlock(&adc->lock);
110
111 return sprintf(buf, "%d\n", reference);
112}
113
114static ssize_t adcxx_set_max(struct device *dev,
115 struct device_attribute *devattr, const char *buf, size_t count)
116{
117 struct spi_device *spi = to_spi_device(dev);
118 struct adcxx *adc = dev_get_drvdata(&spi->dev);
119 unsigned long value;
120
121 if (strict_strtoul(buf, 10, &value))
122 return -EINVAL;
123
124 if (mutex_lock_interruptible(&adc->lock))
125 return -ERESTARTSYS;
126
127 adc->reference = value;
128
129 mutex_unlock(&adc->lock);
130
131 return count;
132}
133
134static ssize_t adcxx_show_name(struct device *dev, struct device_attribute
135 *devattr, char *buf)
136{
137 struct spi_device *spi = to_spi_device(dev);
138 struct adcxx *adc = dev_get_drvdata(&spi->dev);
139
140 return sprintf(buf, "adcxx%ds\n", adc->channels);
141}
142
143static struct sensor_device_attribute ad_input[] = {
144 SENSOR_ATTR(name, S_IRUGO, adcxx_show_name, NULL, 0),
145 SENSOR_ATTR(in_min, S_IRUGO, adcxx_show_min, NULL, 0),
146 SENSOR_ATTR(in_max, S_IWUSR | S_IRUGO, adcxx_show_max,
147 adcxx_set_max, 0),
148 SENSOR_ATTR(in0_input, S_IRUGO, adcxx_read, NULL, 0),
149 SENSOR_ATTR(in1_input, S_IRUGO, adcxx_read, NULL, 1),
150 SENSOR_ATTR(in2_input, S_IRUGO, adcxx_read, NULL, 2),
151 SENSOR_ATTR(in3_input, S_IRUGO, adcxx_read, NULL, 3),
152 SENSOR_ATTR(in4_input, S_IRUGO, adcxx_read, NULL, 4),
153 SENSOR_ATTR(in5_input, S_IRUGO, adcxx_read, NULL, 5),
154 SENSOR_ATTR(in6_input, S_IRUGO, adcxx_read, NULL, 6),
155 SENSOR_ATTR(in7_input, S_IRUGO, adcxx_read, NULL, 7),
156};
157
158/*----------------------------------------------------------------------*/
159
160static int __devinit adcxx_probe(struct spi_device *spi, int channels)
161{
162 struct adcxx *adc;
163 int status;
164 int i;
165
166 adc = kzalloc(sizeof *adc, GFP_KERNEL);
167 if (!adc)
168 return -ENOMEM;
169
170 /* set a default value for the reference */
171 adc->reference = 3300;
172 adc->channels = channels;
173 mutex_init(&adc->lock);
174
175 mutex_lock(&adc->lock);
176
177 dev_set_drvdata(&spi->dev, adc);
178
179 for (i = 0; i < 3 + adc->channels; i++) {
180 status = device_create_file(&spi->dev, &ad_input[i].dev_attr);
181 if (status) {
182 dev_err(&spi->dev, "device_create_file failed.\n");
183 goto out_err;
184 }
185 }
186
187 adc->hwmon_dev = hwmon_device_register(&spi->dev);
188 if (IS_ERR(adc->hwmon_dev)) {
189 dev_err(&spi->dev, "hwmon_device_register failed.\n");
190 status = PTR_ERR(adc->hwmon_dev);
191 goto out_err;
192 }
193
194 mutex_unlock(&adc->lock);
195 return 0;
196
197out_err:
198 for (i--; i >= 0; i--)
199 device_remove_file(&spi->dev, &ad_input[i].dev_attr);
200
201 dev_set_drvdata(&spi->dev, NULL);
202 mutex_unlock(&adc->lock);
203 kfree(adc);
204 return status;
205}
206
207static int __devinit adcxx1s_probe(struct spi_device *spi)
208{
209 return adcxx_probe(spi, 1);
210}
211
212static int __devinit adcxx2s_probe(struct spi_device *spi)
213{
214 return adcxx_probe(spi, 2);
215}
216
217static int __devinit adcxx4s_probe(struct spi_device *spi)
218{
219 return adcxx_probe(spi, 4);
220}
221
222static int __devinit adcxx8s_probe(struct spi_device *spi)
223{
224 return adcxx_probe(spi, 8);
225}
226
227static int __devexit adcxx_remove(struct spi_device *spi)
228{
229 struct adcxx *adc = dev_get_drvdata(&spi->dev);
230 int i;
231
232 mutex_lock(&adc->lock);
233 hwmon_device_unregister(adc->hwmon_dev);
234 for (i = 0; i < 3 + adc->channels; i++)
235 device_remove_file(&spi->dev, &ad_input[i].dev_attr);
236
237 dev_set_drvdata(&spi->dev, NULL);
238 mutex_unlock(&adc->lock);
239 kfree(adc);
240
241 return 0;
242}
243
244static struct spi_driver adcxx1s_driver = {
245 .driver = {
246 .name = "adcxx1s",
247 .owner = THIS_MODULE,
248 },
249 .probe = adcxx1s_probe,
250 .remove = __devexit_p(adcxx_remove),
251};
252
253static struct spi_driver adcxx2s_driver = {
254 .driver = {
255 .name = "adcxx2s",
256 .owner = THIS_MODULE,
257 },
258 .probe = adcxx2s_probe,
259 .remove = __devexit_p(adcxx_remove),
260};
261
262static struct spi_driver adcxx4s_driver = {
263 .driver = {
264 .name = "adcxx4s",
265 .owner = THIS_MODULE,
266 },
267 .probe = adcxx4s_probe,
268 .remove = __devexit_p(adcxx_remove),
269};
270
271static struct spi_driver adcxx8s_driver = {
272 .driver = {
273 .name = "adcxx8s",
274 .owner = THIS_MODULE,
275 },
276 .probe = adcxx8s_probe,
277 .remove = __devexit_p(adcxx_remove),
278};
279
280static int __init init_adcxx(void)
281{
282 int status;
283 status = spi_register_driver(&adcxx1s_driver);
284 if (status)
285 goto reg_1_failed;
286
287 status = spi_register_driver(&adcxx2s_driver);
288 if (status)
289 goto reg_2_failed;
290
291 status = spi_register_driver(&adcxx4s_driver);
292 if (status)
293 goto reg_4_failed;
294
295 status = spi_register_driver(&adcxx8s_driver);
296 if (status)
297 goto reg_8_failed;
298
299 return status;
300
301reg_8_failed:
302 spi_unregister_driver(&adcxx4s_driver);
303reg_4_failed:
304 spi_unregister_driver(&adcxx2s_driver);
305reg_2_failed:
306 spi_unregister_driver(&adcxx1s_driver);
307reg_1_failed:
308 return status;
309}
310
311static void __exit exit_adcxx(void)
312{
313 spi_unregister_driver(&adcxx1s_driver);
314 spi_unregister_driver(&adcxx2s_driver);
315 spi_unregister_driver(&adcxx4s_driver);
316 spi_unregister_driver(&adcxx8s_driver);
317}
318
319module_init(init_adcxx);
320module_exit(exit_adcxx);
321
322MODULE_AUTHOR("Marc Pignat");
323MODULE_DESCRIPTION("National Semiconductor adcxx8sxxx Linux driver");
324MODULE_LICENSE("GPL");
325
326MODULE_ALIAS("adcxx1s");
327MODULE_ALIAS("adcxx2s");
328MODULE_ALIAS("adcxx4s");
329MODULE_ALIAS("adcxx8s");
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index aacc0c4b809c..b06b8e090a27 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -98,6 +98,12 @@ static const char* temperature_sensors_sets[][36] = {
98 "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", 98 "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
99 "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", 99 "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
100 "TM9S", "TN0H", "TS0C", NULL }, 100 "TM9S", "TN0H", "TS0C", NULL },
101/* Set 5: iMac */
102 { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
103 "Tp0C", NULL },
104/* Set 6: Macbook3 set */
105 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
106 "Th0S", "Th1H", NULL },
101}; 107};
102 108
103/* List of keys used to read/write fan speeds */ 109/* List of keys used to read/write fan speeds */
@@ -1223,6 +1229,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1223 { .accelerometer = 0, .light = 0, .temperature_set = 3 }, 1229 { .accelerometer = 0, .light = 0, .temperature_set = 3 },
1224/* MacPro: temperature set 4 */ 1230/* MacPro: temperature set 4 */
1225 { .accelerometer = 0, .light = 0, .temperature_set = 4 }, 1231 { .accelerometer = 0, .light = 0, .temperature_set = 4 },
1232/* iMac: temperature set 5 */
1233 { .accelerometer = 0, .light = 0, .temperature_set = 5 },
1234/* MacBook3: accelerometer and temperature set 6 */
1235 { .accelerometer = 1, .light = 0, .temperature_set = 6 },
1226}; 1236};
1227 1237
1228/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". 1238/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1232,10 +1242,14 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
1232 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1242 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1233 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, 1243 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1234 (void*)&applesmc_dmi_data[0]}, 1244 (void*)&applesmc_dmi_data[0]},
1235 { applesmc_dmi_match, "Apple MacBook", { 1245 { applesmc_dmi_match, "Apple MacBook (v2)", {
1236 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1246 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1237 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, 1247 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
1238 (void*)&applesmc_dmi_data[1]}, 1248 (void*)&applesmc_dmi_data[1]},
1249 { applesmc_dmi_match, "Apple MacBook (v3)", {
1250 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1251 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
1252 (void*)&applesmc_dmi_data[6]},
1239 { applesmc_dmi_match, "Apple MacBook", { 1253 { applesmc_dmi_match, "Apple MacBook", {
1240 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1254 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1241 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, 1255 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
@@ -1248,6 +1262,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
1248 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1262 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1249 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, 1263 DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
1250 (void*)&applesmc_dmi_data[4]}, 1264 (void*)&applesmc_dmi_data[4]},
1265 { applesmc_dmi_match, "Apple iMac", {
1266 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1267 DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
1268 (void*)&applesmc_dmi_data[5]},
1251 { .ident = NULL } 1269 { .ident = NULL }
1252}; 1270};
1253 1271
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 70239acecc8e..93c17223b527 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -413,10 +413,11 @@ static int __init coretemp_init(void)
413 for_each_online_cpu(i) { 413 for_each_online_cpu(i) {
414 struct cpuinfo_x86 *c = &cpu_data(i); 414 struct cpuinfo_x86 *c = &cpu_data(i);
415 415
416 /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */ 416 /* check if family 6, models 0xe, 0xf, 0x16, 0x17, 0x1A */
417 if ((c->cpuid_level < 0) || (c->x86 != 0x6) || 417 if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
418 !((c->x86_model == 0xe) || (c->x86_model == 0xf) || 418 !((c->x86_model == 0xe) || (c->x86_model == 0xf) ||
419 (c->x86_model == 0x16) || (c->x86_model == 0x17))) { 419 (c->x86_model == 0x16) || (c->x86_model == 0x17) ||
420 (c->x86_model == 0x1A))) {
420 421
421 /* supported CPU not found, but report the unknown 422 /* supported CPU not found, but report the unknown
422 family 6 CPU */ 423 family 6 CPU */
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 5e2cf0aef480..cdb8311e4ef7 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * dme1737.c - Driver for the SMSC DME1737, Asus A8000, and SMSC SCH311x 2 * dme1737.c - Driver for the SMSC DME1737, Asus A8000, SMSC SCH311x and
3 * Super-I/O chips integrated hardware monitoring features. 3 * SCH5027 Super-I/O chips integrated hardware monitoring features.
4 * Copyright (c) 2007 Juerg Haefliger <juergh@gmail.com> 4 * Copyright (c) 2007, 2008 Juerg Haefliger <juergh@gmail.com>
5 * 5 *
6 * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access 6 * This driver is an I2C/ISA hybrid, meaning that it uses the I2C bus to access
7 * the chip registers if a DME1737 (or A8000) is found and the ISA bus if a 7 * the chip registers if a DME1737, A8000, or SCH5027 is found and the ISA bus
8 * SCH311x chip is found. Both types of chips have very similar hardware 8 * if a SCH311x chip is found. Both types of chips have very similar hardware
9 * monitoring capabilities but differ in the way they can be accessed. 9 * monitoring capabilities but differ in the way they can be accessed.
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
@@ -57,7 +57,10 @@ MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC "
57static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; 57static const unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
58 58
59/* Insmod parameters */ 59/* Insmod parameters */
60I2C_CLIENT_INSMOD_1(dme1737); 60I2C_CLIENT_INSMOD_2(dme1737, sch5027);
61
62/* ISA chip types */
63enum isa_chips { sch311x = sch5027 + 1 };
61 64
62/* --------------------------------------------------------------------- 65/* ---------------------------------------------------------------------
63 * Registers 66 * Registers
@@ -163,6 +166,7 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
163#define DME1737_VERSTEP 0x88 166#define DME1737_VERSTEP 0x88
164#define DME1737_VERSTEP_MASK 0xf8 167#define DME1737_VERSTEP_MASK 0xf8
165#define SCH311X_DEVICE 0x8c 168#define SCH311X_DEVICE 0x8c
169#define SCH5027_VERSTEP 0x69
166 170
167/* Length of ISA address segment */ 171/* Length of ISA address segment */
168#define DME1737_EXTENT 2 172#define DME1737_EXTENT 2
@@ -182,6 +186,7 @@ struct dme1737_data {
182 unsigned long last_update; /* in jiffies */ 186 unsigned long last_update; /* in jiffies */
183 unsigned long last_vbat; /* in jiffies */ 187 unsigned long last_vbat; /* in jiffies */
184 enum chips type; 188 enum chips type;
189 const int *in_nominal; /* pointer to IN_NOMINAL array */
185 190
186 u8 vid; 191 u8 vid;
187 u8 pwm_rr_en; 192 u8 pwm_rr_en;
@@ -220,23 +225,23 @@ static const int IN_NOMINAL_DME1737[] = {5000, 2250, 3300, 5000, 12000, 3300,
220 3300}; 225 3300};
221static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300, 226static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300,
222 3300}; 227 3300};
223#define IN_NOMINAL(ix, type) (((type) == dme1737) ? \ 228static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300,
224 IN_NOMINAL_DME1737[(ix)] : \ 229 3300};
225 IN_NOMINAL_SCH311x[(ix)]) 230#define IN_NOMINAL(type) ((type) == sch311x ? IN_NOMINAL_SCH311x : \
231 (type) == sch5027 ? IN_NOMINAL_SCH5027 : \
232 IN_NOMINAL_DME1737)
226 233
227/* Voltage input 234/* Voltage input
228 * Voltage inputs have 16 bits resolution, limit values have 8 bits 235 * Voltage inputs have 16 bits resolution, limit values have 8 bits
229 * resolution. */ 236 * resolution. */
230static inline int IN_FROM_REG(int reg, int ix, int res, int type) 237static inline int IN_FROM_REG(int reg, int nominal, int res)
231{ 238{
232 return (reg * IN_NOMINAL(ix, type) + (3 << (res - 3))) / 239 return (reg * nominal + (3 << (res - 3))) / (3 << (res - 2));
233 (3 << (res - 2));
234} 240}
235 241
236static inline int IN_TO_REG(int val, int ix, int type) 242static inline int IN_TO_REG(int val, int nominal)
237{ 243{
238 return SENSORS_LIMIT((val * 192 + IN_NOMINAL(ix, type) / 2) / 244 return SENSORS_LIMIT((val * 192 + nominal / 2) / nominal, 0, 255);
239 IN_NOMINAL(ix, type), 0, 255);
240} 245}
241 246
242/* Temperature input 247/* Temperature input
@@ -565,7 +570,10 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
565 570
566 /* Sample register contents every 1 sec */ 571 /* Sample register contents every 1 sec */
567 if (time_after(jiffies, data->last_update + HZ) || !data->valid) { 572 if (time_after(jiffies, data->last_update + HZ) || !data->valid) {
568 data->vid = dme1737_read(client, DME1737_REG_VID) & 0x3f; 573 if (data->type != sch5027) {
574 data->vid = dme1737_read(client, DME1737_REG_VID) &
575 0x3f;
576 }
569 577
570 /* In (voltage) registers */ 578 /* In (voltage) registers */
571 for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { 579 for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
@@ -593,8 +601,10 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
593 DME1737_REG_TEMP_MIN(ix)); 601 DME1737_REG_TEMP_MIN(ix));
594 data->temp_max[ix] = dme1737_read(client, 602 data->temp_max[ix] = dme1737_read(client,
595 DME1737_REG_TEMP_MAX(ix)); 603 DME1737_REG_TEMP_MAX(ix));
596 data->temp_offset[ix] = dme1737_read(client, 604 if (data->type != sch5027) {
597 DME1737_REG_TEMP_OFFSET(ix)); 605 data->temp_offset[ix] = dme1737_read(client,
606 DME1737_REG_TEMP_OFFSET(ix));
607 }
598 } 608 }
599 609
600 /* In and temp LSB registers 610 /* In and temp LSB registers
@@ -669,9 +679,11 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
669 data->zone_abs[ix] = dme1737_read(client, 679 data->zone_abs[ix] = dme1737_read(client,
670 DME1737_REG_ZONE_ABS(ix)); 680 DME1737_REG_ZONE_ABS(ix));
671 } 681 }
672 for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) { 682 if (data->type != sch5027) {
673 data->zone_hyst[ix] = dme1737_read(client, 683 for (ix = 0; ix < ARRAY_SIZE(data->zone_hyst); ix++) {
684 data->zone_hyst[ix] = dme1737_read(client,
674 DME1737_REG_ZONE_HYST(ix)); 685 DME1737_REG_ZONE_HYST(ix));
686 }
675 } 687 }
676 688
677 /* Alarm registers */ 689 /* Alarm registers */
@@ -735,13 +747,13 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr,
735 747
736 switch (fn) { 748 switch (fn) {
737 case SYS_IN_INPUT: 749 case SYS_IN_INPUT:
738 res = IN_FROM_REG(data->in[ix], ix, 16, data->type); 750 res = IN_FROM_REG(data->in[ix], data->in_nominal[ix], 16);
739 break; 751 break;
740 case SYS_IN_MIN: 752 case SYS_IN_MIN:
741 res = IN_FROM_REG(data->in_min[ix], ix, 8, data->type); 753 res = IN_FROM_REG(data->in_min[ix], data->in_nominal[ix], 8);
742 break; 754 break;
743 case SYS_IN_MAX: 755 case SYS_IN_MAX:
744 res = IN_FROM_REG(data->in_max[ix], ix, 8, data->type); 756 res = IN_FROM_REG(data->in_max[ix], data->in_nominal[ix], 8);
745 break; 757 break;
746 case SYS_IN_ALARM: 758 case SYS_IN_ALARM:
747 res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01; 759 res = (data->alarms >> DME1737_BIT_ALARM_IN[ix]) & 0x01;
@@ -768,12 +780,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
768 mutex_lock(&data->update_lock); 780 mutex_lock(&data->update_lock);
769 switch (fn) { 781 switch (fn) {
770 case SYS_IN_MIN: 782 case SYS_IN_MIN:
771 data->in_min[ix] = IN_TO_REG(val, ix, data->type); 783 data->in_min[ix] = IN_TO_REG(val, data->in_nominal[ix]);
772 dme1737_write(client, DME1737_REG_IN_MIN(ix), 784 dme1737_write(client, DME1737_REG_IN_MIN(ix),
773 data->in_min[ix]); 785 data->in_min[ix]);
774 break; 786 break;
775 case SYS_IN_MAX: 787 case SYS_IN_MAX:
776 data->in_max[ix] = IN_TO_REG(val, ix, data->type); 788 data->in_max[ix] = IN_TO_REG(val, data->in_nominal[ix]);
777 dme1737_write(client, DME1737_REG_IN_MAX(ix), 789 dme1737_write(client, DME1737_REG_IN_MAX(ix),
778 data->in_max[ix]); 790 data->in_max[ix]);
779 break; 791 break;
@@ -1166,7 +1178,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
1166 return sprintf(buf, "%d\n", res); 1178 return sprintf(buf, "%d\n", res);
1167} 1179}
1168 1180
1169static struct attribute *dme1737_attr_pwm[]; 1181static struct attribute *dme1737_pwm_chmod_attr[];
1170static void dme1737_chmod_file(struct device*, struct attribute*, mode_t); 1182static void dme1737_chmod_file(struct device*, struct attribute*, mode_t);
1171 1183
1172static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, 1184static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
@@ -1230,7 +1242,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
1230 switch (val) { 1242 switch (val) {
1231 case 0: 1243 case 0:
1232 /* Change permissions of pwm[ix] to read-only */ 1244 /* Change permissions of pwm[ix] to read-only */
1233 dme1737_chmod_file(dev, dme1737_attr_pwm[ix], 1245 dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
1234 S_IRUGO); 1246 S_IRUGO);
1235 /* Turn fan fully on */ 1247 /* Turn fan fully on */
1236 data->pwm_config[ix] = PWM_EN_TO_REG(0, 1248 data->pwm_config[ix] = PWM_EN_TO_REG(0,
@@ -1245,12 +1257,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
1245 dme1737_write(client, DME1737_REG_PWM_CONFIG(ix), 1257 dme1737_write(client, DME1737_REG_PWM_CONFIG(ix),
1246 data->pwm_config[ix]); 1258 data->pwm_config[ix]);
1247 /* Change permissions of pwm[ix] to read-writeable */ 1259 /* Change permissions of pwm[ix] to read-writeable */
1248 dme1737_chmod_file(dev, dme1737_attr_pwm[ix], 1260 dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
1249 S_IRUGO | S_IWUSR); 1261 S_IRUGO | S_IWUSR);
1250 break; 1262 break;
1251 case 2: 1263 case 2:
1252 /* Change permissions of pwm[ix] to read-only */ 1264 /* Change permissions of pwm[ix] to read-only */
1253 dme1737_chmod_file(dev, dme1737_attr_pwm[ix], 1265 dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
1254 S_IRUGO); 1266 S_IRUGO);
1255 /* Turn on auto mode using the saved zone channel 1267 /* Turn on auto mode using the saved zone channel
1256 * assignment */ 1268 * assignment */
@@ -1570,88 +1582,98 @@ static struct attribute *dme1737_attr[] ={
1570 &sensor_dev_attr_temp1_max.dev_attr.attr, 1582 &sensor_dev_attr_temp1_max.dev_attr.attr,
1571 &sensor_dev_attr_temp1_alarm.dev_attr.attr, 1583 &sensor_dev_attr_temp1_alarm.dev_attr.attr,
1572 &sensor_dev_attr_temp1_fault.dev_attr.attr, 1584 &sensor_dev_attr_temp1_fault.dev_attr.attr,
1573 &sensor_dev_attr_temp1_offset.dev_attr.attr,
1574 &sensor_dev_attr_temp2_input.dev_attr.attr, 1585 &sensor_dev_attr_temp2_input.dev_attr.attr,
1575 &sensor_dev_attr_temp2_min.dev_attr.attr, 1586 &sensor_dev_attr_temp2_min.dev_attr.attr,
1576 &sensor_dev_attr_temp2_max.dev_attr.attr, 1587 &sensor_dev_attr_temp2_max.dev_attr.attr,
1577 &sensor_dev_attr_temp2_alarm.dev_attr.attr, 1588 &sensor_dev_attr_temp2_alarm.dev_attr.attr,
1578 &sensor_dev_attr_temp2_fault.dev_attr.attr, 1589 &sensor_dev_attr_temp2_fault.dev_attr.attr,
1579 &sensor_dev_attr_temp2_offset.dev_attr.attr,
1580 &sensor_dev_attr_temp3_input.dev_attr.attr, 1590 &sensor_dev_attr_temp3_input.dev_attr.attr,
1581 &sensor_dev_attr_temp3_min.dev_attr.attr, 1591 &sensor_dev_attr_temp3_min.dev_attr.attr,
1582 &sensor_dev_attr_temp3_max.dev_attr.attr, 1592 &sensor_dev_attr_temp3_max.dev_attr.attr,
1583 &sensor_dev_attr_temp3_alarm.dev_attr.attr, 1593 &sensor_dev_attr_temp3_alarm.dev_attr.attr,
1584 &sensor_dev_attr_temp3_fault.dev_attr.attr, 1594 &sensor_dev_attr_temp3_fault.dev_attr.attr,
1585 &sensor_dev_attr_temp3_offset.dev_attr.attr,
1586 /* Zones */ 1595 /* Zones */
1587 &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
1588 &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, 1596 &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
1589 &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, 1597 &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
1590 &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, 1598 &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
1591 &sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr, 1599 &sensor_dev_attr_zone1_auto_channels_temp.dev_attr.attr,
1592 &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
1593 &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, 1600 &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
1594 &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, 1601 &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
1595 &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, 1602 &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
1596 &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr, 1603 &sensor_dev_attr_zone2_auto_channels_temp.dev_attr.attr,
1597 &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
1598 &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, 1604 &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
1599 &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, 1605 &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
1600 &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, 1606 &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
1601 &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr, 1607 &sensor_dev_attr_zone3_auto_channels_temp.dev_attr.attr,
1608 NULL
1609};
1610
1611static const struct attribute_group dme1737_group = {
1612 .attrs = dme1737_attr,
1613};
1614
1615/* The following struct holds misc attributes, which are not available in all
1616 * chips. Their creation depends on the chip type which is determined during
1617 * module load. */
1618static struct attribute *dme1737_misc_attr[] = {
1619 /* Temperatures */
1620 &sensor_dev_attr_temp1_offset.dev_attr.attr,
1621 &sensor_dev_attr_temp2_offset.dev_attr.attr,
1622 &sensor_dev_attr_temp3_offset.dev_attr.attr,
1623 /* Zones */
1624 &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
1625 &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
1626 &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
1602 /* Misc */ 1627 /* Misc */
1603 &dev_attr_vrm.attr, 1628 &dev_attr_vrm.attr,
1604 &dev_attr_cpu0_vid.attr, 1629 &dev_attr_cpu0_vid.attr,
1605 NULL 1630 NULL
1606}; 1631};
1607 1632
1608static const struct attribute_group dme1737_group = { 1633static const struct attribute_group dme1737_misc_group = {
1609 .attrs = dme1737_attr, 1634 .attrs = dme1737_misc_attr,
1610}; 1635};
1611 1636
1612/* The following structs hold the PWM attributes, some of which are optional. 1637/* The following structs hold the PWM attributes, some of which are optional.
1613 * Their creation depends on the chip configuration which is determined during 1638 * Their creation depends on the chip configuration which is determined during
1614 * module load. */ 1639 * module load. */
1615static struct attribute *dme1737_attr_pwm1[] = { 1640static struct attribute *dme1737_pwm1_attr[] = {
1616 &sensor_dev_attr_pwm1.dev_attr.attr, 1641 &sensor_dev_attr_pwm1.dev_attr.attr,
1617 &sensor_dev_attr_pwm1_freq.dev_attr.attr, 1642 &sensor_dev_attr_pwm1_freq.dev_attr.attr,
1618 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 1643 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1619 &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, 1644 &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
1620 &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, 1645 &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
1621 &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
1622 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, 1646 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
1623 &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, 1647 &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
1624 NULL 1648 NULL
1625}; 1649};
1626static struct attribute *dme1737_attr_pwm2[] = { 1650static struct attribute *dme1737_pwm2_attr[] = {
1627 &sensor_dev_attr_pwm2.dev_attr.attr, 1651 &sensor_dev_attr_pwm2.dev_attr.attr,
1628 &sensor_dev_attr_pwm2_freq.dev_attr.attr, 1652 &sensor_dev_attr_pwm2_freq.dev_attr.attr,
1629 &sensor_dev_attr_pwm2_enable.dev_attr.attr, 1653 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1630 &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, 1654 &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
1631 &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, 1655 &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
1632 &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
1633 &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, 1656 &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
1634 &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, 1657 &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
1635 NULL 1658 NULL
1636}; 1659};
1637static struct attribute *dme1737_attr_pwm3[] = { 1660static struct attribute *dme1737_pwm3_attr[] = {
1638 &sensor_dev_attr_pwm3.dev_attr.attr, 1661 &sensor_dev_attr_pwm3.dev_attr.attr,
1639 &sensor_dev_attr_pwm3_freq.dev_attr.attr, 1662 &sensor_dev_attr_pwm3_freq.dev_attr.attr,
1640 &sensor_dev_attr_pwm3_enable.dev_attr.attr, 1663 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1641 &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, 1664 &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
1642 &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, 1665 &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
1643 &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
1644 &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, 1666 &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
1645 &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, 1667 &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
1646 NULL 1668 NULL
1647}; 1669};
1648static struct attribute *dme1737_attr_pwm5[] = { 1670static struct attribute *dme1737_pwm5_attr[] = {
1649 &sensor_dev_attr_pwm5.dev_attr.attr, 1671 &sensor_dev_attr_pwm5.dev_attr.attr,
1650 &sensor_dev_attr_pwm5_freq.dev_attr.attr, 1672 &sensor_dev_attr_pwm5_freq.dev_attr.attr,
1651 &sensor_dev_attr_pwm5_enable.dev_attr.attr, 1673 &sensor_dev_attr_pwm5_enable.dev_attr.attr,
1652 NULL 1674 NULL
1653}; 1675};
1654static struct attribute *dme1737_attr_pwm6[] = { 1676static struct attribute *dme1737_pwm6_attr[] = {
1655 &sensor_dev_attr_pwm6.dev_attr.attr, 1677 &sensor_dev_attr_pwm6.dev_attr.attr,
1656 &sensor_dev_attr_pwm6_freq.dev_attr.attr, 1678 &sensor_dev_attr_pwm6_freq.dev_attr.attr,
1657 &sensor_dev_attr_pwm6_enable.dev_attr.attr, 1679 &sensor_dev_attr_pwm6_enable.dev_attr.attr,
@@ -1659,53 +1681,62 @@ static struct attribute *dme1737_attr_pwm6[] = {
1659}; 1681};
1660 1682
1661static const struct attribute_group dme1737_pwm_group[] = { 1683static const struct attribute_group dme1737_pwm_group[] = {
1662 { .attrs = dme1737_attr_pwm1 }, 1684 { .attrs = dme1737_pwm1_attr },
1663 { .attrs = dme1737_attr_pwm2 }, 1685 { .attrs = dme1737_pwm2_attr },
1664 { .attrs = dme1737_attr_pwm3 }, 1686 { .attrs = dme1737_pwm3_attr },
1665 { .attrs = NULL }, 1687 { .attrs = NULL },
1666 { .attrs = dme1737_attr_pwm5 }, 1688 { .attrs = dme1737_pwm5_attr },
1667 { .attrs = dme1737_attr_pwm6 }, 1689 { .attrs = dme1737_pwm6_attr },
1690};
1691
1692/* The following struct holds misc PWM attributes, which are not available in
1693 * all chips. Their creation depends on the chip type which is determined
1694 * during module load. */
1695static struct attribute *dme1737_pwm_misc_attr[] = {
1696 &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
1697 &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
1698 &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
1668}; 1699};
1669 1700
1670/* The following structs hold the fan attributes, some of which are optional. 1701/* The following structs hold the fan attributes, some of which are optional.
1671 * Their creation depends on the chip configuration which is determined during 1702 * Their creation depends on the chip configuration which is determined during
1672 * module load. */ 1703 * module load. */
1673static struct attribute *dme1737_attr_fan1[] = { 1704static struct attribute *dme1737_fan1_attr[] = {
1674 &sensor_dev_attr_fan1_input.dev_attr.attr, 1705 &sensor_dev_attr_fan1_input.dev_attr.attr,
1675 &sensor_dev_attr_fan1_min.dev_attr.attr, 1706 &sensor_dev_attr_fan1_min.dev_attr.attr,
1676 &sensor_dev_attr_fan1_alarm.dev_attr.attr, 1707 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1677 &sensor_dev_attr_fan1_type.dev_attr.attr, 1708 &sensor_dev_attr_fan1_type.dev_attr.attr,
1678 NULL 1709 NULL
1679}; 1710};
1680static struct attribute *dme1737_attr_fan2[] = { 1711static struct attribute *dme1737_fan2_attr[] = {
1681 &sensor_dev_attr_fan2_input.dev_attr.attr, 1712 &sensor_dev_attr_fan2_input.dev_attr.attr,
1682 &sensor_dev_attr_fan2_min.dev_attr.attr, 1713 &sensor_dev_attr_fan2_min.dev_attr.attr,
1683 &sensor_dev_attr_fan2_alarm.dev_attr.attr, 1714 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1684 &sensor_dev_attr_fan2_type.dev_attr.attr, 1715 &sensor_dev_attr_fan2_type.dev_attr.attr,
1685 NULL 1716 NULL
1686}; 1717};
1687static struct attribute *dme1737_attr_fan3[] = { 1718static struct attribute *dme1737_fan3_attr[] = {
1688 &sensor_dev_attr_fan3_input.dev_attr.attr, 1719 &sensor_dev_attr_fan3_input.dev_attr.attr,
1689 &sensor_dev_attr_fan3_min.dev_attr.attr, 1720 &sensor_dev_attr_fan3_min.dev_attr.attr,
1690 &sensor_dev_attr_fan3_alarm.dev_attr.attr, 1721 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
1691 &sensor_dev_attr_fan3_type.dev_attr.attr, 1722 &sensor_dev_attr_fan3_type.dev_attr.attr,
1692 NULL 1723 NULL
1693}; 1724};
1694static struct attribute *dme1737_attr_fan4[] = { 1725static struct attribute *dme1737_fan4_attr[] = {
1695 &sensor_dev_attr_fan4_input.dev_attr.attr, 1726 &sensor_dev_attr_fan4_input.dev_attr.attr,
1696 &sensor_dev_attr_fan4_min.dev_attr.attr, 1727 &sensor_dev_attr_fan4_min.dev_attr.attr,
1697 &sensor_dev_attr_fan4_alarm.dev_attr.attr, 1728 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
1698 &sensor_dev_attr_fan4_type.dev_attr.attr, 1729 &sensor_dev_attr_fan4_type.dev_attr.attr,
1699 NULL 1730 NULL
1700}; 1731};
1701static struct attribute *dme1737_attr_fan5[] = { 1732static struct attribute *dme1737_fan5_attr[] = {
1702 &sensor_dev_attr_fan5_input.dev_attr.attr, 1733 &sensor_dev_attr_fan5_input.dev_attr.attr,
1703 &sensor_dev_attr_fan5_min.dev_attr.attr, 1734 &sensor_dev_attr_fan5_min.dev_attr.attr,
1704 &sensor_dev_attr_fan5_alarm.dev_attr.attr, 1735 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
1705 &sensor_dev_attr_fan5_max.dev_attr.attr, 1736 &sensor_dev_attr_fan5_max.dev_attr.attr,
1706 NULL 1737 NULL
1707}; 1738};
1708static struct attribute *dme1737_attr_fan6[] = { 1739static struct attribute *dme1737_fan6_attr[] = {
1709 &sensor_dev_attr_fan6_input.dev_attr.attr, 1740 &sensor_dev_attr_fan6_input.dev_attr.attr,
1710 &sensor_dev_attr_fan6_min.dev_attr.attr, 1741 &sensor_dev_attr_fan6_min.dev_attr.attr,
1711 &sensor_dev_attr_fan6_alarm.dev_attr.attr, 1742 &sensor_dev_attr_fan6_alarm.dev_attr.attr,
@@ -1714,94 +1745,83 @@ static struct attribute *dme1737_attr_fan6[] = {
1714}; 1745};
1715 1746
1716static const struct attribute_group dme1737_fan_group[] = { 1747static const struct attribute_group dme1737_fan_group[] = {
1717 { .attrs = dme1737_attr_fan1 }, 1748 { .attrs = dme1737_fan1_attr },
1718 { .attrs = dme1737_attr_fan2 }, 1749 { .attrs = dme1737_fan2_attr },
1719 { .attrs = dme1737_attr_fan3 }, 1750 { .attrs = dme1737_fan3_attr },
1720 { .attrs = dme1737_attr_fan4 }, 1751 { .attrs = dme1737_fan4_attr },
1721 { .attrs = dme1737_attr_fan5 }, 1752 { .attrs = dme1737_fan5_attr },
1722 { .attrs = dme1737_attr_fan6 }, 1753 { .attrs = dme1737_fan6_attr },
1723}; 1754};
1724 1755
1725/* The permissions of all of the following attributes are changed to read- 1756/* The permissions of the following zone attributes are changed to read-
1726 * writeable if the chip is *not* locked. Otherwise they stay read-only. */ 1757 * writeable if the chip is *not* locked. Otherwise they stay read-only. */
1727static struct attribute *dme1737_attr_lock[] = { 1758static struct attribute *dme1737_zone_chmod_attr[] = {
1728 /* Temperatures */
1729 &sensor_dev_attr_temp1_offset.dev_attr.attr,
1730 &sensor_dev_attr_temp2_offset.dev_attr.attr,
1731 &sensor_dev_attr_temp3_offset.dev_attr.attr,
1732 /* Zones */
1733 &sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
1734 &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr, 1759 &sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
1735 &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr, 1760 &sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
1736 &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr, 1761 &sensor_dev_attr_zone1_auto_point3_temp.dev_attr.attr,
1737 &sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
1738 &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr, 1762 &sensor_dev_attr_zone2_auto_point1_temp.dev_attr.attr,
1739 &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr, 1763 &sensor_dev_attr_zone2_auto_point2_temp.dev_attr.attr,
1740 &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr, 1764 &sensor_dev_attr_zone2_auto_point3_temp.dev_attr.attr,
1741 &sensor_dev_attr_zone3_auto_point1_temp_hyst.dev_attr.attr,
1742 &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr, 1765 &sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
1743 &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr, 1766 &sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
1744 &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr, 1767 &sensor_dev_attr_zone3_auto_point3_temp.dev_attr.attr,
1745 NULL 1768 NULL
1746}; 1769};
1747 1770
1748static const struct attribute_group dme1737_lock_group = { 1771static const struct attribute_group dme1737_zone_chmod_group = {
1749 .attrs = dme1737_attr_lock, 1772 .attrs = dme1737_zone_chmod_attr,
1750}; 1773};
1751 1774
1752/* The permissions of the following PWM attributes are changed to read- 1775/* The permissions of the following PWM attributes are changed to read-
1753 * writeable if the chip is *not* locked and the respective PWM is available. 1776 * writeable if the chip is *not* locked and the respective PWM is available.
1754 * Otherwise they stay read-only. */ 1777 * Otherwise they stay read-only. */
1755static struct attribute *dme1737_attr_pwm1_lock[] = { 1778static struct attribute *dme1737_pwm1_chmod_attr[] = {
1756 &sensor_dev_attr_pwm1_freq.dev_attr.attr, 1779 &sensor_dev_attr_pwm1_freq.dev_attr.attr,
1757 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 1780 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1758 &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr, 1781 &sensor_dev_attr_pwm1_ramp_rate.dev_attr.attr,
1759 &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr, 1782 &sensor_dev_attr_pwm1_auto_channels_zone.dev_attr.attr,
1760 &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
1761 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, 1783 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
1762 NULL 1784 NULL
1763}; 1785};
1764static struct attribute *dme1737_attr_pwm2_lock[] = { 1786static struct attribute *dme1737_pwm2_chmod_attr[] = {
1765 &sensor_dev_attr_pwm2_freq.dev_attr.attr, 1787 &sensor_dev_attr_pwm2_freq.dev_attr.attr,
1766 &sensor_dev_attr_pwm2_enable.dev_attr.attr, 1788 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1767 &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr, 1789 &sensor_dev_attr_pwm2_ramp_rate.dev_attr.attr,
1768 &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr, 1790 &sensor_dev_attr_pwm2_auto_channels_zone.dev_attr.attr,
1769 &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
1770 &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, 1791 &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
1771 NULL 1792 NULL
1772}; 1793};
1773static struct attribute *dme1737_attr_pwm3_lock[] = { 1794static struct attribute *dme1737_pwm3_chmod_attr[] = {
1774 &sensor_dev_attr_pwm3_freq.dev_attr.attr, 1795 &sensor_dev_attr_pwm3_freq.dev_attr.attr,
1775 &sensor_dev_attr_pwm3_enable.dev_attr.attr, 1796 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1776 &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr, 1797 &sensor_dev_attr_pwm3_ramp_rate.dev_attr.attr,
1777 &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr, 1798 &sensor_dev_attr_pwm3_auto_channels_zone.dev_attr.attr,
1778 &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
1779 &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, 1799 &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
1780 NULL 1800 NULL
1781}; 1801};
1782static struct attribute *dme1737_attr_pwm5_lock[] = { 1802static struct attribute *dme1737_pwm5_chmod_attr[] = {
1783 &sensor_dev_attr_pwm5.dev_attr.attr, 1803 &sensor_dev_attr_pwm5.dev_attr.attr,
1784 &sensor_dev_attr_pwm5_freq.dev_attr.attr, 1804 &sensor_dev_attr_pwm5_freq.dev_attr.attr,
1785 NULL 1805 NULL
1786}; 1806};
1787static struct attribute *dme1737_attr_pwm6_lock[] = { 1807static struct attribute *dme1737_pwm6_chmod_attr[] = {
1788 &sensor_dev_attr_pwm6.dev_attr.attr, 1808 &sensor_dev_attr_pwm6.dev_attr.attr,
1789 &sensor_dev_attr_pwm6_freq.dev_attr.attr, 1809 &sensor_dev_attr_pwm6_freq.dev_attr.attr,
1790 NULL 1810 NULL
1791}; 1811};
1792 1812
1793static const struct attribute_group dme1737_pwm_lock_group[] = { 1813static const struct attribute_group dme1737_pwm_chmod_group[] = {
1794 { .attrs = dme1737_attr_pwm1_lock }, 1814 { .attrs = dme1737_pwm1_chmod_attr },
1795 { .attrs = dme1737_attr_pwm2_lock }, 1815 { .attrs = dme1737_pwm2_chmod_attr },
1796 { .attrs = dme1737_attr_pwm3_lock }, 1816 { .attrs = dme1737_pwm3_chmod_attr },
1797 { .attrs = NULL }, 1817 { .attrs = NULL },
1798 { .attrs = dme1737_attr_pwm5_lock }, 1818 { .attrs = dme1737_pwm5_chmod_attr },
1799 { .attrs = dme1737_attr_pwm6_lock }, 1819 { .attrs = dme1737_pwm6_chmod_attr },
1800}; 1820};
1801 1821
1802/* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the 1822/* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the
1803 * chip is not locked. Otherwise they are read-only. */ 1823 * chip is not locked. Otherwise they are read-only. */
1804static struct attribute *dme1737_attr_pwm[] = { 1824static struct attribute *dme1737_pwm_chmod_attr[] = {
1805 &sensor_dev_attr_pwm1.dev_attr.attr, 1825 &sensor_dev_attr_pwm1.dev_attr.attr,
1806 &sensor_dev_attr_pwm2.dev_attr.attr, 1826 &sensor_dev_attr_pwm2.dev_attr.attr,
1807 &sensor_dev_attr_pwm3.dev_attr.attr, 1827 &sensor_dev_attr_pwm3.dev_attr.attr,
@@ -1875,9 +1895,17 @@ static void dme1737_remove_files(struct device *dev)
1875 if (data->has_pwm & (1 << ix)) { 1895 if (data->has_pwm & (1 << ix)) {
1876 sysfs_remove_group(&dev->kobj, 1896 sysfs_remove_group(&dev->kobj,
1877 &dme1737_pwm_group[ix]); 1897 &dme1737_pwm_group[ix]);
1898 if (data->type != sch5027 && ix < 3) {
1899 sysfs_remove_file(&dev->kobj,
1900 dme1737_pwm_misc_attr[ix]);
1901 }
1878 } 1902 }
1879 } 1903 }
1880 1904
1905 if (data->type != sch5027) {
1906 sysfs_remove_group(&dev->kobj, &dme1737_misc_group);
1907 }
1908
1881 sysfs_remove_group(&dev->kobj, &dme1737_group); 1909 sysfs_remove_group(&dev->kobj, &dme1737_group);
1882 1910
1883 if (!data->client.driver) { 1911 if (!data->client.driver) {
@@ -1901,6 +1929,13 @@ static int dme1737_create_files(struct device *dev)
1901 goto exit_remove; 1929 goto exit_remove;
1902 } 1930 }
1903 1931
1932 /* Create misc sysfs attributes */
1933 if ((data->type != sch5027) &&
1934 (err = sysfs_create_group(&dev->kobj,
1935 &dme1737_misc_group))) {
1936 goto exit_remove;
1937 }
1938
1904 /* Create fan sysfs attributes */ 1939 /* Create fan sysfs attributes */
1905 for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) { 1940 for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
1906 if (data->has_fan & (1 << ix)) { 1941 if (data->has_fan & (1 << ix)) {
@@ -1918,6 +1953,11 @@ static int dme1737_create_files(struct device *dev)
1918 &dme1737_pwm_group[ix]))) { 1953 &dme1737_pwm_group[ix]))) {
1919 goto exit_remove; 1954 goto exit_remove;
1920 } 1955 }
1956 if (data->type != sch5027 && ix < 3 &&
1957 (err = sysfs_create_file(&dev->kobj,
1958 dme1737_pwm_misc_attr[ix]))) {
1959 goto exit_remove;
1960 }
1921 } 1961 }
1922 } 1962 }
1923 1963
@@ -1927,16 +1967,27 @@ static int dme1737_create_files(struct device *dev)
1927 dev_info(dev, "Device is locked. Some attributes " 1967 dev_info(dev, "Device is locked. Some attributes "
1928 "will be read-only.\n"); 1968 "will be read-only.\n");
1929 } else { 1969 } else {
1930 /* Change permissions of standard attributes */ 1970 /* Change permissions of zone sysfs attributes */
1931 dme1737_chmod_group(dev, &dme1737_lock_group, 1971 dme1737_chmod_group(dev, &dme1737_zone_chmod_group,
1932 S_IRUGO | S_IWUSR); 1972 S_IRUGO | S_IWUSR);
1933 1973
1934 /* Change permissions of PWM attributes */ 1974 /* Change permissions of misc sysfs attributes */
1935 for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_lock_group); ix++) { 1975 if (data->type != sch5027) {
1976 dme1737_chmod_group(dev, &dme1737_misc_group,
1977 S_IRUGO | S_IWUSR);
1978 }
1979
1980 /* Change permissions of PWM sysfs attributes */
1981 for (ix = 0; ix < ARRAY_SIZE(dme1737_pwm_chmod_group); ix++) {
1936 if (data->has_pwm & (1 << ix)) { 1982 if (data->has_pwm & (1 << ix)) {
1937 dme1737_chmod_group(dev, 1983 dme1737_chmod_group(dev,
1938 &dme1737_pwm_lock_group[ix], 1984 &dme1737_pwm_chmod_group[ix],
1985 S_IRUGO | S_IWUSR);
1986 if (data->type != sch5027 && ix < 3) {
1987 dme1737_chmod_file(dev,
1988 dme1737_pwm_misc_attr[ix],
1939 S_IRUGO | S_IWUSR); 1989 S_IRUGO | S_IWUSR);
1990 }
1940 } 1991 }
1941 } 1992 }
1942 1993
@@ -1945,7 +1996,7 @@ static int dme1737_create_files(struct device *dev)
1945 if ((data->has_pwm & (1 << ix)) && 1996 if ((data->has_pwm & (1 << ix)) &&
1946 (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) { 1997 (PWM_EN_FROM_REG(data->pwm_config[ix]) == 1)) {
1947 dme1737_chmod_file(dev, 1998 dme1737_chmod_file(dev,
1948 dme1737_attr_pwm[ix], 1999 dme1737_pwm_chmod_attr[ix],
1949 S_IRUGO | S_IWUSR); 2000 S_IRUGO | S_IWUSR);
1950 } 2001 }
1951 } 2002 }
@@ -1966,6 +2017,9 @@ static int dme1737_init_device(struct device *dev)
1966 int ix; 2017 int ix;
1967 u8 reg; 2018 u8 reg;
1968 2019
2020 /* Point to the right nominal voltages array */
2021 data->in_nominal = IN_NOMINAL(data->type);
2022
1969 data->config = dme1737_read(client, DME1737_REG_CONFIG); 2023 data->config = dme1737_read(client, DME1737_REG_CONFIG);
1970 /* Inform if part is not monitoring/started */ 2024 /* Inform if part is not monitoring/started */
1971 if (!(data->config & 0x01)) { 2025 if (!(data->config & 0x01)) {
@@ -2076,7 +2130,9 @@ static int dme1737_init_device(struct device *dev)
2076 data->pwm_acz[2] = 4; /* pwm3 -> zone3 */ 2130 data->pwm_acz[2] = 4; /* pwm3 -> zone3 */
2077 2131
2078 /* Set VRM */ 2132 /* Set VRM */
2079 data->vrm = vid_which_vrm(); 2133 if (data->type != sch5027) {
2134 data->vrm = vid_which_vrm();
2135 }
2080 2136
2081 return 0; 2137 return 0;
2082} 2138}
@@ -2095,9 +2151,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data)
2095 dme1737_sio_enter(sio_cip); 2151 dme1737_sio_enter(sio_cip);
2096 2152
2097 /* Check device ID 2153 /* Check device ID
2098 * The DME1737 can return either 0x78 or 0x77 as its device ID. */ 2154 * The DME1737 can return either 0x78 or 0x77 as its device ID.
2155 * The SCH5027 returns 0x89 as its device ID. */
2099 reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20); 2156 reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
2100 if (!(reg == 0x77 || reg == 0x78)) { 2157 if (!(reg == 0x77 || reg == 0x78 || reg == 0x89)) {
2101 err = -ENODEV; 2158 err = -ENODEV;
2102 goto exit; 2159 goto exit;
2103 } 2160 }
@@ -2166,15 +2223,24 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address,
2166 company = dme1737_read(client, DME1737_REG_COMPANY); 2223 company = dme1737_read(client, DME1737_REG_COMPANY);
2167 verstep = dme1737_read(client, DME1737_REG_VERSTEP); 2224 verstep = dme1737_read(client, DME1737_REG_VERSTEP);
2168 2225
2169 if (!((company == DME1737_COMPANY_SMSC) && 2226 if (company == DME1737_COMPANY_SMSC &&
2170 ((verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP))) { 2227 (verstep & DME1737_VERSTEP_MASK) == DME1737_VERSTEP) {
2228 kind = dme1737;
2229 } else if (company == DME1737_COMPANY_SMSC &&
2230 verstep == SCH5027_VERSTEP) {
2231 kind = sch5027;
2232 } else {
2171 err = -ENODEV; 2233 err = -ENODEV;
2172 goto exit_kfree; 2234 goto exit_kfree;
2173 } 2235 }
2174 } 2236 }
2175 2237
2176 kind = dme1737; 2238 if (kind == sch5027) {
2177 name = "dme1737"; 2239 name = "sch5027";
2240 } else {
2241 kind = dme1737;
2242 name = "dme1737";
2243 }
2178 data->type = kind; 2244 data->type = kind;
2179 2245
2180 /* Fill in the remaining client fields and put it into the global 2246 /* Fill in the remaining client fields and put it into the global
@@ -2187,8 +2253,9 @@ static int dme1737_i2c_detect(struct i2c_adapter *adapter, int address,
2187 goto exit_kfree; 2253 goto exit_kfree;
2188 } 2254 }
2189 2255
2190 dev_info(dev, "Found a DME1737 chip at 0x%02x (rev 0x%02x).\n", 2256 dev_info(dev, "Found a %s chip at 0x%02x (rev 0x%02x).\n",
2191 client->addr, verstep); 2257 kind == sch5027 ? "SCH5027" : "DME1737", client->addr,
2258 verstep);
2192 2259
2193 /* Initialize the DME1737 chip */ 2260 /* Initialize the DME1737 chip */
2194 if ((err = dme1737_init_device(dev))) { 2261 if ((err = dme1737_init_device(dev))) {
@@ -2360,15 +2427,18 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
2360 client->addr = res->start; 2427 client->addr = res->start;
2361 platform_set_drvdata(pdev, data); 2428 platform_set_drvdata(pdev, data);
2362 2429
2363 company = dme1737_read(client, DME1737_REG_COMPANY); 2430 /* Skip chip detection if module is loaded with force_id parameter */
2364 device = dme1737_read(client, DME1737_REG_DEVICE); 2431 if (!force_id) {
2432 company = dme1737_read(client, DME1737_REG_COMPANY);
2433 device = dme1737_read(client, DME1737_REG_DEVICE);
2365 2434
2366 if (!((company == DME1737_COMPANY_SMSC) && 2435 if (!((company == DME1737_COMPANY_SMSC) &&
2367 (device == SCH311X_DEVICE))) { 2436 (device == SCH311X_DEVICE))) {
2368 err = -ENODEV; 2437 err = -ENODEV;
2369 goto exit_kfree; 2438 goto exit_kfree;
2439 }
2370 } 2440 }
2371 data->type = -1; 2441 data->type = sch311x;
2372 2442
2373 /* Fill in the remaining client fields and initialize the mutex */ 2443 /* Fill in the remaining client fields and initialize the mutex */
2374 strlcpy(client->name, "sch311x", I2C_NAME_SIZE); 2444 strlcpy(client->name, "sch311x", I2C_NAME_SIZE);
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index cbeb4984b5c7..67067e9a323e 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -87,8 +87,6 @@ static inline void superio_enter(int base);
87static inline void superio_select(int base, int ld); 87static inline void superio_select(int base, int ld);
88static inline void superio_exit(int base); 88static inline void superio_exit(int base);
89 89
90static inline u16 fan_from_reg ( u16 reg );
91
92struct f71882fg_data { 90struct f71882fg_data {
93 unsigned short addr; 91 unsigned short addr;
94 struct device *hwmon_dev; 92 struct device *hwmon_dev;
@@ -116,10 +114,6 @@ struct f71882fg_data {
116 u8 temp_diode_open; 114 u8 temp_diode_open;
117}; 115};
118 116
119static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg);
120static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg);
121static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val);
122
123/* Sysfs in*/ 117/* Sysfs in*/
124static ssize_t show_in(struct device *dev, struct device_attribute *devattr, 118static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
125 char *buf); 119 char *buf);
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 3330667280b9..c54eff92be4a 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -1,76 +1,82 @@
1/* 1/*
2 hwmon-vid.c - VID/VRM/VRD voltage conversions 2 * hwmon-vid.c - VID/VRM/VRD voltage conversions
3 3 *
4 Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz> 4 * Copyright (c) 2004 Rudolf Marek <r.marek@assembler.cz>
5 5 *
6 Partly imported from i2c-vid.h of the lm_sensors project 6 * Partly imported from i2c-vid.h of the lm_sensors project
7 Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> 7 * Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
8 With assistance from Trent Piepho <xyzzy@speakeasy.org> 8 * With assistance from Trent Piepho <xyzzy@speakeasy.org>
9 9 *
10 This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version. 13 * (at your option) any later version.
14 14 *
15 This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details. 18 * GNU General Public License for more details.
19 19 *
20 You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23*/ 23 */
24 24
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/hwmon-vid.h> 27#include <linux/hwmon-vid.h>
28 28
29/* 29/*
30 Common code for decoding VID pins. 30 * Common code for decoding VID pins.
31 31 *
32 References: 32 * References:
33 33 *
34 For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines", 34 * For VRM 8.4 to 9.1, "VRM x.y DC-DC Converter Design Guidelines",
35 available at http://developer.intel.com/. 35 * available at http://developer.intel.com/.
36 36 *
37 For VRD 10.0 and up, "VRD x.y Design Guide", 37 * For VRD 10.0 and up, "VRD x.y Design Guide",
38 available at http://developer.intel.com/. 38 * available at http://developer.intel.com/.
39 39 *
40 AMD Opteron processors don't follow the Intel specifications. 40 * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094,
41 I'm going to "make up" 2.4 as the spec number for the Opterons. 41 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/26094.PDF
42 No good reason just a mnemonic for the 24x Opteron processor 42 * Table 74. VID Code Voltages
43 series. 43 * This corresponds to an arbitrary VRM code of 24 in the functions below.
44 44 * These CPU models (K8 revision <= E) have 5 VID pins. See also:
45 Opteron VID encoding is: 45 * Revision Guide for AMD Athlon 64 and AMD Opteron Processors, AMD Publication 25759,
46 00000 = 1.550 V 46 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf
47 00001 = 1.525 V 47 *
48 . . . . 48 * AMD NPT Family 0Fh Processors, AMD Publication 32559,
49 11110 = 0.800 V 49 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
50 11111 = 0.000 V (off) 50 * Table 71. VID Code Voltages
51 51 * This corresponds to an arbitrary VRM code of 25 in the functions below.
52 The 17 specification is in fact Intel Mobile Voltage Positioning - 52 * These CPU models (K8 revision >= F) have 6 VID pins. See also:
53 (IMVP-II). You can find more information in the datasheet of Max1718 53 * Revision Guide for AMD NPT Family 0Fh Processors, AMD Publication 33610,
54 http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452 54 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf
55 55 *
56 The 13 specification corresponds to the Intel Pentium M series. There 56 * The 17 specification is in fact Intel Mobile Voltage Positioning -
57 doesn't seem to be any named specification for these. The conversion 57 * (IMVP-II). You can find more information in the datasheet of Max1718
58 tables are detailed directly in the various Pentium M datasheets: 58 * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452
59 http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm 59 *
60 60 * The 13 specification corresponds to the Intel Pentium M series. There
61 The 14 specification corresponds to Intel Core series. There 61 * doesn't seem to be any named specification for these. The conversion
62 doesn't seem to be any named specification for these. The conversion 62 * tables are detailed directly in the various Pentium M datasheets:
63 tables are detailed directly in the various Pentium Core datasheets: 63 * http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm
64 http://www.intel.com/design/mobile/datashts/309221.htm 64 *
65 65 * The 14 specification corresponds to Intel Core series. There
66 The 110 (VRM 11) specification corresponds to Intel Conroe based series. 66 * doesn't seem to be any named specification for these. The conversion
67 http://www.intel.com/design/processor/applnots/313214.htm 67 * tables are detailed directly in the various Pentium Core datasheets:
68*/ 68 * http://www.intel.com/design/mobile/datashts/309221.htm
69 69 *
70/* vrm is the VRM/VRD document version multiplied by 10. 70 * The 110 (VRM 11) specification corresponds to Intel Conroe based series.
71 val is the 4-bit or more VID code. 71 * http://www.intel.com/design/processor/applnots/313214.htm
72 Returned value is in mV to avoid floating point in the kernel. 72 */
73 Some VID have some bits in uV scale, this is rounded to mV */ 73
74/*
75 * vrm is the VRM/VRD document version multiplied by 10.
76 * val is the 4-bit or more VID code.
77 * Returned value is in mV to avoid floating point in the kernel.
78 * Some VID have some bits in uV scale, this is rounded to mV.
79 */
74int vid_from_reg(int val, u8 vrm) 80int vid_from_reg(int val, u8 vrm)
75{ 81{
76 int vid; 82 int vid;
@@ -96,9 +102,16 @@ int vid_from_reg(int val, u8 vrm)
96 if (val < 0x02 || val > 0xb2) 102 if (val < 0x02 || val > 0xb2)
97 return 0; 103 return 0;
98 return((1600000 - (val - 2) * 6250 + 500) / 1000); 104 return((1600000 - (val - 2) * 6250 + 500) / 1000);
99 case 24: /* Opteron processor */ 105
106 case 24: /* Athlon64 & Opteron */
100 val &= 0x1f; 107 val &= 0x1f;
101 return(val == 0x1f ? 0 : 1550 - val * 25); 108 if (val == 0x1f)
109 return 0;
110 /* fall through */
111 case 25: /* AMD NPT 0Fh */
112 val &= 0x3f;
113 return (val < 32) ? 1550 - 25 * val
114 : 775 - (25 * (val - 31)) / 2;
102 115
103 case 91: /* VRM 9.1 */ 116 case 91: /* VRM 9.1 */
104 case 90: /* VRM 9.0 */ 117 case 90: /* VRM 9.0 */
@@ -141,9 +154,9 @@ int vid_from_reg(int val, u8 vrm)
141 154
142 155
143/* 156/*
144 After this point is the code to automatically determine which 157 * After this point is the code to automatically determine which
145 VRM/VRD specification should be used depending on the CPU. 158 * VRM/VRD specification should be used depending on the CPU.
146*/ 159 */
147 160
148struct vrm_model { 161struct vrm_model {
149 u8 vendor; 162 u8 vendor;
@@ -157,11 +170,16 @@ struct vrm_model {
157 170
158#ifdef CONFIG_X86 171#ifdef CONFIG_X86
159 172
160/* the stepping parameter is highest acceptable stepping for current line */ 173/*
174 * The stepping parameter is highest acceptable stepping for current line.
175 * The model match must be exact for 4-bit values. For model values 0x10
176 * and above (extended model), all models below the parameter will match.
177 */
161 178
162static struct vrm_model vrm_models[] = { 179static struct vrm_model vrm_models[] = {
163 {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ 180 {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */
164 {X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */ 181 {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */
182 {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* NPT family 0Fh */
165 {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ 183 {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */
166 {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ 184 {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */
167 {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ 185 {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */
@@ -189,6 +207,8 @@ static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
189 if (vrm_models[i].vendor==vendor) 207 if (vrm_models[i].vendor==vendor)
190 if ((vrm_models[i].eff_family==eff_family) 208 if ((vrm_models[i].eff_family==eff_family)
191 && ((vrm_models[i].eff_model==eff_model) || 209 && ((vrm_models[i].eff_model==eff_model) ||
210 (vrm_models[i].eff_model >= 0x10 &&
211 eff_model <= vrm_models[i].eff_model) ||
192 (vrm_models[i].eff_model==ANY)) && 212 (vrm_models[i].eff_model==ANY)) &&
193 (eff_stepping <= vrm_models[i].eff_stepping)) 213 (eff_stepping <= vrm_models[i].eff_stepping))
194 return vrm_models[i].vrm_type; 214 return vrm_models[i].vrm_type;
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index f9e2ed621f7b..2ede9388096b 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -81,6 +81,8 @@ static unsigned long amb_reg_temp(unsigned int amb)
81#define MAX_AMBS_PER_CHANNEL 16 81#define MAX_AMBS_PER_CHANNEL 16
82#define MAX_AMBS (MAX_MEM_CHANNELS * \ 82#define MAX_AMBS (MAX_MEM_CHANNELS * \
83 MAX_AMBS_PER_CHANNEL) 83 MAX_AMBS_PER_CHANNEL)
84#define CHANNEL_SHIFT 4
85#define DIMM_MASK 0xF
84/* 86/*
85 * Ugly hack: For some reason the highest bit is set if there 87 * Ugly hack: For some reason the highest bit is set if there
86 * are _any_ DIMMs in the channel. Attempting to read from 88 * are _any_ DIMMs in the channel. Attempting to read from
@@ -89,7 +91,7 @@ static unsigned long amb_reg_temp(unsigned int amb)
89 * might prevent us from seeing the 16th DIMM in the channel. 91 * might prevent us from seeing the 16th DIMM in the channel.
90 */ 92 */
91#define REAL_MAX_AMBS_PER_CHANNEL 15 93#define REAL_MAX_AMBS_PER_CHANNEL 15
92#define KNOBS_PER_AMB 5 94#define KNOBS_PER_AMB 6
93 95
94static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) 96static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit)
95{ 97{
@@ -238,6 +240,16 @@ static ssize_t show_amb_temp(struct device *dev,
238 500 * amb_read_byte(data, amb_reg_temp(attr->index))); 240 500 * amb_read_byte(data, amb_reg_temp(attr->index)));
239} 241}
240 242
243static ssize_t show_label(struct device *dev,
244 struct device_attribute *devattr,
245 char *buf)
246{
247 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
248
249 return sprintf(buf, "Ch. %d DIMM %d\n", attr->index >> CHANNEL_SHIFT,
250 attr->index & DIMM_MASK);
251}
252
241static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) 253static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev)
242{ 254{
243 int i, j, k, d = 0; 255 int i, j, k, d = 0;
@@ -268,6 +280,20 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev)
268 continue; 280 continue;
269 d++; 281 d++;
270 282
283 /* sysfs label */
284 iattr = data->attrs + data->num_attrs;
285 snprintf(iattr->name, AMB_SYSFS_NAME_LEN,
286 "temp%d_label", d);
287 iattr->s_attr.dev_attr.attr.name = iattr->name;
288 iattr->s_attr.dev_attr.attr.mode = S_IRUGO;
289 iattr->s_attr.dev_attr.show = show_label;
290 iattr->s_attr.index = k;
291 res = device_create_file(&pdev->dev,
292 &iattr->s_attr.dev_attr);
293 if (res)
294 goto exit_remove;
295 data->num_attrs++;
296
271 /* Temperature sysfs knob */ 297 /* Temperature sysfs knob */
272 iattr = data->attrs + data->num_attrs; 298 iattr = data->attrs + data->num_attrs;
273 snprintf(iattr->name, AMB_SYSFS_NAME_LEN, 299 snprintf(iattr->name, AMB_SYSFS_NAME_LEN,
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index c9416e657487..0f70dc204105 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * A hwmon driver for the IBM Active Energy Manager temperature/power sensors 2 * A hwmon driver for the IBM System Director Active Energy Manager (AEM)
3 * and capping functionality. 3 * temperature/power/energy sensors and capping functionality.
4 * Copyright (C) 2008 IBM 4 * Copyright (C) 2008 IBM
5 * 5 *
6 * Author: Darrick J. Wong <djwong@us.ibm.com> 6 * Author: Darrick J. Wong <djwong@us.ibm.com>
@@ -463,12 +463,18 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
463} 463}
464 464
465/* Update AEM energy registers */ 465/* Update AEM energy registers */
466static void update_aem_energy_one(struct aem_data *data, int which)
467{
468 aem_read_sensor(data, AEM_ENERGY_ELEMENT, which,
469 &data->energy[which], 8);
470}
471
466static void update_aem_energy(struct aem_data *data) 472static void update_aem_energy(struct aem_data *data)
467{ 473{
468 aem_read_sensor(data, AEM_ENERGY_ELEMENT, 0, &data->energy[0], 8); 474 update_aem_energy_one(data, 0);
469 if (data->ver_major < 2) 475 if (data->ver_major < 2)
470 return; 476 return;
471 aem_read_sensor(data, AEM_ENERGY_ELEMENT, 1, &data->energy[1], 8); 477 update_aem_energy_one(data, 1);
472} 478}
473 479
474/* Update all AEM1 sensors */ 480/* Update all AEM1 sensors */
@@ -676,7 +682,8 @@ static int aem_find_aem2(struct aem_ipmi_data *data,
676 return -ETIMEDOUT; 682 return -ETIMEDOUT;
677 683
678 if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) || 684 if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) ||
679 memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id))) 685 memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id)) ||
686 fi_resp->num_instances <= instance_num)
680 return -ENOENT; 687 return -ENOENT;
681 688
682 return 0; 689 return 0;
@@ -849,7 +856,7 @@ static ssize_t aem_show_power(struct device *dev,
849 struct timespec b, a; 856 struct timespec b, a;
850 857
851 mutex_lock(&data->lock); 858 mutex_lock(&data->lock);
852 update_aem_energy(data); 859 update_aem_energy_one(data, attr->index);
853 getnstimeofday(&b); 860 getnstimeofday(&b);
854 before = data->energy[attr->index]; 861 before = data->energy[attr->index];
855 862
@@ -861,7 +868,7 @@ static ssize_t aem_show_power(struct device *dev,
861 return 0; 868 return 0;
862 } 869 }
863 870
864 update_aem_energy(data); 871 update_aem_energy_one(data, attr->index);
865 getnstimeofday(&a); 872 getnstimeofday(&a);
866 after = data->energy[attr->index]; 873 after = data->energy[attr->index];
867 mutex_unlock(&data->lock); 874 mutex_unlock(&data->lock);
@@ -880,7 +887,9 @@ static ssize_t aem_show_energy(struct device *dev,
880{ 887{
881 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 888 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
882 struct aem_data *a = dev_get_drvdata(dev); 889 struct aem_data *a = dev_get_drvdata(dev);
883 a->update(a); 890 mutex_lock(&a->lock);
891 update_aem_energy_one(a, attr->index);
892 mutex_unlock(&a->lock);
884 893
885 return sprintf(buf, "%llu\n", 894 return sprintf(buf, "%llu\n",
886 (unsigned long long)a->energy[attr->index] * 1000); 895 (unsigned long long)a->energy[attr->index] * 1000);
@@ -1104,7 +1113,7 @@ static void __exit aem_exit(void)
1104} 1113}
1105 1114
1106MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); 1115MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
1107MODULE_DESCRIPTION("IBM Active Energy Manager power/temp sensor driver"); 1116MODULE_DESCRIPTION("IBM AEM power/temp/energy sensor driver");
1108MODULE_LICENSE("GPL"); 1117MODULE_LICENSE("GPL");
1109 1118
1110module_init(aem_init); 1119module_init(aem_init);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index e12c132ff83a..30cdb0956779 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -151,9 +151,9 @@ static int fix_pwm_polarity;
151/* The IT8718F has the VID value in a different register, in Super-I/O 151/* The IT8718F has the VID value in a different register, in Super-I/O
152 configuration space. */ 152 configuration space. */
153#define IT87_REG_VID 0x0a 153#define IT87_REG_VID 0x0a
154/* Warning: register 0x0b is used for something completely different in 154/* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
155 new chips/revisions. I suspect only 16-bit tachometer mode will work 155 for fan divisors. Later IT8712F revisions must use 16-bit tachometer
156 for these. */ 156 mode. */
157#define IT87_REG_FAN_DIV 0x0b 157#define IT87_REG_FAN_DIV 0x0b
158#define IT87_REG_FAN_16BIT 0x0c 158#define IT87_REG_FAN_16BIT 0x0c
159 159
@@ -234,6 +234,7 @@ static const unsigned int pwm_freq[8] = {
234struct it87_sio_data { 234struct it87_sio_data {
235 enum chips type; 235 enum chips type;
236 /* Values read from Super-I/O config space */ 236 /* Values read from Super-I/O config space */
237 u8 revision;
237 u8 vid_value; 238 u8 vid_value;
238}; 239};
239 240
@@ -242,6 +243,7 @@ struct it87_sio_data {
242struct it87_data { 243struct it87_data {
243 struct device *hwmon_dev; 244 struct device *hwmon_dev;
244 enum chips type; 245 enum chips type;
246 u8 revision;
245 247
246 unsigned short addr; 248 unsigned short addr;
247 const char *name; 249 const char *name;
@@ -268,6 +270,16 @@ struct it87_data {
268 u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ 270 u8 manual_pwm_ctl[3]; /* manual PWM value set by user */
269}; 271};
270 272
273static inline int has_16bit_fans(const struct it87_data *data)
274{
275 /* IT8705F Datasheet 0.4.1, 3h == Version G.
276 IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I.
277 These are the first revisions with 16bit tachometer support. */
278 return (data->type == it87 && data->revision >= 0x03)
279 || (data->type == it8712 && data->revision >= 0x07)
280 || data->type == it8716
281 || data->type == it8718;
282}
271 283
272static int it87_probe(struct platform_device *pdev); 284static int it87_probe(struct platform_device *pdev);
273static int __devexit it87_remove(struct platform_device *pdev); 285static int __devexit it87_remove(struct platform_device *pdev);
@@ -991,8 +1003,9 @@ static int __init it87_find(unsigned short *address,
991 } 1003 }
992 1004
993 err = 0; 1005 err = 0;
1006 sio_data->revision = superio_inb(DEVREV) & 0x0f;
994 pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", 1007 pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
995 chip_type, *address, superio_inb(DEVREV) & 0x0f); 1008 chip_type, *address, sio_data->revision);
996 1009
997 /* Read GPIO config and VID value from LDN 7 (GPIO) */ 1010 /* Read GPIO config and VID value from LDN 7 (GPIO) */
998 if (chip_type != IT8705F_DEVID) { 1011 if (chip_type != IT8705F_DEVID) {
@@ -1045,6 +1058,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1045 1058
1046 data->addr = res->start; 1059 data->addr = res->start;
1047 data->type = sio_data->type; 1060 data->type = sio_data->type;
1061 data->revision = sio_data->revision;
1048 data->name = names[sio_data->type]; 1062 data->name = names[sio_data->type];
1049 1063
1050 /* Now, we do the remaining detection. */ 1064 /* Now, we do the remaining detection. */
@@ -1069,7 +1083,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1069 goto ERROR2; 1083 goto ERROR2;
1070 1084
1071 /* Do not create fan files for disabled fans */ 1085 /* Do not create fan files for disabled fans */
1072 if (data->type == it8716 || data->type == it8718) { 1086 if (has_16bit_fans(data)) {
1073 /* 16-bit tachometers */ 1087 /* 16-bit tachometers */
1074 if (data->has_fan & (1 << 0)) { 1088 if (data->has_fan & (1 << 0)) {
1075 if ((err = device_create_file(dev, 1089 if ((err = device_create_file(dev,
@@ -1350,7 +1364,7 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1350 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; 1364 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
1351 1365
1352 /* Set tachometers to 16-bit mode if needed */ 1366 /* Set tachometers to 16-bit mode if needed */
1353 if (data->type == it8716 || data->type == it8718) { 1367 if (has_16bit_fans(data)) {
1354 tmp = it87_read_value(data, IT87_REG_FAN_16BIT); 1368 tmp = it87_read_value(data, IT87_REG_FAN_16BIT);
1355 if (~tmp & 0x07 & data->has_fan) { 1369 if (~tmp & 0x07 & data->has_fan) {
1356 dev_dbg(&pdev->dev, 1370 dev_dbg(&pdev->dev,
@@ -1358,10 +1372,13 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1358 it87_write_value(data, IT87_REG_FAN_16BIT, 1372 it87_write_value(data, IT87_REG_FAN_16BIT,
1359 tmp | 0x07); 1373 tmp | 0x07);
1360 } 1374 }
1361 if (tmp & (1 << 4)) 1375 /* IT8705F only supports three fans. */
1362 data->has_fan |= (1 << 3); /* fan4 enabled */ 1376 if (data->type != it87) {
1363 if (tmp & (1 << 5)) 1377 if (tmp & (1 << 4))
1364 data->has_fan |= (1 << 4); /* fan5 enabled */ 1378 data->has_fan |= (1 << 3); /* fan4 enabled */
1379 if (tmp & (1 << 5))
1380 data->has_fan |= (1 << 4); /* fan5 enabled */
1381 }
1365 } 1382 }
1366 1383
1367 /* Set current fan mode registers and the default settings for the 1384 /* Set current fan mode registers and the default settings for the
@@ -1426,7 +1443,7 @@ static struct it87_data *it87_update_device(struct device *dev)
1426 data->fan[i] = it87_read_value(data, 1443 data->fan[i] = it87_read_value(data,
1427 IT87_REG_FAN[i]); 1444 IT87_REG_FAN[i]);
1428 /* Add high byte if in 16-bit mode */ 1445 /* Add high byte if in 16-bit mode */
1429 if (data->type == it8716 || data->type == it8718) { 1446 if (has_16bit_fans(data)) {
1430 data->fan[i] |= it87_read_value(data, 1447 data->fan[i] |= it87_read_value(data,
1431 IT87_REG_FANX[i]) << 8; 1448 IT87_REG_FANX[i]) << 8;
1432 data->fan_min[i] |= it87_read_value(data, 1449 data->fan_min[i] |= it87_read_value(data,
@@ -1443,8 +1460,7 @@ static struct it87_data *it87_update_device(struct device *dev)
1443 } 1460 }
1444 1461
1445 /* Newer chips don't have clock dividers */ 1462 /* Newer chips don't have clock dividers */
1446 if ((data->has_fan & 0x07) && data->type != it8716 1463 if ((data->has_fan & 0x07) && !has_16bit_fans(data)) {
1447 && data->type != it8718) {
1448 i = it87_read_value(data, IT87_REG_FAN_DIV); 1464 i = it87_read_value(data, IT87_REG_FAN_DIV);
1449 data->fan_div[0] = i & 0x07; 1465 data->fan_div[0] = i & 0x07;
1450 data->fan_div[1] = (i >> 3) & 0x07; 1466 data->fan_div[1] = (i >> 3) & 0x07;
@@ -1460,7 +1476,8 @@ static struct it87_data *it87_update_device(struct device *dev)
1460 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); 1476 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
1461 1477
1462 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 1478 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
1463 /* The 8705 does not have VID capability */ 1479 /* The 8705 does not have VID capability.
1480 The 8718 does not use IT87_REG_VID for the same purpose. */
1464 if (data->type == it8712 || data->type == it8716) { 1481 if (data->type == it8712 || data->type == it8716) {
1465 data->vid = it87_read_value(data, IT87_REG_VID); 1482 data->vid = it87_read_value(data, IT87_REG_VID);
1466 /* The older IT8712F revisions had only 5 VID pins, 1483 /* The older IT8712F revisions had only 5 VID pins,
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 7880c273c2c5..8f9595f2fb53 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -54,11 +54,11 @@ enum lm75_type { /* keep sorted in alphabetical order */
54 tmp75, 54 tmp75,
55}; 55};
56 56
57/* Addresses scanned by legacy style driver binding */ 57/* Addresses scanned */
58static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 58static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
59 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 59 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
60 60
61/* Insmod parameters (only for legacy style driver binding) */ 61/* Insmod parameters */
62I2C_CLIENT_INSMOD_1(lm75); 62I2C_CLIENT_INSMOD_1(lm75);
63 63
64 64
@@ -72,7 +72,6 @@ static const u8 LM75_REG_TEMP[3] = {
72 72
73/* Each client has this additional data */ 73/* Each client has this additional data */
74struct lm75_data { 74struct lm75_data {
75 struct i2c_client *client;
76 struct device *hwmon_dev; 75 struct device *hwmon_dev;
77 struct mutex update_lock; 76 struct mutex update_lock;
78 u8 orig_conf; 77 u8 orig_conf;
@@ -138,7 +137,7 @@ static const struct attribute_group lm75_group = {
138 137
139/*-----------------------------------------------------------------------*/ 138/*-----------------------------------------------------------------------*/
140 139
141/* "New style" I2C driver binding -- following the driver model */ 140/* device probe and removal */
142 141
143static int 142static int
144lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) 143lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -157,8 +156,6 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
157 return -ENOMEM; 156 return -ENOMEM;
158 157
159 i2c_set_clientdata(client, data); 158 i2c_set_clientdata(client, data);
160
161 data->client = client;
162 mutex_init(&data->update_lock); 159 mutex_init(&data->update_lock);
163 160
164 /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. 161 /* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
@@ -236,45 +233,16 @@ static const struct i2c_device_id lm75_ids[] = {
236}; 233};
237MODULE_DEVICE_TABLE(i2c, lm75_ids); 234MODULE_DEVICE_TABLE(i2c, lm75_ids);
238 235
239static struct i2c_driver lm75_driver = { 236/* Return 0 if detection is successful, -ENODEV otherwise */
240 .driver = { 237static int lm75_detect(struct i2c_client *new_client, int kind,
241 .name = "lm75", 238 struct i2c_board_info *info)
242 },
243 .probe = lm75_probe,
244 .remove = lm75_remove,
245 .id_table = lm75_ids,
246};
247
248/*-----------------------------------------------------------------------*/
249
250/* "Legacy" I2C driver binding */
251
252static struct i2c_driver lm75_legacy_driver;
253
254/* This function is called by i2c_probe */
255static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
256{ 239{
240 struct i2c_adapter *adapter = new_client->adapter;
257 int i; 241 int i;
258 struct i2c_client *new_client;
259 int err = 0;
260 242
261 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 243 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
262 I2C_FUNC_SMBUS_WORD_DATA)) 244 I2C_FUNC_SMBUS_WORD_DATA))
263 goto exit; 245 return -ENODEV;
264
265 /* OK. For now, we presume we have a valid address. We create the
266 client structure, even though there may be no sensor present.
267 But it allows us to use i2c_smbus_read_*_data() calls. */
268 new_client = kzalloc(sizeof *new_client, GFP_KERNEL);
269 if (!new_client) {
270 err = -ENOMEM;
271 goto exit;
272 }
273
274 new_client->addr = address;
275 new_client->adapter = adapter;
276 new_client->driver = &lm75_legacy_driver;
277 new_client->flags = 0;
278 246
279 /* Now, we do the remaining detection. There is no identification- 247 /* Now, we do the remaining detection. There is no identification-
280 dedicated register so we have to rely on several tricks: 248 dedicated register so we have to rely on several tricks:
@@ -294,71 +262,44 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
294 || i2c_smbus_read_word_data(new_client, 5) != hyst 262 || i2c_smbus_read_word_data(new_client, 5) != hyst
295 || i2c_smbus_read_word_data(new_client, 6) != hyst 263 || i2c_smbus_read_word_data(new_client, 6) != hyst
296 || i2c_smbus_read_word_data(new_client, 7) != hyst) 264 || i2c_smbus_read_word_data(new_client, 7) != hyst)
297 goto exit_free; 265 return -ENODEV;
298 os = i2c_smbus_read_word_data(new_client, 3); 266 os = i2c_smbus_read_word_data(new_client, 3);
299 if (i2c_smbus_read_word_data(new_client, 4) != os 267 if (i2c_smbus_read_word_data(new_client, 4) != os
300 || i2c_smbus_read_word_data(new_client, 5) != os 268 || i2c_smbus_read_word_data(new_client, 5) != os
301 || i2c_smbus_read_word_data(new_client, 6) != os 269 || i2c_smbus_read_word_data(new_client, 6) != os
302 || i2c_smbus_read_word_data(new_client, 7) != os) 270 || i2c_smbus_read_word_data(new_client, 7) != os)
303 goto exit_free; 271 return -ENODEV;
304 272
305 /* Unused bits */ 273 /* Unused bits */
306 if (conf & 0xe0) 274 if (conf & 0xe0)
307 goto exit_free; 275 return -ENODEV;
308 276
309 /* Addresses cycling */ 277 /* Addresses cycling */
310 for (i = 8; i < 0xff; i += 8) 278 for (i = 8; i < 0xff; i += 8)
311 if (i2c_smbus_read_byte_data(new_client, i + 1) != conf 279 if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
312 || i2c_smbus_read_word_data(new_client, i + 2) != hyst 280 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
313 || i2c_smbus_read_word_data(new_client, i + 3) != os) 281 || i2c_smbus_read_word_data(new_client, i + 3) != os)
314 goto exit_free; 282 return -ENODEV;
315 } 283 }
316 284
317 /* NOTE: we treat "force=..." and "force_lm75=..." the same. 285 /* NOTE: we treat "force=..." and "force_lm75=..." the same.
318 * Only new-style driver binding distinguishes chip types. 286 * Only new-style driver binding distinguishes chip types.
319 */ 287 */
320 strlcpy(new_client->name, "lm75", I2C_NAME_SIZE); 288 strlcpy(info->type, "lm75", I2C_NAME_SIZE);
321
322 /* Tell the I2C layer a new client has arrived */
323 err = i2c_attach_client(new_client);
324 if (err)
325 goto exit_free;
326
327 err = lm75_probe(new_client, NULL);
328 if (err < 0)
329 goto exit_detach;
330 289
331 return 0; 290 return 0;
332
333exit_detach:
334 i2c_detach_client(new_client);
335exit_free:
336 kfree(new_client);
337exit:
338 return err;
339}
340
341static int lm75_attach_adapter(struct i2c_adapter *adapter)
342{
343 if (!(adapter->class & I2C_CLASS_HWMON))
344 return 0;
345 return i2c_probe(adapter, &addr_data, lm75_detect);
346} 291}
347 292
348static int lm75_detach_client(struct i2c_client *client) 293static struct i2c_driver lm75_driver = {
349{ 294 .class = I2C_CLASS_HWMON,
350 lm75_remove(client);
351 i2c_detach_client(client);
352 kfree(client);
353 return 0;
354}
355
356static struct i2c_driver lm75_legacy_driver = {
357 .driver = { 295 .driver = {
358 .name = "lm75_legacy", 296 .name = "lm75",
359 }, 297 },
360 .attach_adapter = lm75_attach_adapter, 298 .probe = lm75_probe,
361 .detach_client = lm75_detach_client, 299 .remove = lm75_remove,
300 .id_table = lm75_ids,
301 .detect = lm75_detect,
302 .address_data = &addr_data,
362}; 303};
363 304
364/*-----------------------------------------------------------------------*/ 305/*-----------------------------------------------------------------------*/
@@ -424,22 +365,11 @@ static struct lm75_data *lm75_update_device(struct device *dev)
424 365
425static int __init sensors_lm75_init(void) 366static int __init sensors_lm75_init(void)
426{ 367{
427 int status; 368 return i2c_add_driver(&lm75_driver);
428
429 status = i2c_add_driver(&lm75_driver);
430 if (status < 0)
431 return status;
432
433 status = i2c_add_driver(&lm75_legacy_driver);
434 if (status < 0)
435 i2c_del_driver(&lm75_driver);
436
437 return status;
438} 369}
439 370
440static void __exit sensors_lm75_exit(void) 371static void __exit sensors_lm75_exit(void)
441{ 372{
442 i2c_del_driver(&lm75_legacy_driver);
443 i2c_del_driver(&lm75_driver); 373 i2c_del_driver(&lm75_driver);
444} 374}
445 375
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 3b01001108c1..7d97431e132f 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -55,8 +55,11 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs "
55static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; 55static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
56static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; 56static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
57static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; 57static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
58static const u8 THMC50_REG_TEMP_CRITICAL[] = { 0x13, 0x14, 0x14 };
59static const u8 THMC50_REG_TEMP_DEFAULT[] = { 0x17, 0x18, 0x18 };
58 60
59#define THMC50_REG_CONF_nFANOFF 0x20 61#define THMC50_REG_CONF_nFANOFF 0x20
62#define THMC50_REG_CONF_PROGRAMMED 0x08
60 63
61/* Each client has this additional data */ 64/* Each client has this additional data */
62struct thmc50_data { 65struct thmc50_data {
@@ -72,6 +75,7 @@ struct thmc50_data {
72 s8 temp_input[3]; 75 s8 temp_input[3];
73 s8 temp_max[3]; 76 s8 temp_max[3];
74 s8 temp_min[3]; 77 s8 temp_min[3];
78 s8 temp_critical[3];
75 u8 analog_out; 79 u8 analog_out;
76 u8 alarms; 80 u8 alarms;
77}; 81};
@@ -199,6 +203,15 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
199 return count; 203 return count;
200} 204}
201 205
206static ssize_t show_temp_critical(struct device *dev,
207 struct device_attribute *attr,
208 char *buf)
209{
210 int nr = to_sensor_dev_attr(attr)->index;
211 struct thmc50_data *data = thmc50_update_device(dev);
212 return sprintf(buf, "%d\n", data->temp_critical[nr] * 1000);
213}
214
202static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, 215static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
203 char *buf) 216 char *buf)
204{ 217{
@@ -214,7 +227,9 @@ static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \
214static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ 227static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
215 show_temp_min, set_temp_min, offset - 1); \ 228 show_temp_min, set_temp_min, offset - 1); \
216static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ 229static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
217 show_temp_max, set_temp_max, offset - 1); 230 show_temp_max, set_temp_max, offset - 1); \
231static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO, \
232 show_temp_critical, NULL, offset - 1);
218 233
219temp_reg(1); 234temp_reg(1);
220temp_reg(2); 235temp_reg(2);
@@ -234,10 +249,12 @@ static struct attribute *thmc50_attributes[] = {
234 &sensor_dev_attr_temp1_max.dev_attr.attr, 249 &sensor_dev_attr_temp1_max.dev_attr.attr,
235 &sensor_dev_attr_temp1_min.dev_attr.attr, 250 &sensor_dev_attr_temp1_min.dev_attr.attr,
236 &sensor_dev_attr_temp1_input.dev_attr.attr, 251 &sensor_dev_attr_temp1_input.dev_attr.attr,
252 &sensor_dev_attr_temp1_crit.dev_attr.attr,
237 &sensor_dev_attr_temp1_alarm.dev_attr.attr, 253 &sensor_dev_attr_temp1_alarm.dev_attr.attr,
238 &sensor_dev_attr_temp2_max.dev_attr.attr, 254 &sensor_dev_attr_temp2_max.dev_attr.attr,
239 &sensor_dev_attr_temp2_min.dev_attr.attr, 255 &sensor_dev_attr_temp2_min.dev_attr.attr,
240 &sensor_dev_attr_temp2_input.dev_attr.attr, 256 &sensor_dev_attr_temp2_input.dev_attr.attr,
257 &sensor_dev_attr_temp2_crit.dev_attr.attr,
241 &sensor_dev_attr_temp2_alarm.dev_attr.attr, 258 &sensor_dev_attr_temp2_alarm.dev_attr.attr,
242 &sensor_dev_attr_temp2_fault.dev_attr.attr, 259 &sensor_dev_attr_temp2_fault.dev_attr.attr,
243 &sensor_dev_attr_pwm1.dev_attr.attr, 260 &sensor_dev_attr_pwm1.dev_attr.attr,
@@ -254,6 +271,7 @@ static struct attribute *temp3_attributes[] = {
254 &sensor_dev_attr_temp3_max.dev_attr.attr, 271 &sensor_dev_attr_temp3_max.dev_attr.attr,
255 &sensor_dev_attr_temp3_min.dev_attr.attr, 272 &sensor_dev_attr_temp3_min.dev_attr.attr,
256 &sensor_dev_attr_temp3_input.dev_attr.attr, 273 &sensor_dev_attr_temp3_input.dev_attr.attr,
274 &sensor_dev_attr_temp3_crit.dev_attr.attr,
257 &sensor_dev_attr_temp3_alarm.dev_attr.attr, 275 &sensor_dev_attr_temp3_alarm.dev_attr.attr,
258 &sensor_dev_attr_temp3_fault.dev_attr.attr, 276 &sensor_dev_attr_temp3_fault.dev_attr.attr,
259 NULL 277 NULL
@@ -429,6 +447,10 @@ static struct thmc50_data *thmc50_update_device(struct device *dev)
429 447
430 int temps = data->has_temp3 ? 3 : 2; 448 int temps = data->has_temp3 ? 3 : 2;
431 int i; 449 int i;
450 int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
451
452 prog &= THMC50_REG_CONF_PROGRAMMED;
453
432 for (i = 0; i < temps; i++) { 454 for (i = 0; i < temps; i++) {
433 data->temp_input[i] = i2c_smbus_read_byte_data(client, 455 data->temp_input[i] = i2c_smbus_read_byte_data(client,
434 THMC50_REG_TEMP[i]); 456 THMC50_REG_TEMP[i]);
@@ -436,6 +458,10 @@ static struct thmc50_data *thmc50_update_device(struct device *dev)
436 THMC50_REG_TEMP_MAX[i]); 458 THMC50_REG_TEMP_MAX[i]);
437 data->temp_min[i] = i2c_smbus_read_byte_data(client, 459 data->temp_min[i] = i2c_smbus_read_byte_data(client,
438 THMC50_REG_TEMP_MIN[i]); 460 THMC50_REG_TEMP_MIN[i]);
461 data->temp_critical[i] =
462 i2c_smbus_read_byte_data(client,
463 prog ? THMC50_REG_TEMP_CRITICAL[i]
464 : THMC50_REG_TEMP_DEFAULT[i]);
439 } 465 }
440 data->analog_out = 466 data->analog_out =
441 i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT); 467 i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 9564fb069957..b30e5796cb26 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -67,10 +67,6 @@ module_param(force_i2c, byte, 0);
67MODULE_PARM_DESC(force_i2c, 67MODULE_PARM_DESC(force_i2c,
68 "Initialize the i2c address of the sensors"); 68 "Initialize the i2c address of the sensors");
69 69
70static int reset;
71module_param(reset, bool, 0);
72MODULE_PARM_DESC(reset, "Set to one to reset chip on load");
73
74static int init = 1; 70static int init = 1;
75module_param(init, bool, 0); 71module_param(init, bool, 0);
76MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); 72MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
@@ -209,6 +205,13 @@ static const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 };
209#define W83627HF_REG_PWM1 0x5A 205#define W83627HF_REG_PWM1 0x5A
210#define W83627HF_REG_PWM2 0x5B 206#define W83627HF_REG_PWM2 0x5B
211 207
208static const u8 W83627THF_REG_PWM_ENABLE[] = {
209 0x04, /* FAN 1 mode */
210 0x04, /* FAN 2 mode */
211 0x12, /* FAN AUX mode */
212};
213static const u8 W83627THF_PWM_ENABLE_SHIFT[] = { 2, 4, 1 };
214
212#define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ 215#define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */
213#define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ 216#define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */
214#define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ 217#define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */
@@ -366,6 +369,9 @@ struct w83627hf_data {
366 u32 alarms; /* Register encoding, combined */ 369 u32 alarms; /* Register encoding, combined */
367 u32 beep_mask; /* Register encoding, combined */ 370 u32 beep_mask; /* Register encoding, combined */
368 u8 pwm[3]; /* Register value */ 371 u8 pwm[3]; /* Register value */
372 u8 pwm_enable[3]; /* 1 = manual
373 2 = thermal cruise (also called SmartFan I)
374 3 = fan speed cruise */
369 u8 pwm_freq[3]; /* Register value */ 375 u8 pwm_freq[3]; /* Register value */
370 u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; 376 u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode;
371 4 = thermistor */ 377 4 = thermistor */
@@ -957,6 +963,42 @@ static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1);
957static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); 963static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2);
958 964
959static ssize_t 965static ssize_t
966show_pwm_enable(struct device *dev, struct device_attribute *devattr, char *buf)
967{
968 int nr = to_sensor_dev_attr(devattr)->index;
969 struct w83627hf_data *data = w83627hf_update_device(dev);
970 return sprintf(buf, "%d\n", data->pwm_enable[nr]);
971}
972
973static ssize_t
974store_pwm_enable(struct device *dev, struct device_attribute *devattr,
975 const char *buf, size_t count)
976{
977 int nr = to_sensor_dev_attr(devattr)->index;
978 struct w83627hf_data *data = dev_get_drvdata(dev);
979 unsigned long val = simple_strtoul(buf, NULL, 10);
980 u8 reg;
981
982 if (!val || (val > 3)) /* modes 1, 2 and 3 are supported */
983 return -EINVAL;
984 mutex_lock(&data->update_lock);
985 data->pwm_enable[nr] = val;
986 reg = w83627hf_read_value(data, W83627THF_REG_PWM_ENABLE[nr]);
987 reg &= ~(0x03 << W83627THF_PWM_ENABLE_SHIFT[nr]);
988 reg |= (val - 1) << W83627THF_PWM_ENABLE_SHIFT[nr];
989 w83627hf_write_value(data, W83627THF_REG_PWM_ENABLE[nr], reg);
990 mutex_unlock(&data->update_lock);
991 return count;
992}
993
994static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
995 store_pwm_enable, 0);
996static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
997 store_pwm_enable, 1);
998static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
999 store_pwm_enable, 2);
1000
1001static ssize_t
960show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) 1002show_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf)
961{ 1003{
962 int nr = to_sensor_dev_attr(devattr)->index; 1004 int nr = to_sensor_dev_attr(devattr)->index;
@@ -1223,6 +1265,11 @@ static struct attribute *w83627hf_attributes_opt[] = {
1223 &sensor_dev_attr_pwm1_freq.dev_attr.attr, 1265 &sensor_dev_attr_pwm1_freq.dev_attr.attr,
1224 &sensor_dev_attr_pwm2_freq.dev_attr.attr, 1266 &sensor_dev_attr_pwm2_freq.dev_attr.attr,
1225 &sensor_dev_attr_pwm3_freq.dev_attr.attr, 1267 &sensor_dev_attr_pwm3_freq.dev_attr.attr,
1268
1269 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1270 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1271 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1272
1226 NULL 1273 NULL
1227}; 1274};
1228 1275
@@ -1366,6 +1413,19 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
1366 &sensor_dev_attr_pwm3_freq.dev_attr))) 1413 &sensor_dev_attr_pwm3_freq.dev_attr)))
1367 goto ERROR4; 1414 goto ERROR4;
1368 1415
1416 if (data->type != w83627hf)
1417 if ((err = device_create_file(dev,
1418 &sensor_dev_attr_pwm1_enable.dev_attr))
1419 || (err = device_create_file(dev,
1420 &sensor_dev_attr_pwm2_enable.dev_attr)))
1421 goto ERROR4;
1422
1423 if (data->type == w83627thf || data->type == w83637hf
1424 || data->type == w83687thf)
1425 if ((err = device_create_file(dev,
1426 &sensor_dev_attr_pwm3_enable.dev_attr)))
1427 goto ERROR4;
1428
1369 data->hwmon_dev = hwmon_device_register(dev); 1429 data->hwmon_dev = hwmon_device_register(dev);
1370 if (IS_ERR(data->hwmon_dev)) { 1430 if (IS_ERR(data->hwmon_dev)) {
1371 err = PTR_ERR(data->hwmon_dev); 1431 err = PTR_ERR(data->hwmon_dev);
@@ -1536,29 +1596,6 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev)
1536 enum chips type = data->type; 1596 enum chips type = data->type;
1537 u8 tmp; 1597 u8 tmp;
1538 1598
1539 if (reset) {
1540 /* Resetting the chip has been the default for a long time,
1541 but repeatedly caused problems (fans going to full
1542 speed...) so it is now optional. It might even go away if
1543 nobody reports it as being useful, as I see very little
1544 reason why this would be needed at all. */
1545 dev_info(&pdev->dev, "If reset=1 solved a problem you were "
1546 "having, please report!\n");
1547
1548 /* save this register */
1549 i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG);
1550 /* Reset all except Watchdog values and last conversion values
1551 This sets fan-divs to 2, among others */
1552 w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80);
1553 /* Restore the register and disable power-on abnormal beep.
1554 This saves FAN 1/2/3 input/output values set by BIOS. */
1555 w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
1556 /* Disable master beep-enable (reset turns it on).
1557 Individual beeps should be reset to off but for some reason
1558 disabling this bit helps some people not get beeped */
1559 w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0);
1560 }
1561
1562 /* Minimize conflicts with other winbond i2c-only clients... */ 1599 /* Minimize conflicts with other winbond i2c-only clients... */
1563 /* disable i2c subclients... how to disable main i2c client?? */ 1600 /* disable i2c subclients... how to disable main i2c client?? */
1564 /* force i2c address to relatively uncommon address */ 1601 /* force i2c address to relatively uncommon address */
@@ -1655,6 +1692,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1655{ 1692{
1656 struct w83627hf_data *data = dev_get_drvdata(dev); 1693 struct w83627hf_data *data = dev_get_drvdata(dev);
1657 int i, num_temps = (data->type == w83697hf) ? 2 : 3; 1694 int i, num_temps = (data->type == w83697hf) ? 2 : 3;
1695 int num_pwms = (data->type == w83697hf) ? 2 : 3;
1658 1696
1659 mutex_lock(&data->update_lock); 1697 mutex_lock(&data->update_lock);
1660 1698
@@ -1707,6 +1745,15 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1707 break; 1745 break;
1708 } 1746 }
1709 } 1747 }
1748 if (data->type != w83627hf) {
1749 for (i = 0; i < num_pwms; i++) {
1750 u8 tmp = w83627hf_read_value(data,
1751 W83627THF_REG_PWM_ENABLE[i]);
1752 data->pwm_enable[i] =
1753 ((tmp >> W83627THF_PWM_ENABLE_SHIFT[i])
1754 & 0x03) + 1;
1755 }
1756 }
1710 for (i = 0; i < num_temps; i++) { 1757 for (i = 0; i < num_temps; i++) {
1711 data->temp[i] = w83627hf_read_value( 1758 data->temp[i] = w83627hf_read_value(
1712 data, w83627hf_reg_temp[i]); 1759 data, w83627hf_reg_temp[i]);
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index e4e91c9d480a..de21142d106c 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -233,11 +233,9 @@ static u8 fan_to_reg(long rpm, int div)
233static u8 div_to_reg(int nr, long val) 233static u8 div_to_reg(int nr, long val)
234{ 234{
235 int i; 235 int i;
236 int max;
237 236
238 /* first three fan's divisor max out at 8, rest max out at 128 */ 237 /* fan divisors max out at 128 */
239 max = (nr < 3) ? 8 : 128; 238 val = SENSORS_LIMIT(val, 1, 128) >> 1;
240 val = SENSORS_LIMIT(val, 1, max) >> 1;
241 for (i = 0; i < 7; i++) { 239 for (i = 0; i < 7; i++) {
242 if (val == 0) 240 if (val == 0)
243 break; 241 break;
@@ -530,6 +528,7 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
530 unsigned long min; 528 unsigned long min;
531 u8 tmp_fan_div; 529 u8 tmp_fan_div;
532 u8 fan_div_reg; 530 u8 fan_div_reg;
531 u8 vbat_reg;
533 int indx = 0; 532 int indx = 0;
534 u8 keep_mask = 0; 533 u8 keep_mask = 0;
535 u8 new_shift = 0; 534 u8 new_shift = 0;
@@ -581,6 +580,16 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
581 w83791d_write(client, W83791D_REG_FAN_DIV[indx], 580 w83791d_write(client, W83791D_REG_FAN_DIV[indx],
582 fan_div_reg | tmp_fan_div); 581 fan_div_reg | tmp_fan_div);
583 582
583 /* Bit 2 of fans 0-2 is stored in the vbat register (bits 5-7) */
584 if (nr < 3) {
585 keep_mask = ~(1 << (nr + 5));
586 vbat_reg = w83791d_read(client, W83791D_REG_VBAT)
587 & keep_mask;
588 tmp_fan_div = (data->fan_div[nr] << (3 + nr)) & ~keep_mask;
589 w83791d_write(client, W83791D_REG_VBAT,
590 vbat_reg | tmp_fan_div);
591 }
592
584 /* Restore fan_min */ 593 /* Restore fan_min */
585 data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr])); 594 data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr]));
586 w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]); 595 w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]);
@@ -1046,9 +1055,10 @@ static int w83791d_probe(struct i2c_client *client,
1046{ 1055{
1047 struct w83791d_data *data; 1056 struct w83791d_data *data;
1048 struct device *dev = &client->dev; 1057 struct device *dev = &client->dev;
1049 int i, val1, err; 1058 int i, err;
1050 1059
1051#ifdef DEBUG 1060#ifdef DEBUG
1061 int val1;
1052 val1 = w83791d_read(client, W83791D_REG_DID_VID4); 1062 val1 = w83791d_read(client, W83791D_REG_DID_VID4);
1053 dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n", 1063 dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n",
1054 (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); 1064 (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1);
@@ -1182,6 +1192,7 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
1182 struct w83791d_data *data = i2c_get_clientdata(client); 1192 struct w83791d_data *data = i2c_get_clientdata(client);
1183 int i, j; 1193 int i, j;
1184 u8 reg_array_tmp[3]; 1194 u8 reg_array_tmp[3];
1195 u8 vbat_reg;
1185 1196
1186 mutex_lock(&data->update_lock); 1197 mutex_lock(&data->update_lock);
1187 1198
@@ -1219,6 +1230,12 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
1219 data->fan_div[3] = reg_array_tmp[2] & 0x07; 1230 data->fan_div[3] = reg_array_tmp[2] & 0x07;
1220 data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07; 1231 data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07;
1221 1232
1233 /* The fan divisor for fans 0-2 get bit 2 from
1234 bits 5-7 respectively of vbat register */
1235 vbat_reg = w83791d_read(client, W83791D_REG_VBAT);
1236 for (i = 0; i < 3; i++)
1237 data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04;
1238
1222 /* Update the first temperature sensor */ 1239 /* Update the first temperature sensor */
1223 for (i = 0; i < 3; i++) { 1240 for (i = 0; i < 3; i++) {
1224 data->temp1[i] = w83791d_read(client, 1241 data->temp1[i] = w83791d_read(client,
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 96867347bcbf..711ca08ab776 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -38,6 +38,20 @@ config I2C_CHARDEV
38 This support is also available as a module. If so, the module 38 This support is also available as a module. If so, the module
39 will be called i2c-dev. 39 will be called i2c-dev.
40 40
41config I2C_HELPER_AUTO
42 bool "Autoselect pertinent helper modules"
43 default y
44 help
45 Some I2C bus drivers require so-called "I2C algorithm" modules
46 to work. These are basically software-only abstractions of generic
47 I2C interfaces. This option will autoselect them so that you don't
48 have to care.
49
50 Unselect this only if you need to enable additional helper
51 modules, for example for use with external I2C bus drivers.
52
53 In doubt, say Y.
54
41source drivers/i2c/algos/Kconfig 55source drivers/i2c/algos/Kconfig
42source drivers/i2c/busses/Kconfig 56source drivers/i2c/busses/Kconfig
43source drivers/i2c/chips/Kconfig 57source drivers/i2c/chips/Kconfig
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index 7137a17402fe..b788579b8227 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -2,15 +2,20 @@
2# I2C algorithm drivers configuration 2# I2C algorithm drivers configuration
3# 3#
4 4
5menu "I2C Algorithms"
6 depends on !I2C_HELPER_AUTO
7
5config I2C_ALGOBIT 8config I2C_ALGOBIT
6 tristate 9 tristate "I2C bit-banging interfaces"
7 10
8config I2C_ALGOPCF 11config I2C_ALGOPCF
9 tristate 12 tristate "I2C PCF 8584 interfaces"
10 13
11config I2C_ALGOPCA 14config I2C_ALGOPCA
12 tristate 15 tristate "I2C PCA 9564 interfaces"
13 16
14config I2C_ALGO_SGI 17config I2C_ALGO_SGI
15 tristate 18 tristate
16 depends on SGI_IP22 || SGI_IP32 || X86_VISWS 19 depends on SGI_IP22 || SGI_IP32 || X86_VISWS
20
21endmenu
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c
index 7c2be3558a24..75089febbc13 100644
--- a/drivers/i2c/busses/i2c-acorn.c
+++ b/drivers/i2c/busses/i2c-acorn.c
@@ -16,7 +16,7 @@
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/i2c-algo-bit.h> 17#include <linux/i2c-algo-bit.h>
18 18
19#include <asm/hardware.h> 19#include <mach/hardware.h>
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/hardware/ioc.h> 21#include <asm/hardware/ioc.h>
22#include <asm/system.h> 22#include <asm/system.h>
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c
index 72872d1e63ef..8ba2bcf727d3 100644
--- a/drivers/i2c/busses/i2c-amd756-s4882.c
+++ b/drivers/i2c/busses/i2c-amd756-s4882.c
@@ -155,6 +155,9 @@ static int __init amd756_s4882_init(void)
155 int i, error; 155 int i, error;
156 union i2c_smbus_data ioconfig; 156 union i2c_smbus_data ioconfig;
157 157
158 if (!amd756_smbus.dev.parent)
159 return -ENODEV;
160
158 /* Configure the PCA9556 multiplexer */ 161 /* Configure the PCA9556 multiplexer */
159 ioconfig.byte = 0x00; /* All I/O to output mode */ 162 ioconfig.byte = 0x00; /* All I/O to output mode */
160 error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, 163 error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
@@ -168,11 +171,7 @@ static int __init amd756_s4882_init(void)
168 /* Unregister physical bus */ 171 /* Unregister physical bus */
169 error = i2c_del_adapter(&amd756_smbus); 172 error = i2c_del_adapter(&amd756_smbus);
170 if (error) { 173 if (error) {
171 if (error == -EINVAL) 174 dev_err(&amd756_smbus.dev, "Physical bus removal failed\n");
172 error = -ENODEV;
173 else
174 dev_err(&amd756_smbus.dev, "Physical bus removal "
175 "failed\n");
176 goto ERROR0; 175 goto ERROR0;
177 } 176 }
178 177
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 73d61946a534..c1adcdbf7979 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -27,9 +27,9 @@
27 27
28#include <asm/io.h> 28#include <asm/io.h>
29 29
30#include <asm/arch/at91_twi.h> 30#include <mach/at91_twi.h>
31#include <asm/arch/board.h> 31#include <mach/board.h>
32#include <asm/arch/cpu.h> 32#include <mach/cpu.h>
33 33
34#define TWI_CLOCK 100000 /* Hz. max 400 Kbits/sec */ 34#define TWI_CLOCK 100000 /* Hz. max 400 Kbits/sec */
35 35
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index af3846eda985..5d7789834b95 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -36,10 +36,9 @@
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/io.h> 37#include <linux/io.h>
38 38
39#include <asm/hardware.h> 39#include <mach/hardware.h>
40#include <asm/mach-types.h>
41 40
42#include <asm/arch/i2c.h> 41#include <mach/i2c.h>
43 42
44/* ----- global defines ----------------------------------------------- */ 43/* ----- global defines ----------------------------------------------- */
45 44
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index 5af9e6521e6c..05d72e981353 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -33,8 +33,8 @@
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/i2c-algo-bit.h> 34#include <linux/i2c-algo-bit.h>
35 35
36#include <asm/hardware.h> /* Pick up IXP2000-specific bits */ 36#include <mach/hardware.h> /* Pick up IXP2000-specific bits */
37#include <asm/arch/gpio.h> 37#include <mach/gpio.h>
38 38
39static inline int ixp2000_scl_pin(void *data) 39static inline int ixp2000_scl_pin(void *data)
40{ 40{
diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c
index d1a4cbcf2aa4..29015eb9ca46 100644
--- a/drivers/i2c/busses/i2c-nforce2-s4985.c
+++ b/drivers/i2c/busses/i2c-nforce2-s4985.c
@@ -150,6 +150,9 @@ static int __init nforce2_s4985_init(void)
150 int i, error; 150 int i, error;
151 union i2c_smbus_data ioconfig; 151 union i2c_smbus_data ioconfig;
152 152
153 if (!nforce2_smbus)
154 return -ENODEV;
155
153 /* Configure the PCA9556 multiplexer */ 156 /* Configure the PCA9556 multiplexer */
154 ioconfig.byte = 0x00; /* All I/O to output mode */ 157 ioconfig.byte = 0x00; /* All I/O to output mode */
155 error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, 158 error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
@@ -161,8 +164,6 @@ static int __init nforce2_s4985_init(void)
161 } 164 }
162 165
163 /* Unregister physical bus */ 166 /* Unregister physical bus */
164 if (!nforce2_smbus)
165 return -ENODEV;
166 error = i2c_del_adapter(nforce2_smbus); 167 error = i2c_del_adapter(nforce2_smbus);
167 if (error) { 168 if (error) {
168 dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n"); 169 dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n");
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 1ca21084ffcf..ec15cff556b9 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -19,7 +19,7 @@
19#include <linux/completion.h> 19#include <linux/completion.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/i2c-pnx.h> 21#include <linux/i2c-pnx.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25 25
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index af9e6034d7fb..44d838410f15 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -34,11 +34,11 @@
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36 36
37#include <asm/hardware.h> 37#include <mach/hardware.h>
38#include <asm/irq.h> 38#include <asm/irq.h>
39#include <asm/io.h> 39#include <asm/io.h>
40#include <asm/arch/i2c.h> 40#include <mach/i2c.h>
41#include <asm/arch/pxa-regs.h> 41#include <mach/pxa-regs.h>
42 42
43struct pxa_i2c { 43struct pxa_i2c {
44 spinlock_t lock; 44 spinlock_t lock;
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 4864723c7425..c772e02c2803 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -35,11 +35,11 @@
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/cpufreq.h> 36#include <linux/cpufreq.h>
37 37
38#include <asm/hardware.h> 38#include <mach/hardware.h>
39#include <asm/irq.h> 39#include <asm/irq.h>
40#include <asm/io.h> 40#include <asm/io.h>
41 41
42#include <asm/arch/regs-gpio.h> 42#include <mach/regs-gpio.h>
43#include <asm/plat-s3c/regs-iic.h> 43#include <asm/plat-s3c/regs-iic.h>
44#include <asm/plat-s3c/iic.h> 44#include <asm/plat-s3c/iic.h>
45 45
diff --git a/drivers/i2c/chips/at24.c b/drivers/i2c/chips/at24.c
index e764c94f3e3d..2a4acb269569 100644
--- a/drivers/i2c/chips/at24.c
+++ b/drivers/i2c/chips/at24.c
@@ -188,7 +188,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
188 count = I2C_SMBUS_BLOCK_MAX; 188 count = I2C_SMBUS_BLOCK_MAX;
189 status = i2c_smbus_read_i2c_block_data(client, offset, 189 status = i2c_smbus_read_i2c_block_data(client, offset,
190 count, buf); 190 count, buf);
191 dev_dbg(&client->dev, "smbus read %zd@%d --> %d\n", 191 dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
192 count, offset, status); 192 count, offset, status);
193 return (status < 0) ? -EIO : status; 193 return (status < 0) ? -EIO : status;
194 } 194 }
@@ -214,7 +214,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
214 msg[1].len = count; 214 msg[1].len = count;
215 215
216 status = i2c_transfer(client->adapter, msg, 2); 216 status = i2c_transfer(client->adapter, msg, 2);
217 dev_dbg(&client->dev, "i2c read %zd@%d --> %d\n", 217 dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
218 count, offset, status); 218 count, offset, status);
219 219
220 if (status == 2) 220 if (status == 2)
@@ -334,7 +334,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
334 if (status == 1) 334 if (status == 1)
335 status = count; 335 status = count;
336 } 336 }
337 dev_dbg(&client->dev, "write %zd@%d --> %zd (%ld)\n", 337 dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n",
338 count, offset, status, jiffies); 338 count, offset, status, jiffies);
339 339
340 if (status == count) 340 if (status == count)
@@ -512,7 +512,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
512 512
513 i2c_set_clientdata(client, at24); 513 i2c_set_clientdata(client, at24);
514 514
515 dev_info(&client->dev, "%Zd byte %s EEPROM %s\n", 515 dev_info(&client->dev, "%zu byte %s EEPROM %s\n",
516 at24->bin.size, client->name, 516 at24->bin.size, client->name,
517 writable ? "(writable)" : "(read-only)"); 517 writable ? "(writable)" : "(read-only)");
518 dev_dbg(&client->dev, 518 dev_dbg(&client->dev,
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index 03a33f1b9cd3..4655b794ebe3 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -33,7 +33,7 @@
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34 34
35#include <asm/irq.h> 35#include <asm/irq.h>
36#include <asm/arch/usb.h> 36#include <mach/usb.h>
37 37
38 38
39#ifndef DEBUG 39#ifndef DEBUG
@@ -94,7 +94,7 @@ struct isp1301 {
94/* board-specific PM hooks */ 94/* board-specific PM hooks */
95 95
96#include <asm/gpio.h> 96#include <asm/gpio.h>
97#include <asm/arch/mux.h> 97#include <mach/mux.h>
98#include <asm/mach-types.h> 98#include <asm/mach-types.h>
99 99
100 100
@@ -1593,7 +1593,7 @@ fail1:
1593 if (machine_is_omap_h2()) { 1593 if (machine_is_omap_h2()) {
1594 /* full speed signaling by default */ 1594 /* full speed signaling by default */
1595 isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, 1595 isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1,
1596 MC1_SPEED_REG); 1596 MC1_SPEED);
1597 isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, 1597 isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2,
1598 MC2_SPD_SUSP_CTRL); 1598 MC2_SPD_SUSP_CTRL);
1599 1599
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index b36db1797c11..176126d3a01d 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -41,11 +41,10 @@
41#include <linux/rtc.h> 41#include <linux/rtc.h>
42#include <linux/bcd.h> 42#include <linux/bcd.h>
43 43
44#include <asm/mach-types.h>
45#include <asm/mach/irq.h> 44#include <asm/mach/irq.h>
46 45
47#include <asm/arch/gpio.h> 46#include <mach/gpio.h>
48#include <asm/arch/menelaus.h> 47#include <mach/menelaus.h>
49 48
50#define DRIVER_NAME "menelaus" 49#define DRIVER_NAME "menelaus"
51 50
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 7bf38c418086..550853f79ae8 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -813,7 +813,12 @@ static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
813int i2c_attach_client(struct i2c_client *client) 813int i2c_attach_client(struct i2c_client *client)
814{ 814{
815 struct i2c_adapter *adapter = client->adapter; 815 struct i2c_adapter *adapter = client->adapter;
816 int res = 0; 816 int res;
817
818 /* Check for address business */
819 res = i2c_check_addr(adapter, client->addr);
820 if (res)
821 return res;
817 822
818 client->dev.parent = &client->adapter->dev; 823 client->dev.parent = &client->adapter->dev;
819 client->dev.bus = &i2c_bus_type; 824 client->dev.bus = &i2c_bus_type;
@@ -1451,9 +1456,11 @@ i2c_new_probed_device(struct i2c_adapter *adap,
1451 if ((addr_list[i] & ~0x07) == 0x30 1456 if ((addr_list[i] & ~0x07) == 0x30
1452 || (addr_list[i] & ~0x0f) == 0x50 1457 || (addr_list[i] & ~0x0f) == 0x50
1453 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) { 1458 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
1459 union i2c_smbus_data data;
1460
1454 if (i2c_smbus_xfer(adap, addr_list[i], 0, 1461 if (i2c_smbus_xfer(adap, addr_list[i], 0,
1455 I2C_SMBUS_READ, 0, 1462 I2C_SMBUS_READ, 0,
1456 I2C_SMBUS_BYTE, NULL) >= 0) 1463 I2C_SMBUS_BYTE, &data) >= 0)
1457 break; 1464 break;
1458 } else { 1465 } else {
1459 if (i2c_smbus_xfer(adap, addr_list[i], 0, 1466 if (i2c_smbus_xfer(adap, addr_list[i], 0,
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 9d55c6383b23..af4491fa7e34 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -147,7 +147,7 @@ static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
147 if (tmp==NULL) 147 if (tmp==NULL)
148 return -ENOMEM; 148 return -ENOMEM;
149 149
150 pr_debug("i2c-dev: i2c-%d reading %zd bytes.\n", 150 pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
151 iminor(file->f_path.dentry->d_inode), count); 151 iminor(file->f_path.dentry->d_inode), count);
152 152
153 ret = i2c_master_recv(client,tmp,count); 153 ret = i2c_master_recv(client,tmp,count);
@@ -175,7 +175,7 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
175 return -EFAULT; 175 return -EFAULT;
176 } 176 }
177 177
178 pr_debug("i2c-dev: i2c-%d writing %zd bytes.\n", 178 pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
179 iminor(file->f_path.dentry->d_inode), count); 179 iminor(file->f_path.dentry->d_inode), count);
180 180
181 ret = i2c_master_send(client,tmp,count); 181 ret = i2c_master_send(client,tmp,count);
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index 176532ffae0e..f728f2927b5a 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -11,13 +11,12 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/ide.h> 12#include <linux/ide.h>
13 13
14#include <asm/mach-types.h>
15#include <asm/irq.h> 14#include <asm/irq.h>
16 15
17#define DRV_NAME "ide_arm" 16#define DRV_NAME "ide_arm"
18 17
19#ifdef CONFIG_ARCH_CLPS7500 18#ifdef CONFIG_ARCH_CLPS7500
20# include <asm/arch/hardware.h> 19# include <mach/hardware.h>
21# 20#
22# define IDE_ARM_IO (ISASLOT_IO + 0x1f0) 21# define IDE_ARM_IO (ISASLOT_IO + 0x1f0)
23# define IDE_ARM_IRQ IRQ_ISA_14 22# define IDE_ARM_IRQ IRQ_ISA_14
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 89a112d513ad..49a8c589e346 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1272,9 +1272,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
1272 */ 1272 */
1273static void msf_from_bcd(struct atapi_msf *msf) 1273static void msf_from_bcd(struct atapi_msf *msf)
1274{ 1274{
1275 msf->minute = BCD2BIN(msf->minute); 1275 msf->minute = bcd2bin(msf->minute);
1276 msf->second = BCD2BIN(msf->second); 1276 msf->second = bcd2bin(msf->second);
1277 msf->frame = BCD2BIN(msf->frame); 1277 msf->frame = bcd2bin(msf->frame);
1278} 1278}
1279 1279
1280int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) 1280int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
@@ -1415,8 +1415,8 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
1415 return stat; 1415 return stat;
1416 1416
1417 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { 1417 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
1418 toc->hdr.first_track = BCD2BIN(toc->hdr.first_track); 1418 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
1419 toc->hdr.last_track = BCD2BIN(toc->hdr.last_track); 1419 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
1420 } 1420 }
1421 1421
1422 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; 1422 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
@@ -1456,8 +1456,8 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
1456 return stat; 1456 return stat;
1457 1457
1458 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { 1458 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
1459 toc->hdr.first_track = (u8)BIN2BCD(CDROM_LEADOUT); 1459 toc->hdr.first_track = (u8)bin2bcd(CDROM_LEADOUT);
1460 toc->hdr.last_track = (u8)BIN2BCD(CDROM_LEADOUT); 1460 toc->hdr.last_track = (u8)bin2bcd(CDROM_LEADOUT);
1461 } else { 1461 } else {
1462 toc->hdr.first_track = CDROM_LEADOUT; 1462 toc->hdr.first_track = CDROM_LEADOUT;
1463 toc->hdr.last_track = CDROM_LEADOUT; 1463 toc->hdr.last_track = CDROM_LEADOUT;
@@ -1470,14 +1470,14 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
1470 toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length); 1470 toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length);
1471 1471
1472 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) { 1472 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
1473 toc->hdr.first_track = BCD2BIN(toc->hdr.first_track); 1473 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
1474 toc->hdr.last_track = BCD2BIN(toc->hdr.last_track); 1474 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
1475 } 1475 }
1476 1476
1477 for (i = 0; i <= ntracks; i++) { 1477 for (i = 0; i <= ntracks; i++) {
1478 if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) { 1478 if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
1479 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) 1479 if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD)
1480 toc->ent[i].track = BCD2BIN(toc->ent[i].track); 1480 toc->ent[i].track = bcd2bin(toc->ent[i].track);
1481 msf_from_bcd(&toc->ent[i].addr.msf); 1481 msf_from_bcd(&toc->ent[i].addr.msf);
1482 } 1482 }
1483 toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute, 1483 toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute,
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 40644b6f1c00..3187215e8f89 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -307,7 +307,7 @@ static struct pci_driver driver = {
307 .name = "AEC62xx_IDE", 307 .name = "AEC62xx_IDE",
308 .id_table = aec62xx_pci_tbl, 308 .id_table = aec62xx_pci_tbl,
309 .probe = aec62xx_init_one, 309 .probe = aec62xx_init_one,
310 .remove = aec62xx_remove, 310 .remove = __devexit_p(aec62xx_remove),
311}; 311};
312 312
313static int __init aec62xx_ide_init(void) 313static int __init aec62xx_ide_init(void)
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index bfae2f882f48..e6d8ee88d56d 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -447,7 +447,7 @@ static struct pci_driver driver = {
447 .name = "Cypress_IDE", 447 .name = "Cypress_IDE",
448 .id_table = cy82c693_pci_tbl, 448 .id_table = cy82c693_pci_tbl,
449 .probe = cy82c693_init_one, 449 .probe = cy82c693_init_one,
450 .remove = cy82c693_remove, 450 .remove = __devexit_p(cy82c693_remove),
451}; 451};
452 452
453static int __init cy82c693_ide_init(void) 453static int __init cy82c693_ide_init(void)
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 748793a413ab..eb107eef0dbc 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1620,7 +1620,7 @@ static struct pci_driver driver = {
1620 .name = "HPT366_IDE", 1620 .name = "HPT366_IDE",
1621 .id_table = hpt366_pci_tbl, 1621 .id_table = hpt366_pci_tbl,
1622 .probe = hpt366_init_one, 1622 .probe = hpt366_init_one,
1623 .remove = hpt366_remove, 1623 .remove = __devexit_p(hpt366_remove),
1624}; 1624};
1625 1625
1626static int __init hpt366_ide_init(void) 1626static int __init hpt366_ide_init(void)
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index b6dc723de702..4a1508a707cc 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -686,7 +686,7 @@ static struct pci_driver driver = {
686 .name = "ITE821x IDE", 686 .name = "ITE821x IDE",
687 .id_table = it821x_pci_tbl, 687 .id_table = it821x_pci_tbl,
688 .probe = it821x_init_one, 688 .probe = it821x_init_one,
689 .remove = it821x_remove, 689 .remove = __devexit_p(it821x_remove),
690}; 690};
691 691
692static int __init it821x_ide_init(void) 692static int __init it821x_ide_init(void)
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 0f609b72f470..d477da6b5858 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -566,7 +566,7 @@ static struct pci_driver driver = {
566 .name = "Promise_IDE", 566 .name = "Promise_IDE",
567 .id_table = pdc202new_pci_tbl, 567 .id_table = pdc202new_pci_tbl,
568 .probe = pdc202new_init_one, 568 .probe = pdc202new_init_one,
569 .remove = pdc202new_remove, 569 .remove = __devexit_p(pdc202new_remove),
570}; 570};
571 571
572static int __init pdc202new_ide_init(void) 572static int __init pdc202new_ide_init(void)
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 6cde48bba6f8..44cccd1e086a 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -954,7 +954,7 @@ static struct pci_driver driver = {
954 .name = "SCC IDE", 954 .name = "SCC IDE",
955 .id_table = scc_pci_tbl, 955 .id_table = scc_pci_tbl,
956 .probe = scc_init_one, 956 .probe = scc_init_one,
957 .remove = scc_remove, 957 .remove = __devexit_p(scc_remove),
958}; 958};
959 959
960static int scc_ide_init(void) 960static int scc_ide_init(void)
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 42eef19a18f1..681306c9d79b 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -621,9 +621,9 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
621 if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, 621 if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
622 DRV_NAME)) { 622 DRV_NAME)) {
623 printk(KERN_ERR 623 printk(KERN_ERR
624 "%s : %s -- ERROR, Addresses " 624 "%s %s: -- ERROR, Addresses "
625 "0x%p to 0x%p ALREADY in use\n", 625 "0x%p to 0x%p ALREADY in use\n",
626 __func__, DRV_NAME, (void *) cmd_phys_base, 626 DRV_NAME, pci_name(dev), (void *)cmd_phys_base,
627 (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); 627 (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
628 return -ENOMEM; 628 return -ENOMEM;
629 } 629 }
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 445ce6fbea33..db2b88a369ab 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -832,7 +832,7 @@ static struct pci_driver driver = {
832 .name = "SiI_IDE", 832 .name = "SiI_IDE",
833 .id_table = siimage_pci_tbl, 833 .id_table = siimage_pci_tbl,
834 .probe = siimage_init_one, 834 .probe = siimage_init_one,
835 .remove = siimage_remove, 835 .remove = __devexit_p(siimage_remove),
836}; 836};
837 837
838static int __init siimage_ide_init(void) 838static int __init siimage_ide_init(void)
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index e5a4b42b4e33..5efe21d6ef97 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -610,7 +610,7 @@ static struct pci_driver driver = {
610 .name = "SIS_IDE", 610 .name = "SIS_IDE",
611 .id_table = sis5513_pci_tbl, 611 .id_table = sis5513_pci_tbl,
612 .probe = sis5513_init_one, 612 .probe = sis5513_init_one,
613 .remove = sis5513_remove, 613 .remove = __devexit_p(sis5513_remove),
614}; 614};
615 615
616static int __init sis5513_ide_init(void) 616static int __init sis5513_ide_init(void)
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 7fc88c375e5d..927277c54ec9 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -249,7 +249,7 @@ static struct pci_driver driver = {
249 .name = "TC86C001", 249 .name = "TC86C001",
250 .id_table = tc86c001_pci_tbl, 250 .id_table = tc86c001_pci_tbl,
251 .probe = tc86c001_init_one, 251 .probe = tc86c001_init_one,
252 .remove = tc86c001_remove, 252 .remove = __devexit_p(tc86c001_remove),
253}; 253};
254 254
255static int __init tc86c001_ide_init(void) 255static int __init tc86c001_ide_init(void)
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index a6b2cc83f293..94fb9ab3223f 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -491,7 +491,7 @@ static struct pci_driver driver = {
491 .name = "VIA_IDE", 491 .name = "VIA_IDE",
492 .id_table = via_pci_tbl, 492 .id_table = via_pci_tbl,
493 .probe = via_init_one, 493 .probe = via_init_one,
494 .remove = via_remove, 494 .remove = __devexit_p(via_remove),
495}; 495};
496 496
497static int __init via_ide_init(void) 497static int __init via_ide_init(void)
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 994a21e5a0aa..16240a789650 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -844,7 +844,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
844 ne->host = host; 844 ne->host = host;
845 ne->nodeid = nodeid; 845 ne->nodeid = nodeid;
846 ne->generation = generation; 846 ne->generation = generation;
847 ne->needs_probe = 1; 847 ne->needs_probe = true;
848 848
849 ne->guid = guid; 849 ne->guid = guid;
850 ne->guid_vendor_id = (guid >> 40) & 0xffffff; 850 ne->guid_vendor_id = (guid >> 40) & 0xffffff;
@@ -1144,7 +1144,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
1144 struct csr1212_keyval *kv, *vendor_name_kv = NULL; 1144 struct csr1212_keyval *kv, *vendor_name_kv = NULL;
1145 u8 last_key_id = 0; 1145 u8 last_key_id = 0;
1146 1146
1147 ne->needs_probe = 0; 1147 ne->needs_probe = false;
1148 1148
1149 csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) { 1149 csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) {
1150 switch (kv->key.id) { 1150 switch (kv->key.id) {
@@ -1295,7 +1295,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
1295 nodemgr_update_bus_options(ne); 1295 nodemgr_update_bus_options(ne);
1296 1296
1297 /* Mark the node as new, so it gets re-probed */ 1297 /* Mark the node as new, so it gets re-probed */
1298 ne->needs_probe = 1; 1298 ne->needs_probe = true;
1299 } else { 1299 } else {
1300 /* old cache is valid, so update its generation */ 1300 /* old cache is valid, so update its generation */
1301 struct nodemgr_csr_info *ci = ne->csr->private; 1301 struct nodemgr_csr_info *ci = ne->csr->private;
@@ -1566,57 +1566,60 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
1566struct probe_param { 1566struct probe_param {
1567 struct host_info *hi; 1567 struct host_info *hi;
1568 int generation; 1568 int generation;
1569 bool probe_now;
1569}; 1570};
1570 1571
1571static int __nodemgr_node_probe(struct device *dev, void *data) 1572static int node_probe(struct device *dev, void *data)
1572{ 1573{
1573 struct probe_param *param = (struct probe_param *)data; 1574 struct probe_param *p = data;
1574 struct node_entry *ne; 1575 struct node_entry *ne;
1575 1576
1577 if (p->generation != get_hpsb_generation(p->hi->host))
1578 return -EAGAIN;
1579
1576 ne = container_of(dev, struct node_entry, node_dev); 1580 ne = container_of(dev, struct node_entry, node_dev);
1577 if (!ne->needs_probe) 1581 if (ne->needs_probe == p->probe_now)
1578 nodemgr_probe_ne(param->hi, ne, param->generation); 1582 nodemgr_probe_ne(p->hi, ne, p->generation);
1579 if (ne->needs_probe)
1580 nodemgr_probe_ne(param->hi, ne, param->generation);
1581 return 0; 1583 return 0;
1582} 1584}
1583 1585
1584static void nodemgr_node_probe(struct host_info *hi, int generation) 1586static void nodemgr_node_probe(struct host_info *hi, int generation)
1585{ 1587{
1586 struct hpsb_host *host = hi->host; 1588 struct probe_param p;
1587 struct probe_param param;
1588 1589
1589 param.hi = hi; 1590 p.hi = hi;
1590 param.generation = generation; 1591 p.generation = generation;
1591 /* Do some processing of the nodes we've probed. This pulls them 1592 /*
1593 * Do some processing of the nodes we've probed. This pulls them
1592 * into the sysfs layer if needed, and can result in processing of 1594 * into the sysfs layer if needed, and can result in processing of
1593 * unit-directories, or just updating the node and it's 1595 * unit-directories, or just updating the node and it's
1594 * unit-directories. 1596 * unit-directories.
1595 * 1597 *
1596 * Run updates before probes. Usually, updates are time-critical 1598 * Run updates before probes. Usually, updates are time-critical
1597 * while probes are time-consuming. (Well, those probes need some 1599 * while probes are time-consuming.
1598 * improvement...) */
1599
1600 class_for_each_device(&nodemgr_ne_class, NULL, &param,
1601 __nodemgr_node_probe);
1602
1603 /* If we had a bus reset while we were scanning the bus, it is
1604 * possible that we did not probe all nodes. In that case, we
1605 * skip the clean up for now, since we could remove nodes that
1606 * were still on the bus. Another bus scan is pending which will
1607 * do the clean up eventually.
1608 * 1600 *
1601 * Meanwhile, another bus reset may have happened. In this case we
1602 * skip everything here and let the next bus scan handle it.
1603 * Otherwise we may prematurely remove nodes which are still there.
1604 */
1605 p.probe_now = false;
1606 if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
1607 return;
1608
1609 p.probe_now = true;
1610 if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
1611 return;
1612 /*
1609 * Now let's tell the bus to rescan our devices. This may seem 1613 * Now let's tell the bus to rescan our devices. This may seem
1610 * like overhead, but the driver-model core will only scan a 1614 * like overhead, but the driver-model core will only scan a
1611 * device for a driver when either the device is added, or when a 1615 * device for a driver when either the device is added, or when a
1612 * new driver is added. A bus reset is a good reason to rescan 1616 * new driver is added. A bus reset is a good reason to rescan
1613 * devices that were there before. For example, an sbp2 device 1617 * devices that were there before. For example, an sbp2 device
1614 * may become available for login, if the host that held it was 1618 * may become available for login, if the host that held it was
1615 * just removed. */ 1619 * just removed.
1616 1620 */
1617 if (generation == get_hpsb_generation(host)) 1621 if (bus_rescan_devices(&ieee1394_bus_type) != 0)
1618 if (bus_rescan_devices(&ieee1394_bus_type)) 1622 HPSB_DEBUG("bus_rescan_devices had an error");
1619 HPSB_DEBUG("bus_rescan_devices had an error");
1620} 1623}
1621 1624
1622static int nodemgr_send_resume_packet(struct hpsb_host *host) 1625static int nodemgr_send_resume_packet(struct hpsb_host *host)
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 919e92e2a955..6eb26465a84c 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -97,7 +97,7 @@ struct node_entry {
97 struct hpsb_host *host; /* Host this node is attached to */ 97 struct hpsb_host *host; /* Host this node is attached to */
98 nodeid_t nodeid; /* NodeID */ 98 nodeid_t nodeid; /* NodeID */
99 struct bus_options busopt; /* Bus Options */ 99 struct bus_options busopt; /* Bus Options */
100 int needs_probe; 100 bool needs_probe;
101 unsigned int generation; /* Synced with hpsb generation */ 101 unsigned int generation; /* Synced with hpsb generation */
102 102
103 /* The following is read from the config rom */ 103 /* The following is read from the config rom */
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 9cbf3154d243..1d6ad3435537 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -731,15 +731,26 @@ static int sbp2_update(struct unit_directory *ud)
731{ 731{
732 struct sbp2_lu *lu = ud->device.driver_data; 732 struct sbp2_lu *lu = ud->device.driver_data;
733 733
734 if (sbp2_reconnect_device(lu)) { 734 if (sbp2_reconnect_device(lu) != 0) {
735 /* Reconnect has failed. Perhaps we didn't reconnect fast 735 /*
736 * enough. Try a regular login, but first log out just in 736 * Reconnect failed. If another bus reset happened,
737 * case of any weirdness. */ 737 * let nodemgr proceed and call sbp2_update again later
738 * (or sbp2_remove if this node went away).
739 */
740 if (!hpsb_node_entry_valid(lu->ne))
741 return 0;
742 /*
743 * Or the target rejected the reconnect because we weren't
744 * fast enough. Try a regular login, but first log out
745 * just in case of any weirdness.
746 */
738 sbp2_logout_device(lu); 747 sbp2_logout_device(lu);
739 748
740 if (sbp2_login_device(lu)) { 749 if (sbp2_login_device(lu) != 0) {
741 /* Login failed too, just fail, and the backend 750 if (!hpsb_node_entry_valid(lu->ne))
742 * will call our sbp2_remove for us */ 751 return 0;
752
753 /* Maybe another initiator won the login. */
743 SBP2_ERR("Failed to reconnect to sbp2 device!"); 754 SBP2_ERR("Failed to reconnect to sbp2 device!");
744 return -EBUSY; 755 return -EBUSY;
745 } 756 }
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index e980ff3335db..d951896ff7fc 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -155,9 +155,7 @@ struct cma_multicast {
155 } multicast; 155 } multicast;
156 struct list_head list; 156 struct list_head list;
157 void *context; 157 void *context;
158 struct sockaddr addr; 158 struct sockaddr_storage addr;
159 u8 pad[sizeof(struct sockaddr_in6) -
160 sizeof(struct sockaddr)];
161}; 159};
162 160
163struct cma_work { 161struct cma_work {
@@ -786,8 +784,8 @@ static void cma_cancel_operation(struct rdma_id_private *id_priv,
786 cma_cancel_route(id_priv); 784 cma_cancel_route(id_priv);
787 break; 785 break;
788 case CMA_LISTEN: 786 case CMA_LISTEN:
789 if (cma_any_addr(&id_priv->id.route.addr.src_addr) && 787 if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)
790 !id_priv->cma_dev) 788 && !id_priv->cma_dev)
791 cma_cancel_listens(id_priv); 789 cma_cancel_listens(id_priv);
792 break; 790 break;
793 default: 791 default:
@@ -1026,7 +1024,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
1026 rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; 1024 rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path;
1027 1025
1028 ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); 1026 ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
1029 ret = rdma_translate_ip(&id->route.addr.src_addr, 1027 ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr,
1030 &id->route.addr.dev_addr); 1028 &id->route.addr.dev_addr);
1031 if (ret) 1029 if (ret)
1032 goto destroy_id; 1030 goto destroy_id;
@@ -1064,7 +1062,7 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
1064 cma_save_net_info(&id->route.addr, &listen_id->route.addr, 1062 cma_save_net_info(&id->route.addr, &listen_id->route.addr,
1065 ip_ver, port, src, dst); 1063 ip_ver, port, src, dst);
1066 1064
1067 ret = rdma_translate_ip(&id->route.addr.src_addr, 1065 ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr,
1068 &id->route.addr.dev_addr); 1066 &id->route.addr.dev_addr);
1069 if (ret) 1067 if (ret)
1070 goto err; 1068 goto err;
@@ -1377,7 +1375,7 @@ static int cma_ib_listen(struct rdma_id_private *id_priv)
1377 if (IS_ERR(id_priv->cm_id.ib)) 1375 if (IS_ERR(id_priv->cm_id.ib))
1378 return PTR_ERR(id_priv->cm_id.ib); 1376 return PTR_ERR(id_priv->cm_id.ib);
1379 1377
1380 addr = &id_priv->id.route.addr.src_addr; 1378 addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
1381 svc_id = cma_get_service_id(id_priv->id.ps, addr); 1379 svc_id = cma_get_service_id(id_priv->id.ps, addr);
1382 if (cma_any_addr(addr)) 1380 if (cma_any_addr(addr))
1383 ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL); 1381 ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL);
@@ -1443,7 +1441,7 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv,
1443 1441
1444 dev_id_priv->state = CMA_ADDR_BOUND; 1442 dev_id_priv->state = CMA_ADDR_BOUND;
1445 memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr, 1443 memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr,
1446 ip_addr_size(&id_priv->id.route.addr.src_addr)); 1444 ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr));
1447 1445
1448 cma_attach_to_dev(dev_id_priv, cma_dev); 1446 cma_attach_to_dev(dev_id_priv, cma_dev);
1449 list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list); 1447 list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list);
@@ -1563,13 +1561,14 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
1563 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); 1561 path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr));
1564 path_rec.numb_path = 1; 1562 path_rec.numb_path = 1;
1565 path_rec.reversible = 1; 1563 path_rec.reversible = 1;
1566 path_rec.service_id = cma_get_service_id(id_priv->id.ps, &addr->dst_addr); 1564 path_rec.service_id = cma_get_service_id(id_priv->id.ps,
1565 (struct sockaddr *) &addr->dst_addr);
1567 1566
1568 comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | 1567 comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
1569 IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | 1568 IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
1570 IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; 1569 IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID;
1571 1570
1572 if (addr->src_addr.sa_family == AF_INET) { 1571 if (addr->src_addr.ss_family == AF_INET) {
1573 path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); 1572 path_rec.qos_class = cpu_to_be16((u16) id_priv->tos);
1574 comp_mask |= IB_SA_PATH_REC_QOS_CLASS; 1573 comp_mask |= IB_SA_PATH_REC_QOS_CLASS;
1575 } else { 1574 } else {
@@ -1848,7 +1847,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv)
1848 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); 1847 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid);
1849 ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); 1848 ib_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid);
1850 1849
1851 if (cma_zero_addr(&id_priv->id.route.addr.src_addr)) { 1850 if (cma_zero_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) {
1852 src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr; 1851 src_in = (struct sockaddr_in *)&id_priv->id.route.addr.src_addr;
1853 dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr; 1852 dst_in = (struct sockaddr_in *)&id_priv->id.route.addr.dst_addr;
1854 src_in->sin_family = dst_in->sin_family; 1853 src_in->sin_family = dst_in->sin_family;
@@ -1897,7 +1896,7 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
1897 if (cma_any_addr(dst_addr)) 1896 if (cma_any_addr(dst_addr))
1898 ret = cma_resolve_loopback(id_priv); 1897 ret = cma_resolve_loopback(id_priv);
1899 else 1898 else
1900 ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr, 1899 ret = rdma_resolve_ip(&addr_client, (struct sockaddr *) &id->route.addr.src_addr,
1901 dst_addr, &id->route.addr.dev_addr, 1900 dst_addr, &id->route.addr.dev_addr,
1902 timeout_ms, addr_handler, id_priv); 1901 timeout_ms, addr_handler, id_priv);
1903 if (ret) 1902 if (ret)
@@ -2021,11 +2020,11 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
2021 * We don't support binding to any address if anyone is bound to 2020 * We don't support binding to any address if anyone is bound to
2022 * a specific address on the same port. 2021 * a specific address on the same port.
2023 */ 2022 */
2024 if (cma_any_addr(&id_priv->id.route.addr.src_addr)) 2023 if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr))
2025 return -EADDRNOTAVAIL; 2024 return -EADDRNOTAVAIL;
2026 2025
2027 hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { 2026 hlist_for_each_entry(cur_id, node, &bind_list->owners, node) {
2028 if (cma_any_addr(&cur_id->id.route.addr.src_addr)) 2027 if (cma_any_addr((struct sockaddr *) &cur_id->id.route.addr.src_addr))
2029 return -EADDRNOTAVAIL; 2028 return -EADDRNOTAVAIL;
2030 2029
2031 cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; 2030 cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr;
@@ -2060,7 +2059,7 @@ static int cma_get_port(struct rdma_id_private *id_priv)
2060 } 2059 }
2061 2060
2062 mutex_lock(&lock); 2061 mutex_lock(&lock);
2063 if (cma_any_port(&id_priv->id.route.addr.src_addr)) 2062 if (cma_any_port((struct sockaddr *) &id_priv->id.route.addr.src_addr))
2064 ret = cma_alloc_any_port(ps, id_priv); 2063 ret = cma_alloc_any_port(ps, id_priv);
2065 else 2064 else
2066 ret = cma_use_port(ps, id_priv); 2065 ret = cma_use_port(ps, id_priv);
@@ -2232,7 +2231,7 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
2232 2231
2233 req.path = route->path_rec; 2232 req.path = route->path_rec;
2234 req.service_id = cma_get_service_id(id_priv->id.ps, 2233 req.service_id = cma_get_service_id(id_priv->id.ps,
2235 &route->addr.dst_addr); 2234 (struct sockaddr *) &route->addr.dst_addr);
2236 req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8); 2235 req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8);
2237 req.max_cm_retries = CMA_MAX_CM_RETRIES; 2236 req.max_cm_retries = CMA_MAX_CM_RETRIES;
2238 2237
@@ -2283,7 +2282,7 @@ static int cma_connect_ib(struct rdma_id_private *id_priv,
2283 req.alternate_path = &route->path_rec[1]; 2282 req.alternate_path = &route->path_rec[1];
2284 2283
2285 req.service_id = cma_get_service_id(id_priv->id.ps, 2284 req.service_id = cma_get_service_id(id_priv->id.ps,
2286 &route->addr.dst_addr); 2285 (struct sockaddr *) &route->addr.dst_addr);
2287 req.qp_num = id_priv->qp_num; 2286 req.qp_num = id_priv->qp_num;
2288 req.qp_type = IB_QPT_RC; 2287 req.qp_type = IB_QPT_RC;
2289 req.starting_psn = id_priv->seq_num; 2288 req.starting_psn = id_priv->seq_num;
@@ -2667,7 +2666,7 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
2667 if (ret) 2666 if (ret)
2668 return ret; 2667 return ret;
2669 2668
2670 cma_set_mgid(id_priv, &mc->addr, &rec.mgid); 2669 cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid);
2671 if (id_priv->id.ps == RDMA_PS_UDP) 2670 if (id_priv->id.ps == RDMA_PS_UDP)
2672 rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); 2671 rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
2673 ib_addr_get_sgid(dev_addr, &rec.port_gid); 2672 ib_addr_get_sgid(dev_addr, &rec.port_gid);
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index d0ef7d61c037..3af2b84cd838 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -133,7 +133,7 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
133 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, 133 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
134 recv_wc->wc->pkey_index, 1, hdr_len, 134 recv_wc->wc->pkey_index, 1, hdr_len,
135 0, GFP_KERNEL); 135 0, GFP_KERNEL);
136 if (!msg) 136 if (IS_ERR(msg))
137 return; 137 return;
138 138
139 format_ack(msg, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv); 139 format_ack(msg, (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv);
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index b41dd26bbfa1..3ddacf39b7ba 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -81,9 +81,7 @@ struct ucma_multicast {
81 81
82 u64 uid; 82 u64 uid;
83 struct list_head list; 83 struct list_head list;
84 struct sockaddr addr; 84 struct sockaddr_storage addr;
85 u8 pad[sizeof(struct sockaddr_in6) -
86 sizeof(struct sockaddr)];
87}; 85};
88 86
89struct ucma_event { 87struct ucma_event {
@@ -603,11 +601,11 @@ static ssize_t ucma_query_route(struct ucma_file *file,
603 return PTR_ERR(ctx); 601 return PTR_ERR(ctx);
604 602
605 memset(&resp, 0, sizeof resp); 603 memset(&resp, 0, sizeof resp);
606 addr = &ctx->cm_id->route.addr.src_addr; 604 addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr;
607 memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ? 605 memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ?
608 sizeof(struct sockaddr_in) : 606 sizeof(struct sockaddr_in) :
609 sizeof(struct sockaddr_in6)); 607 sizeof(struct sockaddr_in6));
610 addr = &ctx->cm_id->route.addr.dst_addr; 608 addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr;
611 memcpy(&resp.dst_addr, addr, addr->sa_family == AF_INET ? 609 memcpy(&resp.dst_addr, addr, addr->sa_family == AF_INET ?
612 sizeof(struct sockaddr_in) : 610 sizeof(struct sockaddr_in) :
613 sizeof(struct sockaddr_in6)); 611 sizeof(struct sockaddr_in6));
@@ -913,7 +911,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,
913 911
914 mc->uid = cmd.uid; 912 mc->uid = cmd.uid;
915 memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr); 913 memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
916 ret = rdma_join_multicast(ctx->cm_id, &mc->addr, mc); 914 ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc);
917 if (ret) 915 if (ret)
918 goto err2; 916 goto err2;
919 917
@@ -929,7 +927,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,
929 return 0; 927 return 0;
930 928
931err3: 929err3:
932 rdma_leave_multicast(ctx->cm_id, &mc->addr); 930 rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr);
933 ucma_cleanup_mc_events(mc); 931 ucma_cleanup_mc_events(mc);
934err2: 932err2:
935 mutex_lock(&mut); 933 mutex_lock(&mut);
@@ -975,7 +973,7 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file,
975 goto out; 973 goto out;
976 } 974 }
977 975
978 rdma_leave_multicast(mc->ctx->cm_id, &mc->addr); 976 rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr);
979 mutex_lock(&mc->ctx->file->mut); 977 mutex_lock(&mc->ctx->file->mut);
980 ucma_cleanup_mc_events(mc); 978 ucma_cleanup_mc_events(mc);
981 list_del(&mc->list); 979 list_del(&mc->list);
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index f6d5747153a5..4dcf08b3fd83 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -725,9 +725,9 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
725 V_TPT_STAG_TYPE(type) | V_TPT_PDID(pdid)); 725 V_TPT_STAG_TYPE(type) | V_TPT_PDID(pdid));
726 BUG_ON(page_size >= 28); 726 BUG_ON(page_size >= 28);
727 tpt.flags_pagesize_qpid = cpu_to_be32(V_TPT_PERM(perm) | 727 tpt.flags_pagesize_qpid = cpu_to_be32(V_TPT_PERM(perm) |
728 F_TPT_MW_BIND_ENABLE | 728 ((perm & TPT_MW_BIND) ? F_TPT_MW_BIND_ENABLE : 0) |
729 V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) | 729 V_TPT_ADDR_TYPE((zbva ? TPT_ZBTO : TPT_VATO)) |
730 V_TPT_PAGE_SIZE(page_size)); 730 V_TPT_PAGE_SIZE(page_size));
731 tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 : 731 tpt.rsvd_pbl_addr = reset_tpt_entry ? 0 :
732 cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3)); 732 cpu_to_be32(V_TPT_PBL_ADDR(PBL_OFF(rdev_p, pbl_addr)>>3));
733 tpt.len = cpu_to_be32(len); 733 tpt.len = cpu_to_be32(len);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index b89640aa6e10..eb778bfd6f66 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -1187,28 +1187,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
1187 return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type); 1187 return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type);
1188} 1188}
1189 1189
1190static int fw_supports_fastreg(struct iwch_dev *iwch_dev)
1191{
1192 struct ethtool_drvinfo info;
1193 struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
1194 char *cp, *next;
1195 unsigned fw_maj, fw_min;
1196
1197 rtnl_lock();
1198 lldev->ethtool_ops->get_drvinfo(lldev, &info);
1199 rtnl_unlock();
1200
1201 next = info.fw_version+1;
1202 cp = strsep(&next, ".");
1203 sscanf(cp, "%i", &fw_maj);
1204 cp = strsep(&next, ".");
1205 sscanf(cp, "%i", &fw_min);
1206
1207 PDBG("%s maj %u min %u\n", __func__, fw_maj, fw_min);
1208
1209 return fw_maj > 6 || (fw_maj == 6 && fw_min > 0);
1210}
1211
1212static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf) 1190static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf)
1213{ 1191{
1214 struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev, 1192 struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
@@ -1325,12 +1303,12 @@ int iwch_register_device(struct iwch_dev *dev)
1325 memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); 1303 memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid));
1326 memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6); 1304 memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6);
1327 dev->ibdev.owner = THIS_MODULE; 1305 dev->ibdev.owner = THIS_MODULE;
1328 dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY | IB_DEVICE_MEM_WINDOW; 1306 dev->device_cap_flags = IB_DEVICE_LOCAL_DMA_LKEY |
1307 IB_DEVICE_MEM_WINDOW |
1308 IB_DEVICE_MEM_MGT_EXTENSIONS;
1329 1309
1330 /* cxgb3 supports STag 0. */ 1310 /* cxgb3 supports STag 0. */
1331 dev->ibdev.local_dma_lkey = 0; 1311 dev->ibdev.local_dma_lkey = 0;
1332 if (fw_supports_fastreg(dev))
1333 dev->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
1334 1312
1335 dev->ibdev.uverbs_cmd_mask = 1313 dev->ibdev.uverbs_cmd_mask =
1336 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | 1314 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h
index f5ceca05c435..a237d49bdcc9 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h
@@ -293,9 +293,16 @@ static inline u32 iwch_ib_to_tpt_access(int acc)
293 return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) | 293 return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) |
294 (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0) | 294 (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0) |
295 (acc & IB_ACCESS_LOCAL_WRITE ? TPT_LOCAL_WRITE : 0) | 295 (acc & IB_ACCESS_LOCAL_WRITE ? TPT_LOCAL_WRITE : 0) |
296 (acc & IB_ACCESS_MW_BIND ? TPT_MW_BIND : 0) |
296 TPT_LOCAL_READ; 297 TPT_LOCAL_READ;
297} 298}
298 299
300static inline u32 iwch_ib_to_tpt_bind_access(int acc)
301{
302 return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) |
303 (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0);
304}
305
299enum iwch_mmid_state { 306enum iwch_mmid_state {
300 IWCH_STAG_STATE_VALID, 307 IWCH_STAG_STATE_VALID,
301 IWCH_STAG_STATE_INVALID 308 IWCH_STAG_STATE_INVALID
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 9a3be3a9d5dc..3e4585c2318a 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -565,7 +565,7 @@ int iwch_bind_mw(struct ib_qp *qp,
565 wqe->bind.type = TPT_VATO; 565 wqe->bind.type = TPT_VATO;
566 566
567 /* TBD: check perms */ 567 /* TBD: check perms */
568 wqe->bind.perms = iwch_ib_to_tpt_access(mw_bind->mw_access_flags); 568 wqe->bind.perms = iwch_ib_to_tpt_bind_access(mw_bind->mw_access_flags);
569 wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey); 569 wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey);
570 wqe->bind.mw_stag = cpu_to_be32(mw->rkey); 570 wqe->bind.mw_stag = cpu_to_be32(mw->rkey);
571 wqe->bind.mw_len = cpu_to_be32(mw_bind->length); 571 wqe->bind.mw_len = cpu_to_be32(mw_bind->length);
@@ -879,20 +879,13 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp,
879 (qhp->attr.mpa_attr.xmit_marker_enabled << 1) | 879 (qhp->attr.mpa_attr.xmit_marker_enabled << 1) |
880 (qhp->attr.mpa_attr.crc_enabled << 2); 880 (qhp->attr.mpa_attr.crc_enabled << 2);
881 881
882 /* 882 init_attr.qpcaps = uP_RI_QP_RDMA_READ_ENABLE |
883 * XXX - The IWCM doesn't quite handle getting these 883 uP_RI_QP_RDMA_WRITE_ENABLE |
884 * attrs set before going into RTS. For now, just turn 884 uP_RI_QP_BIND_ENABLE;
885 * them on always... 885 if (!qhp->ibqp.uobject)
886 */ 886 init_attr.qpcaps |= uP_RI_QP_STAG0_ENABLE |
887#if 0 887 uP_RI_QP_FAST_REGISTER_ENABLE;
888 init_attr.qpcaps = qhp->attr.enableRdmaRead | 888
889 (qhp->attr.enableRdmaWrite << 1) |
890 (qhp->attr.enableBind << 2) |
891 (qhp->attr.enable_stag0_fastreg << 3) |
892 (qhp->attr.enable_stag0_fastreg << 4);
893#else
894 init_attr.qpcaps = 0x1f;
895#endif
896 init_attr.tcp_emss = qhp->ep->emss; 889 init_attr.tcp_emss = qhp->ep->emss;
897 init_attr.ord = qhp->attr.max_ord; 890 init_attr.ord = qhp->attr.max_ord;
898 init_attr.ird = qhp->attr.max_ird; 891 init_attr.ird = qhp->attr.max_ird;
@@ -900,8 +893,6 @@ static int rdma_init(struct iwch_dev *rhp, struct iwch_qp *qhp,
900 init_attr.qp_dma_size = (1UL << qhp->wq.size_log2); 893 init_attr.qp_dma_size = (1UL << qhp->wq.size_log2);
901 init_attr.rqe_count = iwch_rqes_posted(qhp); 894 init_attr.rqe_count = iwch_rqes_posted(qhp);
902 init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0; 895 init_attr.flags = qhp->attr.mpa_attr.initiator ? MPA_INITIATOR : 0;
903 if (!qhp->ibqp.uobject)
904 init_attr.flags |= PRIV_QP;
905 if (peer2peer) { 896 if (peer2peer) {
906 init_attr.rtr_type = RTR_READ; 897 init_attr.rtr_type = RTR_READ;
907 if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator) 898 if (init_attr.ord == 0 && qhp->attr.mpa_attr.initiator)
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 0b0618edd645..1ab919f836a8 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -156,6 +156,14 @@ struct ehca_mod_qp_parm {
156 156
157#define EHCA_MOD_QP_PARM_MAX 4 157#define EHCA_MOD_QP_PARM_MAX 4
158 158
159#define QMAP_IDX_MASK 0xFFFFULL
160
161/* struct for tracking if cqes have been reported to the application */
162struct ehca_qmap_entry {
163 u16 app_wr_id;
164 u16 reported;
165};
166
159struct ehca_qp { 167struct ehca_qp {
160 union { 168 union {
161 struct ib_qp ib_qp; 169 struct ib_qp ib_qp;
@@ -165,6 +173,7 @@ struct ehca_qp {
165 enum ehca_ext_qp_type ext_type; 173 enum ehca_ext_qp_type ext_type;
166 enum ib_qp_state state; 174 enum ib_qp_state state;
167 struct ipz_queue ipz_squeue; 175 struct ipz_queue ipz_squeue;
176 struct ehca_qmap_entry *sq_map;
168 struct ipz_queue ipz_rqueue; 177 struct ipz_queue ipz_rqueue;
169 struct h_galpas galpas; 178 struct h_galpas galpas;
170 u32 qkey; 179 u32 qkey;
diff --git a/drivers/infiniband/hw/ehca/ehca_qes.h b/drivers/infiniband/hw/ehca/ehca_qes.h
index 818803057ebf..5d28e3e98a20 100644
--- a/drivers/infiniband/hw/ehca/ehca_qes.h
+++ b/drivers/infiniband/hw/ehca/ehca_qes.h
@@ -213,6 +213,7 @@ struct ehca_wqe {
213#define WC_STATUS_ERROR_BIT 0x80000000 213#define WC_STATUS_ERROR_BIT 0x80000000
214#define WC_STATUS_REMOTE_ERROR_FLAGS 0x0000F800 214#define WC_STATUS_REMOTE_ERROR_FLAGS 0x0000F800
215#define WC_STATUS_PURGE_BIT 0x10 215#define WC_STATUS_PURGE_BIT 0x10
216#define WC_SEND_RECEIVE_BIT 0x80
216 217
217struct ehca_cqe { 218struct ehca_cqe {
218 u64 work_request_id; 219 u64 work_request_id;
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index ea13efddf175..b6bcee036734 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -412,6 +412,7 @@ static struct ehca_qp *internal_create_qp(
412 struct ehca_shca *shca = container_of(pd->device, struct ehca_shca, 412 struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
413 ib_device); 413 ib_device);
414 struct ib_ucontext *context = NULL; 414 struct ib_ucontext *context = NULL;
415 u32 nr_qes;
415 u64 h_ret; 416 u64 h_ret;
416 int is_llqp = 0, has_srq = 0; 417 int is_llqp = 0, has_srq = 0;
417 int qp_type, max_send_sge, max_recv_sge, ret; 418 int qp_type, max_send_sge, max_recv_sge, ret;
@@ -715,6 +716,15 @@ static struct ehca_qp *internal_create_qp(
715 "and pages ret=%i", ret); 716 "and pages ret=%i", ret);
716 goto create_qp_exit2; 717 goto create_qp_exit2;
717 } 718 }
719 nr_qes = my_qp->ipz_squeue.queue_length /
720 my_qp->ipz_squeue.qe_size;
721 my_qp->sq_map = vmalloc(nr_qes *
722 sizeof(struct ehca_qmap_entry));
723 if (!my_qp->sq_map) {
724 ehca_err(pd->device, "Couldn't allocate squeue "
725 "map ret=%i", ret);
726 goto create_qp_exit3;
727 }
718 } 728 }
719 729
720 if (HAS_RQ(my_qp)) { 730 if (HAS_RQ(my_qp)) {
@@ -724,7 +734,7 @@ static struct ehca_qp *internal_create_qp(
724 if (ret) { 734 if (ret) {
725 ehca_err(pd->device, "Couldn't initialize rqueue " 735 ehca_err(pd->device, "Couldn't initialize rqueue "
726 "and pages ret=%i", ret); 736 "and pages ret=%i", ret);
727 goto create_qp_exit3; 737 goto create_qp_exit4;
728 } 738 }
729 } 739 }
730 740
@@ -770,7 +780,7 @@ static struct ehca_qp *internal_create_qp(
770 if (!my_qp->mod_qp_parm) { 780 if (!my_qp->mod_qp_parm) {
771 ehca_err(pd->device, 781 ehca_err(pd->device,
772 "Could not alloc mod_qp_parm"); 782 "Could not alloc mod_qp_parm");
773 goto create_qp_exit4; 783 goto create_qp_exit5;
774 } 784 }
775 } 785 }
776 } 786 }
@@ -780,7 +790,7 @@ static struct ehca_qp *internal_create_qp(
780 h_ret = ehca_define_sqp(shca, my_qp, init_attr); 790 h_ret = ehca_define_sqp(shca, my_qp, init_attr);
781 if (h_ret != H_SUCCESS) { 791 if (h_ret != H_SUCCESS) {
782 ret = ehca2ib_return_code(h_ret); 792 ret = ehca2ib_return_code(h_ret);
783 goto create_qp_exit5; 793 goto create_qp_exit6;
784 } 794 }
785 } 795 }
786 796
@@ -789,7 +799,7 @@ static struct ehca_qp *internal_create_qp(
789 if (ret) { 799 if (ret) {
790 ehca_err(pd->device, 800 ehca_err(pd->device,
791 "Couldn't assign qp to send_cq ret=%i", ret); 801 "Couldn't assign qp to send_cq ret=%i", ret);
792 goto create_qp_exit5; 802 goto create_qp_exit6;
793 } 803 }
794 } 804 }
795 805
@@ -815,22 +825,26 @@ static struct ehca_qp *internal_create_qp(
815 if (ib_copy_to_udata(udata, &resp, sizeof resp)) { 825 if (ib_copy_to_udata(udata, &resp, sizeof resp)) {
816 ehca_err(pd->device, "Copy to udata failed"); 826 ehca_err(pd->device, "Copy to udata failed");
817 ret = -EINVAL; 827 ret = -EINVAL;
818 goto create_qp_exit6; 828 goto create_qp_exit7;
819 } 829 }
820 } 830 }
821 831
822 return my_qp; 832 return my_qp;
823 833
824create_qp_exit6: 834create_qp_exit7:
825 ehca_cq_unassign_qp(my_qp->send_cq, my_qp->real_qp_num); 835 ehca_cq_unassign_qp(my_qp->send_cq, my_qp->real_qp_num);
826 836
827create_qp_exit5: 837create_qp_exit6:
828 kfree(my_qp->mod_qp_parm); 838 kfree(my_qp->mod_qp_parm);
829 839
830create_qp_exit4: 840create_qp_exit5:
831 if (HAS_RQ(my_qp)) 841 if (HAS_RQ(my_qp))
832 ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); 842 ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
833 843
844create_qp_exit4:
845 if (HAS_SQ(my_qp))
846 vfree(my_qp->sq_map);
847
834create_qp_exit3: 848create_qp_exit3:
835 if (HAS_SQ(my_qp)) 849 if (HAS_SQ(my_qp))
836 ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); 850 ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
@@ -1534,8 +1548,6 @@ static int internal_modify_qp(struct ib_qp *ibqp,
1534 if (attr_mask & IB_QP_QKEY) 1548 if (attr_mask & IB_QP_QKEY)
1535 my_qp->qkey = attr->qkey; 1549 my_qp->qkey = attr->qkey;
1536 1550
1537 my_qp->state = qp_new_state;
1538
1539modify_qp_exit2: 1551modify_qp_exit2:
1540 if (squeue_locked) { /* this means: sqe -> rts */ 1552 if (squeue_locked) { /* this means: sqe -> rts */
1541 spin_unlock_irqrestore(&my_qp->spinlock_s, flags); 1553 spin_unlock_irqrestore(&my_qp->spinlock_s, flags);
@@ -1551,6 +1563,8 @@ modify_qp_exit1:
1551int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, 1563int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
1552 struct ib_udata *udata) 1564 struct ib_udata *udata)
1553{ 1565{
1566 int ret = 0;
1567
1554 struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca, 1568 struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
1555 ib_device); 1569 ib_device);
1556 struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp); 1570 struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
@@ -1597,12 +1611,18 @@ int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
1597 attr->qp_state, my_qp->init_attr.port_num, 1611 attr->qp_state, my_qp->init_attr.port_num,
1598 ibqp->qp_type); 1612 ibqp->qp_type);
1599 spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); 1613 spin_unlock_irqrestore(&sport->mod_sqp_lock, flags);
1600 return 0; 1614 goto out;
1601 } 1615 }
1602 spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); 1616 spin_unlock_irqrestore(&sport->mod_sqp_lock, flags);
1603 } 1617 }
1604 1618
1605 return internal_modify_qp(ibqp, attr, attr_mask, 0); 1619 ret = internal_modify_qp(ibqp, attr, attr_mask, 0);
1620
1621out:
1622 if ((ret == 0) && (attr_mask & IB_QP_STATE))
1623 my_qp->state = attr->qp_state;
1624
1625 return ret;
1606} 1626}
1607 1627
1608void ehca_recover_sqp(struct ib_qp *sqp) 1628void ehca_recover_sqp(struct ib_qp *sqp)
@@ -1973,8 +1993,10 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
1973 1993
1974 if (HAS_RQ(my_qp)) 1994 if (HAS_RQ(my_qp))
1975 ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); 1995 ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue);
1976 if (HAS_SQ(my_qp)) 1996 if (HAS_SQ(my_qp)) {
1977 ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); 1997 ipz_queue_dtor(my_pd, &my_qp->ipz_squeue);
1998 vfree(my_qp->sq_map);
1999 }
1978 kmem_cache_free(qp_cache, my_qp); 2000 kmem_cache_free(qp_cache, my_qp);
1979 atomic_dec(&shca->num_qps); 2001 atomic_dec(&shca->num_qps);
1980 return 0; 2002 return 0;
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 898c8b5c38dd..4426d82fe798 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -139,6 +139,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr)
139static inline int ehca_write_swqe(struct ehca_qp *qp, 139static inline int ehca_write_swqe(struct ehca_qp *qp,
140 struct ehca_wqe *wqe_p, 140 struct ehca_wqe *wqe_p,
141 const struct ib_send_wr *send_wr, 141 const struct ib_send_wr *send_wr,
142 u32 sq_map_idx,
142 int hidden) 143 int hidden)
143{ 144{
144 u32 idx; 145 u32 idx;
@@ -157,7 +158,11 @@ static inline int ehca_write_swqe(struct ehca_qp *qp,
157 /* clear wqe header until sglist */ 158 /* clear wqe header until sglist */
158 memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list)); 159 memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list));
159 160
160 wqe_p->work_request_id = send_wr->wr_id; 161 wqe_p->work_request_id = send_wr->wr_id & ~QMAP_IDX_MASK;
162 wqe_p->work_request_id |= sq_map_idx & QMAP_IDX_MASK;
163
164 qp->sq_map[sq_map_idx].app_wr_id = send_wr->wr_id & QMAP_IDX_MASK;
165 qp->sq_map[sq_map_idx].reported = 0;
161 166
162 switch (send_wr->opcode) { 167 switch (send_wr->opcode) {
163 case IB_WR_SEND: 168 case IB_WR_SEND:
@@ -381,6 +386,7 @@ static inline int post_one_send(struct ehca_qp *my_qp,
381{ 386{
382 struct ehca_wqe *wqe_p; 387 struct ehca_wqe *wqe_p;
383 int ret; 388 int ret;
389 u32 sq_map_idx;
384 u64 start_offset = my_qp->ipz_squeue.current_q_offset; 390 u64 start_offset = my_qp->ipz_squeue.current_q_offset;
385 391
386 /* get pointer next to free WQE */ 392 /* get pointer next to free WQE */
@@ -393,8 +399,15 @@ static inline int post_one_send(struct ehca_qp *my_qp,
393 "qp_num=%x", my_qp->ib_qp.qp_num); 399 "qp_num=%x", my_qp->ib_qp.qp_num);
394 return -ENOMEM; 400 return -ENOMEM;
395 } 401 }
402
403 /*
404 * Get the index of the WQE in the send queue. The same index is used
405 * for writing into the sq_map.
406 */
407 sq_map_idx = start_offset / my_qp->ipz_squeue.qe_size;
408
396 /* write a SEND WQE into the QUEUE */ 409 /* write a SEND WQE into the QUEUE */
397 ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr, hidden); 410 ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr, sq_map_idx, hidden);
398 /* 411 /*
399 * if something failed, 412 * if something failed,
400 * reset the free entry pointer to the start value 413 * reset the free entry pointer to the start value
@@ -589,7 +602,7 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc)
589 struct ehca_qp *my_qp; 602 struct ehca_qp *my_qp;
590 int cqe_count = 0, is_error; 603 int cqe_count = 0, is_error;
591 604
592poll_cq_one_read_cqe: 605repoll:
593 cqe = (struct ehca_cqe *) 606 cqe = (struct ehca_cqe *)
594 ipz_qeit_get_inc_valid(&my_cq->ipz_queue); 607 ipz_qeit_get_inc_valid(&my_cq->ipz_queue);
595 if (!cqe) { 608 if (!cqe) {
@@ -617,7 +630,7 @@ poll_cq_one_read_cqe:
617 ehca_dmp(cqe, 64, "cq_num=%x qp_num=%x", 630 ehca_dmp(cqe, 64, "cq_num=%x qp_num=%x",
618 my_cq->cq_number, cqe->local_qp_number); 631 my_cq->cq_number, cqe->local_qp_number);
619 /* ignore this purged cqe */ 632 /* ignore this purged cqe */
620 goto poll_cq_one_read_cqe; 633 goto repoll;
621 } 634 }
622 spin_lock_irqsave(&qp->spinlock_s, flags); 635 spin_lock_irqsave(&qp->spinlock_s, flags);
623 purgeflag = qp->sqerr_purgeflag; 636 purgeflag = qp->sqerr_purgeflag;
@@ -636,7 +649,7 @@ poll_cq_one_read_cqe:
636 * that caused sqe and turn off purge flag 649 * that caused sqe and turn off purge flag
637 */ 650 */
638 qp->sqerr_purgeflag = 0; 651 qp->sqerr_purgeflag = 0;
639 goto poll_cq_one_read_cqe; 652 goto repoll;
640 } 653 }
641 } 654 }
642 655
@@ -654,8 +667,34 @@ poll_cq_one_read_cqe:
654 my_cq, my_cq->cq_number); 667 my_cq, my_cq->cq_number);
655 } 668 }
656 669
657 /* we got a completion! */ 670 read_lock(&ehca_qp_idr_lock);
658 wc->wr_id = cqe->work_request_id; 671 my_qp = idr_find(&ehca_qp_idr, cqe->qp_token);
672 read_unlock(&ehca_qp_idr_lock);
673 if (!my_qp)
674 goto repoll;
675 wc->qp = &my_qp->ib_qp;
676
677 if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT)) {
678 struct ehca_qmap_entry *qmap_entry;
679 /*
680 * We got a send completion and need to restore the original
681 * wr_id.
682 */
683 qmap_entry = &my_qp->sq_map[cqe->work_request_id &
684 QMAP_IDX_MASK];
685
686 if (qmap_entry->reported) {
687 ehca_warn(cq->device, "Double cqe on qp_num=%#x",
688 my_qp->real_qp_num);
689 /* found a double cqe, discard it and read next one */
690 goto repoll;
691 }
692 wc->wr_id = cqe->work_request_id & ~QMAP_IDX_MASK;
693 wc->wr_id |= qmap_entry->app_wr_id;
694 qmap_entry->reported = 1;
695 } else
696 /* We got a receive completion. */
697 wc->wr_id = cqe->work_request_id;
659 698
660 /* eval ib_wc_opcode */ 699 /* eval ib_wc_opcode */
661 wc->opcode = ib_wc_opcode[cqe->optype]-1; 700 wc->opcode = ib_wc_opcode[cqe->optype]-1;
@@ -667,7 +706,7 @@ poll_cq_one_read_cqe:
667 ehca_dmp(cqe, 64, "ehca_cq=%p cq_num=%x", 706 ehca_dmp(cqe, 64, "ehca_cq=%p cq_num=%x",
668 my_cq, my_cq->cq_number); 707 my_cq, my_cq->cq_number);
669 /* update also queue adder to throw away this entry!!! */ 708 /* update also queue adder to throw away this entry!!! */
670 goto poll_cq_one_exit0; 709 goto repoll;
671 } 710 }
672 711
673 /* eval ib_wc_status */ 712 /* eval ib_wc_status */
@@ -678,11 +717,6 @@ poll_cq_one_read_cqe:
678 } else 717 } else
679 wc->status = IB_WC_SUCCESS; 718 wc->status = IB_WC_SUCCESS;
680 719
681 read_lock(&ehca_qp_idr_lock);
682 my_qp = idr_find(&ehca_qp_idr, cqe->qp_token);
683 wc->qp = &my_qp->ib_qp;
684 read_unlock(&ehca_qp_idr_lock);
685
686 wc->byte_len = cqe->nr_bytes_transferred; 720 wc->byte_len = cqe->nr_bytes_transferred;
687 wc->pkey_index = cqe->pkey_index; 721 wc->pkey_index = cqe->pkey_index;
688 wc->slid = cqe->rlid; 722 wc->slid = cqe->rlid;
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index daad09a45910..ad0aab60b051 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -1259,7 +1259,7 @@ reloop:
1259 */ 1259 */
1260 ipath_cdbg(ERRPKT, "Error Pkt, but no eflags! egrbuf" 1260 ipath_cdbg(ERRPKT, "Error Pkt, but no eflags! egrbuf"
1261 " %x, len %x hdrq+%x rhf: %Lx\n", 1261 " %x, len %x hdrq+%x rhf: %Lx\n",
1262 etail, tlen, l, 1262 etail, tlen, l, (unsigned long long)
1263 le64_to_cpu(*(__le64 *) rhf_addr)); 1263 le64_to_cpu(*(__le64 *) rhf_addr));
1264 if (ipath_debug & __IPATH_ERRPKTDBG) { 1264 if (ipath_debug & __IPATH_ERRPKTDBG) {
1265 u32 j, *d, dw = rsize-2; 1265 u32 j, *d, dw = rsize-2;
@@ -1457,7 +1457,8 @@ static void ipath_reset_availshadow(struct ipath_devdata *dd)
1457 0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */ 1457 0xaaaaaaaaaaaaaaaaULL); /* All BUSY bits in qword */
1458 if (oldval != dd->ipath_pioavailshadow[i]) 1458 if (oldval != dd->ipath_pioavailshadow[i])
1459 ipath_dbg("shadow[%d] was %Lx, now %lx\n", 1459 ipath_dbg("shadow[%d] was %Lx, now %lx\n",
1460 i, oldval, dd->ipath_pioavailshadow[i]); 1460 i, (unsigned long long) oldval,
1461 dd->ipath_pioavailshadow[i]);
1461 } 1462 }
1462 spin_unlock_irqrestore(&ipath_pioavail_lock, flags); 1463 spin_unlock_irqrestore(&ipath_pioavail_lock, flags);
1463} 1464}
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c
index fadbfbf55a6a..d90f5e9a54fa 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba7220.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c
@@ -1032,7 +1032,7 @@ static int ipath_7220_bringup_serdes(struct ipath_devdata *dd)
1032 ipath_cdbg(VERBOSE, "done: xgxs=%llx from %llx\n", 1032 ipath_cdbg(VERBOSE, "done: xgxs=%llx from %llx\n",
1033 (unsigned long long) 1033 (unsigned long long)
1034 ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig), 1034 ipath_read_kreg64(dd, dd->ipath_kregs->kr_xgxsconfig),
1035 prev_val); 1035 (unsigned long long) prev_val);
1036 1036
1037 guid = be64_to_cpu(dd->ipath_guid); 1037 guid = be64_to_cpu(dd->ipath_guid);
1038 1038
@@ -1042,7 +1042,8 @@ static int ipath_7220_bringup_serdes(struct ipath_devdata *dd)
1042 ipath_dbg("No GUID for heartbeat, faking %llx\n", 1042 ipath_dbg("No GUID for heartbeat, faking %llx\n",
1043 (unsigned long long)guid); 1043 (unsigned long long)guid);
1044 } else 1044 } else
1045 ipath_cdbg(VERBOSE, "Wrote %llX to HRTBT_GUID\n", guid); 1045 ipath_cdbg(VERBOSE, "Wrote %llX to HRTBT_GUID\n",
1046 (unsigned long long) guid);
1046 ipath_write_kreg(dd, dd->ipath_kregs->kr_hrtbt_guid, guid); 1047 ipath_write_kreg(dd, dd->ipath_kregs->kr_hrtbt_guid, guid);
1047 return ret; 1048 return ret;
1048} 1049}
@@ -2505,7 +2506,7 @@ done:
2505 if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) { 2506 if (dd->ipath_flags & IPATH_IB_AUTONEG_INPROG) {
2506 ipath_dbg("Did not get to DDR INIT (%x) after %Lu msecs\n", 2507 ipath_dbg("Did not get to DDR INIT (%x) after %Lu msecs\n",
2507 ipath_ib_state(dd, dd->ipath_lastibcstat), 2508 ipath_ib_state(dd, dd->ipath_lastibcstat),
2508 jiffies_to_msecs(jiffies)-startms); 2509 (unsigned long long) jiffies_to_msecs(jiffies)-startms);
2509 dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG; 2510 dd->ipath_flags &= ~IPATH_IB_AUTONEG_INPROG;
2510 if (dd->ipath_autoneg_tries == IPATH_AUTONEG_TRIES) { 2511 if (dd->ipath_autoneg_tries == IPATH_AUTONEG_TRIES) {
2511 dd->ipath_flags |= IPATH_IB_AUTONEG_FAILED; 2512 dd->ipath_flags |= IPATH_IB_AUTONEG_FAILED;
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 26900b3b7a4e..6c21b4b5ec71 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -356,9 +356,10 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
356 dd->ipath_cregs->cr_iblinkerrrecovcnt); 356 dd->ipath_cregs->cr_iblinkerrrecovcnt);
357 if (linkrecov != dd->ipath_lastlinkrecov) { 357 if (linkrecov != dd->ipath_lastlinkrecov) {
358 ipath_dbg("IB linkrecov up %Lx (%s %s) recov %Lu\n", 358 ipath_dbg("IB linkrecov up %Lx (%s %s) recov %Lu\n",
359 ibcs, ib_linkstate(dd, ibcs), 359 (unsigned long long) ibcs,
360 ib_linkstate(dd, ibcs),
360 ipath_ibcstatus_str[ltstate], 361 ipath_ibcstatus_str[ltstate],
361 linkrecov); 362 (unsigned long long) linkrecov);
362 /* and no more until active again */ 363 /* and no more until active again */
363 dd->ipath_lastlinkrecov = 0; 364 dd->ipath_lastlinkrecov = 0;
364 ipath_set_linkstate(dd, IPATH_IB_LINKDOWN); 365 ipath_set_linkstate(dd, IPATH_IB_LINKDOWN);
@@ -1118,9 +1119,11 @@ irqreturn_t ipath_intr(int irq, void *data)
1118 if (unlikely(istat & ~dd->ipath_i_bitsextant)) 1119 if (unlikely(istat & ~dd->ipath_i_bitsextant))
1119 ipath_dev_err(dd, 1120 ipath_dev_err(dd,
1120 "interrupt with unknown interrupts %Lx set\n", 1121 "interrupt with unknown interrupts %Lx set\n",
1122 (unsigned long long)
1121 istat & ~dd->ipath_i_bitsextant); 1123 istat & ~dd->ipath_i_bitsextant);
1122 else if (istat & ~INFINIPATH_I_ERROR) /* errors do own printing */ 1124 else if (istat & ~INFINIPATH_I_ERROR) /* errors do own printing */
1123 ipath_cdbg(VERBOSE, "intr stat=0x%Lx\n", istat); 1125 ipath_cdbg(VERBOSE, "intr stat=0x%Lx\n",
1126 (unsigned long long) istat);
1124 1127
1125 if (istat & INFINIPATH_I_ERROR) { 1128 if (istat & INFINIPATH_I_ERROR) {
1126 ipath_stats.sps_errints++; 1129 ipath_stats.sps_errints++;
@@ -1128,7 +1131,8 @@ irqreturn_t ipath_intr(int irq, void *data)
1128 dd->ipath_kregs->kr_errorstatus); 1131 dd->ipath_kregs->kr_errorstatus);
1129 if (!estat) 1132 if (!estat)
1130 dev_info(&dd->pcidev->dev, "error interrupt (%Lx), " 1133 dev_info(&dd->pcidev->dev, "error interrupt (%Lx), "
1131 "but no error bits set!\n", istat); 1134 "but no error bits set!\n",
1135 (unsigned long long) istat);
1132 else if (estat == -1LL) 1136 else if (estat == -1LL)
1133 /* 1137 /*
1134 * should we try clearing all, or hope next read 1138 * should we try clearing all, or hope next read
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 55c718828826..b766e40e9ebf 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1021,7 +1021,7 @@ static void sdma_complete(void *cookie, int status)
1021 struct ipath_verbs_txreq *tx = cookie; 1021 struct ipath_verbs_txreq *tx = cookie;
1022 struct ipath_qp *qp = tx->qp; 1022 struct ipath_qp *qp = tx->qp;
1023 struct ipath_ibdev *dev = to_idev(qp->ibqp.device); 1023 struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
1024 unsigned int flags; 1024 unsigned long flags;
1025 enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ? 1025 enum ib_wc_status ibs = status == IPATH_SDMA_TXREQ_S_OK ?
1026 IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR; 1026 IB_WC_SUCCESS : IB_WC_WR_FLUSH_ERR;
1027 1027
@@ -1051,7 +1051,7 @@ static void sdma_complete(void *cookie, int status)
1051 1051
1052static void decrement_dma_busy(struct ipath_qp *qp) 1052static void decrement_dma_busy(struct ipath_qp *qp)
1053{ 1053{
1054 unsigned int flags; 1054 unsigned long flags;
1055 1055
1056 if (atomic_dec_and_test(&qp->s_dma_busy)) { 1056 if (atomic_dec_and_test(&qp->s_dma_busy)) {
1057 spin_lock_irqsave(&qp->s_lock, flags); 1057 spin_lock_irqsave(&qp->s_lock, flags);
@@ -1221,7 +1221,7 @@ static int ipath_verbs_send_pio(struct ipath_qp *qp,
1221 unsigned flush_wc; 1221 unsigned flush_wc;
1222 u32 control; 1222 u32 control;
1223 int ret; 1223 int ret;
1224 unsigned int flags; 1224 unsigned long flags;
1225 1225
1226 piobuf = ipath_getpiobuf(dd, plen, NULL); 1226 piobuf = ipath_getpiobuf(dd, plen, NULL);
1227 if (unlikely(piobuf == NULL)) { 1227 if (unlikely(piobuf == NULL)) {
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index a1464574bfdd..d0866a3636e2 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -515,17 +515,17 @@ static void mlx4_ib_handle_error_cqe(struct mlx4_err_cqe *cqe,
515 wc->vendor_err = cqe->vendor_err_syndrome; 515 wc->vendor_err = cqe->vendor_err_syndrome;
516} 516}
517 517
518static int mlx4_ib_ipoib_csum_ok(__be32 status, __be16 checksum) 518static int mlx4_ib_ipoib_csum_ok(__be16 status, __be16 checksum)
519{ 519{
520 return ((status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4 | 520 return ((status & cpu_to_be16(MLX4_CQE_STATUS_IPV4 |
521 MLX4_CQE_IPOIB_STATUS_IPV4F | 521 MLX4_CQE_STATUS_IPV4F |
522 MLX4_CQE_IPOIB_STATUS_IPV4OPT | 522 MLX4_CQE_STATUS_IPV4OPT |
523 MLX4_CQE_IPOIB_STATUS_IPV6 | 523 MLX4_CQE_STATUS_IPV6 |
524 MLX4_CQE_IPOIB_STATUS_IPOK)) == 524 MLX4_CQE_STATUS_IPOK)) ==
525 cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4 | 525 cpu_to_be16(MLX4_CQE_STATUS_IPV4 |
526 MLX4_CQE_IPOIB_STATUS_IPOK)) && 526 MLX4_CQE_STATUS_IPOK)) &&
527 (status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_UDP | 527 (status & cpu_to_be16(MLX4_CQE_STATUS_UDP |
528 MLX4_CQE_IPOIB_STATUS_TCP)) && 528 MLX4_CQE_STATUS_TCP)) &&
529 checksum == cpu_to_be16(0xffff); 529 checksum == cpu_to_be16(0xffff);
530} 530}
531 531
@@ -582,17 +582,17 @@ repoll:
582 } 582 }
583 583
584 if (!*cur_qp || 584 if (!*cur_qp ||
585 (be32_to_cpu(cqe->my_qpn) & 0xffffff) != (*cur_qp)->mqp.qpn) { 585 (be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK) != (*cur_qp)->mqp.qpn) {
586 /* 586 /*
587 * We do not have to take the QP table lock here, 587 * We do not have to take the QP table lock here,
588 * because CQs will be locked while QPs are removed 588 * because CQs will be locked while QPs are removed
589 * from the table. 589 * from the table.
590 */ 590 */
591 mqp = __mlx4_qp_lookup(to_mdev(cq->ibcq.device)->dev, 591 mqp = __mlx4_qp_lookup(to_mdev(cq->ibcq.device)->dev,
592 be32_to_cpu(cqe->my_qpn)); 592 be32_to_cpu(cqe->vlan_my_qpn));
593 if (unlikely(!mqp)) { 593 if (unlikely(!mqp)) {
594 printk(KERN_WARNING "CQ %06x with entry for unknown QPN %06x\n", 594 printk(KERN_WARNING "CQ %06x with entry for unknown QPN %06x\n",
595 cq->mcq.cqn, be32_to_cpu(cqe->my_qpn) & 0xffffff); 595 cq->mcq.cqn, be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK);
596 return -EINVAL; 596 return -EINVAL;
597 } 597 }
598 598
@@ -692,14 +692,13 @@ repoll:
692 } 692 }
693 693
694 wc->slid = be16_to_cpu(cqe->rlid); 694 wc->slid = be16_to_cpu(cqe->rlid);
695 wc->sl = cqe->sl >> 4; 695 wc->sl = be16_to_cpu(cqe->sl_vid >> 12);
696 g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn); 696 g_mlpath_rqpn = be32_to_cpu(cqe->g_mlpath_rqpn);
697 wc->src_qp = g_mlpath_rqpn & 0xffffff; 697 wc->src_qp = g_mlpath_rqpn & 0xffffff;
698 wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f; 698 wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f;
699 wc->wc_flags |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0; 699 wc->wc_flags |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0;
700 wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f; 700 wc->pkey_index = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f;
701 wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->ipoib_status, 701 wc->csum_ok = mlx4_ib_ipoib_csum_ok(cqe->status, cqe->checksum);
702 cqe->checksum);
703 } 702 }
704 703
705 return 0; 704 return 0;
@@ -767,7 +766,7 @@ void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq)
767 */ 766 */
768 while ((int) --prod_index - (int) cq->mcq.cons_index >= 0) { 767 while ((int) --prod_index - (int) cq->mcq.cons_index >= 0) {
769 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); 768 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
770 if ((be32_to_cpu(cqe->my_qpn) & 0xffffff) == qpn) { 769 if ((be32_to_cpu(cqe->vlan_my_qpn) & MLX4_CQE_QPN_MASK) == qpn) {
771 if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK)) 770 if (srq && !(cqe->owner_sr_opcode & MLX4_CQE_IS_SEND_MASK))
772 mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index)); 771 mlx4_ib_free_srq_wqe(srq, be16_to_cpu(cqe->wqe_index));
773 ++nfreed; 772 ++nfreed;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index f7bc7dd8578a..f29dbb767e87 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -902,7 +902,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
902 context->mtu_msgmax = (IB_MTU_4096 << 5) | 902 context->mtu_msgmax = (IB_MTU_4096 << 5) |
903 ilog2(dev->dev->caps.max_gso_sz); 903 ilog2(dev->dev->caps.max_gso_sz);
904 else 904 else
905 context->mtu_msgmax = (IB_MTU_4096 << 5) | 11; 905 context->mtu_msgmax = (IB_MTU_4096 << 5) | 12;
906 } else if (attr_mask & IB_QP_PATH_MTU) { 906 } else if (attr_mask & IB_QP_PATH_MTU) {
907 if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) { 907 if (attr->path_mtu < IB_MTU_256 || attr->path_mtu > IB_MTU_4096) {
908 printk(KERN_ERR "path MTU (%u) is invalid\n", 908 printk(KERN_ERR "path MTU (%u) is invalid\n",
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 0f2d3045061a..341ffedafed6 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -202,7 +202,7 @@ static void ipoib_cm_free_rx_ring(struct net_device *dev,
202 dev_kfree_skb_any(rx_ring[i].skb); 202 dev_kfree_skb_any(rx_ring[i].skb);
203 } 203 }
204 204
205 kfree(rx_ring); 205 vfree(rx_ring);
206} 206}
207 207
208static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv *priv) 208static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv *priv)
@@ -337,7 +337,7 @@ static void ipoib_cm_init_rx_wr(struct net_device *dev,
337 sge[i].length = PAGE_SIZE; 337 sge[i].length = PAGE_SIZE;
338 338
339 wr->next = NULL; 339 wr->next = NULL;
340 wr->sg_list = priv->cm.rx_sge; 340 wr->sg_list = sge;
341 wr->num_sge = priv->cm.num_frags; 341 wr->num_sge = priv->cm.num_frags;
342} 342}
343 343
@@ -352,9 +352,14 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i
352 int ret; 352 int ret;
353 int i; 353 int i;
354 354
355 rx->rx_ring = kcalloc(ipoib_recvq_size, sizeof *rx->rx_ring, GFP_KERNEL); 355 rx->rx_ring = vmalloc(ipoib_recvq_size * sizeof *rx->rx_ring);
356 if (!rx->rx_ring) 356 if (!rx->rx_ring) {
357 printk(KERN_WARNING "%s: failed to allocate CM non-SRQ ring (%d entries)\n",
358 priv->ca->name, ipoib_recvq_size);
357 return -ENOMEM; 359 return -ENOMEM;
360 }
361
362 memset(rx->rx_ring, 0, ipoib_recvq_size * sizeof *rx->rx_ring);
358 363
359 t = kmalloc(sizeof *t, GFP_KERNEL); 364 t = kmalloc(sizeof *t, GFP_KERNEL);
360 if (!t) { 365 if (!t) {
@@ -1494,14 +1499,16 @@ static void ipoib_cm_create_srq(struct net_device *dev, int max_sge)
1494 return; 1499 return;
1495 } 1500 }
1496 1501
1497 priv->cm.srq_ring = kzalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring, 1502 priv->cm.srq_ring = vmalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring);
1498 GFP_KERNEL);
1499 if (!priv->cm.srq_ring) { 1503 if (!priv->cm.srq_ring) {
1500 printk(KERN_WARNING "%s: failed to allocate CM SRQ ring (%d entries)\n", 1504 printk(KERN_WARNING "%s: failed to allocate CM SRQ ring (%d entries)\n",
1501 priv->ca->name, ipoib_recvq_size); 1505 priv->ca->name, ipoib_recvq_size);
1502 ib_destroy_srq(priv->cm.srq); 1506 ib_destroy_srq(priv->cm.srq);
1503 priv->cm.srq = NULL; 1507 priv->cm.srq = NULL;
1508 return;
1504 } 1509 }
1510
1511 memset(priv->cm.srq_ring, 0, ipoib_recvq_size * sizeof *priv->cm.srq_ring);
1505} 1512}
1506 1513
1507int ipoib_cm_dev_init(struct net_device *dev) 1514int ipoib_cm_dev_init(struct net_device *dev)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 2d65411f6763..3524bef62be6 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -647,6 +647,47 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
647 return copy_to_user(p, str, len) ? -EFAULT : len; 647 return copy_to_user(p, str, len) ? -EFAULT : len;
648} 648}
649 649
650#define OLD_KEY_MAX 0x1ff
651static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user *p, int compat_mode)
652{
653 static unsigned long keymax_warn_time;
654 unsigned long *bits;
655 int len;
656
657 switch (_IOC_NR(cmd) & EV_MAX) {
658
659 case 0: bits = dev->evbit; len = EV_MAX; break;
660 case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
661 case EV_REL: bits = dev->relbit; len = REL_MAX; break;
662 case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
663 case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
664 case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
665 case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
666 case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
667 case EV_SW: bits = dev->swbit; len = SW_MAX; break;
668 default: return -EINVAL;
669 }
670
671 /*
672 * Work around bugs in userspace programs that like to do
673 * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len'
674 * should be in bytes, not in bits.
675 */
676 if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) {
677 len = OLD_KEY_MAX;
678 if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))
679 printk(KERN_WARNING
680 "evdev.c(EVIOCGBIT): Suspicious buffer size %u, "
681 "limiting output to %zu bytes. See "
682 "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n",
683 OLD_KEY_MAX,
684 BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
685 }
686
687 return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
688}
689#undef OLD_KEY_MAX
690
650static long evdev_do_ioctl(struct file *file, unsigned int cmd, 691static long evdev_do_ioctl(struct file *file, unsigned int cmd,
651 void __user *p, int compat_mode) 692 void __user *p, int compat_mode)
652{ 693{
@@ -733,26 +774,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
733 774
734 if (_IOC_DIR(cmd) == _IOC_READ) { 775 if (_IOC_DIR(cmd) == _IOC_READ) {
735 776
736 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) { 777 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
737 778 return handle_eviocgbit(dev, cmd, p, compat_mode);
738 unsigned long *bits;
739 int len;
740
741 switch (_IOC_NR(cmd) & EV_MAX) {
742
743 case 0: bits = dev->evbit; len = EV_MAX; break;
744 case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
745 case EV_REL: bits = dev->relbit; len = REL_MAX; break;
746 case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
747 case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
748 case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
749 case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
750 case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
751 case EV_SW: bits = dev->swbit; len = SW_MAX; break;
752 default: return -EINVAL;
753 }
754 return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
755 }
756 779
757 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) 780 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
758 return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), 781 return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 87d3e7eabffd..6791be81eb29 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -127,6 +127,7 @@ static const struct xpad_device {
127 { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, 127 { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
128 { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, 128 { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
129 { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, 129 { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
130 { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX },
130 { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, 131 { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
131 { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, 132 { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX },
132 { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, 133 { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c
index 8a77bfcd05bc..18222a689a03 100644
--- a/drivers/input/keyboard/aaed2000_kbd.c
+++ b/drivers/input/keyboard/aaed2000_kbd.c
@@ -20,8 +20,8 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22 22
23#include <asm/arch/hardware.h> 23#include <mach/hardware.h>
24#include <asm/arch/aaed2000.h> 24#include <mach/aaed2000.h>
25 25
26#define KB_ROWS 12 26#define KB_ROWS 12
27#define KB_COLS 8 27#define KB_COLS 8
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 1aa46ae12630..134e67bf6a90 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -20,10 +20,10 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22 22
23#include <asm/arch/corgi.h> 23#include <mach/corgi.h>
24#include <asm/arch/hardware.h> 24#include <mach/hardware.h>
25#include <asm/arch/pxa-regs.h> 25#include <mach/pxa-regs.h>
26#include <asm/arch/pxa2xx-gpio.h> 26#include <mach/pxa2xx-gpio.h>
27#include <asm/hardware/scoop.h> 27#include <asm/hardware/scoop.h>
28 28
29#define KB_ROWS 8 29#define KB_ROWS 8
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index be58730e636a..ec96b369dd7a 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -9,7 +9,6 @@
9 */ 9 */
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/version.h>
13 12
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/fs.h> 14#include <linux/fs.h>
@@ -118,6 +117,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
118 unsigned int type = button->type ?: EV_KEY; 117 unsigned int type = button->type ?: EV_KEY;
119 118
120 bdata->input = input; 119 bdata->input = input;
120 bdata->button = button;
121 setup_timer(&bdata->timer, 121 setup_timer(&bdata->timer,
122 gpio_check_button, (unsigned long)bdata); 122 gpio_check_button, (unsigned long)bdata);
123 123
@@ -256,7 +256,7 @@ static int gpio_keys_resume(struct platform_device *pdev)
256#define gpio_keys_resume NULL 256#define gpio_keys_resume NULL
257#endif 257#endif
258 258
259struct platform_driver gpio_keys_device_driver = { 259static struct platform_driver gpio_keys_device_driver = {
260 .probe = gpio_keys_probe, 260 .probe = gpio_keys_probe,
261 .remove = __devexit_p(gpio_keys_remove), 261 .remove = __devexit_p(gpio_keys_remove),
262 .suspend = gpio_keys_suspend, 262 .suspend = gpio_keys_suspend,
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c
index ce650af6d649..4e016d823069 100644
--- a/drivers/input/keyboard/jornada720_kbd.c
+++ b/drivers/input/keyboard/jornada720_kbd.c
@@ -24,8 +24,8 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26 26
27#include <asm/arch/jornada720.h> 27#include <mach/jornada720.h>
28#include <asm/hardware.h> 28#include <mach/hardware.h>
29 29
30MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>"); 30MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>");
31MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver"); 31MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver");
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 10afd2068068..dcea87a0bc56 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -34,14 +34,13 @@
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <asm/arch/gpio.h> 37#include <mach/gpio.h>
38#include <asm/arch/keypad.h> 38#include <mach/keypad.h>
39#include <asm/arch/menelaus.h> 39#include <mach/menelaus.h>
40#include <asm/irq.h> 40#include <asm/irq.h>
41#include <asm/hardware.h> 41#include <mach/hardware.h>
42#include <asm/io.h> 42#include <asm/io.h>
43#include <asm/mach-types.h> 43#include <mach/mux.h>
44#include <asm/arch/mux.h>
45 44
46#undef NEW_BOARD_LEARNING_MODE 45#undef NEW_BOARD_LEARNING_MODE
47 46
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 6f1516f50750..6d30c6d334c3 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -26,12 +26,11 @@
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/err.h> 27#include <linux/err.h>
28 28
29#include <asm/mach-types.h>
30#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
31#include <asm/mach/map.h> 30#include <asm/mach/map.h>
32 31
33#include <asm/arch/hardware.h> 32#include <mach/hardware.h>
34#include <asm/arch/pxa27x_keypad.h> 33#include <mach/pxa27x_keypad.h>
35 34
36/* 35/*
37 * Keypad Controller registers 36 * Keypad Controller registers
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 1aa37181c40f..de67b8e0a799 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -20,10 +20,10 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22 22
23#include <asm/arch/spitz.h> 23#include <mach/spitz.h>
24#include <asm/arch/hardware.h> 24#include <mach/hardware.h>
25#include <asm/arch/pxa-regs.h> 25#include <mach/pxa-regs.h>
26#include <asm/arch/pxa2xx-gpio.h> 26#include <mach/pxa2xx-gpio.h>
27 27
28#define KB_ROWS 7 28#define KB_ROWS 7
29#define KB_COLS 11 29#define KB_COLS 11
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
index b12b7ee4b6aa..44cb50af3ce9 100644
--- a/drivers/input/keyboard/tosakbd.c
+++ b/drivers/input/keyboard/tosakbd.c
@@ -19,8 +19,8 @@
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21 21
22#include <asm/arch/gpio.h> 22#include <mach/gpio.h>
23#include <asm/arch/tosa.h> 23#include <mach/tosa.h>
24 24
25#define KB_ROWMASK(r) (1 << (r)) 25#define KB_ROWMASK(r) (1 << (r))
26#define SCANCODE(r, c) (((r)<<4) + (c) + 1) 26#define SCANCODE(r, c) (((r)<<4) + (c) + 1)
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index 6a1f48b76e32..2adf9cb265da 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -148,6 +148,9 @@ static int __devexit cobalt_buttons_remove(struct platform_device *pdev)
148 return 0; 148 return 0;
149} 149}
150 150
151MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
152MODULE_DESCRIPTION("Cobalt button interface driver");
153MODULE_LICENSE("GPL");
151/* work with hotplug and coldplug */ 154/* work with hotplug and coldplug */
152MODULE_ALIAS("platform:Cobalt buttons"); 155MODULE_ALIAS("platform:Cobalt buttons");
153 156
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c
index 798d84c44d03..9946d73624b9 100644
--- a/drivers/input/misc/ixp4xx-beeper.c
+++ b/drivers/input/misc/ixp4xx-beeper.c
@@ -20,7 +20,7 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <asm/hardware.h> 23#include <mach/hardware.h>
24 24
25MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); 25MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
26MODULE_DESCRIPTION("ixp4xx beeper driver"); 26MODULE_DESCRIPTION("ixp4xx beeper driver");
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 7bbea097cda2..f996546fc443 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -130,6 +130,29 @@ config MOUSE_APPLETOUCH
130 To compile this driver as a module, choose M here: the 130 To compile this driver as a module, choose M here: the
131 module will be called appletouch. 131 module will be called appletouch.
132 132
133config MOUSE_BCM5974
134 tristate "Apple USB BCM5974 Multitouch trackpad support"
135 depends on USB_ARCH_HAS_HCD
136 select USB
137 help
138 Say Y here if you have an Apple USB BCM5974 Multitouch
139 trackpad.
140
141 The BCM5974 is the multitouch trackpad found in the Macbook
142 Air (JAN2008) and Macbook Pro Penryn (FEB2008) laptops.
143
144 It is also found in the IPhone (2007) and Ipod Touch (2008).
145
146 This driver provides multitouch functionality together with
147 the synaptics X11 driver.
148
149 The interface is currently identical to the appletouch interface,
150 for further information, see
151 <file:Documentation/input/appletouch.txt>.
152
153 To compile this driver as a module, choose M here: the
154 module will be called bcm5974.
155
133config MOUSE_INPORT 156config MOUSE_INPORT
134 tristate "InPort/MS/ATIXL busmouse" 157 tristate "InPort/MS/ATIXL busmouse"
135 depends on ISA 158 depends on ISA
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 9e6e36330820..d4d202516090 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -6,6 +6,7 @@
6 6
7obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o 7obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o
8obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o 8obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
9obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
9obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o 10obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
10obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o 11obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
11obj-$(CONFIG_MOUSE_INPORT) += inport.o 12obj-$(CONFIG_MOUSE_INPORT) += inport.o
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
new file mode 100644
index 000000000000..2ec921bf3c60
--- /dev/null
+++ b/drivers/input/mouse/bcm5974.c
@@ -0,0 +1,681 @@
1/*
2 * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver
3 *
4 * Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se)
5 *
6 * The USB initialization and package decoding was made by
7 * Scott Shawcroft as part of the touchd user-space driver project:
8 * Copyright (C) 2008 Scott Shawcroft (scott.shawcroft@gmail.com)
9 *
10 * The BCM5974 driver is based on the appletouch driver:
11 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
12 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
13 * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
14 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
15 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
16 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
17 * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 *
33 */
34
35#include <linux/kernel.h>
36#include <linux/errno.h>
37#include <linux/init.h>
38#include <linux/slab.h>
39#include <linux/module.h>
40#include <linux/usb/input.h>
41#include <linux/hid.h>
42#include <linux/mutex.h>
43
44#define USB_VENDOR_ID_APPLE 0x05ac
45
46/* MacbookAir, aka wellspring */
47#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
48#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
49#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
50/* MacbookProPenryn, aka wellspring2 */
51#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
52#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
53#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
54
55#define BCM5974_DEVICE(prod) { \
56 .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
57 USB_DEVICE_ID_MATCH_INT_CLASS | \
58 USB_DEVICE_ID_MATCH_INT_PROTOCOL), \
59 .idVendor = USB_VENDOR_ID_APPLE, \
60 .idProduct = (prod), \
61 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \
62 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \
63}
64
65/* table of devices that work with this driver */
66static const struct usb_device_id bcm5974_table [] = {
67 /* MacbookAir1.1 */
68 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
69 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
70 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
71 /* MacbookProPenryn */
72 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
73 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
74 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
75 /* Terminating entry */
76 {}
77};
78MODULE_DEVICE_TABLE(usb, bcm5974_table);
79
80MODULE_AUTHOR("Henrik Rydberg");
81MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver");
82MODULE_LICENSE("GPL");
83
84#define dprintk(level, format, a...)\
85 { if (debug >= level) printk(KERN_DEBUG format, ##a); }
86
87static int debug = 1;
88module_param(debug, int, 0644);
89MODULE_PARM_DESC(debug, "Activate debugging output");
90
91/* button data structure */
92struct bt_data {
93 u8 unknown1; /* constant */
94 u8 button; /* left button */
95 u8 rel_x; /* relative x coordinate */
96 u8 rel_y; /* relative y coordinate */
97};
98
99/* trackpad header structure */
100struct tp_header {
101 u8 unknown1[16]; /* constants, timers, etc */
102 u8 fingers; /* number of fingers on trackpad */
103 u8 unknown2[9]; /* constants, timers, etc */
104};
105
106/* trackpad finger structure */
107struct tp_finger {
108 __le16 origin; /* left/right origin? */
109 __le16 abs_x; /* absolute x coodinate */
110 __le16 abs_y; /* absolute y coodinate */
111 __le16 rel_x; /* relative x coodinate */
112 __le16 rel_y; /* relative y coodinate */
113 __le16 size_major; /* finger size, major axis? */
114 __le16 size_minor; /* finger size, minor axis? */
115 __le16 orientation; /* 16384 when point, else 15 bit angle */
116 __le16 force_major; /* trackpad force, major axis? */
117 __le16 force_minor; /* trackpad force, minor axis? */
118 __le16 unused[3]; /* zeros */
119 __le16 multi; /* one finger: varies, more fingers: constant */
120};
121
122/* trackpad data structure, empirically at least ten fingers */
123struct tp_data {
124 struct tp_header header;
125 struct tp_finger finger[16];
126};
127
128/* device-specific parameters */
129struct bcm5974_param {
130 int dim; /* logical dimension */
131 int fuzz; /* logical noise value */
132 int devmin; /* device minimum reading */
133 int devmax; /* device maximum reading */
134};
135
136/* device-specific configuration */
137struct bcm5974_config {
138 int ansi, iso, jis; /* the product id of this device */
139 int bt_ep; /* the endpoint of the button interface */
140 int bt_datalen; /* data length of the button interface */
141 int tp_ep; /* the endpoint of the trackpad interface */
142 int tp_datalen; /* data length of the trackpad interface */
143 struct bcm5974_param p; /* finger pressure limits */
144 struct bcm5974_param w; /* finger width limits */
145 struct bcm5974_param x; /* horizontal limits */
146 struct bcm5974_param y; /* vertical limits */
147};
148
149/* logical device structure */
150struct bcm5974 {
151 char phys[64];
152 struct usb_device *udev; /* usb device */
153 struct usb_interface *intf; /* our interface */
154 struct input_dev *input; /* input dev */
155 struct bcm5974_config cfg; /* device configuration */
156 struct mutex pm_mutex; /* serialize access to open/suspend */
157 int opened; /* 1: opened, 0: closed */
158 struct urb *bt_urb; /* button usb request block */
159 struct bt_data *bt_data; /* button transferred data */
160 struct urb *tp_urb; /* trackpad usb request block */
161 struct tp_data *tp_data; /* trackpad transferred data */
162};
163
164/* logical dimensions */
165#define DIM_PRESSURE 256 /* maximum finger pressure */
166#define DIM_WIDTH 16 /* maximum finger width */
167#define DIM_X 1280 /* maximum trackpad x value */
168#define DIM_Y 800 /* maximum trackpad y value */
169
170/* logical signal quality */
171#define SN_PRESSURE 45 /* pressure signal-to-noise ratio */
172#define SN_WIDTH 100 /* width signal-to-noise ratio */
173#define SN_COORD 250 /* coordinate signal-to-noise ratio */
174
175/* device constants */
176static const struct bcm5974_config bcm5974_config_table[] = {
177 {
178 USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
179 USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
180 USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
181 0x84, sizeof(struct bt_data),
182 0x81, sizeof(struct tp_data),
183 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
184 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
185 { DIM_X, DIM_X / SN_COORD, -4824, 5342 },
186 { DIM_Y, DIM_Y / SN_COORD, -172, 5820 }
187 },
188 {
189 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
190 USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
191 USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
192 0x84, sizeof(struct bt_data),
193 0x81, sizeof(struct tp_data),
194 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
195 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
196 { DIM_X, DIM_X / SN_COORD, -4824, 4824 },
197 { DIM_Y, DIM_Y / SN_COORD, -172, 4290 }
198 },
199 {}
200};
201
202/* return the device-specific configuration by device */
203static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev)
204{
205 u16 id = le16_to_cpu(udev->descriptor.idProduct);
206 const struct bcm5974_config *cfg;
207
208 for (cfg = bcm5974_config_table; cfg->ansi; ++cfg)
209 if (cfg->ansi == id || cfg->iso == id || cfg->jis == id)
210 return cfg;
211
212 return bcm5974_config_table;
213}
214
215/* convert 16-bit little endian to signed integer */
216static inline int raw2int(__le16 x)
217{
218 return (signed short)le16_to_cpu(x);
219}
220
221/* scale device data to logical dimensions (asserts devmin < devmax) */
222static inline int int2scale(const struct bcm5974_param *p, int x)
223{
224 return x * p->dim / (p->devmax - p->devmin);
225}
226
227/* all logical value ranges are [0,dim). */
228static inline int int2bound(const struct bcm5974_param *p, int x)
229{
230 int s = int2scale(p, x);
231
232 return clamp_val(s, 0, p->dim - 1);
233}
234
235/* setup which logical events to report */
236static void setup_events_to_report(struct input_dev *input_dev,
237 const struct bcm5974_config *cfg)
238{
239 __set_bit(EV_ABS, input_dev->evbit);
240
241 input_set_abs_params(input_dev, ABS_PRESSURE,
242 0, cfg->p.dim, cfg->p.fuzz, 0);
243 input_set_abs_params(input_dev, ABS_TOOL_WIDTH,
244 0, cfg->w.dim, cfg->w.fuzz, 0);
245 input_set_abs_params(input_dev, ABS_X,
246 0, cfg->x.dim, cfg->x.fuzz, 0);
247 input_set_abs_params(input_dev, ABS_Y,
248 0, cfg->y.dim, cfg->y.fuzz, 0);
249
250 __set_bit(EV_KEY, input_dev->evbit);
251 __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
252 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
253 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
254 __set_bit(BTN_LEFT, input_dev->keybit);
255}
256
257/* report button data as logical button state */
258static int report_bt_state(struct bcm5974 *dev, int size)
259{
260 if (size != sizeof(struct bt_data))
261 return -EIO;
262
263 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
264 input_sync(dev->input);
265
266 return 0;
267}
268
269/* report trackpad data as logical trackpad state */
270static int report_tp_state(struct bcm5974 *dev, int size)
271{
272 const struct bcm5974_config *c = &dev->cfg;
273 const struct tp_finger *f = dev->tp_data->finger;
274 struct input_dev *input = dev->input;
275 const int fingers = (size - 26) / 28;
276 int p = 0, w, x, y, n = 0;
277
278 if (size < 26 || (size - 26) % 28 != 0)
279 return -EIO;
280
281 if (fingers) {
282 p = raw2int(f->force_major);
283 w = raw2int(f->size_major);
284 x = raw2int(f->abs_x);
285 y = raw2int(f->abs_y);
286 n = p > 0 ? fingers : 0;
287
288 dprintk(9,
289 "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
290 p, w, x, y, n);
291
292 input_report_abs(input, ABS_TOOL_WIDTH, int2bound(&c->w, w));
293 input_report_abs(input, ABS_X, int2bound(&c->x, x - c->x.devmin));
294 input_report_abs(input, ABS_Y, int2bound(&c->y, c->y.devmax - y));
295 }
296
297 input_report_abs(input, ABS_PRESSURE, int2bound(&c->p, p));
298
299 input_report_key(input, BTN_TOOL_FINGER, n == 1);
300 input_report_key(input, BTN_TOOL_DOUBLETAP, n == 2);
301 input_report_key(input, BTN_TOOL_TRIPLETAP, n > 2);
302
303 input_sync(input);
304
305 return 0;
306}
307
308/* Wellspring initialization constants */
309#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1
310#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9
311#define BCM5974_WELLSPRING_MODE_REQUEST_VALUE 0x300
312#define BCM5974_WELLSPRING_MODE_REQUEST_INDEX 0
313#define BCM5974_WELLSPRING_MODE_VENDOR_VALUE 0x01
314
315static int bcm5974_wellspring_mode(struct bcm5974 *dev)
316{
317 char *data = kmalloc(8, GFP_KERNEL);
318 int retval = 0, size;
319
320 if (!data) {
321 err("bcm5974: out of memory");
322 retval = -ENOMEM;
323 goto out;
324 }
325
326 /* read configuration */
327 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
328 BCM5974_WELLSPRING_MODE_READ_REQUEST_ID,
329 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
330 BCM5974_WELLSPRING_MODE_REQUEST_VALUE,
331 BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
332
333 if (size != 8) {
334 err("bcm5974: could not read from device");
335 retval = -EIO;
336 goto out;
337 }
338
339 /* apply the mode switch */
340 data[0] = BCM5974_WELLSPRING_MODE_VENDOR_VALUE;
341
342 /* write configuration */
343 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
344 BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,
345 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
346 BCM5974_WELLSPRING_MODE_REQUEST_VALUE,
347 BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
348
349 if (size != 8) {
350 err("bcm5974: could not write to device");
351 retval = -EIO;
352 goto out;
353 }
354
355 dprintk(2, "bcm5974: switched to wellspring mode.\n");
356
357 out:
358 kfree(data);
359 return retval;
360}
361
362static void bcm5974_irq_button(struct urb *urb)
363{
364 struct bcm5974 *dev = urb->context;
365 int error;
366
367 switch (urb->status) {
368 case 0:
369 break;
370 case -EOVERFLOW:
371 case -ECONNRESET:
372 case -ENOENT:
373 case -ESHUTDOWN:
374 dbg("bcm5974: button urb shutting down: %d", urb->status);
375 return;
376 default:
377 dbg("bcm5974: button urb status: %d", urb->status);
378 goto exit;
379 }
380
381 if (report_bt_state(dev, dev->bt_urb->actual_length))
382 dprintk(1, "bcm5974: bad button package, length: %d\n",
383 dev->bt_urb->actual_length);
384
385exit:
386 error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC);
387 if (error)
388 err("bcm5974: button urb failed: %d", error);
389}
390
391static void bcm5974_irq_trackpad(struct urb *urb)
392{
393 struct bcm5974 *dev = urb->context;
394 int error;
395
396 switch (urb->status) {
397 case 0:
398 break;
399 case -EOVERFLOW:
400 case -ECONNRESET:
401 case -ENOENT:
402 case -ESHUTDOWN:
403 dbg("bcm5974: trackpad urb shutting down: %d", urb->status);
404 return;
405 default:
406 dbg("bcm5974: trackpad urb status: %d", urb->status);
407 goto exit;
408 }
409
410 /* control response ignored */
411 if (dev->tp_urb->actual_length == 2)
412 goto exit;
413
414 if (report_tp_state(dev, dev->tp_urb->actual_length))
415 dprintk(1, "bcm5974: bad trackpad package, length: %d\n",
416 dev->tp_urb->actual_length);
417
418exit:
419 error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
420 if (error)
421 err("bcm5974: trackpad urb failed: %d", error);
422}
423
424/*
425 * The Wellspring trackpad, like many recent Apple trackpads, share
426 * the usb device with the keyboard. Since keyboards are usually
427 * handled by the HID system, the device ends up being handled by two
428 * modules. Setting up the device therefore becomes slightly
429 * complicated. To enable multitouch features, a mode switch is
430 * required, which is usually applied via the control interface of the
431 * device. It can be argued where this switch should take place. In
432 * some drivers, like appletouch, the switch is made during
433 * probe. However, the hid module may also alter the state of the
434 * device, resulting in trackpad malfunction under certain
435 * circumstances. To get around this problem, there is at least one
436 * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to
437 * recieve a reset_resume request rather than the normal resume.
438 * Since the implementation of reset_resume is equal to mode switch
439 * plus start_traffic, it seems easier to always do the switch when
440 * starting traffic on the device.
441 */
442static int bcm5974_start_traffic(struct bcm5974 *dev)
443{
444 if (bcm5974_wellspring_mode(dev)) {
445 dprintk(1, "bcm5974: mode switch failed\n");
446 goto error;
447 }
448
449 if (usb_submit_urb(dev->bt_urb, GFP_KERNEL))
450 goto error;
451
452 if (usb_submit_urb(dev->tp_urb, GFP_KERNEL))
453 goto err_kill_bt;
454
455 return 0;
456
457err_kill_bt:
458 usb_kill_urb(dev->bt_urb);
459error:
460 return -EIO;
461}
462
463static void bcm5974_pause_traffic(struct bcm5974 *dev)
464{
465 usb_kill_urb(dev->tp_urb);
466 usb_kill_urb(dev->bt_urb);
467}
468
469/*
470 * The code below implements open/close and manual suspend/resume.
471 * All functions may be called in random order.
472 *
473 * Opening a suspended device fails with EACCES - permission denied.
474 *
475 * Failing a resume leaves the device resumed but closed.
476 */
477static int bcm5974_open(struct input_dev *input)
478{
479 struct bcm5974 *dev = input_get_drvdata(input);
480 int error;
481
482 error = usb_autopm_get_interface(dev->intf);
483 if (error)
484 return error;
485
486 mutex_lock(&dev->pm_mutex);
487
488 error = bcm5974_start_traffic(dev);
489 if (!error)
490 dev->opened = 1;
491
492 mutex_unlock(&dev->pm_mutex);
493
494 if (error)
495 usb_autopm_put_interface(dev->intf);
496
497 return error;
498}
499
500static void bcm5974_close(struct input_dev *input)
501{
502 struct bcm5974 *dev = input_get_drvdata(input);
503
504 mutex_lock(&dev->pm_mutex);
505
506 bcm5974_pause_traffic(dev);
507 dev->opened = 0;
508
509 mutex_unlock(&dev->pm_mutex);
510
511 usb_autopm_put_interface(dev->intf);
512}
513
514static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message)
515{
516 struct bcm5974 *dev = usb_get_intfdata(iface);
517
518 mutex_lock(&dev->pm_mutex);
519
520 if (dev->opened)
521 bcm5974_pause_traffic(dev);
522
523 mutex_unlock(&dev->pm_mutex);
524
525 return 0;
526}
527
528static int bcm5974_resume(struct usb_interface *iface)
529{
530 struct bcm5974 *dev = usb_get_intfdata(iface);
531 int error = 0;
532
533 mutex_lock(&dev->pm_mutex);
534
535 if (dev->opened)
536 error = bcm5974_start_traffic(dev);
537
538 mutex_unlock(&dev->pm_mutex);
539
540 return error;
541}
542
543static int bcm5974_probe(struct usb_interface *iface,
544 const struct usb_device_id *id)
545{
546 struct usb_device *udev = interface_to_usbdev(iface);
547 const struct bcm5974_config *cfg;
548 struct bcm5974 *dev;
549 struct input_dev *input_dev;
550 int error = -ENOMEM;
551
552 /* find the product index */
553 cfg = bcm5974_get_config(udev);
554
555 /* allocate memory for our device state and initialize it */
556 dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL);
557 input_dev = input_allocate_device();
558 if (!dev || !input_dev) {
559 err("bcm5974: out of memory");
560 goto err_free_devs;
561 }
562
563 dev->udev = udev;
564 dev->intf = iface;
565 dev->input = input_dev;
566 dev->cfg = *cfg;
567 mutex_init(&dev->pm_mutex);
568
569 /* setup urbs */
570 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
571 if (!dev->bt_urb)
572 goto err_free_devs;
573
574 dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL);
575 if (!dev->tp_urb)
576 goto err_free_bt_urb;
577
578 dev->bt_data = usb_buffer_alloc(dev->udev,
579 dev->cfg.bt_datalen, GFP_KERNEL,
580 &dev->bt_urb->transfer_dma);
581 if (!dev->bt_data)
582 goto err_free_urb;
583
584 dev->tp_data = usb_buffer_alloc(dev->udev,
585 dev->cfg.tp_datalen, GFP_KERNEL,
586 &dev->tp_urb->transfer_dma);
587 if (!dev->tp_data)
588 goto err_free_bt_buffer;
589
590 usb_fill_int_urb(dev->bt_urb, udev,
591 usb_rcvintpipe(udev, cfg->bt_ep),
592 dev->bt_data, dev->cfg.bt_datalen,
593 bcm5974_irq_button, dev, 1);
594
595 usb_fill_int_urb(dev->tp_urb, udev,
596 usb_rcvintpipe(udev, cfg->tp_ep),
597 dev->tp_data, dev->cfg.tp_datalen,
598 bcm5974_irq_trackpad, dev, 1);
599
600 /* create bcm5974 device */
601 usb_make_path(udev, dev->phys, sizeof(dev->phys));
602 strlcat(dev->phys, "/input0", sizeof(dev->phys));
603
604 input_dev->name = "bcm5974";
605 input_dev->phys = dev->phys;
606 usb_to_input_id(dev->udev, &input_dev->id);
607 input_dev->dev.parent = &iface->dev;
608
609 input_set_drvdata(input_dev, dev);
610
611 input_dev->open = bcm5974_open;
612 input_dev->close = bcm5974_close;
613
614 setup_events_to_report(input_dev, cfg);
615
616 error = input_register_device(dev->input);
617 if (error)
618 goto err_free_buffer;
619
620 /* save our data pointer in this interface device */
621 usb_set_intfdata(iface, dev);
622
623 return 0;
624
625err_free_buffer:
626 usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
627 dev->tp_data, dev->tp_urb->transfer_dma);
628err_free_bt_buffer:
629 usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
630 dev->bt_data, dev->bt_urb->transfer_dma);
631err_free_urb:
632 usb_free_urb(dev->tp_urb);
633err_free_bt_urb:
634 usb_free_urb(dev->bt_urb);
635err_free_devs:
636 usb_set_intfdata(iface, NULL);
637 input_free_device(input_dev);
638 kfree(dev);
639 return error;
640}
641
642static void bcm5974_disconnect(struct usb_interface *iface)
643{
644 struct bcm5974 *dev = usb_get_intfdata(iface);
645
646 usb_set_intfdata(iface, NULL);
647
648 input_unregister_device(dev->input);
649 usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
650 dev->tp_data, dev->tp_urb->transfer_dma);
651 usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
652 dev->bt_data, dev->bt_urb->transfer_dma);
653 usb_free_urb(dev->tp_urb);
654 usb_free_urb(dev->bt_urb);
655 kfree(dev);
656}
657
658static struct usb_driver bcm5974_driver = {
659 .name = "bcm5974",
660 .probe = bcm5974_probe,
661 .disconnect = bcm5974_disconnect,
662 .suspend = bcm5974_suspend,
663 .resume = bcm5974_resume,
664 .reset_resume = bcm5974_resume,
665 .id_table = bcm5974_table,
666 .supports_autosuspend = 1,
667};
668
669static int __init bcm5974_init(void)
670{
671 return usb_register(&bcm5974_driver);
672}
673
674static void __exit bcm5974_exit(void)
675{
676 usb_deregister(&bcm5974_driver);
677}
678
679module_init(bcm5974_init);
680module_exit(bcm5974_exit);
681
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 339290184871..72cf5e33790e 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -9,7 +9,6 @@
9 */ 9 */
10 10
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/version.h>
13#include <linux/module.h> 12#include <linux/module.h>
14#include <linux/platform_device.h> 13#include <linux/platform_device.h>
15#include <linux/input-polldev.h> 14#include <linux/input-polldev.h>
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
index 18a48636ba4a..56c079ef5018 100644
--- a/drivers/input/mouse/rpcmouse.c
+++ b/drivers/input/mouse/rpcmouse.c
@@ -23,7 +23,7 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/input.h> 24#include <linux/input.h>
25 25
26#include <asm/hardware.h> 26#include <mach/hardware.h>
27#include <asm/irq.h> 27#include <asm/irq.h>
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/hardware/iomd.h> 29#include <asm/hardware/iomd.h>
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index d9ca55891cd7..692a79ec2a22 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -1,10 +1,11 @@
1#ifndef _I8042_SPARCIO_H 1#ifndef _I8042_SPARCIO_H
2#define _I8042_SPARCIO_H 2#define _I8042_SPARCIO_H
3 3
4#include <linux/of_device.h>
5
4#include <asm/io.h> 6#include <asm/io.h>
5#include <asm/oplib.h> 7#include <asm/oplib.h>
6#include <asm/prom.h> 8#include <asm/prom.h>
7#include <asm/of_device.h>
8 9
9static int i8042_kbd_irq = -1; 10static int i8042_kbd_irq = -1;
10static int i8042_aux_irq = -1; 11static int i8042_aux_irq = -1;
@@ -41,6 +42,8 @@ static inline void i8042_write_command(int val)
41 writeb(val, kbd_iobase + 0x64UL); 42 writeb(val, kbd_iobase + 0x64UL);
42} 43}
43 44
45#ifdef CONFIG_PCI
46
44#define OBP_PS2KBD_NAME1 "kb_ps2" 47#define OBP_PS2KBD_NAME1 "kb_ps2"
45#define OBP_PS2KBD_NAME2 "keyboard" 48#define OBP_PS2KBD_NAME2 "keyboard"
46#define OBP_PS2MS_NAME1 "kdmouse" 49#define OBP_PS2MS_NAME1 "kdmouse"
@@ -101,9 +104,6 @@ static struct of_platform_driver sparc_i8042_driver = {
101 104
102static int __init i8042_platform_init(void) 105static int __init i8042_platform_init(void)
103{ 106{
104#ifndef CONFIG_PCI
105 return -ENODEV;
106#else
107 struct device_node *root = of_find_node_by_path("/"); 107 struct device_node *root = of_find_node_by_path("/");
108 108
109 if (!strcmp(root->name, "SUNW,JavaStation-1")) { 109 if (!strcmp(root->name, "SUNW,JavaStation-1")) {
@@ -131,17 +131,25 @@ static int __init i8042_platform_init(void)
131 i8042_reset = 1; 131 i8042_reset = 1;
132 132
133 return 0; 133 return 0;
134#endif /* CONFIG_PCI */
135} 134}
136 135
137static inline void i8042_platform_exit(void) 136static inline void i8042_platform_exit(void)
138{ 137{
139#ifdef CONFIG_PCI
140 struct device_node *root = of_find_node_by_path("/"); 138 struct device_node *root = of_find_node_by_path("/");
141 139
142 if (strcmp(root->name, "SUNW,JavaStation-1")) 140 if (strcmp(root->name, "SUNW,JavaStation-1"))
143 of_unregister_driver(&sparc_i8042_driver); 141 of_unregister_driver(&sparc_i8042_driver);
144#endif
145} 142}
146 143
144#else /* !CONFIG_PCI */
145static int __init i8042_platform_init(void)
146{
147 return -ENODEV;
148}
149
150static inline void i8042_platform_exit(void)
151{
152}
153#endif /* !CONFIG_PCI */
154
147#endif /* _I8042_SPARCIO_H */ 155#endif /* _I8042_SPARCIO_H */
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index fe732a574ec2..3282b741e246 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -394,6 +394,13 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
394 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), 394 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
395 }, 395 },
396 }, 396 },
397 {
398 .ident = "Acer TravelMate 4280",
399 .matches = {
400 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
401 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
402 },
403 },
397 { } 404 { }
398}; 405};
399 406
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 1567b7782478..7f36edd34f8b 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -35,7 +35,7 @@
35#include <linux/platform_device.h> 35#include <linux/platform_device.h>
36 36
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/hardware.h> 38#include <mach/hardware.h>
39#include <asm/io.h> 39#include <asm/io.h>
40#include <asm/hardware/iomd.h> 40#include <asm/hardware/iomd.h>
41#include <asm/system.h> 41#include <asm/system.h>
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 0ed044d5e685..765007899d9a 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -269,8 +269,8 @@ static int xps2_setup(struct device *dev, struct resource *regs_res,
269 * we have the PS2 in a good state */ 269 * we have the PS2 in a good state */
270 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); 270 out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);
271 271
272 dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%08X, irq=%d\n", 272 dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%p, irq=%d\n",
273 drvdata->phys_addr, (u32)drvdata->base_address, drvdata->irq); 273 drvdata->phys_addr, drvdata->base_address, drvdata->irq);
274 274
275 serio = &drvdata->serio; 275 serio = &drvdata->serio;
276 serio->id.type = SERIO_8042; 276 serio->id.type = SERIO_8042;
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index b9b7a98bc5a5..7df0228e836e 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -64,7 +64,6 @@ Scott Hill shill@gtcocalcomp.com
64#include <asm/byteorder.h> 64#include <asm/byteorder.h>
65 65
66 66
67#include <linux/version.h>
68#include <linux/usb/input.h> 67#include <linux/usb/input.h>
69 68
70/* Version with a Major number of 2 is for kernel inclusion only. */ 69/* Version with a Major number of 2 is for kernel inclusion only. */
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6e60a97a234c..25287e80e236 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -249,29 +249,26 @@ config TOUCHSCREEN_WM97XX
249config TOUCHSCREEN_WM9705 249config TOUCHSCREEN_WM9705
250 bool "WM9705 Touchscreen interface support" 250 bool "WM9705 Touchscreen interface support"
251 depends on TOUCHSCREEN_WM97XX 251 depends on TOUCHSCREEN_WM97XX
252 default y
252 help 253 help
253 Say Y here if you have a Wolfson Microelectronics WM9705 254 Say Y here to enable support for the Wolfson Microelectronics
254 touchscreen controller connected to your system. 255 WM9705 touchscreen controller.
255
256 If unsure, say N.
257 256
258config TOUCHSCREEN_WM9712 257config TOUCHSCREEN_WM9712
259 bool "WM9712 Touchscreen interface support" 258 bool "WM9712 Touchscreen interface support"
260 depends on TOUCHSCREEN_WM97XX 259 depends on TOUCHSCREEN_WM97XX
260 default y
261 help 261 help
262 Say Y here if you have a Wolfson Microelectronics WM9712 262 Say Y here to enable support for the Wolfson Microelectronics
263 touchscreen controller connected to your system. 263 WM9712 touchscreen controller.
264
265 If unsure, say N.
266 264
267config TOUCHSCREEN_WM9713 265config TOUCHSCREEN_WM9713
268 bool "WM9713 Touchscreen interface support" 266 bool "WM9713 Touchscreen interface support"
269 depends on TOUCHSCREEN_WM97XX 267 depends on TOUCHSCREEN_WM97XX
268 default y
270 help 269 help
271 Say Y here if you have a Wolfson Microelectronics WM9713 touchscreen 270 Say Y here to enable support for the Wolfson Microelectronics
272 controller connected to your system. 271 WM9713 touchscreen controller.
273
274 If unsure, say N.
275 272
276config TOUCHSCREEN_WM97XX_MAINSTONE 273config TOUCHSCREEN_WM97XX_MAINSTONE
277 tristate "WM97xx Mainstone accelerated touch" 274 tristate "WM97xx Mainstone accelerated touch"
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index d0e13fc4a88c..65202c9f63ff 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -19,10 +19,10 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/irq.h> 20#include <linux/irq.h>
21 21
22#include <asm/arch/sharpsl.h> 22#include <mach/sharpsl.h>
23#include <asm/arch/hardware.h> 23#include <mach/hardware.h>
24#include <asm/arch/pxa-regs.h> 24#include <mach/pxa-regs.h>
25#include <asm/arch/pxa2xx-gpio.h> 25#include <mach/pxa2xx-gpio.h>
26 26
27 27
28#define PWR_MODE_ACTIVE 0 28#define PWR_MODE_ACTIVE 0
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index 4f86081dc7fc..4d3139e2099d 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -39,8 +39,8 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40 40
41/* SA1100 serial defines */ 41/* SA1100 serial defines */
42#include <asm/arch/hardware.h> 42#include <mach/hardware.h>
43#include <asm/arch/irqs.h> 43#include <mach/irqs.h>
44 44
45#define DRIVER_DESC "H3600 touchscreen driver" 45#define DRIVER_DESC "H3600 touchscreen driver"
46 46
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c
index 1aca108b1031..bf44f9d68342 100644
--- a/drivers/input/touchscreen/jornada720_ts.c
+++ b/drivers/input/touchscreen/jornada720_ts.c
@@ -19,8 +19,8 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/module.h> 20#include <linux/module.h>
21 21
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/arch/jornada720.h> 23#include <mach/jornada720.h>
24 24
25MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>"); 25MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
26MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver"); 26MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver");
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 590a1379aa32..283f93a0cee2 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -33,7 +33,7 @@
33#include <linux/interrupt.h> 33#include <linux/interrupt.h>
34#include <linux/wm97xx.h> 34#include <linux/wm97xx.h>
35#include <linux/io.h> 35#include <linux/io.h>
36#include <asm/arch/pxa-regs.h> 36#include <mach/pxa-regs.h>
37 37
38#define VERSION "0.13" 38#define VERSION "0.13"
39 39
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c
index 978e1a13ffc7..372efbc694ff 100644
--- a/drivers/input/touchscreen/wm9705.c
+++ b/drivers/input/touchscreen/wm9705.c
@@ -17,7 +17,6 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/version.h>
21#include <linux/kernel.h> 20#include <linux/kernel.h>
22#include <linux/input.h> 21#include <linux/input.h>
23#include <linux/delay.h> 22#include <linux/delay.h>
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c
index 4c5d85a249ae..c8bb1e7335fc 100644
--- a/drivers/input/touchscreen/wm9712.c
+++ b/drivers/input/touchscreen/wm9712.c
@@ -17,7 +17,6 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/version.h>
21#include <linux/kernel.h> 20#include <linux/kernel.h>
22#include <linux/input.h> 21#include <linux/input.h>
23#include <linux/delay.h> 22#include <linux/delay.h>
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c
index 838458792ea0..781ee83547e6 100644
--- a/drivers/input/touchscreen/wm9713.c
+++ b/drivers/input/touchscreen/wm9713.c
@@ -17,7 +17,6 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/version.h>
21#include <linux/kernel.h> 20#include <linux/kernel.h>
22#include <linux/input.h> 21#include <linux/input.h>
23#include <linux/delay.h> 22#include <linux/delay.h>
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index cdc24ad314e0..d589ab0e3adc 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -37,7 +37,6 @@
37 37
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/moduleparam.h> 39#include <linux/moduleparam.h>
40#include <linux/version.h>
41#include <linux/kernel.h> 40#include <linux/kernel.h>
42#include <linux/init.h> 41#include <linux/init.h>
43#include <linux/delay.h> 42#include <linux/delay.h>
diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c
index c37bb0d5a0c5..32c98b2efa3f 100644
--- a/drivers/leds/leds-ams-delta.c
+++ b/drivers/leds/leds-ams-delta.c
@@ -12,7 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/leds.h> 14#include <linux/leds.h>
15#include <asm/arch/board-ams-delta.h> 15#include <mach/board-ams-delta.h>
16 16
17/* 17/*
18 * Our context 18 * Our context
diff --git a/drivers/leds/leds-cm-x270.c b/drivers/leds/leds-cm-x270.c
index accc7eddb788..836a43d776e6 100644
--- a/drivers/leds/leds-cm-x270.c
+++ b/drivers/leds/leds-cm-x270.c
@@ -18,8 +18,8 @@
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/leds.h> 19#include <linux/leds.h>
20 20
21#include <asm/arch/hardware.h> 21#include <mach/hardware.h>
22#include <asm/arch/pxa-regs.h> 22#include <mach/pxa-regs.h>
23 23
24#define GPIO_RED_LED (93) 24#define GPIO_RED_LED (93)
25#define GPIO_GREEN_LED (94) 25#define GPIO_GREEN_LED (94)
diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c
index a709704b9f93..bc2dcd89f635 100644
--- a/drivers/leds/leds-corgi.c
+++ b/drivers/leds/leds-corgi.c
@@ -15,10 +15,9 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <asm/mach-types.h> 18#include <mach/corgi.h>
19#include <asm/arch/corgi.h> 19#include <mach/hardware.h>
20#include <asm/arch/hardware.h> 20#include <mach/pxa-regs.h>
21#include <asm/arch/pxa-regs.h>
22#include <asm/hardware/scoop.h> 21#include <asm/hardware/scoop.h>
23 22
24static void corgiled_amber_set(struct led_classdev *led_cdev, 23static void corgiled_amber_set(struct led_classdev *led_cdev,
diff --git a/drivers/leds/leds-fsg.c b/drivers/leds/leds-fsg.c
index a7421b8c47d8..be0e12144b8b 100644
--- a/drivers/leds/leds-fsg.c
+++ b/drivers/leds/leds-fsg.c
@@ -19,7 +19,7 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/leds.h> 21#include <linux/leds.h>
22#include <asm/arch/hardware.h> 22#include <mach/hardware.h>
23#include <asm/io.h> 23#include <asm/io.h>
24 24
25static short __iomem *latch_address; 25static short __iomem *latch_address;
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
index 73c705021686..11b77a70bbcb 100644
--- a/drivers/leds/leds-h1940.c
+++ b/drivers/leds/leds-h1940.c
@@ -16,9 +16,9 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/ctype.h> 17#include <linux/ctype.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19#include <asm/arch/regs-gpio.h> 19#include <mach/regs-gpio.h>
20#include <asm/hardware.h> 20#include <mach/hardware.h>
21#include <asm/arch/h1940-latch.h> 21#include <mach/h1940-latch.h>
22 22
23/* 23/*
24 * Green led. 24 * Green led.
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 7295f7f52185..5d91362e3066 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -13,7 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/leds.h> 14#include <linux/leds.h>
15 15
16#include <asm/hardware.h> 16#include <mach/hardware.h>
17#include <asm/hardware/locomo.h> 17#include <asm/hardware/locomo.h>
18 18
19static void locomoled_brightness_set(struct led_classdev *led_cdev, 19static void locomoled_brightness_set(struct led_classdev *led_cdev,
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index d4f5021dccbf..25a07f2643ad 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -16,9 +16,9 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/leds.h> 17#include <linux/leds.h>
18 18
19#include <asm/hardware.h> 19#include <mach/hardware.h>
20#include <asm/arch/regs-gpio.h> 20#include <mach/regs-gpio.h>
21#include <asm/arch/leds-gpio.h> 21#include <mach/leds-gpio.h>
22 22
23/* our context */ 23/* our context */
24 24
diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c
index e75e8543bc5a..178831c64bfb 100644
--- a/drivers/leds/leds-spitz.c
+++ b/drivers/leds/leds-spitz.c
@@ -17,9 +17,9 @@
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <asm/hardware/scoop.h> 18#include <asm/hardware/scoop.h>
19#include <asm/mach-types.h> 19#include <asm/mach-types.h>
20#include <asm/arch/hardware.h> 20#include <mach/hardware.h>
21#include <asm/arch/pxa-regs.h> 21#include <mach/pxa-regs.h>
22#include <asm/arch/spitz.h> 22#include <mach/spitz.h>
23 23
24static void spitzled_amber_set(struct led_classdev *led_cdev, 24static void spitzled_amber_set(struct led_classdev *led_cdev,
25 enum led_brightness value) 25 enum led_brightness value)
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index d93500f24fbb..81d0c6053447 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -108,9 +108,8 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
108} 108}
109/*:*/ 109/*:*/
110 110
111/*M:014 get_pfn is slow; it takes the mmap sem and calls get_user_pages. We 111/*M:014 get_pfn is slow: we could probably try to grab batches of pages here as
112 * could probably try to grab batches of pages here as an optimization 112 * an optimization (ie. pre-faulting). :*/
113 * (ie. pre-faulting). :*/
114 113
115/*H:350 This routine takes a page number given by the Guest and converts it to 114/*H:350 This routine takes a page number given by the Guest and converts it to
116 * an actual, physical page number. It can fail for several reasons: the 115 * an actual, physical page number. It can fail for several reasons: the
@@ -123,19 +122,13 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
123static unsigned long get_pfn(unsigned long virtpfn, int write) 122static unsigned long get_pfn(unsigned long virtpfn, int write)
124{ 123{
125 struct page *page; 124 struct page *page;
126 /* This value indicates failure. */
127 unsigned long ret = -1UL;
128 125
129 /* get_user_pages() is a complex interface: it gets the "struct 126 /* gup me one page at this address please! */
130 * vm_area_struct" and "struct page" assocated with a range of pages. 127 if (get_user_pages_fast(virtpfn << PAGE_SHIFT, 1, write, &page) == 1)
131 * It also needs the task's mmap_sem held, and is not very quick. 128 return page_to_pfn(page);
132 * It returns the number of pages it got. */ 129
133 down_read(&current->mm->mmap_sem); 130 /* This value indicates failure. */
134 if (get_user_pages(current, current->mm, virtpfn << PAGE_SHIFT, 131 return -1UL;
135 1, write, 1, &page, NULL) == 1)
136 ret = page_to_pfn(page);
137 up_read(&current->mm->mmap_sem);
138 return ret;
139} 132}
140 133
141/*H:340 Converting a Guest page table entry to a shadow (ie. real) page table 134/*H:340 Converting a Guest page table entry to a shadow (ie. real) page table
@@ -174,7 +167,7 @@ static pte_t gpte_to_spte(struct lg_cpu *cpu, pte_t gpte, int write)
174/*H:460 And to complete the chain, release_pte() looks like this: */ 167/*H:460 And to complete the chain, release_pte() looks like this: */
175static void release_pte(pte_t pte) 168static void release_pte(pte_t pte)
176{ 169{
177 /* Remember that get_user_pages() took a reference to the page, in 170 /* Remember that get_user_pages_fast() took a reference to the page, in
178 * get_pfn()? We have to put it back now. */ 171 * get_pfn()? We have to put it back now. */
179 if (pte_flags(pte) & _PAGE_PRESENT) 172 if (pte_flags(pte) & _PAGE_PRESENT)
180 put_page(pfn_to_page(pte_pfn(pte))); 173 put_page(pfn_to_page(pte_pfn(pte)));
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c7aae66c6f9b..8cfadc5bd2ba 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2393,6 +2393,8 @@ static void analyze_sbs(mddev_t * mddev)
2393 2393
2394} 2394}
2395 2395
2396static void md_safemode_timeout(unsigned long data);
2397
2396static ssize_t 2398static ssize_t
2397safe_delay_show(mddev_t *mddev, char *page) 2399safe_delay_show(mddev_t *mddev, char *page)
2398{ 2400{
@@ -2432,9 +2434,12 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
2432 if (msec == 0) 2434 if (msec == 0)
2433 mddev->safemode_delay = 0; 2435 mddev->safemode_delay = 0;
2434 else { 2436 else {
2437 unsigned long old_delay = mddev->safemode_delay;
2435 mddev->safemode_delay = (msec*HZ)/1000; 2438 mddev->safemode_delay = (msec*HZ)/1000;
2436 if (mddev->safemode_delay == 0) 2439 if (mddev->safemode_delay == 0)
2437 mddev->safemode_delay = 1; 2440 mddev->safemode_delay = 1;
2441 if (mddev->safemode_delay < old_delay)
2442 md_safemode_timeout((unsigned long)mddev);
2438 } 2443 }
2439 return len; 2444 return len;
2440} 2445}
@@ -4634,6 +4639,11 @@ static int update_size(mddev_t *mddev, sector_t num_sectors)
4634 */ 4639 */
4635 if (mddev->sync_thread) 4640 if (mddev->sync_thread)
4636 return -EBUSY; 4641 return -EBUSY;
4642 if (mddev->bitmap)
4643 /* Sorry, cannot grow a bitmap yet, just remove it,
4644 * grow, and re-add.
4645 */
4646 return -EBUSY;
4637 rdev_for_each(rdev, tmp, mddev) { 4647 rdev_for_each(rdev, tmp, mddev) {
4638 sector_t avail; 4648 sector_t avail;
4639 avail = rdev->size * 2; 4649 avail = rdev->size * 2;
@@ -5993,7 +6003,7 @@ static int remove_and_add_spares(mddev_t *mddev)
5993 } 6003 }
5994 } 6004 }
5995 6005
5996 if (mddev->degraded) { 6006 if (mddev->degraded && ! mddev->ro) {
5997 rdev_for_each(rdev, rtmp, mddev) { 6007 rdev_for_each(rdev, rtmp, mddev) {
5998 if (rdev->raid_disk >= 0 && 6008 if (rdev->raid_disk >= 0 &&
5999 !test_bit(In_sync, &rdev->flags) && 6009 !test_bit(In_sync, &rdev->flags) &&
@@ -6067,6 +6077,8 @@ void md_check_recovery(mddev_t *mddev)
6067 flush_signals(current); 6077 flush_signals(current);
6068 } 6078 }
6069 6079
6080 if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
6081 return;
6070 if ( ! ( 6082 if ( ! (
6071 (mddev->flags && !mddev->external) || 6083 (mddev->flags && !mddev->external) ||
6072 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || 6084 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
@@ -6080,6 +6092,15 @@ void md_check_recovery(mddev_t *mddev)
6080 if (mddev_trylock(mddev)) { 6092 if (mddev_trylock(mddev)) {
6081 int spares = 0; 6093 int spares = 0;
6082 6094
6095 if (mddev->ro) {
6096 /* Only thing we do on a ro array is remove
6097 * failed devices.
6098 */
6099 remove_and_add_spares(mddev);
6100 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
6101 goto unlock;
6102 }
6103
6083 if (!mddev->external) { 6104 if (!mddev->external) {
6084 int did_change = 0; 6105 int did_change = 0;
6085 spin_lock_irq(&mddev->write_lock); 6106 spin_lock_irq(&mddev->write_lock);
@@ -6117,7 +6138,8 @@ void md_check_recovery(mddev_t *mddev)
6117 /* resync has finished, collect result */ 6138 /* resync has finished, collect result */
6118 md_unregister_thread(mddev->sync_thread); 6139 md_unregister_thread(mddev->sync_thread);
6119 mddev->sync_thread = NULL; 6140 mddev->sync_thread = NULL;
6120 if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { 6141 if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
6142 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
6121 /* success...*/ 6143 /* success...*/
6122 /* activate any spares */ 6144 /* activate any spares */
6123 if (mddev->pers->spare_active(mddev)) 6145 if (mddev->pers->spare_active(mddev))
@@ -6169,6 +6191,7 @@ void md_check_recovery(mddev_t *mddev)
6169 } else if ((spares = remove_and_add_spares(mddev))) { 6191 } else if ((spares = remove_and_add_spares(mddev))) {
6170 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); 6192 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
6171 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); 6193 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
6194 clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
6172 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); 6195 set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
6173 } else if (mddev->recovery_cp < MaxSector) { 6196 } else if (mddev->recovery_cp < MaxSector) {
6174 set_bit(MD_RECOVERY_SYNC, &mddev->recovery); 6197 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
@@ -6232,7 +6255,11 @@ static int md_notify_reboot(struct notifier_block *this,
6232 6255
6233 for_each_mddev(mddev, tmp) 6256 for_each_mddev(mddev, tmp)
6234 if (mddev_trylock(mddev)) { 6257 if (mddev_trylock(mddev)) {
6235 do_md_stop (mddev, 1, 0); 6258 /* Force a switch to readonly even array
6259 * appears to still be in use. Hence
6260 * the '100'.
6261 */
6262 do_md_stop (mddev, 1, 100);
6236 mddev_unlock(mddev); 6263 mddev_unlock(mddev);
6237 } 6264 }
6238 /* 6265 /*
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d41bebb6da0f..e34cd0e62473 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -76,11 +76,13 @@ static void r10bio_pool_free(void *r10_bio, void *data)
76 kfree(r10_bio); 76 kfree(r10_bio);
77} 77}
78 78
79/* Maximum size of each resync request */
79#define RESYNC_BLOCK_SIZE (64*1024) 80#define RESYNC_BLOCK_SIZE (64*1024)
80//#define RESYNC_BLOCK_SIZE PAGE_SIZE
81#define RESYNC_SECTORS (RESYNC_BLOCK_SIZE >> 9)
82#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) 81#define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE)
83#define RESYNC_WINDOW (2048*1024) 82/* amount of memory to reserve for resync requests */
83#define RESYNC_WINDOW (1024*1024)
84/* maximum number of concurrent requests, memory permitting */
85#define RESYNC_DEPTH (32*1024*1024/RESYNC_BLOCK_SIZE)
84 86
85/* 87/*
86 * When performing a resync, we need to read and compare, so 88 * When performing a resync, we need to read and compare, so
@@ -690,7 +692,6 @@ static int flush_pending_writes(conf_t *conf)
690 * there is no normal IO happeing. It must arrange to call 692 * there is no normal IO happeing. It must arrange to call
691 * lower_barrier when the particular background IO completes. 693 * lower_barrier when the particular background IO completes.
692 */ 694 */
693#define RESYNC_DEPTH 32
694 695
695static void raise_barrier(conf_t *conf, int force) 696static void raise_barrier(conf_t *conf, int force)
696{ 697{
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 40e939675657..224de022e7c5 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2568,10 +2568,10 @@ static bool handle_stripe5(struct stripe_head *sh)
2568 if (dev->written) 2568 if (dev->written)
2569 s.written++; 2569 s.written++;
2570 rdev = rcu_dereference(conf->disks[i].rdev); 2570 rdev = rcu_dereference(conf->disks[i].rdev);
2571 if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { 2571 if (blocked_rdev == NULL &&
2572 rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
2572 blocked_rdev = rdev; 2573 blocked_rdev = rdev;
2573 atomic_inc(&rdev->nr_pending); 2574 atomic_inc(&rdev->nr_pending);
2574 break;
2575 } 2575 }
2576 if (!rdev || !test_bit(In_sync, &rdev->flags)) { 2576 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
2577 /* The ReadError flag will just be confusing now */ 2577 /* The ReadError flag will just be confusing now */
@@ -2588,8 +2588,14 @@ static bool handle_stripe5(struct stripe_head *sh)
2588 rcu_read_unlock(); 2588 rcu_read_unlock();
2589 2589
2590 if (unlikely(blocked_rdev)) { 2590 if (unlikely(blocked_rdev)) {
2591 set_bit(STRIPE_HANDLE, &sh->state); 2591 if (s.syncing || s.expanding || s.expanded ||
2592 goto unlock; 2592 s.to_write || s.written) {
2593 set_bit(STRIPE_HANDLE, &sh->state);
2594 goto unlock;
2595 }
2596 /* There is nothing for the blocked_rdev to block */
2597 rdev_dec_pending(blocked_rdev, conf->mddev);
2598 blocked_rdev = NULL;
2593 } 2599 }
2594 2600
2595 if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) { 2601 if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) {
@@ -2832,10 +2838,10 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
2832 if (dev->written) 2838 if (dev->written)
2833 s.written++; 2839 s.written++;
2834 rdev = rcu_dereference(conf->disks[i].rdev); 2840 rdev = rcu_dereference(conf->disks[i].rdev);
2835 if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { 2841 if (blocked_rdev == NULL &&
2842 rdev && unlikely(test_bit(Blocked, &rdev->flags))) {
2836 blocked_rdev = rdev; 2843 blocked_rdev = rdev;
2837 atomic_inc(&rdev->nr_pending); 2844 atomic_inc(&rdev->nr_pending);
2838 break;
2839 } 2845 }
2840 if (!rdev || !test_bit(In_sync, &rdev->flags)) { 2846 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
2841 /* The ReadError flag will just be confusing now */ 2847 /* The ReadError flag will just be confusing now */
@@ -2853,9 +2859,16 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
2853 rcu_read_unlock(); 2859 rcu_read_unlock();
2854 2860
2855 if (unlikely(blocked_rdev)) { 2861 if (unlikely(blocked_rdev)) {
2856 set_bit(STRIPE_HANDLE, &sh->state); 2862 if (s.syncing || s.expanding || s.expanded ||
2857 goto unlock; 2863 s.to_write || s.written) {
2864 set_bit(STRIPE_HANDLE, &sh->state);
2865 goto unlock;
2866 }
2867 /* There is nothing for the blocked_rdev to block */
2868 rdev_dec_pending(blocked_rdev, conf->mddev);
2869 blocked_rdev = NULL;
2858 } 2870 }
2871
2859 pr_debug("locked=%d uptodate=%d to_read=%d" 2872 pr_debug("locked=%d uptodate=%d to_read=%d"
2860 " to_write=%d failed=%d failed_num=%d,%d\n", 2873 " to_write=%d failed=%d failed_num=%d,%d\n",
2861 s.locked, s.uptodate, s.to_read, s.to_write, s.failed, 2874 s.locked, s.uptodate, s.to_read, s.to_write, s.failed,
@@ -4446,6 +4459,9 @@ static int raid5_check_reshape(mddev_t *mddev)
4446 return -EINVAL; /* Cannot shrink array or change level yet */ 4459 return -EINVAL; /* Cannot shrink array or change level yet */
4447 if (mddev->delta_disks == 0) 4460 if (mddev->delta_disks == 0)
4448 return 0; /* nothing to do */ 4461 return 0; /* nothing to do */
4462 if (mddev->bitmap)
4463 /* Cannot grow a bitmap yet */
4464 return -EBUSY;
4449 4465
4450 /* Can only proceed if there are plenty of stripe_heads. 4466 /* Can only proceed if there are plenty of stripe_heads.
4451 * We need a minimum of one full stripe,, and for sensible progress 4467 * We need a minimum of one full stripe,, and for sensible progress
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 578afce6884c..aaa0b6f0b521 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -565,7 +565,8 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
565 565
566static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) 566static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg)
567{ 567{
568 struct dvb_usb_device *d = ptr; 568 struct dvb_usb_adapter *adap = ptr;
569 struct dvb_usb_device *d = adap->dev;
569 570
570 switch (command) { 571 switch (command) {
571 case XC2028_TUNER_RESET: 572 case XC2028_TUNER_RESET:
@@ -593,9 +594,9 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
593 .callback = dvico_bluebird_xc2028_callback, 594 .callback = dvico_bluebird_xc2028_callback,
594 }; 595 };
595 static struct xc2028_ctrl ctl = { 596 static struct xc2028_ctrl ctl = {
596 .fname = "xc3028-dvico-au-01.fw", 597 .fname = "xc3028-v27.fw",
597 .max_len = 64, 598 .max_len = 64,
598 .scode_table = XC3028_FE_ZARLINK456, 599 .demod = XC3028_FE_ZARLINK456,
599 }; 600 };
600 601
601 fe = dvb_attach(xc2028_attach, adap->fe, &cfg); 602 fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 574dffe91b68..7dbb4a223c99 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -135,9 +135,8 @@ config DVB_CX22702
135 135
136config DVB_DRX397XD 136config DVB_DRX397XD
137 tristate "Micronas DRX3975D/DRX3977D based" 137 tristate "Micronas DRX3975D/DRX3977D based"
138 depends on DVB_CORE && I2C && HOTPLUG 138 depends on DVB_CORE && I2C
139 default m if DVB_FE_CUSTOMISE 139 default m if DVB_FE_CUSTOMISE
140 select FW_LOADER
141 help 140 help
142 A DVB-T tuner module. Say Y when you want to support this frontend. 141 A DVB-T tuner module. Say Y when you want to support this frontend.
143 142
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index d4a6e56a7135..ecbfa1b39b70 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -630,7 +630,7 @@ config VIDEO_ZORAN_ZR36060
630 depends on VIDEO_ZORAN 630 depends on VIDEO_ZORAN
631 help 631 help
632 Say Y to support Zoran boards based on 36060 chips. 632 Say Y to support Zoran boards based on 36060 chips.
633 This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33 633 This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33
634 and 33 R10 and AverMedia 6 boards. 634 and 33 R10 and AverMedia 6 boards.
635 635
636config VIDEO_ZORAN_BUZ 636config VIDEO_ZORAN_BUZ
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 56ebfd5ef6fa..9e436ad3d34b 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -29,6 +29,7 @@
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/videodev.h> 30#include <linux/videodev.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32#include <media/v4l2-ioctl.h>
32#include <linux/mutex.h> 33#include <linux/mutex.h>
33 34
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -755,7 +756,6 @@ static const struct file_operations ar_fops = {
755 756
756static struct video_device ar_template = { 757static struct video_device ar_template = {
757 .name = "Colour AR VGA", 758 .name = "Colour AR VGA",
758 .type = VID_TYPE_CAPTURE,
759 .fops = &ar_fops, 759 .fops = &ar_fops,
760 .release = ar_release, 760 .release = ar_release,
761 .minor = -1, 761 .minor = -1,
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 476ae44a62d2..452da70e719f 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1015,6 +1015,7 @@ struct em28xx_board em28xx_boards[] = {
1015 .valid = EM28XX_BOARD_NOT_VALIDATED, 1015 .valid = EM28XX_BOARD_NOT_VALIDATED,
1016 .vchannels = 3, 1016 .vchannels = 3,
1017 .tuner_type = TUNER_XC2028, 1017 .tuner_type = TUNER_XC2028,
1018 .mts_firmware = 1,
1018 .decoder = EM28XX_TVP5150, 1019 .decoder = EM28XX_TVP5150,
1019 .input = { { 1020 .input = { {
1020 .type = EM28XX_VMUX_TELEVISION, 1021 .type = EM28XX_VMUX_TELEVISION,
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 44b0bffeb20e..cd3a3f5829b2 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -123,7 +123,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
123{ 123{
124 struct usb_device *dev = gspca_dev->dev; 124 struct usb_device *dev = gspca_dev->dev;
125 125
126#ifdef CONFIG_VIDEO_ADV_DEBUG 126#ifdef GSPCA_DEBUG
127 if (len > sizeof gspca_dev->usb_buf) { 127 if (len > sizeof gspca_dev->usb_buf) {
128 err("reg_r: buffer overflow"); 128 err("reg_r: buffer overflow");
129 return; 129 return;
@@ -163,7 +163,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
163{ 163{
164 struct usb_device *dev = gspca_dev->dev; 164 struct usb_device *dev = gspca_dev->dev;
165 165
166#ifdef CONFIG_VIDEO_ADV_DEBUG 166#ifdef GSPCA_DEBUG
167 if (len > sizeof gspca_dev->usb_buf) { 167 if (len > sizeof gspca_dev->usb_buf) {
168 err("reg_w: buffer overflow"); 168 err("reg_w: buffer overflow");
169 return; 169 return;
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index c8c2f02fcf00..1dbe92d01e6a 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -233,7 +233,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
233{ 233{
234 struct usb_device *dev = gspca_dev->dev; 234 struct usb_device *dev = gspca_dev->dev;
235 235
236#ifdef CONFIG_VIDEO_ADV_DEBUG 236#ifdef GSPCA_DEBUG
237 if (len > sizeof gspca_dev->usb_buf) { 237 if (len > sizeof gspca_dev->usb_buf) {
238 err("reg_r: buffer overflow"); 238 err("reg_r: buffer overflow");
239 return; 239 return;
@@ -271,7 +271,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
271{ 271{
272 struct usb_device *dev = gspca_dev->dev; 272 struct usb_device *dev = gspca_dev->dev;
273 273
274#ifdef CONFIG_VIDEO_ADV_DEBUG 274#ifdef GSPCA_DEBUG
275 if (len > sizeof gspca_dev->usb_buf) { 275 if (len > sizeof gspca_dev->usb_buf) {
276 err("reg_w: buffer overflow"); 276 err("reg_w: buffer overflow");
277 return; 277 return;
@@ -461,6 +461,52 @@ static void Et_init2(struct gspca_dev *gspca_dev)
461 reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ 461 reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */
462} 462}
463 463
464static void setbrightness(struct gspca_dev *gspca_dev)
465{
466 struct sd *sd = (struct sd *) gspca_dev;
467 int i;
468 __u8 brightness = sd->brightness;
469
470 for (i = 0; i < 4; i++)
471 reg_w_val(gspca_dev, ET_O_RED + i, brightness);
472}
473
474static void getbrightness(struct gspca_dev *gspca_dev)
475{
476 struct sd *sd = (struct sd *) gspca_dev;
477 int i;
478 int brightness = 0;
479
480 for (i = 0; i < 4; i++) {
481 reg_r(gspca_dev, ET_O_RED + i, 1);
482 brightness += gspca_dev->usb_buf[0];
483 }
484 sd->brightness = brightness >> 3;
485}
486
487static void setcontrast(struct gspca_dev *gspca_dev)
488{
489 struct sd *sd = (struct sd *) gspca_dev;
490 __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
491 __u8 contrast = sd->contrast;
492
493 memset(RGBG, contrast, sizeof(RGBG) - 2);
494 reg_w(gspca_dev, ET_G_RED, RGBG, 6);
495}
496
497static void getcontrast(struct gspca_dev *gspca_dev)
498{
499 struct sd *sd = (struct sd *) gspca_dev;
500 int i;
501 int contrast = 0;
502
503 for (i = 0; i < 4; i++) {
504 reg_r(gspca_dev, ET_G_RED + i, 1);
505 contrast += gspca_dev->usb_buf[0];
506 }
507 sd->contrast = contrast >> 2;
508}
509
464static void setcolors(struct gspca_dev *gspca_dev) 510static void setcolors(struct gspca_dev *gspca_dev)
465{ 511{
466 struct sd *sd = (struct sd *) gspca_dev; 512 struct sd *sd = (struct sd *) gspca_dev;
@@ -492,6 +538,16 @@ static void getcolors(struct gspca_dev *gspca_dev)
492 } 538 }
493} 539}
494 540
541static void setautogain(struct gspca_dev *gspca_dev)
542{
543 struct sd *sd = (struct sd *) gspca_dev;
544
545 if (sd->autogain)
546 sd->ag_cnt = AG_CNT_START;
547 else
548 sd->ag_cnt = -1;
549}
550
495static void Et_init1(struct gspca_dev *gspca_dev) 551static void Et_init1(struct gspca_dev *gspca_dev)
496{ 552{
497 __u8 value; 553 __u8 value;
@@ -614,6 +670,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
614 sd->contrast = CONTRAST_DEF; 670 sd->contrast = CONTRAST_DEF;
615 sd->colors = COLOR_DEF; 671 sd->colors = COLOR_DEF;
616 sd->autogain = AUTOGAIN_DEF; 672 sd->autogain = AUTOGAIN_DEF;
673 sd->ag_cnt = -1;
617 return 0; 674 return 0;
618} 675}
619 676
@@ -641,6 +698,8 @@ static void sd_start(struct gspca_dev *gspca_dev)
641 else 698 else
642 Et_init2(gspca_dev); 699 Et_init2(gspca_dev);
643 700
701 setautogain(gspca_dev);
702
644 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); 703 reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
645 et_video(gspca_dev, 1); /* video on */ 704 et_video(gspca_dev, 1); /* video on */
646} 705}
@@ -658,52 +717,6 @@ static void sd_close(struct gspca_dev *gspca_dev)
658{ 717{
659} 718}
660 719
661static void setbrightness(struct gspca_dev *gspca_dev)
662{
663 struct sd *sd = (struct sd *) gspca_dev;
664 int i;
665 __u8 brightness = sd->brightness;
666
667 for (i = 0; i < 4; i++)
668 reg_w_val(gspca_dev, ET_O_RED + i, brightness);
669}
670
671static void getbrightness(struct gspca_dev *gspca_dev)
672{
673 struct sd *sd = (struct sd *) gspca_dev;
674 int i;
675 int brightness = 0;
676
677 for (i = 0; i < 4; i++) {
678 reg_r(gspca_dev, ET_O_RED + i, 1);
679 brightness += gspca_dev->usb_buf[0];
680 }
681 sd->brightness = brightness >> 3;
682}
683
684static void setcontrast(struct gspca_dev *gspca_dev)
685{
686 struct sd *sd = (struct sd *) gspca_dev;
687 __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
688 __u8 contrast = sd->contrast;
689
690 memset(RGBG, contrast, sizeof(RGBG) - 2);
691 reg_w(gspca_dev, ET_G_RED, RGBG, 6);
692}
693
694static void getcontrast(struct gspca_dev *gspca_dev)
695{
696 struct sd *sd = (struct sd *) gspca_dev;
697 int i;
698 int contrast = 0;
699
700 for (i = 0; i < 4; i++) {
701 reg_r(gspca_dev, ET_G_RED + i, 1);
702 contrast += gspca_dev->usb_buf[0];
703 }
704 sd->contrast = contrast >> 2;
705}
706
707static __u8 Et_getgainG(struct gspca_dev *gspca_dev) 720static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
708{ 721{
709 struct sd *sd = (struct sd *) gspca_dev; 722 struct sd *sd = (struct sd *) gspca_dev;
@@ -733,15 +746,22 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
733#define LIMIT(color) \ 746#define LIMIT(color) \
734 (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) 747 (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color))
735 748
736static void setautogain(struct gspca_dev *gspca_dev) 749static void do_autogain(struct gspca_dev *gspca_dev)
737{ 750{
738 __u8 luma = 0; 751 struct sd *sd = (struct sd *) gspca_dev;
752 __u8 luma;
739 __u8 luma_mean = 128; 753 __u8 luma_mean = 128;
740 __u8 luma_delta = 20; 754 __u8 luma_delta = 20;
741 __u8 spring = 4; 755 __u8 spring = 4;
742 int Gbright = 0; 756 int Gbright;
743 __u8 r, g, b; 757 __u8 r, g, b;
744 758
759 if (sd->ag_cnt < 0)
760 return;
761 if (--sd->ag_cnt >= 0)
762 return;
763 sd->ag_cnt = AG_CNT_START;
764
745 Gbright = Et_getgainG(gspca_dev); 765 Gbright = Et_getgainG(gspca_dev);
746 reg_r(gspca_dev, ET_LUMA_CENTER, 4); 766 reg_r(gspca_dev, ET_LUMA_CENTER, 4);
747 g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; 767 g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
@@ -768,7 +788,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
768 __u8 *data, /* isoc packet */ 788 __u8 *data, /* isoc packet */
769 int len) /* iso packet length */ 789 int len) /* iso packet length */
770{ 790{
771 struct sd *sd;
772 int seqframe; 791 int seqframe;
773 792
774 seqframe = data[0] & 0x3f; 793 seqframe = data[0] & 0x3f;
@@ -783,13 +802,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
783 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 802 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
784 data, 0); 803 data, 0);
785 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); 804 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
786 sd = (struct sd *) gspca_dev;
787 if (sd->ag_cnt >= 0) {
788 if (--sd->ag_cnt < 0) {
789 sd->ag_cnt = AG_CNT_START;
790 setautogain(gspca_dev);
791 }
792 }
793 return; 805 return;
794 } 806 }
795 if (len) { 807 if (len) {
@@ -862,10 +874,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
862 struct sd *sd = (struct sd *) gspca_dev; 874 struct sd *sd = (struct sd *) gspca_dev;
863 875
864 sd->autogain = val; 876 sd->autogain = val;
865 if (val) 877 if (gspca_dev->streaming)
866 sd->ag_cnt = AG_CNT_START; 878 setautogain(gspca_dev);
867 else
868 sd->ag_cnt = -1;
869 return 0; 879 return 0;
870} 880}
871 881
@@ -889,6 +899,7 @@ static struct sd_desc sd_desc = {
889 .stop0 = sd_stop0, 899 .stop0 = sd_stop0,
890 .close = sd_close, 900 .close = sd_close,
891 .pkt_scan = sd_pkt_scan, 901 .pkt_scan = sd_pkt_scan,
902 .dq_callback = do_autogain,
892}; 903};
893 904
894/* -- module initialisation -- */ 905/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 3a051c925ff6..15d302b28b79 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@ MODULE_LICENSE("GPL");
47 47
48static int video_nr = -1; 48static int video_nr = -1;
49 49
50#ifdef CONFIG_VIDEO_ADV_DEBUG 50#ifdef GSPCA_DEBUG
51int gspca_debug = D_ERR | D_PROBE; 51int gspca_debug = D_ERR | D_PROBE;
52EXPORT_SYMBOL(gspca_debug); 52EXPORT_SYMBOL(gspca_debug);
53 53
@@ -677,7 +677,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
677 w = fmt->fmt.pix.width; 677 w = fmt->fmt.pix.width;
678 h = fmt->fmt.pix.height; 678 h = fmt->fmt.pix.height;
679 679
680#ifdef CONFIG_VIDEO_ADV_DEBUG 680#ifdef GSPCA_DEBUG
681 if (gspca_debug & D_CONF) 681 if (gspca_debug & D_CONF)
682 PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); 682 PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h);
683#endif 683#endif
@@ -785,7 +785,7 @@ static int dev_open(struct inode *inode, struct file *file)
785 } 785 }
786 gspca_dev->users++; 786 gspca_dev->users++;
787 file->private_data = gspca_dev; 787 file->private_data = gspca_dev;
788#ifdef CONFIG_VIDEO_ADV_DEBUG 788#ifdef GSPCA_DEBUG
789 /* activate the v4l2 debug */ 789 /* activate the v4l2 debug */
790 if (gspca_debug & D_V4L2) 790 if (gspca_debug & D_V4L2)
791 gspca_dev->vdev.debug |= 3; 791 gspca_dev->vdev.debug |= 3;
@@ -904,7 +904,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
904 if (ctrl->id != ctrls->qctrl.id) 904 if (ctrl->id != ctrls->qctrl.id)
905 continue; 905 continue;
906 if (ctrl->value < ctrls->qctrl.minimum 906 if (ctrl->value < ctrls->qctrl.minimum
907 && ctrl->value > ctrls->qctrl.maximum) 907 || ctrl->value > ctrls->qctrl.maximum)
908 return -ERANGE; 908 return -ERANGE;
909 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); 909 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
910 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) 910 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
@@ -1080,7 +1080,7 @@ static int vidioc_streamon(struct file *file, void *priv,
1080 if (ret < 0) 1080 if (ret < 0)
1081 goto out; 1081 goto out;
1082 } 1082 }
1083#ifdef CONFIG_VIDEO_ADV_DEBUG 1083#ifdef GSPCA_DEBUG
1084 if (gspca_debug & D_STREAM) { 1084 if (gspca_debug & D_STREAM) {
1085 PDEBUG_MODE("stream on OK", 1085 PDEBUG_MODE("stream on OK",
1086 gspca_dev->pixfmt, 1086 gspca_dev->pixfmt,
@@ -1913,7 +1913,7 @@ static void __exit gspca_exit(void)
1913module_init(gspca_init); 1913module_init(gspca_init);
1914module_exit(gspca_exit); 1914module_exit(gspca_exit);
1915 1915
1916#ifdef CONFIG_VIDEO_ADV_DEBUG 1916#ifdef GSPCA_DEBUG
1917module_param_named(debug, gspca_debug, int, 0644); 1917module_param_named(debug, gspca_debug, int, 0644);
1918MODULE_PARM_DESC(debug, 1918MODULE_PARM_DESC(debug,
1919 "Debug (bit) 0x01:error 0x02:probe 0x04:config" 1919 "Debug (bit) 0x01:error 0x02:probe 0x04:config"
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 3fd2c4eee204..67e448940eaa 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -9,7 +9,10 @@
9#include <media/v4l2-common.h> 9#include <media/v4l2-common.h>
10#include <linux/mutex.h> 10#include <linux/mutex.h>
11 11
12#ifdef CONFIG_VIDEO_ADV_DEBUG 12/* compilation option */
13#define GSPCA_DEBUG 1
14
15#ifdef GSPCA_DEBUG
13/* GSPCA our debug messages */ 16/* GSPCA our debug messages */
14extern int gspca_debug; 17extern int gspca_debug;
15#define PDEBUG(level, fmt, args...) \ 18#define PDEBUG(level, fmt, args...) \
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 83139efc4629..b4f00ec0885c 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -40,14 +40,15 @@ struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */ 40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 41
42 /* Determined by sensor type */ 42 /* Determined by sensor type */
43 short maxwidth; 43 char sif;
44 short maxheight;
45 44
46 unsigned char primary_i2c_slave; /* I2C write id of sensor */ 45 unsigned char primary_i2c_slave; /* I2C write id of sensor */
47 46
48 unsigned char brightness; 47 unsigned char brightness;
49 unsigned char contrast; 48 unsigned char contrast;
50 unsigned char colors; 49 unsigned char colors;
50 __u8 hflip;
51 __u8 vflip;
51 52
52 char compress; /* Should the next frame be compressed? */ 53 char compress; /* Should the next frame be compressed? */
53 char compress_inited; /* Are compression params uploaded? */ 54 char compress_inited; /* Are compression params uploaded? */
@@ -77,9 +78,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 78static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 79static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 80static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
81static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
80 85
81static struct ctrl sd_ctrls[] = { 86static struct ctrl sd_ctrls[] = {
82#define SD_BRIGHTNESS 0
83 { 87 {
84 { 88 {
85 .id = V4L2_CID_BRIGHTNESS, 89 .id = V4L2_CID_BRIGHTNESS,
@@ -88,12 +92,12 @@ static struct ctrl sd_ctrls[] = {
88 .minimum = 0, 92 .minimum = 0,
89 .maximum = 255, 93 .maximum = 255,
90 .step = 1, 94 .step = 1,
91 .default_value = 127, 95#define BRIGHTNESS_DEF 127
96 .default_value = BRIGHTNESS_DEF,
92 }, 97 },
93 .set = sd_setbrightness, 98 .set = sd_setbrightness,
94 .get = sd_getbrightness, 99 .get = sd_getbrightness,
95 }, 100 },
96#define SD_CONTRAST 1
97 { 101 {
98 { 102 {
99 .id = V4L2_CID_CONTRAST, 103 .id = V4L2_CID_CONTRAST,
@@ -102,31 +106,61 @@ static struct ctrl sd_ctrls[] = {
102 .minimum = 0, 106 .minimum = 0,
103 .maximum = 255, 107 .maximum = 255,
104 .step = 1, 108 .step = 1,
105 .default_value = 127, 109#define CONTRAST_DEF 127
110 .default_value = CONTRAST_DEF,
106 }, 111 },
107 .set = sd_setcontrast, 112 .set = sd_setcontrast,
108 .get = sd_getcontrast, 113 .get = sd_getcontrast,
109 }, 114 },
110#define SD_COLOR 2
111 { 115 {
112 { 116 {
113 .id = V4L2_CID_SATURATION, 117 .id = V4L2_CID_SATURATION,
114 .type = V4L2_CTRL_TYPE_INTEGER, 118 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Saturation", 119 .name = "Color",
116 .minimum = 0, 120 .minimum = 0,
117 .maximum = 255, 121 .maximum = 255,
118 .step = 1, 122 .step = 1,
119 .default_value = 127, 123#define COLOR_DEF 127
124 .default_value = COLOR_DEF,
120 }, 125 },
121 .set = sd_setcolors, 126 .set = sd_setcolors,
122 .get = sd_getcolors, 127 .get = sd_getcolors,
123 }, 128 },
129/* next controls work with ov7670 only */
130 {
131 {
132 .id = V4L2_CID_HFLIP,
133 .type = V4L2_CTRL_TYPE_BOOLEAN,
134 .name = "Mirror",
135 .minimum = 0,
136 .maximum = 1,
137 .step = 1,
138#define HFLIP_DEF 0
139 .default_value = HFLIP_DEF,
140 },
141 .set = sd_sethflip,
142 .get = sd_gethflip,
143 },
144 {
145 {
146 .id = V4L2_CID_VFLIP,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .name = "Vflip",
149 .minimum = 0,
150 .maximum = 1,
151 .step = 1,
152#define VFLIP_DEF 0
153 .default_value = VFLIP_DEF,
154 },
155 .set = sd_setvflip,
156 .get = sd_getvflip,
157 },
124}; 158};
125 159
126static struct v4l2_pix_format vga_mode[] = { 160static struct v4l2_pix_format vga_mode[] = {
127 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 161 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
128 .bytesperline = 320, 162 .bytesperline = 320,
129 .sizeimage = 320 * 240 * 3 / 8 + 589, 163 .sizeimage = 320 * 240 * 3 / 8 + 590,
130 .colorspace = V4L2_COLORSPACE_JPEG, 164 .colorspace = V4L2_COLORSPACE_JPEG,
131 .priv = 1}, 165 .priv = 1},
132 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 166 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -138,12 +172,12 @@ static struct v4l2_pix_format vga_mode[] = {
138static struct v4l2_pix_format sif_mode[] = { 172static struct v4l2_pix_format sif_mode[] = {
139 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 173 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
140 .bytesperline = 176, 174 .bytesperline = 176,
141 .sizeimage = 176 * 144 * 3 / 8 + 589, 175 .sizeimage = 176 * 144 * 3 / 8 + 590,
142 .colorspace = V4L2_COLORSPACE_JPEG, 176 .colorspace = V4L2_COLORSPACE_JPEG,
143 .priv = 1}, 177 .priv = 1},
144 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 178 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
145 .bytesperline = 352, 179 .bytesperline = 352,
146 .sizeimage = 352 * 288 * 3 / 8 + 589, 180 .sizeimage = 352 * 288 * 3 / 8 + 590,
147 .colorspace = V4L2_COLORSPACE_JPEG, 181 .colorspace = V4L2_COLORSPACE_JPEG,
148 .priv = 0}, 182 .priv = 0},
149}; 183};
@@ -225,6 +259,7 @@ static struct v4l2_pix_format sif_mode[] = {
225#define OV7670_REG_VSTART 0x19 /* Vert start high bits */ 259#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
226#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ 260#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
227#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ 261#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
262#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */
228#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ 263#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
229#define OV7670_REG_AEW 0x24 /* AGC upper limit */ 264#define OV7670_REG_AEW 0x24 /* AGC upper limit */
230#define OV7670_REG_AEB 0x25 /* AGC lower limit */ 265#define OV7670_REG_AEB 0x25 /* AGC lower limit */
@@ -258,16 +293,6 @@ static struct v4l2_pix_format sif_mode[] = {
258#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ 293#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
259#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ 294#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
260 295
261struct ovsensor_window {
262 short x;
263 short y;
264 short width;
265 short height;
266/* int format; */
267 short quarter; /* Scale width and height down 2x */
268 short clockdiv; /* Clock divisor setting */
269};
270
271static unsigned char ov7670_abs_to_sm(unsigned char v) 296static unsigned char ov7670_abs_to_sm(unsigned char v)
272{ 297{
273 if (v > 127) 298 if (v > 127)
@@ -499,19 +524,6 @@ static int init_ov_sensor(struct sd *sd)
499 return 0; 524 return 0;
500} 525}
501 526
502/* Switch on standard JPEG compression. Returns 0 for success. */
503static int ov519_init_compression(struct sd *sd)
504{
505 if (!sd->compress_inited) {
506 if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) {
507 PDEBUG(D_ERR, "Error switching to compressed mode");
508 return -EIO;
509 }
510 sd->compress_inited = 1;
511 }
512 return 0;
513}
514
515/* Set the read and write slave IDs. The "slave" argument is the write slave, 527/* Set the read and write slave IDs. The "slave" argument is the write slave,
516 * and the read slave will be set to (slave + 1). 528 * and the read slave will be set to (slave + 1).
517 * This should not be called from outside the i2c I/O functions. 529 * This should not be called from outside the i2c I/O functions.
@@ -681,21 +693,17 @@ static int ov8xx0_configure(struct sd *sd)
681 return -1; 693 return -1;
682 } 694 }
683 if ((rc & 3) == 1) { 695 if ((rc & 3) == 1) {
684 PDEBUG(D_PROBE, "Sensor is an OV8610");
685 sd->sensor = SEN_OV8610; 696 sd->sensor = SEN_OV8610;
686 } else { 697 } else {
687 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); 698 PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
688 return -1; 699 return -1;
689 } 700 }
690 PDEBUG(D_PROBE, "Writing 8610 registers"); 701 PDEBUG(D_PROBE, "Writing 8610 registers");
691 if (write_i2c_regvals(sd, 702 if (write_i2c_regvals(sd, norm_8610, ARRAY_SIZE(norm_8610)))
692 norm_8610,
693 sizeof norm_8610 / sizeof norm_8610[0]))
694 return -1; 703 return -1;
695 704
696 /* Set sensor-specific vars */ 705 /* Set sensor-specific vars */
697 sd->maxwidth = 640; 706/* sd->sif = 0; already done */
698 sd->maxheight = 480;
699 return 0; 707 return 0;
700} 708}
701 709
@@ -825,7 +833,7 @@ static int ov7xx0_configure(struct sd *sd)
825 { OV7670_REG_COM7, OV7670_COM7_RESET }, 833 { OV7670_REG_COM7, OV7670_COM7_RESET },
826 { OV7670_REG_TSLB, 0x04 }, /* OV */ 834 { OV7670_REG_TSLB, 0x04 }, /* OV */
827 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ 835 { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
828 { OV7670_REG_CLKRC, 0x1 }, 836 { OV7670_REG_CLKRC, 0x01 },
829 /* 837 /*
830 * Set the hardware window. These values from OV don't entirely 838 * Set the hardware window. These values from OV don't entirely
831 * make sense - hstop is less than hstart. But they work... 839 * make sense - hstop is less than hstart. But they work...
@@ -839,16 +847,12 @@ static int ov7xx0_configure(struct sd *sd)
839 { 0x70, 0x3a }, { 0x71, 0x35 }, 847 { 0x70, 0x3a }, { 0x71, 0x35 },
840 { 0x72, 0x11 }, { 0x73, 0xf0 }, 848 { 0x72, 0x11 }, { 0x73, 0xf0 },
841 { 0xa2, 0x02 }, 849 { 0xa2, 0x02 },
842/* jfm */ 850/* { OV7670_REG_COM10, 0x0 }, */
843/* { OV7670_REG_COM10, 0x0 }, */
844 851
845 /* Gamma curve values */ 852 /* Gamma curve values */
846 { 0x7a, 0x20 }, 853 { 0x7a, 0x20 },
847/* jfm:win 7b=1c */
848 { 0x7b, 0x10 }, 854 { 0x7b, 0x10 },
849/* jfm:win 7c=28 */
850 { 0x7c, 0x1e }, 855 { 0x7c, 0x1e },
851/* jfm:win 7d=3c */
852 { 0x7d, 0x35 }, 856 { 0x7d, 0x35 },
853 { 0x7e, 0x5a }, { 0x7f, 0x69 }, 857 { 0x7e, 0x5a }, { 0x7f, 0x69 },
854 { 0x80, 0x76 }, { 0x81, 0x80 }, 858 { 0x80, 0x76 }, { 0x81, 0x80 },
@@ -864,13 +868,11 @@ static int ov7xx0_configure(struct sd *sd)
864 | OV7670_COM8_BFILT }, 868 | OV7670_COM8_BFILT },
865 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, 869 { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 },
866 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ 870 { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
867/* jfm:win 14=38 */
868 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ 871 { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
869 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, 872 { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 },
870 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, 873 { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 },
871 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, 874 { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 },
872 { OV7670_REG_HAECC2, 0x68 }, 875 { OV7670_REG_HAECC2, 0x68 },
873/* jfm:win a1=0b */
874 { 0xa1, 0x03 }, /* magic */ 876 { 0xa1, 0x03 }, /* magic */
875 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, 877 { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 },
876 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, 878 { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 },
@@ -884,8 +886,6 @@ static int ov7xx0_configure(struct sd *sd)
884 /* Almost all of these are magic "reserved" values. */ 886 /* Almost all of these are magic "reserved" values. */
885 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, 887 { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b },
886 { 0x16, 0x02 }, 888 { 0x16, 0x02 },
887/* jfm */
888/* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */
889 { OV7670_REG_MVFP, 0x07 }, 889 { OV7670_REG_MVFP, 0x07 },
890 { 0x21, 0x02 }, { 0x22, 0x91 }, 890 { 0x21, 0x02 }, { 0x22, 0x91 },
891 { 0x29, 0x07 }, { 0x33, 0x0b }, 891 { 0x29, 0x07 }, { 0x33, 0x0b },
@@ -930,7 +930,10 @@ static int ov7xx0_configure(struct sd *sd)
930 { OV7670_REG_EDGE, 0 }, 930 { OV7670_REG_EDGE, 0 },
931 { 0x75, 0x05 }, { 0x76, 0xe1 }, 931 { 0x75, 0x05 }, { 0x76, 0xe1 },
932 { 0x4c, 0 }, { 0x77, 0x01 }, 932 { 0x4c, 0 }, { 0x77, 0x01 },
933 { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, 933 { OV7670_REG_COM13, OV7670_COM13_GAMMA
934 | OV7670_COM13_UVSAT
935 | 2}, /* was 3 */
936 { 0x4b, 0x09 },
934 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, 937 { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
935 { 0x56, 0x40 }, 938 { 0x56, 0x40 },
936 939
@@ -956,30 +959,10 @@ static int ov7xx0_configure(struct sd *sd)
956 { 0x79, 0x03 }, { 0xc8, 0x40 }, 959 { 0x79, 0x03 }, { 0xc8, 0x40 },
957 { 0x79, 0x05 }, { 0xc8, 0x30 }, 960 { 0x79, 0x05 }, { 0xc8, 0x30 },
958 { 0x79, 0x26 }, 961 { 0x79, 0x26 },
959 962 };
960 /* Format YUV422 */
961 { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */
962 { OV7670_REG_RGB444, 0 }, /* No RGB444 please */
963 { OV7670_REG_COM1, 0 },
964 { OV7670_REG_COM15, OV7670_COM15_R00FF },
965 { OV7670_REG_COM9, 0x18 },
966 /* 4x gain ceiling; 0x8 is reserved bit */
967 { 0x4f, 0x80 }, /* "matrix coefficient 1" */
968 { 0x50, 0x80 }, /* "matrix coefficient 2" */
969 { 0x52, 0x22 }, /* "matrix coefficient 4" */
970 { 0x53, 0x5e }, /* "matrix coefficient 5" */
971 { 0x54, 0x80 }, /* "matrix coefficient 6" */
972 { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT },
973};
974 963
975 PDEBUG(D_PROBE, "starting OV7xx0 configuration"); 964 PDEBUG(D_PROBE, "starting OV7xx0 configuration");
976 965
977/* jfm:already done? */
978 if (init_ov_sensor(sd) < 0)
979 PDEBUG(D_ERR, "Failed to read sensor ID");
980 else
981 PDEBUG(D_PROBE, "OV7xx0 initialized");
982
983 /* Detect sensor (sub)type */ 966 /* Detect sensor (sub)type */
984 rc = i2c_r(sd, OV7610_REG_COM_I); 967 rc = i2c_r(sd, OV7610_REG_COM_I);
985 968
@@ -1025,20 +1008,25 @@ static int ov7xx0_configure(struct sd *sd)
1025 return low; 1008 return low;
1026 } 1009 }
1027 if (high == 0x76) { 1010 if (high == 0x76) {
1028 if (low == 0x30) { 1011 switch (low) {
1012 case 0x30:
1029 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); 1013 PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
1030 sd->sensor = SEN_OV7630; 1014 sd->sensor = SEN_OV7630;
1031 } else if (low == 0x40) { 1015 break;
1016 case 0x40:
1032 PDEBUG(D_PROBE, "Sensor is an OV7645"); 1017 PDEBUG(D_PROBE, "Sensor is an OV7645");
1033 sd->sensor = SEN_OV7640; /* FIXME */ 1018 sd->sensor = SEN_OV7640; /* FIXME */
1034 } else if (low == 0x45) { 1019 break;
1020 case 0x45:
1035 PDEBUG(D_PROBE, "Sensor is an OV7645B"); 1021 PDEBUG(D_PROBE, "Sensor is an OV7645B");
1036 sd->sensor = SEN_OV7640; /* FIXME */ 1022 sd->sensor = SEN_OV7640; /* FIXME */
1037 } else if (low == 0x48) { 1023 break;
1024 case 0x48:
1038 PDEBUG(D_PROBE, "Sensor is an OV7648"); 1025 PDEBUG(D_PROBE, "Sensor is an OV7648");
1039 sd->sensor = SEN_OV7640; /* FIXME */ 1026 sd->sensor = SEN_OV7640; /* FIXME */
1040 } else { 1027 break;
1041 PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); 1028 default:
1029 PDEBUG(D_PROBE, "Unknown sensor: 0x76%x", low);
1042 return -1; 1030 return -1;
1043 } 1031 }
1044 } else { 1032 } else {
@@ -1050,34 +1038,34 @@ static int ov7xx0_configure(struct sd *sd)
1050 return -1; 1038 return -1;
1051 } 1039 }
1052 1040
1053 if (sd->sensor == SEN_OV7620) { 1041 switch (sd->sensor) {
1042 case SEN_OV7620:
1054 PDEBUG(D_PROBE, "Writing 7620 registers"); 1043 PDEBUG(D_PROBE, "Writing 7620 registers");
1055 if (write_i2c_regvals(sd, norm_7620, 1044 if (write_i2c_regvals(sd, norm_7620, ARRAY_SIZE(norm_7620)))
1056 sizeof norm_7620 / sizeof norm_7620[0]))
1057 return -1; 1045 return -1;
1058 } else if (sd->sensor == SEN_OV7630) { 1046 break;
1047 case SEN_OV7630:
1059 PDEBUG(D_ERR, "7630 is not supported by this driver version"); 1048 PDEBUG(D_ERR, "7630 is not supported by this driver version");
1060 return -1; 1049 return -1;
1061 } else if (sd->sensor == SEN_OV7640) { 1050 case SEN_OV7640:
1062 PDEBUG(D_PROBE, "Writing 7640 registers"); 1051 PDEBUG(D_PROBE, "Writing 7640 registers");
1063 if (write_i2c_regvals(sd, norm_7640, 1052 if (write_i2c_regvals(sd, norm_7640, ARRAY_SIZE(norm_7640)))
1064 sizeof norm_7640 / sizeof norm_7640[0]))
1065 return -1; 1053 return -1;
1066 } else if (sd->sensor == SEN_OV7670) { 1054 break;
1055 case SEN_OV7670:
1067 PDEBUG(D_PROBE, "Writing 7670 registers"); 1056 PDEBUG(D_PROBE, "Writing 7670 registers");
1068 if (write_i2c_regvals(sd, norm_7670, 1057 if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
1069 sizeof norm_7670 / sizeof norm_7670[0]))
1070 return -1; 1058 return -1;
1071 } else { 1059 break;
1060 default:
1072 PDEBUG(D_PROBE, "Writing 7610 registers"); 1061 PDEBUG(D_PROBE, "Writing 7610 registers");
1073 if (write_i2c_regvals(sd, norm_7610, 1062 if (write_i2c_regvals(sd, norm_7610, ARRAY_SIZE(norm_7610)))
1074 sizeof norm_7610 / sizeof norm_7610[0]))
1075 return -1; 1063 return -1;
1064 break;
1076 } 1065 }
1077 1066
1078 /* Set sensor-specific vars */ 1067 /* Set sensor-specific vars */
1079 sd->maxwidth = 640; 1068/* sd->sif = 0; already done */
1080 sd->maxheight = 480;
1081 return 0; 1069 return 0;
1082} 1070}
1083 1071
@@ -1231,43 +1219,45 @@ static int ov6xx0_configure(struct sd *sd)
1231 /* Ugh. The first two bits are the version bits, but 1219 /* Ugh. The first two bits are the version bits, but
1232 * the entire register value must be used. I guess OVT 1220 * the entire register value must be used. I guess OVT
1233 * underestimated how many variants they would make. */ 1221 * underestimated how many variants they would make. */
1234 if (rc == 0x00) { 1222 switch (rc) {
1223 case 0x00:
1235 sd->sensor = SEN_OV6630; 1224 sd->sensor = SEN_OV6630;
1236 PDEBUG(D_ERR, 1225 PDEBUG(D_ERR,
1237 "WARNING: Sensor is an OV66308. Your camera may have"); 1226 "WARNING: Sensor is an OV66308. Your camera may have");
1238 PDEBUG(D_ERR, "been misdetected in previous driver versions."); 1227 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
1239 } else if (rc == 0x01) { 1228 break;
1229 case 0x01:
1240 sd->sensor = SEN_OV6620; 1230 sd->sensor = SEN_OV6620;
1241 PDEBUG(D_PROBE, "Sensor is an OV6620"); 1231 break;
1242 } else if (rc == 0x02) { 1232 case 0x02:
1243 sd->sensor = SEN_OV6630; 1233 sd->sensor = SEN_OV6630;
1244 PDEBUG(D_PROBE, "Sensor is an OV66308AE"); 1234 PDEBUG(D_PROBE, "Sensor is an OV66308AE");
1245 } else if (rc == 0x03) { 1235 break;
1236 case 0x03:
1246 sd->sensor = SEN_OV6630; 1237 sd->sensor = SEN_OV6630;
1247 PDEBUG(D_PROBE, "Sensor is an OV66308AF"); 1238 PDEBUG(D_PROBE, "Sensor is an OV66308AF");
1248 } else if (rc == 0x90) { 1239 break;
1240 case 0x90:
1249 sd->sensor = SEN_OV6630; 1241 sd->sensor = SEN_OV6630;
1250 PDEBUG(D_ERR, 1242 PDEBUG(D_ERR,
1251 "WARNING: Sensor is an OV66307. Your camera may have"); 1243 "WARNING: Sensor is an OV66307. Your camera may have");
1252 PDEBUG(D_ERR, "been misdetected in previous driver versions."); 1244 PDEBUG(D_ERR, "been misdetected in previous driver versions.");
1253 } else { 1245 break;
1246 default:
1254 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); 1247 PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
1255 return -1; 1248 return -1;
1256 } 1249 }
1257 1250
1258 /* Set sensor-specific vars */ 1251 /* Set sensor-specific vars */
1259 sd->maxwidth = 352; 1252 sd->sif = 1;
1260 sd->maxheight = 288;
1261 1253
1262 if (sd->sensor == SEN_OV6620) { 1254 if (sd->sensor == SEN_OV6620) {
1263 PDEBUG(D_PROBE, "Writing 6x20 registers"); 1255 PDEBUG(D_PROBE, "Writing 6x20 registers");
1264 if (write_i2c_regvals(sd, norm_6x20, 1256 if (write_i2c_regvals(sd, norm_6x20, ARRAY_SIZE(norm_6x20)))
1265 sizeof norm_6x20 / sizeof norm_6x20[0]))
1266 return -1; 1257 return -1;
1267 } else { 1258 } else {
1268 PDEBUG(D_PROBE, "Writing 6x30 registers"); 1259 PDEBUG(D_PROBE, "Writing 6x30 registers");
1269 if (write_i2c_regvals(sd, norm_6x30, 1260 if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
1270 sizeof norm_6x30 / sizeof norm_6x30[0]))
1271 return -1; 1261 return -1;
1272 } 1262 }
1273 return 0; 1263 return 0;
@@ -1276,14 +1266,8 @@ static int ov6xx0_configure(struct sd *sd)
1276/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ 1266/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
1277static void ov51x_led_control(struct sd *sd, int on) 1267static void ov51x_led_control(struct sd *sd, int on)
1278{ 1268{
1279 PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); 1269/* PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); */
1280 1270 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1281/* if (sd->bridge == BRG_OV511PLUS) */
1282/* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */
1283/* else if (sd->bridge == BRG_OV519) */
1284 reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
1285/* else if (sd->bclass == BCL_OV518) */
1286/* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */
1287} 1271}
1288 1272
1289/* this function is called at probe time */ 1273/* this function is called at probe time */
@@ -1293,11 +1277,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
1293 struct sd *sd = (struct sd *) gspca_dev; 1277 struct sd *sd = (struct sd *) gspca_dev;
1294 struct cam *cam; 1278 struct cam *cam;
1295 1279
1296/* (from ov519_configure) */
1297 static const struct ov_regvals init_519[] = { 1280 static const struct ov_regvals init_519[] = {
1298 { 0x5a, 0x6d }, /* EnableSystem */ 1281 { 0x5a, 0x6d }, /* EnableSystem */
1299/* jfm trace usbsnoop3-1.txt */
1300/* jfm 53 = fb */
1301 { 0x53, 0x9b }, 1282 { 0x53, 0x9b },
1302 { 0x54, 0xff }, /* set bit2 to enable jpeg */ 1283 { 0x54, 0xff }, /* set bit2 to enable jpeg */
1303 { 0x5d, 0x03 }, 1284 { 0x5d, 0x03 },
@@ -1314,9 +1295,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1314 1295
1315 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) 1296 if (write_regvals(sd, init_519, ARRAY_SIZE(init_519)))
1316 goto error; 1297 goto error;
1317/* jfm: not seen in windows trace */
1318 if (ov519_init_compression(sd))
1319 goto error;
1320 ov51x_led_control(sd, 0); /* turn LED off */ 1298 ov51x_led_control(sd, 0); /* turn LED off */
1321 1299
1322 /* Test for 76xx */ 1300 /* Test for 76xx */
@@ -1365,16 +1343,18 @@ static int sd_config(struct gspca_dev *gspca_dev,
1365 1343
1366 cam = &gspca_dev->cam; 1344 cam = &gspca_dev->cam;
1367 cam->epaddr = OV511_ENDPOINT_ADDRESS; 1345 cam->epaddr = OV511_ENDPOINT_ADDRESS;
1368 if (sd->maxwidth == 640) { 1346 if (!sd->sif) {
1369 cam->cam_mode = vga_mode; 1347 cam->cam_mode = vga_mode;
1370 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; 1348 cam->nmodes = ARRAY_SIZE(vga_mode);
1371 } else { 1349 } else {
1372 cam->cam_mode = sif_mode; 1350 cam->cam_mode = sif_mode;
1373 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; 1351 cam->nmodes = ARRAY_SIZE(sif_mode);
1374 } 1352 }
1375 sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; 1353 sd->brightness = BRIGHTNESS_DEF;
1376 sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; 1354 sd->contrast = CONTRAST_DEF;
1377 sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; 1355 sd->colors = COLOR_DEF;
1356 sd->hflip = HFLIP_DEF;
1357 sd->vflip = VFLIP_DEF;
1378 return 0; 1358 return 0;
1379error: 1359error:
1380 PDEBUG(D_ERR, "OV519 Config failed"); 1360 PDEBUG(D_ERR, "OV519 Config failed");
@@ -1394,8 +1374,7 @@ static int sd_open(struct gspca_dev *gspca_dev)
1394 * 1374 *
1395 * Do not put any sensor-specific code in here (including I2C I/O functions) 1375 * Do not put any sensor-specific code in here (including I2C I/O functions)
1396 */ 1376 */
1397static int ov519_mode_init_regs(struct sd *sd, 1377static int ov519_mode_init_regs(struct sd *sd)
1398 int width, int height)
1399{ 1378{
1400 static const struct ov_regvals mode_init_519_ov7670[] = { 1379 static const struct ov_regvals mode_init_519_ov7670[] = {
1401 { 0x5d, 0x03 }, /* Turn off suspend mode */ 1380 { 0x5d, 0x03 }, /* Turn off suspend mode */
@@ -1441,36 +1420,23 @@ static int ov519_mode_init_regs(struct sd *sd,
1441 /* windows reads 0x55 at this point, why? */ 1420 /* windows reads 0x55 at this point, why? */
1442 }; 1421 };
1443 1422
1444/* int hi_res; */
1445
1446 PDEBUG(D_CONF, "mode init %dx%d", width, height);
1447
1448/* if (width >= 800 && height >= 600)
1449 hi_res = 1;
1450 else
1451 hi_res = 0; */
1452
1453/* if (ov51x_stop(sd) < 0)
1454 return -EIO; */
1455
1456 /******** Set the mode ********/ 1423 /******** Set the mode ********/
1457 if (sd->sensor != SEN_OV7670) { 1424 if (sd->sensor != SEN_OV7670) {
1458 if (write_regvals(sd, mode_init_519, 1425 if (write_regvals(sd, mode_init_519,
1459 ARRAY_SIZE(mode_init_519))) 1426 ARRAY_SIZE(mode_init_519)))
1460 return -EIO; 1427 return -EIO;
1428 if (sd->sensor == SEN_OV7640) {
1429 /* Select 8-bit input mode */
1430 reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
1431 }
1461 } else { 1432 } else {
1462 if (write_regvals(sd, mode_init_519_ov7670, 1433 if (write_regvals(sd, mode_init_519_ov7670,
1463 ARRAY_SIZE(mode_init_519_ov7670))) 1434 ARRAY_SIZE(mode_init_519_ov7670)))
1464 return -EIO; 1435 return -EIO;
1465 } 1436 }
1466 1437
1467 if (sd->sensor == SEN_OV7640) { 1438 reg_w(sd, OV519_CAM_H_SIZE, sd->gspca_dev.width >> 4);
1468 /* Select 8-bit input mode */ 1439 reg_w(sd, OV519_CAM_V_SIZE, sd->gspca_dev.height >> 3);
1469 reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
1470 }
1471
1472 reg_w(sd, OV519_CAM_H_SIZE, width >> 4);
1473 reg_w(sd, OV519_CAM_V_SIZE, height >> 3);
1474 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); 1440 reg_w(sd, OV519_CAM_X_OFFSETL, 0x00);
1475 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); 1441 reg_w(sd, OV519_CAM_X_OFFSETH, 0x00);
1476 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); 1442 reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00);
@@ -1485,9 +1451,10 @@ static int ov519_mode_init_regs(struct sd *sd,
1485 1451
1486/* FIXME: These are only valid at the max resolution. */ 1452/* FIXME: These are only valid at the max resolution. */
1487 sd->clockdiv = 0; 1453 sd->clockdiv = 0;
1488 if (sd->sensor == SEN_OV7640) { 1454 switch (sd->sensor) {
1455 case SEN_OV7640:
1489 switch (sd->frame_rate) { 1456 switch (sd->frame_rate) {
1490/*jfm: default was 30 fps */ 1457/*fixme: default was 30 fps */
1491 case 30: 1458 case 30:
1492 reg_w(sd, 0xa4, 0x0c); 1459 reg_w(sd, 0xa4, 0x0c);
1493 reg_w(sd, 0x23, 0xff); 1460 reg_w(sd, 0x23, 0xff);
@@ -1517,7 +1484,8 @@ static int ov519_mode_init_regs(struct sd *sd,
1517 sd->clockdiv = 1; 1484 sd->clockdiv = 1;
1518 break; 1485 break;
1519 } 1486 }
1520 } else if (sd->sensor == SEN_OV8610) { 1487 break;
1488 case SEN_OV8610:
1521 switch (sd->frame_rate) { 1489 switch (sd->frame_rate) {
1522 default: /* 15 fps */ 1490 default: /* 15 fps */
1523/* case 15: */ 1491/* case 15: */
@@ -1533,41 +1501,37 @@ static int ov519_mode_init_regs(struct sd *sd,
1533 reg_w(sd, 0x23, 0x1b); 1501 reg_w(sd, 0x23, 0x1b);
1534 break; 1502 break;
1535 } 1503 }
1536 sd->clockdiv = 0; 1504 break;
1537 } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ 1505 case SEN_OV7670: /* guesses, based on 7640 */
1538 PDEBUG(D_STREAM, "Setting framerate to %d fps", 1506 PDEBUG(D_STREAM, "Setting framerate to %d fps",
1539 (sd->frame_rate == 0) ? 15 : sd->frame_rate); 1507 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
1508 reg_w(sd, 0xa4, 0x10);
1540 switch (sd->frame_rate) { 1509 switch (sd->frame_rate) {
1541 case 30: 1510 case 30:
1542 reg_w(sd, 0xa4, 0x10);
1543 reg_w(sd, 0x23, 0xff); 1511 reg_w(sd, 0x23, 0xff);
1544 break; 1512 break;
1545 case 20: 1513 case 20:
1546 reg_w(sd, 0xa4, 0x10);
1547 reg_w(sd, 0x23, 0x1b); 1514 reg_w(sd, 0x23, 0x1b);
1548 break; 1515 break;
1549 default: /* 15 fps */ 1516 default:
1550/* case 15: */ 1517/* case 15: */
1551 reg_w(sd, 0xa4, 0x10);
1552 reg_w(sd, 0x23, 0xff); 1518 reg_w(sd, 0x23, 0xff);
1553 sd->clockdiv = 1; 1519 sd->clockdiv = 1;
1554 break; 1520 break;
1555 } 1521 }
1522 break;
1556 } 1523 }
1557 1524
1558/* if (ov51x_restart(sd) < 0)
1559 return -EIO; */
1560
1561 /* Reset it just for good measure */
1562/* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0)
1563 return -EIO; */
1564 return 0; 1525 return 0;
1565} 1526}
1566 1527
1567static int mode_init_ov_sensor_regs(struct sd *sd, 1528static int mode_init_ov_sensor_regs(struct sd *sd)
1568 struct ovsensor_window *win)
1569{ 1529{
1570 int qvga = win->quarter; 1530 struct gspca_dev *gspca_dev;
1531 int qvga;
1532
1533 gspca_dev = &sd->gspca_dev;
1534 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1571 1535
1572 /******** Mode (VGA/QVGA) and sensor specific regs ********/ 1536 /******** Mode (VGA/QVGA) and sensor specific regs ********/
1573 switch (sd->sensor) { 1537 switch (sd->sensor) {
@@ -1611,8 +1575,6 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1611 OV7670_COM7_FMT_MASK); 1575 OV7670_COM7_FMT_MASK);
1612 break; 1576 break;
1613 case SEN_OV6620: 1577 case SEN_OV6620:
1614 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
1615 break;
1616 case SEN_OV6630: 1578 case SEN_OV6630:
1617 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); 1579 i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
1618 break; 1580 break;
@@ -1621,24 +1583,21 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1621 } 1583 }
1622 1584
1623 /******** Palette-specific regs ********/ 1585 /******** Palette-specific regs ********/
1624/* Need to do work here for the OV7670 */ 1586 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
1625 1587 /* not valid on the OV6620/OV7620/6630? */
1626 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { 1588 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
1627 /* not valid on the OV6620/OV7620/6630? */ 1589 }
1628 i2c_w_mask(sd, 0x0e, 0x00, 0x40);
1629 }
1630 1590
1631 /* The OV518 needs special treatment. Although both the OV518 1591 /* The OV518 needs special treatment. Although both the OV518
1632 * and the OV6630 support a 16-bit video bus, only the 8 bit Y 1592 * and the OV6630 support a 16-bit video bus, only the 8 bit Y
1633 * bus is actually used. The UV bus is tied to ground. 1593 * bus is actually used. The UV bus is tied to ground.
1634 * Therefore, the OV6630 needs to be in 8-bit multiplexed 1594 * Therefore, the OV6630 needs to be in 8-bit multiplexed
1635 * output mode */ 1595 * output mode */
1636 1596
1637 /* OV7640 is 8-bit only */ 1597 /* OV7640 is 8-bit only */
1638 1598
1639 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) 1599 if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640)
1640 i2c_w_mask(sd, 0x13, 0x00, 0x20); 1600 i2c_w_mask(sd, 0x13, 0x00, 0x20);
1641/* } */
1642 1601
1643 /******** Clock programming ********/ 1602 /******** Clock programming ********/
1644 /* The OV6620 needs special handling. This prevents the 1603 /* The OV6620 needs special handling. This prevents the
@@ -1647,14 +1606,14 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1647 1606
1648 /* Clock down */ 1607 /* Clock down */
1649 i2c_w(sd, 0x2a, 0x04); 1608 i2c_w(sd, 0x2a, 0x04);
1650 i2c_w(sd, 0x11, win->clockdiv); 1609 i2c_w(sd, 0x11, sd->clockdiv);
1651 i2c_w(sd, 0x2a, 0x84); 1610 i2c_w(sd, 0x2a, 0x84);
1652 /* This next setting is critical. It seems to improve 1611 /* This next setting is critical. It seems to improve
1653 * the gain or the contrast. The "reserved" bits seem 1612 * the gain or the contrast. The "reserved" bits seem
1654 * to have some effect in this case. */ 1613 * to have some effect in this case. */
1655 i2c_w(sd, 0x2d, 0x85); 1614 i2c_w(sd, 0x2d, 0x85);
1656 } else if (win->clockdiv >= 0) { 1615 } else if (sd->clockdiv >= 0) {
1657 i2c_w(sd, 0x11, win->clockdiv); 1616 i2c_w(sd, 0x11, sd->clockdiv);
1658 } 1617 }
1659 1618
1660 /******** Special Features ********/ 1619 /******** Special Features ********/
@@ -1674,7 +1633,7 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1674 /* is fully tested. */ 1633 /* is fully tested. */
1675 /* 7620/6620/6630? don't have register 0x35, so play it safe */ 1634 /* 7620/6620/6630? don't have register 0x35, so play it safe */
1676 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { 1635 if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
1677 if (win->width == 640 /*&& win->height == 480*/) 1636 if (!qvga)
1678 i2c_w(sd, 0x35, 0x9e); 1637 i2c_w(sd, 0x35, 0x9e);
1679 else 1638 else
1680 i2c_w(sd, 0x35, 0x1e); 1639 i2c_w(sd, 0x35, 0x1e);
@@ -1682,13 +1641,31 @@ static int mode_init_ov_sensor_regs(struct sd *sd,
1682 return 0; 1641 return 0;
1683} 1642}
1684 1643
1685static int set_ov_sensor_window(struct sd *sd, 1644static void sethvflip(struct sd *sd)
1686 struct ovsensor_window *win)
1687{ 1645{
1646 if (sd->sensor != SEN_OV7670)
1647 return;
1648 if (sd->gspca_dev.streaming)
1649 ov51x_stop(sd);
1650 i2c_w_mask(sd, OV7670_REG_MVFP,
1651 OV7670_MVFP_MIRROR * sd->hflip
1652 | OV7670_MVFP_VFLIP * sd->vflip,
1653 OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
1654 if (sd->gspca_dev.streaming)
1655 ov51x_restart(sd);
1656}
1657
1658static int set_ov_sensor_window(struct sd *sd)
1659{
1660 struct gspca_dev *gspca_dev;
1661 int qvga;
1688 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; 1662 int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
1689 int ret, hstart, hstop, vstop, vstart; 1663 int ret, hstart, hstop, vstop, vstart;
1690 __u8 v; 1664 __u8 v;
1691 1665
1666 gspca_dev = &sd->gspca_dev;
1667 qvga = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1668
1692 /* The different sensor ICs handle setting up of window differently. 1669 /* The different sensor ICs handle setting up of window differently.
1693 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ 1670 * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
1694 switch (sd->sensor) { 1671 switch (sd->sensor) {
@@ -1733,7 +1710,7 @@ static int set_ov_sensor_window(struct sd *sd,
1733 switch (sd->sensor) { 1710 switch (sd->sensor) {
1734 case SEN_OV6620: 1711 case SEN_OV6620:
1735 case SEN_OV6630: 1712 case SEN_OV6630:
1736 if (win->quarter) { /* QCIF */ 1713 if (qvga) { /* QCIF */
1737 hwscale = 0; 1714 hwscale = 0;
1738 vwscale = 0; 1715 vwscale = 0;
1739 } else { /* CIF */ 1716 } else { /* CIF */
@@ -1743,7 +1720,7 @@ static int set_ov_sensor_window(struct sd *sd,
1743 } 1720 }
1744 break; 1721 break;
1745 case SEN_OV8610: 1722 case SEN_OV8610:
1746 if (win->quarter) { /* QSVGA */ 1723 if (qvga) { /* QSVGA */
1747 hwscale = 1; 1724 hwscale = 1;
1748 vwscale = 1; 1725 vwscale = 1;
1749 } else { /* SVGA */ 1726 } else { /* SVGA */
@@ -1752,7 +1729,7 @@ static int set_ov_sensor_window(struct sd *sd,
1752 } 1729 }
1753 break; 1730 break;
1754 default: /* SEN_OV7xx0 */ 1731 default: /* SEN_OV7xx0 */
1755 if (win->quarter) { /* QVGA */ 1732 if (qvga) { /* QVGA */
1756 hwscale = 1; 1733 hwscale = 1;
1757 vwscale = 0; 1734 vwscale = 0;
1758 } else { /* VGA */ 1735 } else { /* VGA */
@@ -1761,7 +1738,7 @@ static int set_ov_sensor_window(struct sd *sd,
1761 } 1738 }
1762 } 1739 }
1763 1740
1764 ret = mode_init_ov_sensor_regs(sd, win); 1741 ret = mode_init_ov_sensor_regs(sd);
1765 if (ret < 0) 1742 if (ret < 0)
1766 return ret; 1743 return ret;
1767 1744
@@ -1782,7 +1759,7 @@ static int set_ov_sensor_window(struct sd *sd,
1782 /* I can hard code this for OV7670s */ 1759 /* I can hard code this for OV7670s */
1783 /* Yes, these numbers do look odd, but they're tested and work! */ 1760 /* Yes, these numbers do look odd, but they're tested and work! */
1784 if (sd->sensor == SEN_OV7670) { 1761 if (sd->sensor == SEN_OV7670) {
1785 if (win->quarter) { /* QVGA from ov7670.c by 1762 if (qvga) { /* QVGA from ov7670.c by
1786 * Jonathan Corbet */ 1763 * Jonathan Corbet */
1787 hstart = 164; 1764 hstart = 164;
1788 hstop = 20; 1765 hstop = 20;
@@ -1796,75 +1773,45 @@ static int set_ov_sensor_window(struct sd *sd,
1796 } 1773 }
1797 /* OV7670 hardware window registers are split across 1774 /* OV7670 hardware window registers are split across
1798 * multiple locations */ 1775 * multiple locations */
1799 i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); 1776 i2c_w(sd, OV7670_REG_HSTART, hstart >> 3);
1800 i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); 1777 i2c_w(sd, OV7670_REG_HSTOP, hstop >> 3);
1801 v = i2c_r(sd, OV7670_REG_HREF); 1778 v = i2c_r(sd, OV7670_REG_HREF);
1802 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); 1779 v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
1803 msleep(10); /* need to sleep between read and write to 1780 msleep(10); /* need to sleep between read and write to
1804 * same reg! */ 1781 * same reg! */
1805 i2c_w(sd, OV7670_REG_HREF, v); 1782 i2c_w(sd, OV7670_REG_HREF, v);
1806 1783
1807 i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); 1784 i2c_w(sd, OV7670_REG_VSTART, vstart >> 2);
1808 i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); 1785 i2c_w(sd, OV7670_REG_VSTOP, vstop >> 2);
1809 v = i2c_r(sd, OV7670_REG_VREF); 1786 v = i2c_r(sd, OV7670_REG_VREF);
1810 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); 1787 v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
1811 msleep(10); /* need to sleep between read and write to 1788 msleep(10); /* need to sleep between read and write to
1812 * same reg! */ 1789 * same reg! */
1813 i2c_w(sd, OV7670_REG_VREF, v); 1790 i2c_w(sd, OV7670_REG_VREF, v);
1814 1791 sethvflip(sd);
1815 } else { 1792 } else {
1816 i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); 1793 i2c_w(sd, 0x17, hwsbase);
1817 i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); 1794 i2c_w(sd, 0x18, hwebase + (sd->gspca_dev.width >> hwscale));
1818 i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); 1795 i2c_w(sd, 0x19, vwsbase);
1819 i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); 1796 i2c_w(sd, 0x1a, vwebase + (sd->gspca_dev.height >> vwscale));
1820 } 1797 }
1821 return 0; 1798 return 0;
1822} 1799}
1823 1800
1824static int ov_sensor_mode_setup(struct sd *sd,
1825 int width, int height)
1826{
1827 struct ovsensor_window win;
1828
1829/* win.format = mode; */
1830
1831 /* Unless subcapture is enabled,
1832 * center the image window and downsample
1833 * if possible to increase the field of view */
1834 /* NOTE: OV518(+) and OV519 does downsampling on its own */
1835 win.width = width;
1836 win.height = height;
1837 if (width == sd->maxwidth)
1838 win.quarter = 0;
1839 else
1840 win.quarter = 1;
1841
1842 /* Center it */
1843 win.x = (win.width - width) / 2;
1844 win.y = (win.height - height) / 2;
1845
1846 /* Clock is determined by OV519 frame rate code */
1847 win.clockdiv = sd->clockdiv;
1848
1849 PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv);
1850 return set_ov_sensor_window(sd, &win);
1851}
1852
1853/* -- start the camera -- */ 1801/* -- start the camera -- */
1854static void sd_start(struct gspca_dev *gspca_dev) 1802static void sd_start(struct gspca_dev *gspca_dev)
1855{ 1803{
1856 struct sd *sd = (struct sd *) gspca_dev; 1804 struct sd *sd = (struct sd *) gspca_dev;
1857 int ret; 1805 int ret;
1858 1806
1859 1807 ret = ov519_mode_init_regs(sd);
1860 ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height);
1861 if (ret < 0) 1808 if (ret < 0)
1862 goto out; 1809 goto out;
1863 ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); 1810 ret = set_ov_sensor_window(sd);
1864 if (ret < 0) 1811 if (ret < 0)
1865 goto out; 1812 goto out;
1866 1813
1867 ret = ov51x_restart((struct sd *) gspca_dev); 1814 ret = ov51x_restart(sd);
1868 if (ret < 0) 1815 if (ret < 0)
1869 goto out; 1816 goto out;
1870 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); 1817 PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
@@ -1938,12 +1885,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1938{ 1885{
1939 struct sd *sd = (struct sd *) gspca_dev; 1886 struct sd *sd = (struct sd *) gspca_dev;
1940 int val; 1887 int val;
1941/* int was_streaming; */
1942 1888
1943 val = sd->brightness; 1889 val = sd->brightness;
1944 PDEBUG(D_CONF, "brightness:%d", val); 1890 PDEBUG(D_CONF, "brightness:%d", val);
1945/* was_streaming = gspca_dev->streaming; 1891/* if (gspca_dev->streaming)
1946 * if (was_streaming)
1947 * ov51x_stop(sd); */ 1892 * ov51x_stop(sd); */
1948 switch (sd->sensor) { 1893 switch (sd->sensor) {
1949 case SEN_OV8610: 1894 case SEN_OV8610:
@@ -1961,12 +1906,12 @@ static void setbrightness(struct gspca_dev *gspca_dev)
1961 i2c_w(sd, OV7610_REG_BRT, val); 1906 i2c_w(sd, OV7610_REG_BRT, val);
1962 break; 1907 break;
1963 case SEN_OV7670: 1908 case SEN_OV7670:
1964/*jfm - from windblows 1909/*win trace
1965 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ 1910 * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
1966 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); 1911 i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
1967 break; 1912 break;
1968 } 1913 }
1969/* if (was_streaming) 1914/* if (gspca_dev->streaming)
1970 * ov51x_restart(sd); */ 1915 * ov51x_restart(sd); */
1971} 1916}
1972 1917
@@ -1974,12 +1919,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
1974{ 1919{
1975 struct sd *sd = (struct sd *) gspca_dev; 1920 struct sd *sd = (struct sd *) gspca_dev;
1976 int val; 1921 int val;
1977/* int was_streaming; */
1978 1922
1979 val = sd->contrast; 1923 val = sd->contrast;
1980 PDEBUG(D_CONF, "contrast:%d", val); 1924 PDEBUG(D_CONF, "contrast:%d", val);
1981/* was_streaming = gspca_dev->streaming; 1925/* if (gspca_dev->streaming)
1982 if (was_streaming)
1983 ov51x_stop(sd); */ 1926 ov51x_stop(sd); */
1984 switch (sd->sensor) { 1927 switch (sd->sensor) {
1985 case SEN_OV7610: 1928 case SEN_OV7610:
@@ -2016,7 +1959,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
2016 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); 1959 i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
2017 break; 1960 break;
2018 } 1961 }
2019/* if (was_streaming) 1962/* if (gspca_dev->streaming)
2020 ov51x_restart(sd); */ 1963 ov51x_restart(sd); */
2021} 1964}
2022 1965
@@ -2024,12 +1967,10 @@ static void setcolors(struct gspca_dev *gspca_dev)
2024{ 1967{
2025 struct sd *sd = (struct sd *) gspca_dev; 1968 struct sd *sd = (struct sd *) gspca_dev;
2026 int val; 1969 int val;
2027/* int was_streaming; */
2028 1970
2029 val = sd->colors; 1971 val = sd->colors;
2030 PDEBUG(D_CONF, "saturation:%d", val); 1972 PDEBUG(D_CONF, "saturation:%d", val);
2031/* was_streaming = gspca_dev->streaming; 1973/* if (gspca_dev->streaming)
2032 if (was_streaming)
2033 ov51x_stop(sd); */ 1974 ov51x_stop(sd); */
2034 switch (sd->sensor) { 1975 switch (sd->sensor) {
2035 case SEN_OV8610: 1976 case SEN_OV8610:
@@ -2055,7 +1996,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
2055 /* set REG_COM13 values for UV sat auto mode */ 1996 /* set REG_COM13 values for UV sat auto mode */
2056 break; 1997 break;
2057 } 1998 }
2058/* if (was_streaming) 1999/* if (gspca_dev->streaming)
2059 ov51x_restart(sd); */ 2000 ov51x_restart(sd); */
2060} 2001}
2061 2002
@@ -2110,6 +2051,40 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2110 return 0; 2051 return 0;
2111} 2052}
2112 2053
2054static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
2055{
2056 struct sd *sd = (struct sd *) gspca_dev;
2057
2058 sd->hflip = val;
2059 sethvflip(sd);
2060 return 0;
2061}
2062
2063static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
2064{
2065 struct sd *sd = (struct sd *) gspca_dev;
2066
2067 *val = sd->hflip;
2068 return 0;
2069}
2070
2071static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2072{
2073 struct sd *sd = (struct sd *) gspca_dev;
2074
2075 sd->vflip = val;
2076 sethvflip(sd);
2077 return 0;
2078}
2079
2080static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2081{
2082 struct sd *sd = (struct sd *) gspca_dev;
2083
2084 *val = sd->vflip;
2085 return 0;
2086}
2087
2113/* sub-driver description */ 2088/* sub-driver description */
2114static const struct sd_desc sd_desc = { 2089static const struct sd_desc sd_desc = {
2115 .name = MODULE_NAME, 2090 .name = MODULE_NAME,
@@ -2178,4 +2153,3 @@ module_exit(sd_mod_exit);
2178 2153
2179module_param(frame_rate, int, 0644); 2154module_param(frame_rate, int, 0644);
2180MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); 2155MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
2181
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index ea3d7021f401..815bea6edc44 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -31,7 +31,9 @@ MODULE_LICENSE("GPL");
31struct sd { 31struct sd {
32 struct gspca_dev gspca_dev; /* !! must be the first item */ 32 struct gspca_dev gspca_dev; /* !! must be the first item */
33 33
34 int avg_lum; 34 int lum_sum;
35 atomic_t avg_lum;
36 atomic_t do_gain;
35 37
36 unsigned char brightness; 38 unsigned char brightness;
37 unsigned char contrast; 39 unsigned char contrast;
@@ -271,6 +273,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
271 sd->contrast = CONTRAST_DEF; 273 sd->contrast = CONTRAST_DEF;
272 sd->colors = COLOR_DEF; 274 sd->colors = COLOR_DEF;
273 sd->autogain = AUTOGAIN_DEF; 275 sd->autogain = AUTOGAIN_DEF;
276 sd->ag_cnt = -1;
274 return 0; 277 return 0;
275} 278}
276 279
@@ -311,6 +314,18 @@ static void setcolors(struct gspca_dev *gspca_dev)
311 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); 314 PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
312} 315}
313 316
317static void setautogain(struct gspca_dev *gspca_dev)
318{
319 struct sd *sd = (struct sd *) gspca_dev;
320
321 if (sd->autogain) {
322 sd->lum_sum = 0;
323 sd->ag_cnt = AG_CNT_START;
324 } else {
325 sd->ag_cnt = -1;
326 }
327}
328
314/* this function is called at open time */ 329/* this function is called at open time */
315static int sd_open(struct gspca_dev *gspca_dev) 330static int sd_open(struct gspca_dev *gspca_dev)
316{ 331{
@@ -320,8 +335,6 @@ static int sd_open(struct gspca_dev *gspca_dev)
320 335
321static void sd_start(struct gspca_dev *gspca_dev) 336static void sd_start(struct gspca_dev *gspca_dev)
322{ 337{
323 struct sd *sd = (struct sd *) gspca_dev;
324
325 reg_w(gspca_dev, 0xff, 0x01); 338 reg_w(gspca_dev, 0xff, 0x01);
326 reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); 339 reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
327 reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); 340 reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
@@ -394,6 +407,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
394 setcontrast(gspca_dev); 407 setcontrast(gspca_dev);
395 setbrightness(gspca_dev); 408 setbrightness(gspca_dev);
396 setcolors(gspca_dev); 409 setcolors(gspca_dev);
410 setautogain(gspca_dev);
397 411
398 /* set correct resolution */ 412 /* set correct resolution */
399 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { 413 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
@@ -431,13 +445,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
431 reg_w(gspca_dev, 0xff, 0x01); 445 reg_w(gspca_dev, 0xff, 0x01);
432 reg_w(gspca_dev, 0x78, 0x04); 446 reg_w(gspca_dev, 0x78, 0x04);
433 reg_w(gspca_dev, 0x78, 0x05); 447 reg_w(gspca_dev, 0x78, 0x05);
434
435 if (sd->autogain) {
436 sd->ag_cnt = AG_CNT_START;
437 sd->avg_lum = 0;
438 } else {
439 sd->ag_cnt = -1;
440 }
441} 448}
442 449
443static void sd_stopN(struct gspca_dev *gspca_dev) 450static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -473,13 +480,20 @@ static void sd_close(struct gspca_dev *gspca_dev)
473 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ 480 reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
474} 481}
475 482
476static void setautogain(struct gspca_dev *gspca_dev, int luma) 483static void do_autogain(struct gspca_dev *gspca_dev)
477{ 484{
485 struct sd *sd = (struct sd *) gspca_dev;
486 int luma;
478 int luma_mean = 128; 487 int luma_mean = 128;
479 int luma_delta = 20; 488 int luma_delta = 20;
480 __u8 spring = 5; 489 __u8 spring = 5;
481 int Gbright; 490 int Gbright;
482 491
492 if (!atomic_read(&sd->do_gain))
493 return;
494 atomic_set(&sd->do_gain, 0);
495
496 luma = atomic_read(&sd->avg_lum);
483 Gbright = reg_r(gspca_dev, 0x02); 497 Gbright = reg_r(gspca_dev, 0x02);
484 PDEBUG(D_FRAM, "luma mean %d", luma); 498 PDEBUG(D_FRAM, "luma mean %d", luma);
485 if (luma < luma_mean - luma_delta || 499 if (luma < luma_mean - luma_delta ||
@@ -523,12 +537,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
523 537
524 /* start of frame */ 538 /* start of frame */
525 if (sd->ag_cnt >= 0 && p > 28) { 539 if (sd->ag_cnt >= 0 && p > 28) {
526 sd->avg_lum += data[p - 23]; 540 sd->lum_sum += data[p - 23];
527 if (--sd->ag_cnt < 0) { 541 if (--sd->ag_cnt < 0) {
528 sd->ag_cnt = AG_CNT_START; 542 sd->ag_cnt = AG_CNT_START;
529 setautogain(gspca_dev, 543 atomic_set(&sd->avg_lum,
530 sd->avg_lum / AG_CNT_START); 544 sd->lum_sum / AG_CNT_START);
531 sd->avg_lum = 0; 545 sd->lum_sum = 0;
546 atomic_set(&sd->do_gain, 1);
532 } 547 }
533 } 548 }
534 549
@@ -677,12 +692,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
677 struct sd *sd = (struct sd *) gspca_dev; 692 struct sd *sd = (struct sd *) gspca_dev;
678 693
679 sd->autogain = val; 694 sd->autogain = val;
680 if (val) { 695 if (gspca_dev->streaming)
681 sd->ag_cnt = AG_CNT_START; 696 setautogain(gspca_dev);
682 sd->avg_lum = 0;
683 } else {
684 sd->ag_cnt = -1;
685 }
686 return 0; 697 return 0;
687} 698}
688 699
@@ -706,6 +717,7 @@ static struct sd_desc sd_desc = {
706 .stop0 = sd_stop0, 717 .stop0 = sd_stop0,
707 .close = sd_close, 718 .close = sd_close,
708 .pkt_scan = sd_pkt_scan, 719 .pkt_scan = sd_pkt_scan,
720 .dq_callback = do_autogain,
709}; 721};
710 722
711/* -- module initialisation -- */ 723/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index e18748c5a14d..11210c71f66c 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -408,7 +408,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
408 const __u8 *buffer, 408 const __u8 *buffer,
409 int len) 409 int len)
410{ 410{
411#ifdef CONFIG_VIDEO_ADV_DEBUG 411#ifdef GSPCA_DEBUG
412 if (len > sizeof gspca_dev->usb_buf) { 412 if (len > sizeof gspca_dev->usb_buf) {
413 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); 413 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
414 return; 414 return;
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 33a3df1f6915..245a30ec5fb1 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL");
32struct sd { 32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */ 33 struct gspca_dev gspca_dev; /* !! must be the first item */
34 34
35 int avg_lum; 35 atomic_t avg_lum;
36 unsigned int exposure; 36 unsigned int exposure;
37 37
38 unsigned short brightness; 38 unsigned short brightness;
@@ -148,55 +148,58 @@ static struct v4l2_pix_format vga_mode[] = {
148 148
149/*Data from sn9c102p+hv71331r */ 149/*Data from sn9c102p+hv71331r */
150static const __u8 sn_hv7131[] = { 150static const __u8 sn_hv7131[] = {
151/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ 151/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
152 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, 152 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
153/* rega regb regc regd rege regf reg10 reg11 */ 153/* reg8 reg9 rega regb regc regd rege regf */
154 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ 154 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
155/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ 155/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
156 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, 156 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
157/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ 157/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 158 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
159}; 159};
160 160
161static const __u8 sn_mi0360[] = { 161static const __u8 sn_mi0360[] = {
162/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ 162/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
163 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, 163 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
164/* rega regb regc regd rege regf reg10 reg11 */ 164/* reg8 reg9 rega regb regc regd rege regf */
165 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 165 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
166/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ 166/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
167 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, 167 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
168/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ 168/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 169 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
170}; 170};
171 171
172static const __u8 sn_mo4000[] = { 172static const __u8 sn_mo4000[] = {
173/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ 173/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
174 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, 174 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
175/* reg9 rega regb regc regd rege regf reg10 reg11*/ 175/* reg8 reg9 rega regb regc regd rege regf */
176 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 176 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ 177/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
178 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, 178 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
179/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ 179/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, 180 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
181 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7,
182 0xd3, 0xdf, 0xea, 0xf5
183}; 181};
184 182
185static const __u8 sn_ov7648[] = { 183static const __u8 sn_ov7648[] = {
186 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, 184/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
187 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, 185 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
188 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 186/* reg8 reg9 rega regb regc regd rege regf */
187 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
188/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
189 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
190/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
191 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
189}; 192};
190 193
191static const __u8 sn_ov7660[] = { 194static const __u8 sn_ov7660[] = {
192/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ 195/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
193 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, 196 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
194/* reg9 rega regb regc regd rege regf reg10 reg11*/ 197/* reg8 reg9 rega regb regc regd rege regf */
195 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 198 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
196/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ 199/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
197 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, 200 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
198/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ 201/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 202 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200}; 203};
201 204
202/* sequence specific to the sensors - !! index = SENSOR_xxx */ 205/* sequence specific to the sensors - !! index = SENSOR_xxx */
@@ -212,10 +215,6 @@ static const __u8 regsn20[] = {
212 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 215 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
213 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff 216 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
214}; 217};
215static const __u8 regsn20_sn9c120[] = {
216 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90,
217 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff
218};
219static const __u8 regsn20_sn9c325[] = { 218static const __u8 regsn20_sn9c325[] = {
220 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, 219 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
221 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 220 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
@@ -227,21 +226,6 @@ static const __u8 reg84[] = {
227/* 0x00, 0x00, 0x00, 0x00, 0x00 */ 226/* 0x00, 0x00, 0x00, 0x00, 0x00 */
228 0xf7, 0x0f, 0x0a, 0x00, 0x00 227 0xf7, 0x0f, 0x0a, 0x00, 0x00
229}; 228};
230static const __u8 reg84_sn9c120_1[] = {
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x0c, 0x00, 0x00
234};
235static const __u8 reg84_sn9c120_2[] = {
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x0c, 0x02, 0x3b
239};
240static const __u8 reg84_sn9c120_3[] = {
241 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f,
242 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f,
243 0xf5, 0x0f, 0x0c, 0x02, 0x3b
244};
245static const __u8 reg84_sn9c325[] = { 229static const __u8 reg84_sn9c325[] = {
246 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, 230 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
247 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, 231 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
@@ -360,17 +344,15 @@ static const __u8 ov7660_sensor_init[][8] = {
360 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ 344 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
361/* (delay 20ms) */ 345/* (delay 20ms) */
362 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, 346 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
363 /* Outformat ?? rawRGB */ 347 /* Outformat = rawRGB */
364 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ 348 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
365 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, 349 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
366/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */
367 /* GAIN BLUE RED VREF */ 350 /* GAIN BLUE RED VREF */
368 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, 351 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
369 /* COM 1 BAVE GEAVE AECHH */ 352 /* COM 1 BAVE GEAVE AECHH */
370 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ 353 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
371 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ 354 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
372 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, 355 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
373/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */
374 /* AECH CLKRC COM7 COM8 */ 356 /* AECH CLKRC COM7 COM8 */
375 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ 357 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
376 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, 358 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
@@ -379,8 +361,8 @@ static const __u8 ov7660_sensor_init[][8] = {
379 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ 361 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
380 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, 362 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
381 /* BOS GBOS GROS ROS (BGGR offset) */ 363 /* BOS GBOS GROS ROS (BGGR offset) */
382 {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, 364/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
383/* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ 365 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
384 /* AEW AEB VPT BBIAS */ 366 /* AEW AEB VPT BBIAS */
385 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, 367 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
386 /* GbBIAS RSVD EXHCH EXHCL */ 368 /* GbBIAS RSVD EXHCH EXHCL */
@@ -407,9 +389,9 @@ static const __u8 ov7660_sensor_init[][8] = {
407 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, 389 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
408 /* LCC1 LCC2 LCC3 LCC4 */ 390 /* LCC1 LCC2 LCC3 LCC4 */
409 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ 391 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
410 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, 392 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
411 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, 393 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
412 /* band gap reference [0..3] DBLV */ 394 /* band gap reference [0:3] DBLV */
413 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ 395 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
414 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ 396 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
415 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ 397 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
@@ -419,37 +401,35 @@ static const __u8 ov7660_sensor_init[][8] = {
419 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ 401 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
420 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ 402 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
421 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ 403 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
422 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, 404 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
423/****** (some exchanges in the win trace) ******/ 405/****** (some exchanges in the win trace) ******/
424 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, 406 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
425 /* bits[3..0]reserved */ 407 /* bits[3..0]reserved */
426 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, 408 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, 409 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
428 /* VREF vertical frame ctrl */ 410 /* VREF vertical frame ctrl */
429 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, 411 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ 412 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
431 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, 413 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
432 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, 414 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
433/* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ 415 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
434 {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, 416/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
435 {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10},
436/****** (some exchanges in the win trace) ******/ 417/****** (some exchanges in the win trace) ******/
437 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ 418 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
438 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ 419 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
439 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, 420 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
440 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, 421 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
441 {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, 422/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
442/****** (some exchanges in the win trace) ******/ 423/****** (some exchanges in the win trace) ******/
443/**********startsensor KO if changed !!****/ 424/******!! startsensor KO if changed !!****/
444 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, 425 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, 426 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, 427 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, 428 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
448/* here may start the isoc exchanges */
449 {} 429 {}
450}; 430};
451/* reg0x04 reg0x07 reg 0x10 */ 431/* reg 0x04 reg 0x07 reg 0x10 */
452/* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ 432/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
453 433
454static const __u8 ov7648_sensor_init[][8] = { 434static const __u8 ov7648_sensor_init[][8] = {
455 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, 435 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
@@ -680,13 +660,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
680 const __u8 *reg9a; 660 const __u8 *reg9a;
681 static const __u8 reg9a_def[] = 661 static const __u8 reg9a_def[] =
682 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; 662 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
683 static const __u8 reg9a_sn9c120[] = /* from win trace */
684 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
685 static const __u8 reg9a_sn9c325[] = 663 static const __u8 reg9a_sn9c325[] =
686 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; 664 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
665 static const __u8 regd4[] = {0x60, 0x00, 0x00};
687 666
688 reg_w1(gspca_dev, 0xf1, 0x00); 667 reg_w1(gspca_dev, 0xf1, 0x00);
689 reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/ 668 reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/
690 669
691 /* configure gpio */ 670 /* configure gpio */
692 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); 671 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
@@ -696,25 +675,17 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
696 case BRIDGE_SN9C325: 675 case BRIDGE_SN9C325:
697 reg9a = reg9a_sn9c325; 676 reg9a = reg9a_sn9c325;
698 break; 677 break;
699 case BRIDGE_SN9C120:
700 reg9a = reg9a_sn9c120;
701 break;
702 default: 678 default:
703 reg9a = reg9a_def; 679 reg9a = reg9a_def;
704 break; 680 break;
705 } 681 }
706 reg_w(gspca_dev, 0x9a, reg9a, 6); 682 reg_w(gspca_dev, 0x9a, reg9a, 6);
707 683
708 reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */ 684 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
709 685
710 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); 686 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
711 687
712 switch (sd->bridge) { 688 switch (sd->bridge) {
713 case BRIDGE_SN9C120: /* from win trace */
714 reg_w1(gspca_dev, 0x01, 0x61);
715 reg_w1(gspca_dev, 0x17, 0x20);
716 reg_w1(gspca_dev, 0x01, 0x60);
717 break;
718 case BRIDGE_SN9C325: 689 case BRIDGE_SN9C325:
719 reg_w1(gspca_dev, 0x01, 0x43); 690 reg_w1(gspca_dev, 0x01, 0x43);
720 reg_w1(gspca_dev, 0x17, 0xae); 691 reg_w1(gspca_dev, 0x17, 0xae);
@@ -810,6 +781,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
810 sd->contrast = CONTRAST_DEF; 781 sd->contrast = CONTRAST_DEF;
811 sd->colors = COLOR_DEF; 782 sd->colors = COLOR_DEF;
812 sd->autogain = AUTOGAIN_DEF; 783 sd->autogain = AUTOGAIN_DEF;
784 sd->ag_cnt = -1;
785
813 return 0; 786 return 0;
814} 787}
815 788
@@ -823,10 +796,11 @@ static int sd_open(struct gspca_dev *gspca_dev)
823 796
824 /* setup a selector by bridge */ 797 /* setup a selector by bridge */
825 reg_w1(gspca_dev, 0xf1, 0x01); 798 reg_w1(gspca_dev, 0xf1, 0x01);
826 reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
827 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
828 reg_r(gspca_dev, 0x00, 1); 799 reg_r(gspca_dev, 0x00, 1);
800 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
801 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
829 regF1 = gspca_dev->usb_buf[0]; 802 regF1 = gspca_dev->usb_buf[0];
803 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
830 switch (sd->bridge) { 804 switch (sd->bridge) {
831 case BRIDGE_SN9C102P: 805 case BRIDGE_SN9C102P:
832 if (regF1 != 0x11) 806 if (regF1 != 0x11)
@@ -937,15 +911,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
937 sd->exposure = setexposure(gspca_dev, expo); 911 sd->exposure = setexposure(gspca_dev, expo);
938 break; 912 break;
939 case SENSOR_MI0360: 913 case SENSOR_MI0360:
940 expo = sd->brightness >> 4;
941 sd->exposure = setexposure(gspca_dev, expo);
942 break;
943 case SENSOR_MO4000: 914 case SENSOR_MO4000:
944 expo = sd->brightness >> 4; 915 expo = sd->brightness >> 4;
945 sd->exposure = setexposure(gspca_dev, expo); 916 sd->exposure = setexposure(gspca_dev, expo);
946 break; 917 break;
947 case SENSOR_OV7660:
948 return; /*jfm??*/
949 } 918 }
950 919
951 k2 = sd->brightness >> 10; 920 k2 = sd->brightness >> 10;
@@ -958,8 +927,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
958 __u8 k2; 927 __u8 k2;
959 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; 928 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
960 929
961 if (sd->sensor == SENSOR_OV7660)
962 return; /*jfm??*/
963 k2 = sd->contrast; 930 k2 = sd->contrast;
964 contrast[2] = k2; 931 contrast[2] = k2;
965 contrast[0] = (k2 + 1) >> 1; 932 contrast[0] = (k2 + 1) >> 1;
@@ -981,20 +948,32 @@ static void setcolors(struct gspca_dev *gspca_dev)
981 reg_w1(gspca_dev, 0x05, data); 948 reg_w1(gspca_dev, 0x05, data);
982} 949}
983 950
951static void setautogain(struct gspca_dev *gspca_dev)
952{
953 struct sd *sd = (struct sd *) gspca_dev;
954
955 switch (sd->sensor) {
956 case SENSOR_HV7131R:
957 case SENSOR_MO4000:
958 case SENSOR_MI0360:
959 if (sd->autogain)
960 sd->ag_cnt = AG_CNT_START;
961 else
962 sd->ag_cnt = -1;
963 break;
964 }
965}
966
984/* -- start the camera -- */ 967/* -- start the camera -- */
985static void sd_start(struct gspca_dev *gspca_dev) 968static void sd_start(struct gspca_dev *gspca_dev)
986{ 969{
987 struct sd *sd = (struct sd *) gspca_dev; 970 struct sd *sd = (struct sd *) gspca_dev;
988 int i; 971 int i;
989 __u8 data; 972 __u8 reg1, reg17, reg18;
990 __u8 reg1;
991 __u8 reg17;
992 const __u8 *sn9c1xx; 973 const __u8 *sn9c1xx;
993 int mode; 974 int mode;
994 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; 975 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
995 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; 976 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
996 static const __u8 CA_sn9c120[] =
997 { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
998 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ 977 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
999 static const __u8 CE_sn9c325[] = 978 static const __u8 CE_sn9c325[] =
1000 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ 979 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */
@@ -1002,9 +981,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
1002 sn9c1xx = sn_tb[(int) sd->sensor]; 981 sn9c1xx = sn_tb[(int) sd->sensor];
1003 configure_gpio(gspca_dev, sn9c1xx); 982 configure_gpio(gspca_dev, sn9c1xx);
1004 983
1005/*fixme:jfm this sequence should appear at end of sd_start */ 984/* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
1006/* with
1007 reg_w1(gspca_dev, 0x01, 0x44); */
1008 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); 985 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1009 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); 986 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1010 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); 987 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
@@ -1016,20 +993,16 @@ static void sd_start(struct gspca_dev *gspca_dev)
1016 reg_w1(gspca_dev, 0xc7, 0x00); 993 reg_w1(gspca_dev, 0xc7, 0x00);
1017 reg_w1(gspca_dev, 0xc8, 0x50); 994 reg_w1(gspca_dev, 0xc8, 0x50);
1018 reg_w1(gspca_dev, 0xc9, 0x3c); 995 reg_w1(gspca_dev, 0xc9, 0x3c);
1019/*fixme:jfm end of ending sequence */
1020 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); 996 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1021 switch (sd->bridge) { 997 switch (sd->bridge) {
1022 case BRIDGE_SN9C325: 998 case BRIDGE_SN9C325:
1023 data = 0xae; 999 reg17 = 0xae;
1024 break;
1025 case BRIDGE_SN9C120:
1026 data = 0xa0;
1027 break; 1000 break;
1028 default: 1001 default:
1029 data = 0x60; 1002 reg17 = 0x60;
1030 break; 1003 break;
1031 } 1004 }
1032 reg_w1(gspca_dev, 0x17, data); 1005 reg_w1(gspca_dev, 0x17, reg17);
1033 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); 1006 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1034 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); 1007 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1035 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); 1008 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
@@ -1044,20 +1017,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
1044 reg_w1(gspca_dev, 0x9a, 0x0a); 1017 reg_w1(gspca_dev, 0x9a, 0x0a);
1045 reg_w1(gspca_dev, 0x99, 0x60); 1018 reg_w1(gspca_dev, 0x99, 0x60);
1046 break; 1019 break;
1047 case BRIDGE_SN9C120:
1048 reg_w(gspca_dev, 0x20, regsn20_sn9c120,
1049 sizeof regsn20_sn9c120);
1050 for (i = 0; i < 2; i++)
1051 reg_w(gspca_dev, 0x84, reg84_sn9c120_1,
1052 sizeof reg84_sn9c120_1);
1053 for (i = 0; i < 6; i++)
1054 reg_w(gspca_dev, 0x84, reg84_sn9c120_2,
1055 sizeof reg84_sn9c120_2);
1056 reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
1057 sizeof reg84_sn9c120_3);
1058 reg_w1(gspca_dev, 0x9a, 0x05);
1059 reg_w1(gspca_dev, 0x99, 0x5b);
1060 break;
1061 default: 1020 default:
1062 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); 1021 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1063 for (i = 0; i < 8; i++) 1022 for (i = 0; i < 8; i++)
@@ -1107,22 +1066,14 @@ static void sd_start(struct gspca_dev *gspca_dev)
1107/* reg1 = 0x44; */ 1066/* reg1 = 0x44; */
1108/* reg1 = 0x46; (done) */ 1067/* reg1 = 0x46; (done) */
1109 } else { 1068 } else {
1110 reg17 = 0xa2; /* 640 */ 1069 reg17 = 0x22; /* 640 MCKSIZE */
1111 reg1 = 0x40; 1070 reg1 = 0x06;
1112 } 1071 }
1113 break; 1072 break;
1114 } 1073 }
1115 reg_w(gspca_dev, 0xc0, C0, 6); 1074 reg_w(gspca_dev, 0xc0, C0, 6);
1075 reg_w(gspca_dev, 0xca, CA, 4);
1116 switch (sd->bridge) { 1076 switch (sd->bridge) {
1117 case BRIDGE_SN9C120: /*jfm ?? */
1118 reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
1119 break;
1120 default:
1121 reg_w(gspca_dev, 0xca, CA, 4);
1122 break;
1123 }
1124 switch (sd->bridge) {
1125 case BRIDGE_SN9C120: /*jfm ?? */
1126 case BRIDGE_SN9C325: 1077 case BRIDGE_SN9C325:
1127 reg_w(gspca_dev, 0xce, CE_sn9c325, 4); 1078 reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
1128 break; 1079 break;
@@ -1133,19 +1084,19 @@ static void sd_start(struct gspca_dev *gspca_dev)
1133 } 1084 }
1134 1085
1135 /* here change size mode 0 -> VGA; 1 -> CIF */ 1086 /* here change size mode 0 -> VGA; 1 -> CIF */
1136 data = 0x40 | sn9c1xx[0x18] | (mode << 4); 1087 reg18 = sn9c1xx[0x18] | (mode << 4);
1137 reg_w1(gspca_dev, 0x18, data); 1088 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1138 1089
1139 reg_w(gspca_dev, 0x100, qtable4, 0x40); 1090 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1140 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); 1091 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1141 1092
1142 data = sn9c1xx[0x18] | (mode << 4); 1093 reg_w1(gspca_dev, 0x18, reg18);
1143 reg_w1(gspca_dev, 0x18, data);
1144 1094
1145 reg_w1(gspca_dev, 0x17, reg17); 1095 reg_w1(gspca_dev, 0x17, reg17);
1146 reg_w1(gspca_dev, 0x01, reg1); 1096 reg_w1(gspca_dev, 0x01, reg1);
1147 setbrightness(gspca_dev); 1097 setbrightness(gspca_dev);
1148 setcontrast(gspca_dev); 1098 setcontrast(gspca_dev);
1099 setautogain(gspca_dev);
1149} 1100}
1150 1101
1151static void sd_stopN(struct gspca_dev *gspca_dev) 1102static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -1168,12 +1119,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1168 i2c_w8(gspca_dev, stopmi0360); 1119 i2c_w8(gspca_dev, stopmi0360);
1169 data = 0x29; 1120 data = 0x29;
1170 break; 1121 break;
1171 case SENSOR_MO4000:
1172 break;
1173 case SENSOR_OV7648: 1122 case SENSOR_OV7648:
1174 data = 0x29; 1123 data = 0x29;
1175 break; 1124 break;
1176 default: 1125 default:
1126/* case SENSOR_MO4000: */
1177/* case SENSOR_OV7660: */ 1127/* case SENSOR_OV7660: */
1178 break; 1128 break;
1179 } 1129 }
@@ -1193,16 +1143,23 @@ static void sd_close(struct gspca_dev *gspca_dev)
1193{ 1143{
1194} 1144}
1195 1145
1196static void setautogain(struct gspca_dev *gspca_dev) 1146static void do_autogain(struct gspca_dev *gspca_dev)
1197{ 1147{
1198 struct sd *sd = (struct sd *) gspca_dev; 1148 struct sd *sd = (struct sd *) gspca_dev;
1199 /* Thanks S., without your advice, autobright should not work :) */
1200 int delta; 1149 int delta;
1201 int expotimes = 0; 1150 int expotimes;
1202 __u8 luma_mean = 130; 1151 __u8 luma_mean = 130;
1203 __u8 luma_delta = 20; 1152 __u8 luma_delta = 20;
1204 1153
1205 delta = sd->avg_lum; 1154 /* Thanks S., without your advice, autobright should not work :) */
1155 if (sd->ag_cnt < 0)
1156 return;
1157 if (--sd->ag_cnt >= 0)
1158 return;
1159 sd->ag_cnt = AG_CNT_START;
1160
1161 delta = atomic_read(&sd->avg_lum);
1162 PDEBUG(D_FRAM, "mean lum %d", delta);
1206 if (delta < luma_mean - luma_delta || 1163 if (delta < luma_mean - luma_delta ||
1207 delta > luma_mean + luma_delta) { 1164 delta > luma_mean + luma_delta) {
1208 switch (sd->sensor) { 1165 switch (sd->sensor) {
@@ -1214,8 +1171,9 @@ static void setautogain(struct gspca_dev *gspca_dev)
1214 sd->exposure = setexposure(gspca_dev, 1171 sd->exposure = setexposure(gspca_dev,
1215 (unsigned int) (expotimes << 8)); 1172 (unsigned int) (expotimes << 8));
1216 break; 1173 break;
1217 case SENSOR_MO4000: 1174 default:
1218 case SENSOR_MI0360: 1175/* case SENSOR_MO4000: */
1176/* case SENSOR_MI0360: */
1219 expotimes = sd->exposure; 1177 expotimes = sd->exposure;
1220 expotimes += (luma_mean - delta) >> 6; 1178 expotimes += (luma_mean - delta) >> 6;
1221 if (expotimes < 0) 1179 if (expotimes < 0)
@@ -1228,6 +1186,8 @@ static void setautogain(struct gspca_dev *gspca_dev)
1228 } 1186 }
1229} 1187}
1230 1188
1189/* scan the URB packets */
1190/* This function is run at interrupt level. */
1231static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1191static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1232 struct gspca_frame *frame, /* target */ 1192 struct gspca_frame *frame, /* target */
1233 __u8 *data, /* isoc packet */ 1193 __u8 *data, /* isoc packet */
@@ -1244,9 +1204,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1244 frame, data, sof + 2); 1204 frame, data, sof + 2);
1245 if (sd->ag_cnt < 0) 1205 if (sd->ag_cnt < 0)
1246 return; 1206 return;
1247 if (--sd->ag_cnt >= 0)
1248 return;
1249 sd->ag_cnt = AG_CNT_START;
1250/* w1 w2 w3 */ 1207/* w1 w2 w3 */
1251/* w4 w5 w6 */ 1208/* w4 w5 w6 */
1252/* w7 w8 */ 1209/* w7 w8 */
@@ -1261,9 +1218,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1261/* w5 */ 1218/* w5 */
1262 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; 1219 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1263 avg_lum >>= 4; 1220 avg_lum >>= 4;
1264 sd->avg_lum = avg_lum; 1221 atomic_set(&sd->avg_lum, avg_lum);
1265 PDEBUG(D_PACK, "mean lum %d", avg_lum);
1266 setautogain(gspca_dev);
1267 return; 1222 return;
1268 } 1223 }
1269 if (gspca_dev->last_packet_type == LAST_PACKET) { 1224 if (gspca_dev->last_packet_type == LAST_PACKET) {
@@ -1300,6 +1255,7 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev)
1300 (hexpo << 10) | (mexpo << 2) | lexpo); 1255 (hexpo << 10) | (mexpo << 2) | lexpo);
1301 return (hexpo << 10) | (mexpo << 2) | lexpo; 1256 return (hexpo << 10) | (mexpo << 2) | lexpo;
1302 default: 1257 default:
1258/* case SENSOR_OV7648: * jfm: is it ok for 7648? */
1303/* case SENSOR_OV7660: */ 1259/* case SENSOR_OV7660: */
1304 /* read sensor exposure */ 1260 /* read sensor exposure */
1305 i2c_r5(gspca_dev, 0x04); 1261 i2c_r5(gspca_dev, 0x04);
@@ -1318,14 +1274,12 @@ static void getbrightness(struct gspca_dev *gspca_dev)
1318 /* hardcoded registers seem not readable */ 1274 /* hardcoded registers seem not readable */
1319 switch (sd->sensor) { 1275 switch (sd->sensor) {
1320 case SENSOR_HV7131R: 1276 case SENSOR_HV7131R:
1321/* sd->brightness = 0x7fff; */
1322 sd->brightness = getexposure(gspca_dev) >> 4; 1277 sd->brightness = getexposure(gspca_dev) >> 4;
1323 break; 1278 break;
1324 case SENSOR_MI0360: 1279 case SENSOR_MI0360:
1325 sd->brightness = getexposure(gspca_dev) << 4; 1280 sd->brightness = getexposure(gspca_dev) << 4;
1326 break; 1281 break;
1327 case SENSOR_MO4000: 1282 case SENSOR_MO4000:
1328/* sd->brightness = 0x1fff; */
1329 sd->brightness = getexposure(gspca_dev) << 4; 1283 sd->brightness = getexposure(gspca_dev) << 4;
1330 break; 1284 break;
1331 } 1285 }
@@ -1391,10 +1345,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1391 struct sd *sd = (struct sd *) gspca_dev; 1345 struct sd *sd = (struct sd *) gspca_dev;
1392 1346
1393 sd->autogain = val; 1347 sd->autogain = val;
1394 if (val) 1348 if (gspca_dev->streaming)
1395 sd->ag_cnt = AG_CNT_START; 1349 setautogain(gspca_dev);
1396 else
1397 sd->ag_cnt = -1;
1398 return 0; 1350 return 0;
1399} 1351}
1400 1352
@@ -1418,6 +1370,7 @@ static const struct sd_desc sd_desc = {
1418 .stop0 = sd_stop0, 1370 .stop0 = sd_stop0,
1419 .close = sd_close, 1371 .close = sd_close,
1420 .pkt_scan = sd_pkt_scan, 1372 .pkt_scan = sd_pkt_scan,
1373 .dq_callback = do_autogain,
1421}; 1374};
1422 1375
1423/* -- module initialisation -- */ 1376/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 3c2be80cbd65..eda29d609359 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -61,27 +61,27 @@ static struct ctrl sd_ctrls[] = {
61 61
62static struct v4l2_pix_format vga_mode[] = { 62static struct v4l2_pix_format vga_mode[] = {
63 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 63 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
64 .bytesperline = 160 * 3, 64 .bytesperline = 160,
65 .sizeimage = 160 * 120 * 3 / 2, 65 .sizeimage = 160 * 120 * 3 / 2,
66 .colorspace = V4L2_COLORSPACE_SRGB, 66 .colorspace = V4L2_COLORSPACE_SRGB,
67 .priv = 5}, 67 .priv = 5},
68 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 68 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
69 .bytesperline = 176 * 3, 69 .bytesperline = 176,
70 .sizeimage = 176 * 144 * 3 / 2, 70 .sizeimage = 176 * 144 * 3 / 2,
71 .colorspace = V4L2_COLORSPACE_SRGB, 71 .colorspace = V4L2_COLORSPACE_SRGB,
72 .priv = 4}, 72 .priv = 4},
73 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 73 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
74 .bytesperline = 320 * 3, 74 .bytesperline = 320,
75 .sizeimage = 320 * 240 * 3 / 2, 75 .sizeimage = 320 * 240 * 3 / 2,
76 .colorspace = V4L2_COLORSPACE_SRGB, 76 .colorspace = V4L2_COLORSPACE_SRGB,
77 .priv = 2}, 77 .priv = 2},
78 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 78 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
79 .bytesperline = 352 * 3, 79 .bytesperline = 352,
80 .sizeimage = 352 * 288 * 3 / 2, 80 .sizeimage = 352 * 288 * 3 / 2,
81 .colorspace = V4L2_COLORSPACE_SRGB, 81 .colorspace = V4L2_COLORSPACE_SRGB,
82 .priv = 1}, 82 .priv = 1},
83 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 83 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
84 .bytesperline = 640 * 3, 84 .bytesperline = 640,
85 .sizeimage = 640 * 480 * 3 / 2, 85 .sizeimage = 640 * 480 * 3 / 2,
86 .colorspace = V4L2_COLORSPACE_SRGB, 86 .colorspace = V4L2_COLORSPACE_SRGB,
87 .priv = 0}, 87 .priv = 0},
@@ -776,7 +776,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
776 default: 776 default:
777 data += 1; 777 data += 1;
778 len -= 1; 778 len -= 1;
779 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 779 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
780 data, len); 780 data, len);
781 break; 781 break;
782 } 782 }
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 6fe715c80ad2..f622fa75766d 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -112,27 +112,27 @@ static struct ctrl sd_ctrls[] = {
112 112
113static struct v4l2_pix_format vga_mode[] = { 113static struct v4l2_pix_format vga_mode[] = {
114 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 114 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
115 .bytesperline = 160 * 3, 115 .bytesperline = 160,
116 .sizeimage = 160 * 120 * 3 / 2, 116 .sizeimage = 160 * 120 * 3 / 2,
117 .colorspace = V4L2_COLORSPACE_SRGB, 117 .colorspace = V4L2_COLORSPACE_SRGB,
118 .priv = 5}, 118 .priv = 5},
119 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 119 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
120 .bytesperline = 176 * 3, 120 .bytesperline = 176,
121 .sizeimage = 176 * 144 * 3 / 2, 121 .sizeimage = 176 * 144 * 3 / 2,
122 .colorspace = V4L2_COLORSPACE_SRGB, 122 .colorspace = V4L2_COLORSPACE_SRGB,
123 .priv = 4}, 123 .priv = 4},
124 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 124 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
125 .bytesperline = 320 * 3, 125 .bytesperline = 320,
126 .sizeimage = 320 * 240 * 3 / 2, 126 .sizeimage = 320 * 240 * 3 / 2,
127 .colorspace = V4L2_COLORSPACE_SRGB, 127 .colorspace = V4L2_COLORSPACE_SRGB,
128 .priv = 2}, 128 .priv = 2},
129 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 129 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
130 .bytesperline = 352 * 3, 130 .bytesperline = 352,
131 .sizeimage = 352 * 288 * 3 / 2, 131 .sizeimage = 352 * 288 * 3 / 2,
132 .colorspace = V4L2_COLORSPACE_SRGB, 132 .colorspace = V4L2_COLORSPACE_SRGB,
133 .priv = 1}, 133 .priv = 1},
134 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, 134 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
135 .bytesperline = 640 * 3, 135 .bytesperline = 640,
136 .sizeimage = 640 * 480 * 3 / 2, 136 .sizeimage = 640 * 480 * 3 / 2,
137 .colorspace = V4L2_COLORSPACE_SRGB, 137 .colorspace = V4L2_COLORSPACE_SRGB,
138 .priv = 0}, 138 .priv = 0},
@@ -588,7 +588,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
588 default: 588 default:
589 data += 1; 589 data += 1;
590 len -= 1; 590 len -= 1;
591 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 591 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
592 data, len); 592 data, len);
593 break; 593 break;
594 } 594 }
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index b608a27ad115..699340c17dea 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -63,23 +63,23 @@ static struct ctrl sd_ctrls[] = {
63}; 63};
64 64
65static struct v4l2_pix_format sif_mode[] = { 65static struct v4l2_pix_format sif_mode[] = {
66 {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 66 {160, 120, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
67 .bytesperline = 160 * 3, 67 .bytesperline = 160,
68 .sizeimage = 160 * 120 * 3 / 2, 68 .sizeimage = 160 * 120 * 3 / 2,
69 .colorspace = V4L2_COLORSPACE_SRGB, 69 .colorspace = V4L2_COLORSPACE_SRGB,
70 .priv = 3}, 70 .priv = 3},
71 {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 71 {176, 144, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
72 .bytesperline = 176 * 3, 72 .bytesperline = 176,
73 .sizeimage = 176 * 144 * 3 / 2, 73 .sizeimage = 176 * 144 * 3 / 2,
74 .colorspace = V4L2_COLORSPACE_SRGB, 74 .colorspace = V4L2_COLORSPACE_SRGB,
75 .priv = 2}, 75 .priv = 2},
76 {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 76 {320, 240, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
77 .bytesperline = 320 * 3, 77 .bytesperline = 320,
78 .sizeimage = 320 * 240 * 3 / 2, 78 .sizeimage = 320 * 240 * 3 / 2,
79 .colorspace = V4L2_COLORSPACE_SRGB, 79 .colorspace = V4L2_COLORSPACE_SRGB,
80 .priv = 1}, 80 .priv = 1},
81 {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 81 {352, 288, V4L2_PIX_FMT_SPCA508, V4L2_FIELD_NONE,
82 .bytesperline = 352 * 3, 82 .bytesperline = 352,
83 .sizeimage = 352 * 288 * 3 / 2, 83 .sizeimage = 352 * 288 * 3 / 2,
84 .colorspace = V4L2_COLORSPACE_SRGB, 84 .colorspace = V4L2_COLORSPACE_SRGB,
85 .priv = 0}, 85 .priv = 0},
@@ -1583,7 +1583,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1583 default: 1583 default:
1584 data += 1; 1584 data += 1;
1585 len -= 1; 1585 len -= 1;
1586 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 1586 gspca_frame_add(gspca_dev, INTER_PACKET, frame,
1587 data, len); 1587 data, len);
1588 break; 1588 break;
1589 } 1589 }
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index a26174508cb9..1073ac3d2ec6 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -644,6 +644,18 @@ static void setcontrast(struct gspca_dev *gspca_dev)
644 } 644 }
645} 645}
646 646
647static void setautogain(struct gspca_dev *gspca_dev)
648{
649 struct sd *sd = (struct sd *) gspca_dev;
650
651 if (sd->chip_revision == Rev072A) {
652 if (sd->autogain)
653 sd->ag_cnt = AG_CNT_START;
654 else
655 sd->ag_cnt = -1;
656 }
657}
658
647static void sd_start(struct gspca_dev *gspca_dev) 659static void sd_start(struct gspca_dev *gspca_dev)
648{ 660{
649 struct sd *sd = (struct sd *) gspca_dev; 661 struct sd *sd = (struct sd *) gspca_dev;
@@ -671,6 +683,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
671 reg_w_val(dev, 0x8500, mode); /* mode */ 683 reg_w_val(dev, 0x8500, mode); /* mode */
672 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ 684 reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
673 reg_w_val(dev, 0x8112, 0x10 | 0x20); 685 reg_w_val(dev, 0x8112, 0x10 | 0x20);
686 setautogain(gspca_dev);
674 break; 687 break;
675 default: 688 default:
676/* case Rev012A: */ 689/* case Rev012A: */
@@ -720,18 +733,24 @@ static void sd_close(struct gspca_dev *gspca_dev)
720 reg_w_val(gspca_dev->dev, 0x8114, 0); 733 reg_w_val(gspca_dev->dev, 0x8114, 0);
721} 734}
722 735
723static void setautogain(struct gspca_dev *gspca_dev) 736static void do_autogain(struct gspca_dev *gspca_dev)
724{ 737{
725 struct sd *sd = (struct sd *) gspca_dev; 738 struct sd *sd = (struct sd *) gspca_dev;
726 int expotimes = 0; 739 int expotimes;
727 int pixelclk = 0; 740 int pixelclk;
728 int gainG = 0; 741 int gainG;
729 __u8 R, Gr, Gb, B; 742 __u8 R, Gr, Gb, B;
730 int y; 743 int y;
731 __u8 luma_mean = 110; 744 __u8 luma_mean = 110;
732 __u8 luma_delta = 20; 745 __u8 luma_delta = 20;
733 __u8 spring = 4; 746 __u8 spring = 4;
734 747
748 if (sd->ag_cnt < 0)
749 return;
750 if (--sd->ag_cnt >= 0)
751 return;
752 sd->ag_cnt = AG_CNT_START;
753
735 switch (sd->chip_revision) { 754 switch (sd->chip_revision) {
736 case Rev072A: 755 case Rev072A:
737 reg_r(gspca_dev, 0x8621, 1); 756 reg_r(gspca_dev, 0x8621, 1);
@@ -795,18 +814,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
795 __u8 *data, /* isoc packet */ 814 __u8 *data, /* isoc packet */
796 int len) /* iso packet length */ 815 int len) /* iso packet length */
797{ 816{
798 struct sd *sd = (struct sd *) gspca_dev;
799
800 switch (data[0]) { 817 switch (data[0]) {
801 case 0: /* start of frame */ 818 case 0: /* start of frame */
802 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 819 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
803 data, 0); 820 data, 0);
804 if (sd->ag_cnt >= 0) {
805 if (--sd->ag_cnt < 0) {
806 sd->ag_cnt = AG_CNT_START;
807 setautogain(gspca_dev);
808 }
809 }
810 data += SPCA561_OFFSET_DATA; 821 data += SPCA561_OFFSET_DATA;
811 len -= SPCA561_OFFSET_DATA; 822 len -= SPCA561_OFFSET_DATA;
812 if (data[1] & 0x10) { 823 if (data[1] & 0x10) {
@@ -944,10 +955,8 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
944 struct sd *sd = (struct sd *) gspca_dev; 955 struct sd *sd = (struct sd *) gspca_dev;
945 956
946 sd->autogain = val; 957 sd->autogain = val;
947 if (val) 958 if (gspca_dev->streaming)
948 sd->ag_cnt = AG_CNT_START; 959 setautogain(gspca_dev);
949 else
950 sd->ag_cnt = -1;
951 return 0; 960 return 0;
952} 961}
953 962
@@ -971,6 +980,7 @@ static const struct sd_desc sd_desc = {
971 .stop0 = sd_stop0, 980 .stop0 = sd_stop0,
972 .close = sd_close, 981 .close = sd_close,
973 .pkt_scan = sd_pkt_scan, 982 .pkt_scan = sd_pkt_scan,
983 .dq_callback = do_autogain,
974}; 984};
975 985
976/* -- module initialisation -- */ 986/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index a4221753e1bf..f4a52956e0d9 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -88,12 +88,12 @@ static struct ctrl sd_ctrls[] = {
88 88
89static struct v4l2_pix_format vc0321_mode[] = { 89static struct v4l2_pix_format vc0321_mode[] = {
90 {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 90 {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
91 .bytesperline = 320 * 2, 91 .bytesperline = 320,
92 .sizeimage = 320 * 240 * 2, 92 .sizeimage = 320 * 240 * 2,
93 .colorspace = V4L2_COLORSPACE_SRGB, 93 .colorspace = V4L2_COLORSPACE_SRGB,
94 .priv = 1}, 94 .priv = 1},
95 {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, 95 {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
96 .bytesperline = 640 * 2, 96 .bytesperline = 640,
97 .sizeimage = 640 * 480 * 2, 97 .sizeimage = 640 * 480 * 2,
98 .colorspace = V4L2_COLORSPACE_SRGB, 98 .colorspace = V4L2_COLORSPACE_SRGB,
99 .priv = 0}, 99 .priv = 0},
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 22a994ccb1d5..bc7d0eedcd81 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -6469,7 +6469,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6469 NULL, Tgradient_1, Tgradient_2, 6469 NULL, Tgradient_1, Tgradient_2,
6470 Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 6470 Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
6471 }; 6471 };
6472#ifdef CONFIG_VIDEO_ADV_DEBUG 6472#ifdef GSPCA_DEBUG
6473 __u8 v[16]; 6473 __u8 v[16];
6474#endif 6474#endif
6475 6475
@@ -6487,7 +6487,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6487 else if (g <= 0) 6487 else if (g <= 0)
6488 g = 1; 6488 g = 1;
6489 reg_w(dev, g, 0x0120 + i); /* gamma */ 6489 reg_w(dev, g, 0x0120 + i); /* gamma */
6490#ifdef CONFIG_VIDEO_ADV_DEBUG 6490#ifdef GSPCA_DEBUG
6491 if (gspca_debug & D_CONF) 6491 if (gspca_debug & D_CONF)
6492 v[i] = g; 6492 v[i] = g;
6493#endif 6493#endif
@@ -6507,7 +6507,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
6507 g = 1; 6507 g = 1;
6508 } 6508 }
6509 reg_w(dev, g, 0x0130 + i); /* gradient */ 6509 reg_w(dev, g, 0x0130 + i); /* gradient */
6510#ifdef CONFIG_VIDEO_ADV_DEBUG 6510#ifdef GSPCA_DEBUG
6511 if (gspca_debug & D_CONF) 6511 if (gspca_debug & D_CONF)
6512 v[i] = g; 6512 v[i] = g;
6513#endif 6513#endif
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index b15f82c49766..388cf94055d3 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -36,8 +36,8 @@
36#include <linux/videodev2.h> 36#include <linux/videodev2.h>
37 37
38#include <asm/dma.h> 38#include <asm/dma.h>
39#include <asm/arch/pxa-regs.h> 39#include <mach/pxa-regs.h>
40#include <asm/arch/camera.h> 40#include <mach/camera.h>
41 41
42#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) 42#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5)
43#define PXA_CAM_DRV_NAME "pxa27x-camera" 43#define PXA_CAM_DRV_NAME "pxa27x-camera"
@@ -128,6 +128,8 @@ struct pxa_camera_dev {
128 128
129 struct pxa_buffer *active; 129 struct pxa_buffer *active;
130 struct pxa_dma_desc *sg_tail[3]; 130 struct pxa_dma_desc *sg_tail[3];
131
132 u32 save_cicr[5];
131}; 133};
132 134
133static const char *pxa_cam_driver_description = "PXA_Camera"; 135static const char *pxa_cam_driver_description = "PXA_Camera";
@@ -997,10 +999,64 @@ static int pxa_camera_querycap(struct soc_camera_host *ici,
997 return 0; 999 return 0;
998} 1000}
999 1001
1002static int pxa_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
1003{
1004 struct soc_camera_host *ici =
1005 to_soc_camera_host(icd->dev.parent);
1006 struct pxa_camera_dev *pcdev = ici->priv;
1007 int i = 0, ret = 0;
1008
1009 pcdev->save_cicr[i++] = CICR0;
1010 pcdev->save_cicr[i++] = CICR1;
1011 pcdev->save_cicr[i++] = CICR2;
1012 pcdev->save_cicr[i++] = CICR3;
1013 pcdev->save_cicr[i++] = CICR4;
1014
1015 if ((pcdev->icd) && (pcdev->icd->ops->suspend))
1016 ret = pcdev->icd->ops->suspend(pcdev->icd, state);
1017
1018 return ret;
1019}
1020
1021static int pxa_camera_resume(struct soc_camera_device *icd)
1022{
1023 struct soc_camera_host *ici =
1024 to_soc_camera_host(icd->dev.parent);
1025 struct pxa_camera_dev *pcdev = ici->priv;
1026 int i = 0, ret = 0;
1027
1028 DRCMR68 = pcdev->dma_chans[0] | DRCMR_MAPVLD;
1029 DRCMR69 = pcdev->dma_chans[1] | DRCMR_MAPVLD;
1030 DRCMR70 = pcdev->dma_chans[2] | DRCMR_MAPVLD;
1031
1032 CICR0 = pcdev->save_cicr[i++] & ~CICR0_ENB;
1033 CICR1 = pcdev->save_cicr[i++];
1034 CICR2 = pcdev->save_cicr[i++];
1035 CICR3 = pcdev->save_cicr[i++];
1036 CICR4 = pcdev->save_cicr[i++];
1037
1038 if ((pcdev->icd) && (pcdev->icd->ops->resume))
1039 ret = pcdev->icd->ops->resume(pcdev->icd);
1040
1041 /* Restart frame capture if active buffer exists */
1042 if (!ret && pcdev->active) {
1043 /* Reset the FIFOs */
1044 CIFR |= CIFR_RESET_F;
1045 /* Enable End-Of-Frame Interrupt */
1046 CICR0 &= ~CICR0_EOFM;
1047 /* Restart the Capture Interface */
1048 CICR0 |= CICR0_ENB;
1049 }
1050
1051 return ret;
1052}
1053
1000static struct soc_camera_host_ops pxa_soc_camera_host_ops = { 1054static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1001 .owner = THIS_MODULE, 1055 .owner = THIS_MODULE,
1002 .add = pxa_camera_add_device, 1056 .add = pxa_camera_add_device,
1003 .remove = pxa_camera_remove_device, 1057 .remove = pxa_camera_remove_device,
1058 .suspend = pxa_camera_suspend,
1059 .resume = pxa_camera_resume,
1004 .set_fmt_cap = pxa_camera_set_fmt_cap, 1060 .set_fmt_cap = pxa_camera_set_fmt_cap,
1005 .try_fmt_cap = pxa_camera_try_fmt_cap, 1061 .try_fmt_cap = pxa_camera_try_fmt_cap,
1006 .init_videobuf = pxa_camera_init_videobuf, 1062 .init_videobuf = pxa_camera_init_videobuf,
@@ -1198,7 +1254,7 @@ static int __devinit pxa_camera_init(void)
1198 1254
1199static void __exit pxa_camera_exit(void) 1255static void __exit pxa_camera_exit(void)
1200{ 1256{
1201 return platform_driver_unregister(&pxa_camera_driver); 1257 platform_driver_unregister(&pxa_camera_driver);
1202} 1258}
1203 1259
1204module_init(pxa_camera_init); 1260module_init(pxa_camera_init);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index f7ca3cb9340a..318754e73132 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -647,7 +647,7 @@ static int __init sh_mobile_ceu_init(void)
647 647
648static void __exit sh_mobile_ceu_exit(void) 648static void __exit sh_mobile_ceu_exit(void)
649{ 649{
650 return platform_driver_unregister(&sh_mobile_ceu_driver); 650 platform_driver_unregister(&sh_mobile_ceu_driver);
651} 651}
652 652
653module_init(sh_mobile_ceu_init); 653module_init(sh_mobile_ceu_init);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index b6be5ee678b6..66ebe5956a87 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -732,10 +732,36 @@ static int soc_camera_remove(struct device *dev)
732 return 0; 732 return 0;
733} 733}
734 734
735static int soc_camera_suspend(struct device *dev, pm_message_t state)
736{
737 struct soc_camera_device *icd = to_soc_camera_dev(dev);
738 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
739 int ret = 0;
740
741 if (ici->ops->suspend)
742 ret = ici->ops->suspend(icd, state);
743
744 return ret;
745}
746
747static int soc_camera_resume(struct device *dev)
748{
749 struct soc_camera_device *icd = to_soc_camera_dev(dev);
750 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
751 int ret = 0;
752
753 if (ici->ops->resume)
754 ret = ici->ops->resume(icd);
755
756 return ret;
757}
758
735static struct bus_type soc_camera_bus_type = { 759static struct bus_type soc_camera_bus_type = {
736 .name = "soc-camera", 760 .name = "soc-camera",
737 .probe = soc_camera_probe, 761 .probe = soc_camera_probe,
738 .remove = soc_camera_remove, 762 .remove = soc_camera_remove,
763 .suspend = soc_camera_suspend,
764 .resume = soc_camera_resume,
739}; 765};
740 766
741static struct device_driver ic_drv = { 767static struct device_driver ic_drv = {
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index eefb0327ebb6..1adc257ebdb9 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -187,7 +187,7 @@ static int __init soc_camera_platform_module_init(void)
187 187
188static void __exit soc_camera_platform_module_exit(void) 188static void __exit soc_camera_platform_module_exit(void)
189{ 189{
190 return platform_driver_unregister(&soc_camera_platform_driver); 190 platform_driver_unregister(&soc_camera_platform_driver);
191} 191}
192 192
193module_init(soc_camera_platform_module_init); 193module_init(soc_camera_platform_module_init);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 626f4ad7e876..6ef3e5297de8 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
585 struct uvc_control_mapping *mapping; 585 struct uvc_control_mapping *mapping;
586 struct uvc_menu_info *menu; 586 struct uvc_menu_info *menu;
587 unsigned int i; 587 unsigned int i;
588 __u8 data[8]; 588 __u8 *data;
589 int ret; 589 int ret;
590 590
591 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); 591 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
592 if (ctrl == NULL) 592 if (ctrl == NULL)
593 return -EINVAL; 593 return -EINVAL;
594 594
595 data = kmalloc(8, GFP_KERNEL);
596 if (data == NULL)
597 return -ENOMEM;
598
595 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); 599 memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
596 v4l2_ctrl->id = mapping->id; 600 v4l2_ctrl->id = mapping->id;
597 v4l2_ctrl->type = mapping->v4l2_type; 601 v4l2_ctrl->type = mapping->v4l2_type;
@@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
604 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { 608 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
605 if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, 609 if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id,
606 video->dev->intfnum, ctrl->info->selector, 610 video->dev->intfnum, ctrl->info->selector,
607 &data, ctrl->info->size)) < 0) 611 data, ctrl->info->size)) < 0)
608 return ret; 612 goto out;
609 v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); 613 v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
610 } 614 }
611 615
@@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
623 } 627 }
624 } 628 }
625 629
626 return 0; 630 ret = 0;
631 goto out;
627 632
628 case V4L2_CTRL_TYPE_BOOLEAN: 633 case V4L2_CTRL_TYPE_BOOLEAN:
629 v4l2_ctrl->minimum = 0; 634 v4l2_ctrl->minimum = 0;
630 v4l2_ctrl->maximum = 1; 635 v4l2_ctrl->maximum = 1;
631 v4l2_ctrl->step = 1; 636 v4l2_ctrl->step = 1;
632 return 0; 637 ret = 0;
638 goto out;
633 639
634 default: 640 default:
635 break; 641 break;
@@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
638 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { 644 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
639 if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, 645 if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id,
640 video->dev->intfnum, ctrl->info->selector, 646 video->dev->intfnum, ctrl->info->selector,
641 &data, ctrl->info->size)) < 0) 647 data, ctrl->info->size)) < 0)
642 return ret; 648 goto out;
643 v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); 649 v4l2_ctrl->minimum = uvc_get_le_value(data, mapping);
644 } 650 }
645 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { 651 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
646 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, 652 if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
647 video->dev->intfnum, ctrl->info->selector, 653 video->dev->intfnum, ctrl->info->selector,
648 &data, ctrl->info->size)) < 0) 654 data, ctrl->info->size)) < 0)
649 return ret; 655 goto out;
650 v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); 656 v4l2_ctrl->maximum = uvc_get_le_value(data, mapping);
651 } 657 }
652 if (ctrl->info->flags & UVC_CONTROL_GET_RES) { 658 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
653 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, 659 if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
654 video->dev->intfnum, ctrl->info->selector, 660 video->dev->intfnum, ctrl->info->selector,
655 &data, ctrl->info->size)) < 0) 661 data, ctrl->info->size)) < 0)
656 return ret; 662 goto out;
657 v4l2_ctrl->step = uvc_get_le_value(data, mapping); 663 v4l2_ctrl->step = uvc_get_le_value(data, mapping);
658 } 664 }
659 665
660 return 0; 666 ret = 0;
667out:
668 kfree(data);
669 return ret;
661} 670}
662 671
663 672
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index b3c4d75e8490..7e102034d38d 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1884,7 +1884,7 @@ static struct usb_device_id uvc_ids[] = {
1884 .bInterfaceSubClass = 1, 1884 .bInterfaceSubClass = 1,
1885 .bInterfaceProtocol = 0, 1885 .bInterfaceProtocol = 0,
1886 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1886 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1887 /* Packard Bell OEM Webcam */ 1887 /* Packard Bell OEM Webcam - Bison Electronics */
1888 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1888 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1889 | USB_DEVICE_ID_MATCH_INT_INFO, 1889 | USB_DEVICE_ID_MATCH_INT_INFO,
1890 .idVendor = 0x5986, 1890 .idVendor = 0x5986,
@@ -1893,7 +1893,7 @@ static struct usb_device_id uvc_ids[] = {
1893 .bInterfaceSubClass = 1, 1893 .bInterfaceSubClass = 1,
1894 .bInterfaceProtocol = 0, 1894 .bInterfaceProtocol = 0,
1895 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1895 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1896 /* Acer Crystal Eye webcam */ 1896 /* Acer Crystal Eye webcam - Bison Electronics */
1897 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1897 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1898 | USB_DEVICE_ID_MATCH_INT_INFO, 1898 | USB_DEVICE_ID_MATCH_INT_INFO,
1899 .idVendor = 0x5986, 1899 .idVendor = 0x5986,
@@ -1902,7 +1902,7 @@ static struct usb_device_id uvc_ids[] = {
1902 .bInterfaceSubClass = 1, 1902 .bInterfaceSubClass = 1,
1903 .bInterfaceProtocol = 0, 1903 .bInterfaceProtocol = 0,
1904 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1904 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1905 /* Medion Akoya Mini E1210 */ 1905 /* Medion Akoya Mini E1210 - Bison Electronics */
1906 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1906 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1907 | USB_DEVICE_ID_MATCH_INT_INFO, 1907 | USB_DEVICE_ID_MATCH_INT_INFO,
1908 .idVendor = 0x5986, 1908 .idVendor = 0x5986,
@@ -1911,7 +1911,7 @@ static struct usb_device_id uvc_ids[] = {
1911 .bInterfaceSubClass = 1, 1911 .bInterfaceSubClass = 1,
1912 .bInterfaceProtocol = 0, 1912 .bInterfaceProtocol = 0,
1913 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1913 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1914 /* Acer OrbiCam - Unknown vendor */ 1914 /* Acer OrbiCam - Bison Electronics */
1915 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 1915 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1916 | USB_DEVICE_ID_MATCH_INT_INFO, 1916 | USB_DEVICE_ID_MATCH_INT_INFO,
1917 .idVendor = 0x5986, 1917 .idVendor = 0x5986,
@@ -1920,6 +1920,24 @@ static struct usb_device_id uvc_ids[] = {
1920 .bInterfaceSubClass = 1, 1920 .bInterfaceSubClass = 1,
1921 .bInterfaceProtocol = 0, 1921 .bInterfaceProtocol = 0,
1922 .driver_info = UVC_QUIRK_PROBE_MINMAX }, 1922 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1923 /* Bison Electronics */
1924 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1925 | USB_DEVICE_ID_MATCH_INT_INFO,
1926 .idVendor = 0x5986,
1927 .idProduct = 0x0300,
1928 .bInterfaceClass = USB_CLASS_VIDEO,
1929 .bInterfaceSubClass = 1,
1930 .bInterfaceProtocol = 0,
1931 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1932 /* Clevo M570TU - Bison Electronics */
1933 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
1934 | USB_DEVICE_ID_MATCH_INT_INFO,
1935 .idVendor = 0x5986,
1936 .idProduct = 0x0303,
1937 .bInterfaceClass = USB_CLASS_VIDEO,
1938 .bInterfaceSubClass = 1,
1939 .bInterfaceProtocol = 0,
1940 .driver_info = UVC_QUIRK_PROBE_MINMAX },
1923 /* Generic USB Video Class */ 1941 /* Generic USB Video Class */
1924 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, 1942 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
1925 {} 1943 {}
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index ad63794fda77..6854ac78a161 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video,
90static int uvc_get_video_ctrl(struct uvc_video_device *video, 90static int uvc_get_video_ctrl(struct uvc_video_device *video,
91 struct uvc_streaming_control *ctrl, int probe, __u8 query) 91 struct uvc_streaming_control *ctrl, int probe, __u8 query)
92{ 92{
93 __u8 data[34]; 93 __u8 *data;
94 __u8 size; 94 __u16 size;
95 int ret; 95 int ret;
96 96
97 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 97 size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
98 data = kmalloc(size, GFP_KERNEL);
99 if (data == NULL)
100 return -ENOMEM;
101
98 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, 102 ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
99 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, 103 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
100 UVC_CTRL_STREAMING_TIMEOUT); 104 UVC_CTRL_STREAMING_TIMEOUT);
101
102 if (ret < 0) 105 if (ret < 0)
103 return ret; 106 goto out;
104 107
105 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); 108 ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
106 ctrl->bFormatIndex = data[2]; 109 ctrl->bFormatIndex = data[2];
@@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
136 */ 139 */
137 uvc_fixup_buffer_size(video, ctrl); 140 uvc_fixup_buffer_size(video, ctrl);
138 141
139 return 0; 142out:
143 kfree(data);
144 return ret;
140} 145}
141 146
142int uvc_set_video_ctrl(struct uvc_video_device *video, 147int uvc_set_video_ctrl(struct uvc_video_device *video,
143 struct uvc_streaming_control *ctrl, int probe) 148 struct uvc_streaming_control *ctrl, int probe)
144{ 149{
145 __u8 data[34]; 150 __u8 *data;
146 __u8 size; 151 __u16 size;
152 int ret;
147 153
148 size = video->dev->uvc_version >= 0x0110 ? 34 : 26; 154 size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
149 memset(data, 0, sizeof data); 155 data = kzalloc(size, GFP_KERNEL);
156 if (data == NULL)
157 return -ENOMEM;
150 158
151 *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); 159 *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint);
152 data[2] = ctrl->bFormatIndex; 160 data[2] = ctrl->bFormatIndex;
@@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
174 data[33] = ctrl->bMaxVersion; 182 data[33] = ctrl->bMaxVersion;
175 } 183 }
176 184
177 return __uvc_query_ctrl(video->dev, SET_CUR, 0, 185 ret = __uvc_query_ctrl(video->dev, SET_CUR, 0,
178 video->streaming->intfnum, 186 video->streaming->intfnum,
179 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, 187 probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
180 UVC_CTRL_STREAMING_TIMEOUT); 188 UVC_CTRL_STREAMING_TIMEOUT);
189
190 kfree(data);
191 return ret;
181} 192}
182 193
183int uvc_probe_video(struct uvc_video_device *video, 194int uvc_probe_video(struct uvc_video_device *video,
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 556615fe93de..6f36006aecda 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -222,11 +222,13 @@ int video_register_device(struct video_device *vfd, int type, int nr)
222EXPORT_SYMBOL(video_register_device); 222EXPORT_SYMBOL(video_register_device);
223 223
224/** 224/**
225 * video_register_device - register video4linux devices 225 * video_register_device_index - register video4linux devices
226 * @vfd: video device structure we want to register 226 * @vfd: video device structure we want to register
227 * @type: type of device to register 227 * @type: type of device to register
228 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... 228 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
229 * -1 == first free) 229 * -1 == first free)
230 * @index: stream number based on parent device;
231 * -1 if auto assign, requested number otherwise
230 * 232 *
231 * The registration code assigns minor numbers based on the type 233 * The registration code assigns minor numbers based on the type
232 * requested. -ENFILE is returned in all the device slots for this 234 * requested. -ENFILE is returned in all the device slots for this
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index ef7572cbc4ab..1edda456fc64 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -41,6 +41,7 @@
41#include <linux/videodev2.h> 41#include <linux/videodev2.h>
42#include <media/v4l2-ioctl.h> 42#include <media/v4l2-ioctl.h>
43#include <media/v4l2-common.h> 43#include <media/v4l2-common.h>
44#include <media/v4l2-ioctl.h>
44#include <linux/video_decoder.h> 45#include <linux/video_decoder.h>
45#include <linux/mutex.h> 46#include <linux/mutex.h>
46 47
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 883e7ea31de2..10c44d3fe01a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -50,10 +50,31 @@ config HTC_PASIC3
50 HTC Magician devices, respectively. Actual functionality is 50 HTC Magician devices, respectively. Actual functionality is
51 handled by the leds-pasic3 and ds1wm drivers. 51 handled by the leds-pasic3 and ds1wm drivers.
52 52
53config MFD_TMIO
54 bool
55 default n
56
57config MFD_T7L66XB
58 bool "Support Toshiba T7L66XB"
59 depends on ARM
60 select MFD_CORE
61 select MFD_TMIO
62 help
63 Support for Toshiba Mobile IO Controller T7L66XB
64
65config MFD_TC6387XB
66 bool "Support Toshiba TC6387XB"
67 depends on ARM
68 select MFD_CORE
69 select MFD_TMIO
70 help
71 Support for Toshiba Mobile IO Controller TC6387XB
72
53config MFD_TC6393XB 73config MFD_TC6393XB
54 bool "Support Toshiba TC6393XB" 74 bool "Support Toshiba TC6393XB"
55 depends on GPIOLIB && ARM 75 depends on GPIOLIB && ARM
56 select MFD_CORE 76 select MFD_CORE
77 select MFD_TMIO
57 help 78 help
58 Support for Toshiba Mobile IO Controller TC6393XB 79 Support for Toshiba Mobile IO Controller TC6393XB
59 80
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 33daa2f45dd8..03ad239ecef0 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -8,6 +8,8 @@ obj-$(CONFIG_MFD_ASIC3) += asic3.o
8obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 8obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
9obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 9obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
10 10
11obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o
12obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o
11obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o 13obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o
12 14
13obj-$(CONFIG_MFD_CORE) += mfd-core.o 15obj-$(CONFIG_MFD_CORE) += mfd-core.o
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index b5272b5ce3fa..28380b20bc70 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -21,12 +21,12 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22 22
23#include <asm/dma.h> 23#include <asm/dma.h>
24#include <asm/hardware.h> 24#include <mach/hardware.h>
25#include <asm/mach-types.h> 25#include <asm/mach-types.h>
26#include <asm/system.h> 26#include <asm/system.h>
27#include <asm/arch/mcp.h> 27#include <mach/mcp.h>
28 28
29#include <asm/arch/assabet.h> 29#include <mach/assabet.h>
30 30
31#include "mcp.h" 31#include "mcp.h"
32 32
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
new file mode 100644
index 000000000000..49a0fffc02af
--- /dev/null
+++ b/drivers/mfd/t7l66xb.c
@@ -0,0 +1,419 @@
1/*
2 *
3 * Toshiba T7L66XB core mfd support
4 *
5 * Copyright (c) 2005, 2007, 2008 Ian Molton
6 * Copyright (c) 2008 Dmitry Baryshkov
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * T7L66 features:
13 *
14 * Supported in this driver:
15 * SD/MMC
16 * SM/NAND flash controller
17 *
18 * As yet not supported
19 * GPIO interface (on NAND pins)
20 * Serial interface
21 * TFT 'interface converter'
22 * PCMCIA interface logic
23 */
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/io.h>
28#include <linux/irq.h>
29#include <linux/platform_device.h>
30#include <linux/mfd/core.h>
31#include <linux/mfd/tmio.h>
32#include <linux/mfd/t7l66xb.h>
33
34enum {
35 T7L66XB_CELL_NAND,
36 T7L66XB_CELL_MMC,
37};
38
39#define SCR_REVID 0x08 /* b Revision ID */
40#define SCR_IMR 0x42 /* b Interrupt Mask */
41#define SCR_DEV_CTL 0xe0 /* b Device control */
42#define SCR_ISR 0xe1 /* b Interrupt Status */
43#define SCR_GPO_OC 0xf0 /* b GPO output control */
44#define SCR_GPO_OS 0xf1 /* b GPO output enable */
45#define SCR_GPI_S 0xf2 /* w GPI status */
46#define SCR_APDC 0xf8 /* b Active pullup down ctrl */
47
48#define SCR_DEV_CTL_USB BIT(0) /* USB enable */
49#define SCR_DEV_CTL_MMC BIT(1) /* MMC enable */
50
51/*--------------------------------------------------------------------------*/
52
53struct t7l66xb {
54 void __iomem *scr;
55 /* Lock to protect registers requiring read/modify/write ops. */
56 spinlock_t lock;
57
58 struct resource rscr;
59 int irq;
60 int irq_base;
61};
62
63/*--------------------------------------------------------------------------*/
64
65static int t7l66xb_mmc_enable(struct platform_device *mmc)
66{
67 struct platform_device *dev = to_platform_device(mmc->dev.parent);
68 struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
69 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
70 unsigned long flags;
71 u8 dev_ctl;
72
73 if (pdata->enable_clk32k)
74 pdata->enable_clk32k(dev);
75
76 spin_lock_irqsave(&t7l66xb->lock, flags);
77
78 dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL);
79 dev_ctl |= SCR_DEV_CTL_MMC;
80 tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL);
81
82 spin_unlock_irqrestore(&t7l66xb->lock, flags);
83
84 return 0;
85}
86
87static int t7l66xb_mmc_disable(struct platform_device *mmc)
88{
89 struct platform_device *dev = to_platform_device(mmc->dev.parent);
90 struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
91 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
92 unsigned long flags;
93 u8 dev_ctl;
94
95 spin_lock_irqsave(&t7l66xb->lock, flags);
96
97 dev_ctl = tmio_ioread8(t7l66xb->scr + SCR_DEV_CTL);
98 dev_ctl &= ~SCR_DEV_CTL_MMC;
99 tmio_iowrite8(dev_ctl, t7l66xb->scr + SCR_DEV_CTL);
100
101 spin_unlock_irqrestore(&t7l66xb->lock, flags);
102
103 if (pdata->disable_clk32k)
104 pdata->disable_clk32k(dev);
105
106 return 0;
107}
108
109/*--------------------------------------------------------------------------*/
110
111const static struct resource t7l66xb_mmc_resources[] = {
112 {
113 .start = 0x800,
114 .end = 0x9ff,
115 .flags = IORESOURCE_MEM,
116 },
117 {
118 .start = 0x200,
119 .end = 0x2ff,
120 .flags = IORESOURCE_MEM,
121 },
122 {
123 .start = IRQ_T7L66XB_MMC,
124 .end = IRQ_T7L66XB_MMC,
125 .flags = IORESOURCE_IRQ,
126 },
127};
128
129const static struct resource t7l66xb_nand_resources[] = {
130 {
131 .start = 0xc00,
132 .end = 0xc07,
133 .flags = IORESOURCE_MEM,
134 },
135 {
136 .start = 0x0100,
137 .end = 0x01ff,
138 .flags = IORESOURCE_MEM,
139 },
140 {
141 .start = IRQ_T7L66XB_NAND,
142 .end = IRQ_T7L66XB_NAND,
143 .flags = IORESOURCE_IRQ,
144 },
145};
146
147static struct mfd_cell t7l66xb_cells[] = {
148 [T7L66XB_CELL_MMC] = {
149 .name = "tmio-mmc",
150 .enable = t7l66xb_mmc_enable,
151 .disable = t7l66xb_mmc_disable,
152 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources),
153 .resources = t7l66xb_mmc_resources,
154 },
155 [T7L66XB_CELL_NAND] = {
156 .name = "tmio-nand",
157 .num_resources = ARRAY_SIZE(t7l66xb_nand_resources),
158 .resources = t7l66xb_nand_resources,
159 },
160};
161
162/*--------------------------------------------------------------------------*/
163
164/* Handle the T7L66XB interrupt mux */
165static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc)
166{
167 struct t7l66xb *t7l66xb = get_irq_data(irq);
168 unsigned int isr;
169 unsigned int i, irq_base;
170
171 irq_base = t7l66xb->irq_base;
172
173 while ((isr = tmio_ioread8(t7l66xb->scr + SCR_ISR) &
174 ~tmio_ioread8(t7l66xb->scr + SCR_IMR)))
175 for (i = 0; i < T7L66XB_NR_IRQS; i++)
176 if (isr & (1 << i))
177 generic_handle_irq(irq_base + i);
178}
179
180static void t7l66xb_irq_mask(unsigned int irq)
181{
182 struct t7l66xb *t7l66xb = get_irq_chip_data(irq);
183 unsigned long flags;
184 u8 imr;
185
186 spin_lock_irqsave(&t7l66xb->lock, flags);
187 imr = tmio_ioread8(t7l66xb->scr + SCR_IMR);
188 imr |= 1 << (irq - t7l66xb->irq_base);
189 tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR);
190 spin_unlock_irqrestore(&t7l66xb->lock, flags);
191}
192
193static void t7l66xb_irq_unmask(unsigned int irq)
194{
195 struct t7l66xb *t7l66xb = get_irq_chip_data(irq);
196 unsigned long flags;
197 u8 imr;
198
199 spin_lock_irqsave(&t7l66xb->lock, flags);
200 imr = tmio_ioread8(t7l66xb->scr + SCR_IMR);
201 imr &= ~(1 << (irq - t7l66xb->irq_base));
202 tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR);
203 spin_unlock_irqrestore(&t7l66xb->lock, flags);
204}
205
206static struct irq_chip t7l66xb_chip = {
207 .name = "t7l66xb",
208 .ack = t7l66xb_irq_mask,
209 .mask = t7l66xb_irq_mask,
210 .unmask = t7l66xb_irq_unmask,
211};
212
213/*--------------------------------------------------------------------------*/
214
215/* Install the IRQ handler */
216static void t7l66xb_attach_irq(struct platform_device *dev)
217{
218 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
219 unsigned int irq, irq_base;
220
221 irq_base = t7l66xb->irq_base;
222
223 for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) {
224 set_irq_chip(irq, &t7l66xb_chip);
225 set_irq_chip_data(irq, t7l66xb);
226 set_irq_handler(irq, handle_level_irq);
227#ifdef CONFIG_ARM
228 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
229#endif
230 }
231
232 set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING);
233 set_irq_data(t7l66xb->irq, t7l66xb);
234 set_irq_chained_handler(t7l66xb->irq, t7l66xb_irq);
235}
236
237static void t7l66xb_detach_irq(struct platform_device *dev)
238{
239 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
240 unsigned int irq, irq_base;
241
242 irq_base = t7l66xb->irq_base;
243
244 set_irq_chained_handler(t7l66xb->irq, NULL);
245 set_irq_data(t7l66xb->irq, NULL);
246
247 for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) {
248#ifdef CONFIG_ARM
249 set_irq_flags(irq, 0);
250#endif
251 set_irq_chip(irq, NULL);
252 set_irq_chip_data(irq, NULL);
253 }
254}
255
256/*--------------------------------------------------------------------------*/
257
258#ifdef CONFIG_PM
259static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state)
260{
261 struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
262
263 if (pdata && pdata->suspend)
264 pdata->suspend(dev);
265
266 return 0;
267}
268
269static int t7l66xb_resume(struct platform_device *dev)
270{
271 struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
272
273 if (pdata && pdata->resume)
274 pdata->resume(dev);
275
276 return 0;
277}
278#else
279#define t7l66xb_suspend NULL
280#define t7l66xb_resume NULL
281#endif
282
283/*--------------------------------------------------------------------------*/
284
285static int t7l66xb_probe(struct platform_device *dev)
286{
287 struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
288 struct t7l66xb *t7l66xb;
289 struct resource *iomem, *rscr;
290 int ret;
291
292 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
293 if (!iomem)
294 return -EINVAL;
295
296 t7l66xb = kzalloc(sizeof *t7l66xb, GFP_KERNEL);
297 if (!t7l66xb)
298 return -ENOMEM;
299
300 spin_lock_init(&t7l66xb->lock);
301
302 platform_set_drvdata(dev, t7l66xb);
303
304 ret = platform_get_irq(dev, 0);
305 if (ret >= 0)
306 t7l66xb->irq = ret;
307 else
308 goto err_noirq;
309
310 t7l66xb->irq_base = pdata->irq_base;
311
312 rscr = &t7l66xb->rscr;
313 rscr->name = "t7l66xb-core";
314 rscr->start = iomem->start;
315 rscr->end = iomem->start + 0xff;
316 rscr->flags = IORESOURCE_MEM;
317
318 ret = request_resource(iomem, rscr);
319 if (ret)
320 goto err_request_scr;
321
322 t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
323 if (!t7l66xb->scr) {
324 ret = -ENOMEM;
325 goto err_ioremap;
326 }
327
328 if (pdata && pdata->enable)
329 pdata->enable(dev);
330
331 /* Mask all interrupts */
332 tmio_iowrite8(0xbf, t7l66xb->scr + SCR_IMR);
333
334 printk(KERN_INFO "%s rev %d @ 0x%08lx, irq %d\n",
335 dev->name, tmio_ioread8(t7l66xb->scr + SCR_REVID),
336 (unsigned long)iomem->start, t7l66xb->irq);
337
338 t7l66xb_attach_irq(dev);
339
340 t7l66xb_cells[T7L66XB_CELL_NAND].driver_data = pdata->nand_data;
341 t7l66xb_cells[T7L66XB_CELL_NAND].platform_data =
342 &t7l66xb_cells[T7L66XB_CELL_NAND];
343 t7l66xb_cells[T7L66XB_CELL_NAND].data_size =
344 sizeof(t7l66xb_cells[T7L66XB_CELL_NAND]);
345
346 t7l66xb_cells[T7L66XB_CELL_MMC].platform_data =
347 &t7l66xb_cells[T7L66XB_CELL_MMC];
348 t7l66xb_cells[T7L66XB_CELL_MMC].data_size =
349 sizeof(t7l66xb_cells[T7L66XB_CELL_MMC]);
350
351 ret = mfd_add_devices(&dev->dev, dev->id,
352 t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells),
353 iomem, t7l66xb->irq_base);
354
355 if (!ret)
356 return 0;
357
358 t7l66xb_detach_irq(dev);
359 iounmap(t7l66xb->scr);
360err_ioremap:
361 release_resource(&t7l66xb->rscr);
362err_noirq:
363err_request_scr:
364 kfree(t7l66xb);
365 return ret;
366}
367
368static int t7l66xb_remove(struct platform_device *dev)
369{
370 struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
371 struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
372 int ret;
373
374 ret = pdata->disable(dev);
375
376 t7l66xb_detach_irq(dev);
377 iounmap(t7l66xb->scr);
378 release_resource(&t7l66xb->rscr);
379 mfd_remove_devices(&dev->dev);
380 platform_set_drvdata(dev, NULL);
381 kfree(t7l66xb);
382
383 return ret;
384
385}
386
387static struct platform_driver t7l66xb_platform_driver = {
388 .driver = {
389 .name = "t7l66xb",
390 .owner = THIS_MODULE,
391 },
392 .suspend = t7l66xb_suspend,
393 .resume = t7l66xb_resume,
394 .probe = t7l66xb_probe,
395 .remove = t7l66xb_remove,
396};
397
398/*--------------------------------------------------------------------------*/
399
400static int __init t7l66xb_init(void)
401{
402 int retval = 0;
403
404 retval = platform_driver_register(&t7l66xb_platform_driver);
405 return retval;
406}
407
408static void __exit t7l66xb_exit(void)
409{
410 platform_driver_unregister(&t7l66xb_platform_driver);
411}
412
413module_init(t7l66xb_init);
414module_exit(t7l66xb_exit);
415
416MODULE_DESCRIPTION("Toshiba T7L66XB core driver");
417MODULE_LICENSE("GPL v2");
418MODULE_AUTHOR("Ian Molton");
419MODULE_ALIAS("platform:t7l66xb");
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
new file mode 100644
index 000000000000..a22b21ac6cf8
--- /dev/null
+++ b/drivers/mfd/tc6387xb.c
@@ -0,0 +1,181 @@
1/*
2 * Toshiba TC6387XB support
3 * Copyright (c) 2005 Ian Molton
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This file contains TC6387XB base support.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/err.h>
16#include <linux/mfd/core.h>
17#include <linux/mfd/tmio.h>
18#include <linux/mfd/tc6387xb.h>
19
20enum {
21 TC6387XB_CELL_MMC,
22};
23
24#ifdef CONFIG_PM
25static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
26{
27 struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
28
29 if (pdata && pdata->suspend)
30 pdata->suspend(dev);
31
32 return 0;
33}
34
35static int tc6387xb_resume(struct platform_device *dev)
36{
37 struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
38
39 if (pdata && pdata->resume)
40 pdata->resume(dev);
41
42 return 0;
43}
44#else
45#define tc6387xb_suspend NULL
46#define tc6387xb_resume NULL
47#endif
48
49/*--------------------------------------------------------------------------*/
50
51static int tc6387xb_mmc_enable(struct platform_device *mmc)
52{
53 struct platform_device *dev = to_platform_device(mmc->dev.parent);
54 struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
55
56 if (tc6387xb->enable_clk32k)
57 tc6387xb->enable_clk32k(dev);
58
59 return 0;
60}
61
62static int tc6387xb_mmc_disable(struct platform_device *mmc)
63{
64 struct platform_device *dev = to_platform_device(mmc->dev.parent);
65 struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
66
67 if (tc6387xb->disable_clk32k)
68 tc6387xb->disable_clk32k(dev);
69
70 return 0;
71}
72
73/*--------------------------------------------------------------------------*/
74
75static struct resource tc6387xb_mmc_resources[] = {
76 {
77 .start = 0x800,
78 .end = 0x9ff,
79 .flags = IORESOURCE_MEM,
80 },
81 {
82 .start = 0x200,
83 .end = 0x2ff,
84 .flags = IORESOURCE_MEM,
85 },
86 {
87 .start = 0,
88 .end = 0,
89 .flags = IORESOURCE_IRQ,
90 },
91};
92
93static struct mfd_cell tc6387xb_cells[] = {
94 [TC6387XB_CELL_MMC] = {
95 .name = "tmio-mmc",
96 .enable = tc6387xb_mmc_enable,
97 .disable = tc6387xb_mmc_disable,
98 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
99 .resources = tc6387xb_mmc_resources,
100 },
101};
102
103static int tc6387xb_probe(struct platform_device *dev)
104{
105 struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
106 struct resource *iomem;
107 int irq, ret;
108
109 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
110 if (!iomem) {
111 ret = -EINVAL;
112 goto err_resource;
113 }
114
115 ret = platform_get_irq(dev, 0);
116 if (ret >= 0)
117 irq = ret;
118 else
119 goto err_resource;
120
121 if (data && data->enable)
122 data->enable(dev);
123
124 printk(KERN_INFO "Toshiba tc6387xb initialised\n");
125
126 tc6387xb_cells[TC6387XB_CELL_MMC].platform_data =
127 &tc6387xb_cells[TC6387XB_CELL_MMC];
128 tc6387xb_cells[TC6387XB_CELL_MMC].data_size =
129 sizeof(tc6387xb_cells[TC6387XB_CELL_MMC]);
130
131 ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells,
132 ARRAY_SIZE(tc6387xb_cells), iomem, irq);
133
134 if (!ret)
135 return 0;
136
137err_resource:
138 return ret;
139}
140
141static int tc6387xb_remove(struct platform_device *dev)
142{
143 struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
144
145 if (data && data->disable)
146 data->disable(dev);
147
148 /* FIXME - free the resources! */
149
150 return 0;
151}
152
153
154static struct platform_driver tc6387xb_platform_driver = {
155 .driver = {
156 .name = "tc6387xb",
157 },
158 .probe = tc6387xb_probe,
159 .remove = tc6387xb_remove,
160 .suspend = tc6387xb_suspend,
161 .resume = tc6387xb_resume,
162};
163
164
165static int __init tc6387xb_init(void)
166{
167 return platform_driver_register(&tc6387xb_platform_driver);
168}
169
170static void __exit tc6387xb_exit(void)
171{
172 platform_driver_unregister(&tc6387xb_platform_driver);
173}
174
175module_init(tc6387xb_init);
176module_exit(tc6387xb_exit);
177
178MODULE_DESCRIPTION("Toshiba TC6387XB core driver");
179MODULE_LICENSE("GPL v2");
180MODULE_AUTHOR("Ian Molton");
181MODULE_ALIAS("platform:tc6387xb");
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index f4fd797c1590..e4c1c788b5f8 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -19,8 +19,8 @@
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/irq.h> 20#include <linux/irq.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/fb.h>
23#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/err.h>
24#include <linux/mfd/core.h> 24#include <linux/mfd/core.h>
25#include <linux/mfd/tmio.h> 25#include <linux/mfd/tmio.h>
26#include <linux/mfd/tc6393xb.h> 26#include <linux/mfd/tc6393xb.h>
@@ -112,6 +112,7 @@ struct tc6393xb {
112 112
113enum { 113enum {
114 TC6393XB_CELL_NAND, 114 TC6393XB_CELL_NAND,
115 TC6393XB_CELL_MMC,
115}; 116};
116 117
117/*--------------------------------------------------------------------------*/ 118/*--------------------------------------------------------------------------*/
@@ -126,7 +127,7 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
126 127
127 /* SMD buffer on */ 128 /* SMD buffer on */
128 dev_dbg(&dev->dev, "SMD buffer on\n"); 129 dev_dbg(&dev->dev, "SMD buffer on\n");
129 iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1)); 130 tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
130 131
131 spin_unlock_irqrestore(&tc6393xb->lock, flags); 132 spin_unlock_irqrestore(&tc6393xb->lock, flags);
132 133
@@ -135,25 +136,40 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
135 136
136static struct resource __devinitdata tc6393xb_nand_resources[] = { 137static struct resource __devinitdata tc6393xb_nand_resources[] = {
137 { 138 {
138 .name = TMIO_NAND_CONFIG, 139 .start = 0x1000,
139 .start = 0x0100, 140 .end = 0x1007,
140 .end = 0x01ff,
141 .flags = IORESOURCE_MEM, 141 .flags = IORESOURCE_MEM,
142 }, 142 },
143 { 143 {
144 .name = TMIO_NAND_CONTROL, 144 .start = 0x0100,
145 .start = 0x1000, 145 .end = 0x01ff,
146 .end = 0x1007,
147 .flags = IORESOURCE_MEM, 146 .flags = IORESOURCE_MEM,
148 }, 147 },
149 { 148 {
150 .name = TMIO_NAND_IRQ,
151 .start = IRQ_TC6393_NAND, 149 .start = IRQ_TC6393_NAND,
152 .end = IRQ_TC6393_NAND, 150 .end = IRQ_TC6393_NAND,
153 .flags = IORESOURCE_IRQ, 151 .flags = IORESOURCE_IRQ,
154 }, 152 },
155}; 153};
156 154
155static struct resource __devinitdata tc6393xb_mmc_resources[] = {
156 {
157 .start = 0x800,
158 .end = 0x9ff,
159 .flags = IORESOURCE_MEM,
160 },
161 {
162 .start = 0x200,
163 .end = 0x2ff,
164 .flags = IORESOURCE_MEM,
165 },
166 {
167 .start = IRQ_TC6393_MMC,
168 .end = IRQ_TC6393_MMC,
169 .flags = IORESOURCE_IRQ,
170 },
171};
172
157static struct mfd_cell __devinitdata tc6393xb_cells[] = { 173static struct mfd_cell __devinitdata tc6393xb_cells[] = {
158 [TC6393XB_CELL_NAND] = { 174 [TC6393XB_CELL_NAND] = {
159 .name = "tmio-nand", 175 .name = "tmio-nand",
@@ -161,6 +177,11 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = {
161 .num_resources = ARRAY_SIZE(tc6393xb_nand_resources), 177 .num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
162 .resources = tc6393xb_nand_resources, 178 .resources = tc6393xb_nand_resources,
163 }, 179 },
180 [TC6393XB_CELL_MMC] = {
181 .name = "tmio-mmc",
182 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
183 .resources = tc6393xb_mmc_resources,
184 },
164}; 185};
165 186
166/*--------------------------------------------------------------------------*/ 187/*--------------------------------------------------------------------------*/
@@ -171,7 +192,7 @@ static int tc6393xb_gpio_get(struct gpio_chip *chip,
171 struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); 192 struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
172 193
173 /* XXX: does dsr also represent inputs? */ 194 /* XXX: does dsr also represent inputs? */
174 return ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)) 195 return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
175 & TC_GPIO_BIT(offset); 196 & TC_GPIO_BIT(offset);
176} 197}
177 198
@@ -181,13 +202,13 @@ static void __tc6393xb_gpio_set(struct gpio_chip *chip,
181 struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio); 202 struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
182 u8 dsr; 203 u8 dsr;
183 204
184 dsr = ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8)); 205 dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
185 if (value) 206 if (value)
186 dsr |= TC_GPIO_BIT(offset); 207 dsr |= TC_GPIO_BIT(offset);
187 else 208 else
188 dsr &= ~TC_GPIO_BIT(offset); 209 dsr &= ~TC_GPIO_BIT(offset);
189 210
190 iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8)); 211 tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
191} 212}
192 213
193static void tc6393xb_gpio_set(struct gpio_chip *chip, 214static void tc6393xb_gpio_set(struct gpio_chip *chip,
@@ -212,9 +233,9 @@ static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
212 233
213 spin_lock_irqsave(&tc6393xb->lock, flags); 234 spin_lock_irqsave(&tc6393xb->lock, flags);
214 235
215 doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 236 doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
216 doecr &= ~TC_GPIO_BIT(offset); 237 doecr &= ~TC_GPIO_BIT(offset);
217 iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 238 tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
218 239
219 spin_unlock_irqrestore(&tc6393xb->lock, flags); 240 spin_unlock_irqrestore(&tc6393xb->lock, flags);
220 241
@@ -232,9 +253,9 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
232 253
233 __tc6393xb_gpio_set(chip, offset, value); 254 __tc6393xb_gpio_set(chip, offset, value);
234 255
235 doecr = ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 256 doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
236 doecr |= TC_GPIO_BIT(offset); 257 doecr |= TC_GPIO_BIT(offset);
237 iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8)); 258 tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
238 259
239 spin_unlock_irqrestore(&tc6393xb->lock, flags); 260 spin_unlock_irqrestore(&tc6393xb->lock, flags);
240 261
@@ -265,8 +286,8 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
265 286
266 irq_base = tc6393xb->irq_base; 287 irq_base = tc6393xb->irq_base;
267 288
268 while ((isr = ioread8(tc6393xb->scr + SCR_ISR) & 289 while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) &
269 ~ioread8(tc6393xb->scr + SCR_IMR))) 290 ~tmio_ioread8(tc6393xb->scr + SCR_IMR)))
270 for (i = 0; i < TC6393XB_NR_IRQS; i++) { 291 for (i = 0; i < TC6393XB_NR_IRQS; i++) {
271 if (isr & (1 << i)) 292 if (isr & (1 << i))
272 generic_handle_irq(irq_base + i); 293 generic_handle_irq(irq_base + i);
@@ -284,9 +305,9 @@ static void tc6393xb_irq_mask(unsigned int irq)
284 u8 imr; 305 u8 imr;
285 306
286 spin_lock_irqsave(&tc6393xb->lock, flags); 307 spin_lock_irqsave(&tc6393xb->lock, flags);
287 imr = ioread8(tc6393xb->scr + SCR_IMR); 308 imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
288 imr |= 1 << (irq - tc6393xb->irq_base); 309 imr |= 1 << (irq - tc6393xb->irq_base);
289 iowrite8(imr, tc6393xb->scr + SCR_IMR); 310 tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
290 spin_unlock_irqrestore(&tc6393xb->lock, flags); 311 spin_unlock_irqrestore(&tc6393xb->lock, flags);
291} 312}
292 313
@@ -297,9 +318,9 @@ static void tc6393xb_irq_unmask(unsigned int irq)
297 u8 imr; 318 u8 imr;
298 319
299 spin_lock_irqsave(&tc6393xb->lock, flags); 320 spin_lock_irqsave(&tc6393xb->lock, flags);
300 imr = ioread8(tc6393xb->scr + SCR_IMR); 321 imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
301 imr &= ~(1 << (irq - tc6393xb->irq_base)); 322 imr &= ~(1 << (irq - tc6393xb->irq_base));
302 iowrite8(imr, tc6393xb->scr + SCR_IMR); 323 tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
303 spin_unlock_irqrestore(&tc6393xb->lock, flags); 324 spin_unlock_irqrestore(&tc6393xb->lock, flags);
304} 325}
305 326
@@ -380,9 +401,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
380{ 401{
381 struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 402 struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
382 struct tc6393xb *tc6393xb; 403 struct tc6393xb *tc6393xb;
383 struct resource *iomem; 404 struct resource *iomem, *rscr;
384 struct resource *rscr; 405 int ret, temp;
385 int retval, temp;
386 int i; 406 int i;
387 407
388 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); 408 iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
@@ -391,20 +411,26 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
391 411
392 tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL); 412 tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
393 if (!tc6393xb) { 413 if (!tc6393xb) {
394 retval = -ENOMEM; 414 ret = -ENOMEM;
395 goto err_kzalloc; 415 goto err_kzalloc;
396 } 416 }
397 417
398 spin_lock_init(&tc6393xb->lock); 418 spin_lock_init(&tc6393xb->lock);
399 419
400 platform_set_drvdata(dev, tc6393xb); 420 platform_set_drvdata(dev, tc6393xb);
421
422 ret = platform_get_irq(dev, 0);
423 if (ret >= 0)
424 tc6393xb->irq = ret;
425 else
426 goto err_noirq;
427
401 tc6393xb->iomem = iomem; 428 tc6393xb->iomem = iomem;
402 tc6393xb->irq = platform_get_irq(dev, 0);
403 tc6393xb->irq_base = tcpd->irq_base; 429 tc6393xb->irq_base = tcpd->irq_base;
404 430
405 tc6393xb->clk = clk_get(&dev->dev, "GPIO27_CLK" /* "CK3P6MI" */); 431 tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI");
406 if (IS_ERR(tc6393xb->clk)) { 432 if (IS_ERR(tc6393xb->clk)) {
407 retval = PTR_ERR(tc6393xb->clk); 433 ret = PTR_ERR(tc6393xb->clk);
408 goto err_clk_get; 434 goto err_clk_get;
409 } 435 }
410 436
@@ -414,71 +440,73 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
414 rscr->end = iomem->start + 0xff; 440 rscr->end = iomem->start + 0xff;
415 rscr->flags = IORESOURCE_MEM; 441 rscr->flags = IORESOURCE_MEM;
416 442
417 retval = request_resource(iomem, rscr); 443 ret = request_resource(iomem, rscr);
418 if (retval) 444 if (ret)
419 goto err_request_scr; 445 goto err_request_scr;
420 446
421 tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); 447 tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
422 if (!tc6393xb->scr) { 448 if (!tc6393xb->scr) {
423 retval = -ENOMEM; 449 ret = -ENOMEM;
424 goto err_ioremap; 450 goto err_ioremap;
425 } 451 }
426 452
427 retval = clk_enable(tc6393xb->clk); 453 ret = clk_enable(tc6393xb->clk);
428 if (retval) 454 if (ret)
429 goto err_clk_enable; 455 goto err_clk_enable;
430 456
431 retval = tcpd->enable(dev); 457 ret = tcpd->enable(dev);
432 if (retval) 458 if (ret)
433 goto err_enable; 459 goto err_enable;
434 460
435 tc6393xb->suspend_state.fer = 0; 461 tc6393xb->suspend_state.fer = 0;
462
436 for (i = 0; i < 3; i++) { 463 for (i = 0; i < 3; i++) {
437 tc6393xb->suspend_state.gpo_dsr[i] = 464 tc6393xb->suspend_state.gpo_dsr[i] =
438 (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff; 465 (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff;
439 tc6393xb->suspend_state.gpo_doecr[i] = 466 tc6393xb->suspend_state.gpo_doecr[i] =
440 (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff; 467 (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff;
441 } 468 }
442 /* 469
443 * It may be necessary to change this back to
444 * platform-dependant code
445 */
446 tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | 470 tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 |
447 SCR_CCR_HCLK_48; 471 SCR_CCR_HCLK_48;
448 472
449 retval = tc6393xb_hw_init(dev); 473 ret = tc6393xb_hw_init(dev);
450 if (retval) 474 if (ret)
451 goto err_hw_init; 475 goto err_hw_init;
452 476
453 printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", 477 printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
454 ioread8(tc6393xb->scr + SCR_REVID), 478 tmio_ioread8(tc6393xb->scr + SCR_REVID),
455 (unsigned long) iomem->start, tc6393xb->irq); 479 (unsigned long) iomem->start, tc6393xb->irq);
456 480
457 tc6393xb->gpio.base = -1; 481 tc6393xb->gpio.base = -1;
458 482
459 if (tcpd->gpio_base >= 0) { 483 if (tcpd->gpio_base >= 0) {
460 retval = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base); 484 ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
461 if (retval) 485 if (ret)
462 goto err_gpio_add; 486 goto err_gpio_add;
463 } 487 }
464 488
465 if (tc6393xb->irq) 489 tc6393xb_attach_irq(dev);
466 tc6393xb_attach_irq(dev);
467 490
468 tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; 491 tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data;
469 tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = 492 tc6393xb_cells[TC6393XB_CELL_NAND].platform_data =
470 &tc6393xb_cells[TC6393XB_CELL_NAND]; 493 &tc6393xb_cells[TC6393XB_CELL_NAND];
471 tc6393xb_cells[TC6393XB_CELL_NAND].data_size = 494 tc6393xb_cells[TC6393XB_CELL_NAND].data_size =
472 sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); 495 sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]);
496 tc6393xb_cells[TC6393XB_CELL_MMC].platform_data =
497 &tc6393xb_cells[TC6393XB_CELL_MMC];
498 tc6393xb_cells[TC6393XB_CELL_MMC].data_size =
499 sizeof(tc6393xb_cells[TC6393XB_CELL_MMC]);
500
473 501
474 retval = mfd_add_devices(&dev->dev, dev->id, 502 ret = mfd_add_devices(&dev->dev, dev->id,
475 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), 503 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
476 iomem, tcpd->irq_base); 504 iomem, tcpd->irq_base);
477 505
478 return 0; 506 if (!ret)
507 return 0;
479 508
480 if (tc6393xb->irq) 509 tc6393xb_detach_irq(dev);
481 tc6393xb_detach_irq(dev);
482 510
483err_gpio_add: 511err_gpio_add:
484 if (tc6393xb->gpio.base != -1) 512 if (tc6393xb->gpio.base != -1)
@@ -493,10 +521,11 @@ err_ioremap:
493 release_resource(&tc6393xb->rscr); 521 release_resource(&tc6393xb->rscr);
494err_request_scr: 522err_request_scr:
495 clk_put(tc6393xb->clk); 523 clk_put(tc6393xb->clk);
524err_noirq:
496err_clk_get: 525err_clk_get:
497 kfree(tc6393xb); 526 kfree(tc6393xb);
498err_kzalloc: 527err_kzalloc:
499 return retval; 528 return ret;
500} 529}
501 530
502static int __devexit tc6393xb_remove(struct platform_device *dev) 531static int __devexit tc6393xb_remove(struct platform_device *dev)
@@ -506,9 +535,7 @@ static int __devexit tc6393xb_remove(struct platform_device *dev)
506 int ret; 535 int ret;
507 536
508 mfd_remove_devices(&dev->dev); 537 mfd_remove_devices(&dev->dev);
509 538 tc6393xb_detach_irq(dev);
510 if (tc6393xb->irq)
511 tc6393xb_detach_irq(dev);
512 539
513 if (tc6393xb->gpio.base != -1) { 540 if (tc6393xb->gpio.base != -1) {
514 ret = gpiochip_remove(&tc6393xb->gpio); 541 ret = gpiochip_remove(&tc6393xb->gpio);
@@ -519,17 +546,11 @@ static int __devexit tc6393xb_remove(struct platform_device *dev)
519 } 546 }
520 547
521 ret = tcpd->disable(dev); 548 ret = tcpd->disable(dev);
522
523 clk_disable(tc6393xb->clk); 549 clk_disable(tc6393xb->clk);
524
525 iounmap(tc6393xb->scr); 550 iounmap(tc6393xb->scr);
526
527 release_resource(&tc6393xb->rscr); 551 release_resource(&tc6393xb->rscr);
528
529 platform_set_drvdata(dev, NULL); 552 platform_set_drvdata(dev, NULL);
530
531 clk_put(tc6393xb->clk); 553 clk_put(tc6393xb->clk);
532
533 kfree(tc6393xb); 554 kfree(tc6393xb);
534 555
535 return ret; 556 return ret;
@@ -540,8 +561,7 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
540{ 561{
541 struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 562 struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
542 struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 563 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
543 int i; 564 int i, ret;
544
545 565
546 tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR); 566 tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR);
547 tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER); 567 tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER);
@@ -554,14 +574,21 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
554 tc6393xb->suspend_state.gpi_bcr[i] = 574 tc6393xb->suspend_state.gpi_bcr[i] =
555 ioread8(tc6393xb->scr + SCR_GPI_BCR(i)); 575 ioread8(tc6393xb->scr + SCR_GPI_BCR(i));
556 } 576 }
577 ret = tcpd->suspend(dev);
578 clk_disable(tc6393xb->clk);
557 579
558 return tcpd->suspend(dev); 580 return ret;
559} 581}
560 582
561static int tc6393xb_resume(struct platform_device *dev) 583static int tc6393xb_resume(struct platform_device *dev)
562{ 584{
563 struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; 585 struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
564 int ret = tcpd->resume(dev); 586 struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
587 int ret;
588
589 clk_enable(tc6393xb->clk);
590
591 ret = tcpd->resume(dev);
565 592
566 if (ret) 593 if (ret)
567 return ret; 594 return ret;
@@ -598,7 +625,7 @@ static void __exit tc6393xb_exit(void)
598subsys_initcall(tc6393xb_init); 625subsys_initcall(tc6393xb_init);
599module_exit(tc6393xb_exit); 626module_exit(tc6393xb_exit);
600 627
601MODULE_LICENSE("GPL"); 628MODULE_LICENSE("GPL v2");
602MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer"); 629MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
603MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller"); 630MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
604MODULE_ALIAS("platform:tc6393xb"); 631MODULE_ALIAS("platform:tc6393xb");
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index f6b10dda31fd..a316f1b75933 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -26,7 +26,7 @@
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27 27
28#include <asm/dma.h> 28#include <asm/dma.h>
29#include <asm/hardware.h> 29#include <mach/hardware.h>
30 30
31#include "ucb1x00.h" 31#include "ucb1x00.h"
32 32
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index ad34e2d22524..44762ca86a8d 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -32,7 +32,7 @@
32#include <linux/kthread.h> 32#include <linux/kthread.h>
33 33
34#include <asm/dma.h> 34#include <asm/dma.h>
35#include <asm/arch/collie.h> 35#include <mach/collie.h>
36#include <asm/mach-types.h> 36#include <asm/mach-types.h>
37 37
38#include "ucb1x00.h" 38#include "ucb1x00.h"
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 82af385460e4..a726f3b01a6b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -427,10 +427,10 @@ config ENCLOSURE_SERVICES
427config SGI_XP 427config SGI_XP
428 tristate "Support communication between SGI SSIs" 428 tristate "Support communication between SGI SSIs"
429 depends on NET 429 depends on NET
430 depends on IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || (X86_64 && SMP) 430 depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_64) && SMP
431 select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 431 select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
432 select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2 432 select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
433 select SGI_GRU if IA64_GENERIC || IA64_SGI_UV || (X86_64 && SMP) 433 select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP
434 ---help--- 434 ---help---
435 An SGI machine can be divided into multiple Single System 435 An SGI machine can be divided into multiple Single System
436 Images which act independently of each other and have 436 Images which act independently of each other and have
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index e7a3fe508dff..b2d9878dc3f0 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -803,11 +803,30 @@ static acpi_status get_u32(u32 *value, u32 cap)
803 803
804static acpi_status set_u32(u32 value, u32 cap) 804static acpi_status set_u32(u32 value, u32 cap)
805{ 805{
806 acpi_status status;
807
806 if (interface->capability & cap) { 808 if (interface->capability & cap) {
807 switch (interface->type) { 809 switch (interface->type) {
808 case ACER_AMW0: 810 case ACER_AMW0:
809 return AMW0_set_u32(value, cap, interface); 811 return AMW0_set_u32(value, cap, interface);
810 case ACER_AMW0_V2: 812 case ACER_AMW0_V2:
813 if (cap == ACER_CAP_MAILLED)
814 return AMW0_set_u32(value, cap, interface);
815
816 /*
817 * On some models, some WMID methods don't toggle
818 * properly. For those cases, we want to run the AMW0
819 * method afterwards to be certain we've really toggled
820 * the device state.
821 */
822 if (cap == ACER_CAP_WIRELESS ||
823 cap == ACER_CAP_BLUETOOTH) {
824 status = WMID_set_u32(value, cap, interface);
825 if (ACPI_FAILURE(status))
826 return status;
827
828 return AMW0_set_u32(value, cap, interface);
829 }
811 case ACER_WMID: 830 case ACER_WMID:
812 return WMID_set_u32(value, cap, interface); 831 return WMID_set_u32(value, cap, interface);
813 default: 832 default:
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index 4251018f70ff..a78f70deeb59 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -279,7 +279,7 @@ struct gru_stats_s {
279#if defined CONFIG_IA64 279#if defined CONFIG_IA64
280#define VADDR_HI_BIT 64 280#define VADDR_HI_BIT 64
281#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3) 281#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
282#elif defined __x86_64 282#elif defined CONFIG_X86_64
283#define VADDR_HI_BIT 48 283#define VADDR_HI_BIT 48
284#define GRUREGION(addr) (0) /* ZZZ could do better */ 284#define GRUREGION(addr) (0) /* ZZZ could do better */
285#else 285#else
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index dc6f2579f85c..ea8d7a3490d9 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -174,3 +174,9 @@ config MMC_SDRICOH_CS
174 To compile this driver as a module, choose M here: the 174 To compile this driver as a module, choose M here: the
175 module will be called sdricoh_cs. 175 module will be called sdricoh_cs.
176 176
177config MMC_TMIO
178 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
179 depends on MFD_TMIO
180 help
181 This provides support for the SD/MMC cell found in TC6393XB,
182 T7L66XB and also ipaq ASIC3
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index db52eebfb50e..c794cc5ce442 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
21obj-$(CONFIG_MMC_SPI) += mmc_spi.o 21obj-$(CONFIG_MMC_SPI) += mmc_spi.o
22obj-$(CONFIG_MMC_S3C) += s3cmci.o 22obj-$(CONFIG_MMC_S3C) += s3cmci.o
23obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o 23obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
24obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
24 25
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index f15e2064305c..6915f40ac8ab 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -73,9 +73,9 @@
73#include <asm/gpio.h> 73#include <asm/gpio.h>
74 74
75#include <asm/mach/mmc.h> 75#include <asm/mach/mmc.h>
76#include <asm/arch/board.h> 76#include <mach/board.h>
77#include <asm/arch/cpu.h> 77#include <mach/cpu.h>
78#include <asm/arch/at91_mci.h> 78#include <mach/at91_mci.h>
79 79
80#define DRIVER_NAME "at91_mci" 80#define DRIVER_NAME "at91_mci"
81 81
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 992b4beb757c..0bd06f5bd62f 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -28,7 +28,7 @@
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/unaligned.h> 29#include <asm/unaligned.h>
30 30
31#include <asm/arch/board.h> 31#include <mach/board.h>
32 32
33#include "atmel-mci-regs.h" 33#include "atmel-mci-regs.h"
34 34
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index f61406da65d2..2f0fcdb869b7 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -42,8 +42,8 @@
42#include <asm/io.h> 42#include <asm/io.h>
43#include <asm/irq.h> 43#include <asm/irq.h>
44#include <asm/sizes.h> 44#include <asm/sizes.h>
45#include <asm/arch/mmc.h> 45#include <mach/mmc.h>
46#include <asm/arch/imx-dma.h> 46#include <mach/imx-dma.h>
47 47
48#include "imxmmc.h" 48#include "imxmmc.h"
49 49
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index dbc26eb6a89e..c16028872bbb 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -29,14 +29,13 @@
29 29
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/irq.h> 31#include <asm/irq.h>
32#include <asm/mach-types.h> 32
33 33#include <mach/board.h>
34#include <asm/arch/board.h> 34#include <mach/mmc.h>
35#include <asm/arch/mmc.h> 35#include <mach/gpio.h>
36#include <asm/arch/gpio.h> 36#include <mach/dma.h>
37#include <asm/arch/dma.h> 37#include <mach/mux.h>
38#include <asm/arch/mux.h> 38#include <mach/fpga.h>
39#include <asm/arch/fpga.h>
40 39
41#define OMAP_MMC_REG_CMD 0x00 40#define OMAP_MMC_REG_CMD 0x00
42#define OMAP_MMC_REG_ARGL 0x04 41#define OMAP_MMC_REG_ARGL 0x04
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index a8e18fe53077..55093ad132ca 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -31,8 +31,8 @@
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/sizes.h> 32#include <asm/sizes.h>
33 33
34#include <asm/arch/pxa-regs.h> 34#include <mach/pxa-regs.h>
35#include <asm/arch/mmc.h> 35#include <mach/mmc.h>
36 36
37#include "pxamci.h" 37#include "pxamci.h"
38 38
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index be550c26da68..ae16d845d746 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -18,8 +18,8 @@
18 18
19#include <asm/dma.h> 19#include <asm/dma.h>
20 20
21#include <asm/arch/regs-sdi.h> 21#include <mach/regs-sdi.h>
22#include <asm/arch/regs-gpio.h> 22#include <mach/regs-gpio.h>
23 23
24#include <asm/plat-s3c24xx/mci.h> 24#include <asm/plat-s3c24xx/mci.h>
25 25
@@ -595,8 +595,9 @@ static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
595 return IRQ_HANDLED; 595 return IRQ_HANDLED;
596} 596}
597 597
598void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch, void *buf_id, 598static void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch,
599 int size, enum s3c2410_dma_buffresult result) 599 void *buf_id, int size,
600 enum s3c2410_dma_buffresult result)
600{ 601{
601 struct s3cmci_host *host = buf_id; 602 struct s3cmci_host *host = buf_id;
602 unsigned long iflags; 603 unsigned long iflags;
@@ -740,8 +741,8 @@ request_done:
740 mmc_request_done(host->mmc, mrq); 741 mmc_request_done(host->mmc, mrq);
741} 742}
742 743
743 744static void s3cmci_dma_setup(struct s3cmci_host *host,
744void s3cmci_dma_setup(struct s3cmci_host *host, enum s3c2410_dmasrc source) 745 enum s3c2410_dmasrc source)
745{ 746{
746 static enum s3c2410_dmasrc last_source = -1; 747 static enum s3c2410_dmasrc last_source = -1;
747 static int setup_ok; 748 static int setup_ok;
@@ -1003,8 +1004,9 @@ static void s3cmci_send_request(struct mmc_host *mmc)
1003 enable_irq(host->irq); 1004 enable_irq(host->irq);
1004} 1005}
1005 1006
1006static int s3cmci_card_present(struct s3cmci_host *host) 1007static int s3cmci_card_present(struct mmc_host *mmc)
1007{ 1008{
1009 struct s3cmci_host *host = mmc_priv(mmc);
1008 struct s3c24xx_mci_pdata *pdata = host->pdata; 1010 struct s3c24xx_mci_pdata *pdata = host->pdata;
1009 int ret; 1011 int ret;
1010 1012
@@ -1023,7 +1025,7 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
1023 host->cmd_is_stop = 0; 1025 host->cmd_is_stop = 0;
1024 host->mrq = mrq; 1026 host->mrq = mrq;
1025 1027
1026 if (s3cmci_card_present(host) == 0) { 1028 if (s3cmci_card_present(mmc) == 0) {
1027 dbg(host, dbg_err, "%s: no medium present\n", __func__); 1029 dbg(host, dbg_err, "%s: no medium present\n", __func__);
1028 host->mrq->cmd->error = -ENOMEDIUM; 1030 host->mrq->cmd->error = -ENOMEDIUM;
1029 mmc_request_done(mmc, mrq); 1031 mmc_request_done(mmc, mrq);
@@ -1138,6 +1140,7 @@ static struct mmc_host_ops s3cmci_ops = {
1138 .request = s3cmci_request, 1140 .request = s3cmci_request,
1139 .set_ios = s3cmci_set_ios, 1141 .set_ios = s3cmci_set_ios,
1140 .get_ro = s3cmci_get_ro, 1142 .get_ro = s3cmci_get_ro,
1143 .get_cd = s3cmci_card_present,
1141}; 1144};
1142 1145
1143static struct s3c24xx_mci_pdata s3cmci_def_pdata = { 1146static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
@@ -1206,7 +1209,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1206 } 1209 }
1207 1210
1208 host->base = ioremap(host->mem->start, RESSIZE(host->mem)); 1211 host->base = ioremap(host->mem->start, RESSIZE(host->mem));
1209 if (host->base == 0) { 1212 if (!host->base) {
1210 dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); 1213 dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
1211 ret = -EINVAL; 1214 ret = -EINVAL;
1212 goto probe_free_mem_region; 1215 goto probe_free_mem_region;
diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c
index f99e9f721629..1df44d966bdb 100644
--- a/drivers/mmc/host/sdricoh_cs.c
+++ b/drivers/mmc/host/sdricoh_cs.c
@@ -29,7 +29,6 @@
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/scatterlist.h> 31#include <linux/scatterlist.h>
32#include <linux/version.h>
33 32
34#include <pcmcia/cs_types.h> 33#include <pcmcia/cs_types.h>
35#include <pcmcia/cs.h> 34#include <pcmcia/cs.h>
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
new file mode 100644
index 000000000000..95430b81ec11
--- /dev/null
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -0,0 +1,691 @@
1/*
2 * linux/drivers/mmc/tmio_mmc.c
3 *
4 * Copyright (C) 2004 Ian Molton
5 * Copyright (C) 2007 Ian Molton
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Driver for the MMC / SD / SDIO cell found in:
12 *
13 * TC6393XB TC6391XB TC6387XB T7L66XB
14 *
15 * This driver draws mainly on scattered spec sheets, Reverse engineering
16 * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit
17 * support). (Further 4 bit support from a later datasheet).
18 *
19 * TODO:
20 * Investigate using a workqueue for PIO transfers
21 * Eliminate FIXMEs
22 * SDIO support
23 * Better Power management
24 * Handle MMC errors better
25 * double buffer support
26 *
27 */
28#include <linux/module.h>
29#include <linux/irq.h>
30#include <linux/device.h>
31#include <linux/delay.h>
32#include <linux/mmc/host.h>
33#include <linux/mfd/core.h>
34#include <linux/mfd/tmio.h>
35
36#include "tmio_mmc.h"
37
38/*
39 * Fixme - documentation conflicts on what the clock values are for the
40 * various dividers.
41 * One document I have says that its a divisor of a 24MHz clock, another 33.
42 * This probably depends on HCLK for a given platform, so we may need to
43 * require HCLK be passed to us from the MFD core.
44 *
45 */
46
47static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
48{
49 void __iomem *cnf = host->cnf;
50 void __iomem *ctl = host->ctl;
51 u32 clk = 0, clock;
52
53 if (new_clock) {
54 for (clock = 46875, clk = 0x100; new_clock >= (clock<<1); ) {
55 clock <<= 1;
56 clk >>= 1;
57 }
58 if (clk & 0x1)
59 clk = 0x20000;
60
61 clk >>= 2;
62 tmio_iowrite8((clk & 0x8000) ? 0 : 1, cnf + CNF_SD_CLK_MODE);
63 clk |= 0x100;
64 }
65
66 tmio_iowrite16(clk, ctl + CTL_SD_CARD_CLK_CTL);
67}
68
69static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
70{
71 void __iomem *ctl = host->ctl;
72
73 tmio_iowrite16(0x0000, ctl + CTL_CLK_AND_WAIT_CTL);
74 msleep(10);
75 tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) & ~0x0100,
76 ctl + CTL_SD_CARD_CLK_CTL);
77 msleep(10);
78}
79
80static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
81{
82 void __iomem *ctl = host->ctl;
83
84 tmio_iowrite16(tmio_ioread16(ctl + CTL_SD_CARD_CLK_CTL) | 0x0100,
85 ctl + CTL_SD_CARD_CLK_CTL);
86 msleep(10);
87 tmio_iowrite16(0x0100, ctl + CTL_CLK_AND_WAIT_CTL);
88 msleep(10);
89}
90
91static void reset(struct tmio_mmc_host *host)
92{
93 void __iomem *ctl = host->ctl;
94
95 /* FIXME - should we set stop clock reg here */
96 tmio_iowrite16(0x0000, ctl + CTL_RESET_SD);
97 tmio_iowrite16(0x0000, ctl + CTL_RESET_SDIO);
98 msleep(10);
99 tmio_iowrite16(0x0001, ctl + CTL_RESET_SD);
100 tmio_iowrite16(0x0001, ctl + CTL_RESET_SDIO);
101 msleep(10);
102}
103
104static void
105tmio_mmc_finish_request(struct tmio_mmc_host *host)
106{
107 struct mmc_request *mrq = host->mrq;
108
109 host->mrq = NULL;
110 host->cmd = NULL;
111 host->data = NULL;
112
113 mmc_request_done(host->mmc, mrq);
114}
115
116/* These are the bitmasks the tmio chip requires to implement the MMC response
117 * types. Note that R1 and R6 are the same in this scheme. */
118#define APP_CMD 0x0040
119#define RESP_NONE 0x0300
120#define RESP_R1 0x0400
121#define RESP_R1B 0x0500
122#define RESP_R2 0x0600
123#define RESP_R3 0x0700
124#define DATA_PRESENT 0x0800
125#define TRANSFER_READ 0x1000
126#define TRANSFER_MULTI 0x2000
127#define SECURITY_CMD 0x4000
128
129static int
130tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
131{
132 void __iomem *ctl = host->ctl;
133 struct mmc_data *data = host->data;
134 int c = cmd->opcode;
135
136 /* Command 12 is handled by hardware */
137 if (cmd->opcode == 12 && !cmd->arg) {
138 tmio_iowrite16(0x001, ctl + CTL_STOP_INTERNAL_ACTION);
139 return 0;
140 }
141
142 switch (mmc_resp_type(cmd)) {
143 case MMC_RSP_NONE: c |= RESP_NONE; break;
144 case MMC_RSP_R1: c |= RESP_R1; break;
145 case MMC_RSP_R1B: c |= RESP_R1B; break;
146 case MMC_RSP_R2: c |= RESP_R2; break;
147 case MMC_RSP_R3: c |= RESP_R3; break;
148 default:
149 pr_debug("Unknown response type %d\n", mmc_resp_type(cmd));
150 return -EINVAL;
151 }
152
153 host->cmd = cmd;
154
155/* FIXME - this seems to be ok comented out but the spec suggest this bit should
156 * be set when issuing app commands.
157 * if(cmd->flags & MMC_FLAG_ACMD)
158 * c |= APP_CMD;
159 */
160 if (data) {
161 c |= DATA_PRESENT;
162 if (data->blocks > 1) {
163 tmio_iowrite16(0x100, ctl + CTL_STOP_INTERNAL_ACTION);
164 c |= TRANSFER_MULTI;
165 }
166 if (data->flags & MMC_DATA_READ)
167 c |= TRANSFER_READ;
168 }
169
170 enable_mmc_irqs(ctl, TMIO_MASK_CMD);
171
172 /* Fire off the command */
173 tmio_iowrite32(cmd->arg, ctl + CTL_ARG_REG);
174 tmio_iowrite16(c, ctl + CTL_SD_CMD);
175
176 return 0;
177}
178
179/* This chip always returns (at least?) as much data as you ask for.
180 * I'm unsure what happens if you ask for less than a block. This should be
181 * looked into to ensure that a funny length read doesnt hose the controller.
182 *
183 */
184static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
185{
186 void __iomem *ctl = host->ctl;
187 struct mmc_data *data = host->data;
188 unsigned short *buf;
189 unsigned int count;
190 unsigned long flags;
191
192 if (!data) {
193 pr_debug("Spurious PIO IRQ\n");
194 return;
195 }
196
197 buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) +
198 host->sg_off);
199
200 count = host->sg_ptr->length - host->sg_off;
201 if (count > data->blksz)
202 count = data->blksz;
203
204 pr_debug("count: %08x offset: %08x flags %08x\n",
205 count, host->sg_off, data->flags);
206
207 /* Transfer the data */
208 if (data->flags & MMC_DATA_READ)
209 tmio_ioread16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1);
210 else
211 tmio_iowrite16_rep(ctl + CTL_SD_DATA_PORT, buf, count >> 1);
212
213 host->sg_off += count;
214
215 tmio_mmc_kunmap_atomic(host, &flags);
216
217 if (host->sg_off == host->sg_ptr->length)
218 tmio_mmc_next_sg(host);
219
220 return;
221}
222
223static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host)
224{
225 void __iomem *ctl = host->ctl;
226 struct mmc_data *data = host->data;
227 struct mmc_command *stop = data->stop;
228
229 host->data = NULL;
230
231 if (!data) {
232 pr_debug("Spurious data end IRQ\n");
233 return;
234 }
235
236 /* FIXME - return correct transfer count on errors */
237 if (!data->error)
238 data->bytes_xfered = data->blocks * data->blksz;
239 else
240 data->bytes_xfered = 0;
241
242 pr_debug("Completed data request\n");
243
244 /*FIXME - other drivers allow an optional stop command of any given type
245 * which we dont do, as the chip can auto generate them.
246 * Perhaps we can be smarter about when to use auto CMD12 and
247 * only issue the auto request when we know this is the desired
248 * stop command, allowing fallback to the stop command the
249 * upper layers expect. For now, we do what works.
250 */
251
252 if (data->flags & MMC_DATA_READ)
253 disable_mmc_irqs(ctl, TMIO_MASK_READOP);
254 else
255 disable_mmc_irqs(ctl, TMIO_MASK_WRITEOP);
256
257 if (stop) {
258 if (stop->opcode == 12 && !stop->arg)
259 tmio_iowrite16(0x000, ctl + CTL_STOP_INTERNAL_ACTION);
260 else
261 BUG();
262 }
263
264 tmio_mmc_finish_request(host);
265}
266
267static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
268 unsigned int stat)
269{
270 void __iomem *ctl = host->ctl, *addr;
271 struct mmc_command *cmd = host->cmd;
272 int i;
273
274 if (!host->cmd) {
275 pr_debug("Spurious CMD irq\n");
276 return;
277 }
278
279 host->cmd = NULL;
280
281 /* This controller is sicker than the PXA one. Not only do we need to
282 * drop the top 8 bits of the first response word, we also need to
283 * modify the order of the response for short response command types.
284 */
285
286 for (i = 3, addr = ctl + CTL_RESPONSE ; i >= 0 ; i--, addr += 4)
287 cmd->resp[i] = tmio_ioread32(addr);
288
289 if (cmd->flags & MMC_RSP_136) {
290 cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24);
291 cmd->resp[1] = (cmd->resp[1] << 8) | (cmd->resp[2] >> 24);
292 cmd->resp[2] = (cmd->resp[2] << 8) | (cmd->resp[3] >> 24);
293 cmd->resp[3] <<= 8;
294 } else if (cmd->flags & MMC_RSP_R3) {
295 cmd->resp[0] = cmd->resp[3];
296 }
297
298 if (stat & TMIO_STAT_CMDTIMEOUT)
299 cmd->error = -ETIMEDOUT;
300 else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC)
301 cmd->error = -EILSEQ;
302
303 /* If there is data to handle we enable data IRQs here, and
304 * we will ultimatley finish the request in the data_end handler.
305 * If theres no data or we encountered an error, finish now.
306 */
307 if (host->data && !cmd->error) {
308 if (host->data->flags & MMC_DATA_READ)
309 enable_mmc_irqs(ctl, TMIO_MASK_READOP);
310 else
311 enable_mmc_irqs(ctl, TMIO_MASK_WRITEOP);
312 } else {
313 tmio_mmc_finish_request(host);
314 }
315
316 return;
317}
318
319
320static irqreturn_t tmio_mmc_irq(int irq, void *devid)
321{
322 struct tmio_mmc_host *host = devid;
323 void __iomem *ctl = host->ctl;
324 unsigned int ireg, irq_mask, status;
325
326 pr_debug("MMC IRQ begin\n");
327
328 status = tmio_ioread32(ctl + CTL_STATUS);
329 irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK);
330 ireg = status & TMIO_MASK_IRQ & ~irq_mask;
331
332 pr_debug_status(status);
333 pr_debug_status(ireg);
334
335 if (!ireg) {
336 disable_mmc_irqs(ctl, status & ~irq_mask);
337
338 pr_debug("tmio_mmc: Spurious irq, disabling! "
339 "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
340 pr_debug_status(status);
341
342 goto out;
343 }
344
345 while (ireg) {
346 /* Card insert / remove attempts */
347 if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
348 ack_mmc_irqs(ctl, TMIO_STAT_CARD_INSERT |
349 TMIO_STAT_CARD_REMOVE);
350 mmc_detect_change(host->mmc, 0);
351 }
352
353 /* CRC and other errors */
354/* if (ireg & TMIO_STAT_ERR_IRQ)
355 * handled |= tmio_error_irq(host, irq, stat);
356 */
357
358 /* Command completion */
359 if (ireg & TMIO_MASK_CMD) {
360 ack_mmc_irqs(ctl, TMIO_MASK_CMD);
361 tmio_mmc_cmd_irq(host, status);
362 }
363
364 /* Data transfer */
365 if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
366 ack_mmc_irqs(ctl, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
367 tmio_mmc_pio_irq(host);
368 }
369
370 /* Data transfer completion */
371 if (ireg & TMIO_STAT_DATAEND) {
372 ack_mmc_irqs(ctl, TMIO_STAT_DATAEND);
373 tmio_mmc_data_irq(host);
374 }
375
376 /* Check status - keep going until we've handled it all */
377 status = tmio_ioread32(ctl + CTL_STATUS);
378 irq_mask = tmio_ioread32(ctl + CTL_IRQ_MASK);
379 ireg = status & TMIO_MASK_IRQ & ~irq_mask;
380
381 pr_debug("Status at end of loop: %08x\n", status);
382 pr_debug_status(status);
383 }
384 pr_debug("MMC IRQ end\n");
385
386out:
387 return IRQ_HANDLED;
388}
389
390static int tmio_mmc_start_data(struct tmio_mmc_host *host,
391 struct mmc_data *data)
392{
393 void __iomem *ctl = host->ctl;
394
395 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
396 data->blksz, data->blocks);
397
398 /* Hardware cannot perform 1 and 2 byte requests in 4 bit mode */
399 if (data->blksz < 4 && host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
400 printk(KERN_ERR "%s: %d byte block unsupported in 4 bit mode\n",
401 mmc_hostname(host->mmc), data->blksz);
402 return -EINVAL;
403 }
404
405 tmio_mmc_init_sg(host, data);
406 host->data = data;
407
408 /* Set transfer length / blocksize */
409 tmio_iowrite16(data->blksz, ctl + CTL_SD_XFER_LEN);
410 tmio_iowrite16(data->blocks, ctl + CTL_XFER_BLK_COUNT);
411
412 return 0;
413}
414
415/* Process requests from the MMC layer */
416static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
417{
418 struct tmio_mmc_host *host = mmc_priv(mmc);
419 int ret;
420
421 if (host->mrq)
422 pr_debug("request not null\n");
423
424 host->mrq = mrq;
425
426 if (mrq->data) {
427 ret = tmio_mmc_start_data(host, mrq->data);
428 if (ret)
429 goto fail;
430 }
431
432 ret = tmio_mmc_start_command(host, mrq->cmd);
433
434 if (!ret)
435 return;
436
437fail:
438 mrq->cmd->error = ret;
439 mmc_request_done(mmc, mrq);
440}
441
442/* Set MMC clock / power.
443 * Note: This controller uses a simple divider scheme therefore it cannot
444 * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
445 * MMC wont run that fast, it has to be clocked at 12MHz which is the next
446 * slowest setting.
447 */
448static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
449{
450 struct tmio_mmc_host *host = mmc_priv(mmc);
451 void __iomem *cnf = host->cnf;
452 void __iomem *ctl = host->ctl;
453
454 if (ios->clock)
455 tmio_mmc_set_clock(host, ios->clock);
456
457 /* Power sequence - OFF -> ON -> UP */
458 switch (ios->power_mode) {
459 case MMC_POWER_OFF: /* power down SD bus */
460 tmio_iowrite8(0x00, cnf + CNF_PWR_CTL_2);
461 tmio_mmc_clk_stop(host);
462 break;
463 case MMC_POWER_ON: /* power up SD bus */
464
465 tmio_iowrite8(0x02, cnf + CNF_PWR_CTL_2);
466 break;
467 case MMC_POWER_UP: /* start bus clock */
468 tmio_mmc_clk_start(host);
469 break;
470 }
471
472 switch (ios->bus_width) {
473 case MMC_BUS_WIDTH_1:
474 tmio_iowrite16(0x80e0, ctl + CTL_SD_MEM_CARD_OPT);
475 break;
476 case MMC_BUS_WIDTH_4:
477 tmio_iowrite16(0x00e0, ctl + CTL_SD_MEM_CARD_OPT);
478 break;
479 }
480
481 /* Let things settle. delay taken from winCE driver */
482 udelay(140);
483}
484
485static int tmio_mmc_get_ro(struct mmc_host *mmc)
486{
487 struct tmio_mmc_host *host = mmc_priv(mmc);
488 void __iomem *ctl = host->ctl;
489
490 return (tmio_ioread16(ctl + CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1;
491}
492
493static struct mmc_host_ops tmio_mmc_ops = {
494 .request = tmio_mmc_request,
495 .set_ios = tmio_mmc_set_ios,
496 .get_ro = tmio_mmc_get_ro,
497};
498
499#ifdef CONFIG_PM
500static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
501{
502 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
503 struct mmc_host *mmc = platform_get_drvdata(dev);
504 int ret;
505
506 ret = mmc_suspend_host(mmc, state);
507
508 /* Tell MFD core it can disable us now.*/
509 if (!ret && cell->disable)
510 cell->disable(dev);
511
512 return ret;
513}
514
515static int tmio_mmc_resume(struct platform_device *dev)
516{
517 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
518 struct mmc_host *mmc = platform_get_drvdata(dev);
519 struct tmio_mmc_host *host = mmc_priv(mmc);
520 void __iomem *cnf = host->cnf;
521 int ret = 0;
522
523 /* Enable the MMC/SD Control registers */
524 tmio_iowrite16(SDCREN, cnf + CNF_CMD);
525 tmio_iowrite32(dev->resource[0].start & 0xfffe, cnf + CNF_CTL_BASE);
526
527 /* Tell the MFD core we are ready to be enabled */
528 if (cell->enable) {
529 ret = cell->enable(dev);
530 if (ret)
531 goto out;
532 }
533
534 mmc_resume_host(mmc);
535
536out:
537 return ret;
538}
539#else
540#define tmio_mmc_suspend NULL
541#define tmio_mmc_resume NULL
542#endif
543
544static int __devinit tmio_mmc_probe(struct platform_device *dev)
545{
546 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
547 struct resource *res_ctl, *res_cnf;
548 struct tmio_mmc_host *host;
549 struct mmc_host *mmc;
550 int ret = -ENOMEM;
551
552 if (dev->num_resources != 3)
553 goto out;
554
555 res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0);
556 res_cnf = platform_get_resource(dev, IORESOURCE_MEM, 1);
557 if (!res_ctl || !res_cnf) {
558 ret = -EINVAL;
559 goto out;
560 }
561
562 mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev);
563 if (!mmc)
564 goto out;
565
566 host = mmc_priv(mmc);
567 host->mmc = mmc;
568 platform_set_drvdata(dev, mmc);
569
570 host->ctl = ioremap(res_ctl->start, res_ctl->end - res_ctl->start);
571 if (!host->ctl)
572 goto host_free;
573
574 host->cnf = ioremap(res_cnf->start, res_cnf->end - res_cnf->start);
575 if (!host->cnf)
576 goto unmap_ctl;
577
578 mmc->ops = &tmio_mmc_ops;
579 mmc->caps = MMC_CAP_4_BIT_DATA;
580 mmc->f_min = 46875; /* 24000000 / 512 */
581 mmc->f_max = 24000000;
582 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
583
584 /* Enable the MMC/SD Control registers */
585 tmio_iowrite16(SDCREN, host->cnf + CNF_CMD);
586 tmio_iowrite32(dev->resource[0].start & 0xfffe,
587 host->cnf + CNF_CTL_BASE);
588
589 /* Tell the MFD core we are ready to be enabled */
590 if (cell->enable) {
591 ret = cell->enable(dev);
592 if (ret)
593 goto unmap_cnf;
594 }
595
596 /* Disable SD power during suspend */
597 tmio_iowrite8(0x01, host->cnf + CNF_PWR_CTL_3);
598
599 /* The below is required but why? FIXME */
600 tmio_iowrite8(0x1f, host->cnf + CNF_STOP_CLK_CTL);
601
602 /* Power down SD bus*/
603 tmio_iowrite8(0x0, host->cnf + CNF_PWR_CTL_2);
604
605 tmio_mmc_clk_stop(host);
606 reset(host);
607
608 ret = platform_get_irq(dev, 0);
609 if (ret >= 0)
610 host->irq = ret;
611 else
612 goto unmap_cnf;
613
614 disable_mmc_irqs(host->ctl, TMIO_MASK_ALL);
615
616 ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc",
617 host);
618 if (ret)
619 goto unmap_cnf;
620
621 set_irq_type(host->irq, IRQ_TYPE_EDGE_FALLING);
622
623 mmc_add_host(mmc);
624
625 printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
626 (unsigned long)host->ctl, host->irq);
627
628 /* Unmask the IRQs we want to know about */
629 enable_mmc_irqs(host->ctl, TMIO_MASK_IRQ);
630
631 return 0;
632
633unmap_cnf:
634 iounmap(host->cnf);
635unmap_ctl:
636 iounmap(host->ctl);
637host_free:
638 mmc_free_host(mmc);
639out:
640 return ret;
641}
642
643static int __devexit tmio_mmc_remove(struct platform_device *dev)
644{
645 struct mmc_host *mmc = platform_get_drvdata(dev);
646
647 platform_set_drvdata(dev, NULL);
648
649 if (mmc) {
650 struct tmio_mmc_host *host = mmc_priv(mmc);
651 mmc_remove_host(mmc);
652 mmc_free_host(mmc);
653 free_irq(host->irq, host);
654 iounmap(host->ctl);
655 iounmap(host->cnf);
656 }
657
658 return 0;
659}
660
661/* ------------------- device registration ----------------------- */
662
663static struct platform_driver tmio_mmc_driver = {
664 .driver = {
665 .name = "tmio-mmc",
666 .owner = THIS_MODULE,
667 },
668 .probe = tmio_mmc_probe,
669 .remove = __devexit_p(tmio_mmc_remove),
670 .suspend = tmio_mmc_suspend,
671 .resume = tmio_mmc_resume,
672};
673
674
675static int __init tmio_mmc_init(void)
676{
677 return platform_driver_register(&tmio_mmc_driver);
678}
679
680static void __exit tmio_mmc_exit(void)
681{
682 platform_driver_unregister(&tmio_mmc_driver);
683}
684
685module_init(tmio_mmc_init);
686module_exit(tmio_mmc_exit);
687
688MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver");
689MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
690MODULE_LICENSE("GPL v2");
691MODULE_ALIAS("platform:tmio-mmc");
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
new file mode 100644
index 000000000000..9e647a06054f
--- /dev/null
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -0,0 +1,194 @@
1/* Definitons for use with the tmio_mmc.c
2 *
3 * (c) 2004 Ian Molton <spyro@f2s.com>
4 * (c) 2007 Ian Molton <spyro@f2s.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#define CNF_CMD 0x04
12#define CNF_CTL_BASE 0x10
13#define CNF_INT_PIN 0x3d
14#define CNF_STOP_CLK_CTL 0x40
15#define CNF_GCLK_CTL 0x41
16#define CNF_SD_CLK_MODE 0x42
17#define CNF_PIN_STATUS 0x44
18#define CNF_PWR_CTL_1 0x48
19#define CNF_PWR_CTL_2 0x49
20#define CNF_PWR_CTL_3 0x4a
21#define CNF_CARD_DETECT_MODE 0x4c
22#define CNF_SD_SLOT 0x50
23#define CNF_EXT_GCLK_CTL_1 0xf0
24#define CNF_EXT_GCLK_CTL_2 0xf1
25#define CNF_EXT_GCLK_CTL_3 0xf9
26#define CNF_SD_LED_EN_1 0xfa
27#define CNF_SD_LED_EN_2 0xfe
28
29#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
30
31#define CTL_SD_CMD 0x00
32#define CTL_ARG_REG 0x04
33#define CTL_STOP_INTERNAL_ACTION 0x08
34#define CTL_XFER_BLK_COUNT 0xa
35#define CTL_RESPONSE 0x0c
36#define CTL_STATUS 0x1c
37#define CTL_IRQ_MASK 0x20
38#define CTL_SD_CARD_CLK_CTL 0x24
39#define CTL_SD_XFER_LEN 0x26
40#define CTL_SD_MEM_CARD_OPT 0x28
41#define CTL_SD_ERROR_DETAIL_STATUS 0x2c
42#define CTL_SD_DATA_PORT 0x30
43#define CTL_TRANSACTION_CTL 0x34
44#define CTL_RESET_SD 0xe0
45#define CTL_SDIO_REGS 0x100
46#define CTL_CLK_AND_WAIT_CTL 0x138
47#define CTL_RESET_SDIO 0x1e0
48
49/* Definitions for values the CTRL_STATUS register can take. */
50#define TMIO_STAT_CMDRESPEND 0x00000001
51#define TMIO_STAT_DATAEND 0x00000004
52#define TMIO_STAT_CARD_REMOVE 0x00000008
53#define TMIO_STAT_CARD_INSERT 0x00000010
54#define TMIO_STAT_SIGSTATE 0x00000020
55#define TMIO_STAT_WRPROTECT 0x00000080
56#define TMIO_STAT_CARD_REMOVE_A 0x00000100
57#define TMIO_STAT_CARD_INSERT_A 0x00000200
58#define TMIO_STAT_SIGSTATE_A 0x00000400
59#define TMIO_STAT_CMD_IDX_ERR 0x00010000
60#define TMIO_STAT_CRCFAIL 0x00020000
61#define TMIO_STAT_STOPBIT_ERR 0x00040000
62#define TMIO_STAT_DATATIMEOUT 0x00080000
63#define TMIO_STAT_RXOVERFLOW 0x00100000
64#define TMIO_STAT_TXUNDERRUN 0x00200000
65#define TMIO_STAT_CMDTIMEOUT 0x00400000
66#define TMIO_STAT_RXRDY 0x01000000
67#define TMIO_STAT_TXRQ 0x02000000
68#define TMIO_STAT_ILL_FUNC 0x20000000
69#define TMIO_STAT_CMD_BUSY 0x40000000
70#define TMIO_STAT_ILL_ACCESS 0x80000000
71
72/* Define some IRQ masks */
73/* This is the mask used at reset by the chip */
74#define TMIO_MASK_ALL 0x837f031d
75#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \
76 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
77#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \
78 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
79#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
80 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
81#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
82
83#define enable_mmc_irqs(ctl, i) \
84 do { \
85 u32 mask;\
86 mask = tmio_ioread32((ctl) + CTL_IRQ_MASK); \
87 mask &= ~((i) & TMIO_MASK_IRQ); \
88 tmio_iowrite32(mask, (ctl) + CTL_IRQ_MASK); \
89 } while (0)
90
91#define disable_mmc_irqs(ctl, i) \
92 do { \
93 u32 mask;\
94 mask = tmio_ioread32((ctl) + CTL_IRQ_MASK); \
95 mask |= ((i) & TMIO_MASK_IRQ); \
96 tmio_iowrite32(mask, (ctl) + CTL_IRQ_MASK); \
97 } while (0)
98
99#define ack_mmc_irqs(ctl, i) \
100 do { \
101 u32 mask;\
102 mask = tmio_ioread32((ctl) + CTL_STATUS); \
103 mask &= ~((i) & TMIO_MASK_IRQ); \
104 tmio_iowrite32(mask, (ctl) + CTL_STATUS); \
105 } while (0)
106
107
108struct tmio_mmc_host {
109 void __iomem *cnf;
110 void __iomem *ctl;
111 struct mmc_command *cmd;
112 struct mmc_request *mrq;
113 struct mmc_data *data;
114 struct mmc_host *mmc;
115 int irq;
116
117 /* pio related stuff */
118 struct scatterlist *sg_ptr;
119 unsigned int sg_len;
120 unsigned int sg_off;
121};
122
123#include <linux/scatterlist.h>
124#include <linux/blkdev.h>
125
126static inline void tmio_mmc_init_sg(struct tmio_mmc_host *host,
127 struct mmc_data *data)
128{
129 host->sg_len = data->sg_len;
130 host->sg_ptr = data->sg;
131 host->sg_off = 0;
132}
133
134static inline int tmio_mmc_next_sg(struct tmio_mmc_host *host)
135{
136 host->sg_ptr = sg_next(host->sg_ptr);
137 host->sg_off = 0;
138 return --host->sg_len;
139}
140
141static inline char *tmio_mmc_kmap_atomic(struct tmio_mmc_host *host,
142 unsigned long *flags)
143{
144 struct scatterlist *sg = host->sg_ptr;
145
146 local_irq_save(*flags);
147 return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
148}
149
150static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host,
151 unsigned long *flags)
152{
153 kunmap_atomic(sg_page(host->sg_ptr), KM_BIO_SRC_IRQ);
154 local_irq_restore(*flags);
155}
156
157#ifdef CONFIG_MMC_DEBUG
158
159#define STATUS_TO_TEXT(a) \
160 do { \
161 if (status & TMIO_STAT_##a) \
162 printf(#a); \
163 } while (0)
164
165void debug_status(u32 status)
166{
167 printk(KERN_DEBUG "status: %08x = ", status);
168 STATUS_TO_TEXT(CARD_REMOVE);
169 STATUS_TO_TEXT(CARD_INSERT);
170 STATUS_TO_TEXT(SIGSTATE);
171 STATUS_TO_TEXT(WRPROTECT);
172 STATUS_TO_TEXT(CARD_REMOVE_A);
173 STATUS_TO_TEXT(CARD_INSERT_A);
174 STATUS_TO_TEXT(SIGSTATE_A);
175 STATUS_TO_TEXT(CMD_IDX_ERR);
176 STATUS_TO_TEXT(STOPBIT_ERR);
177 STATUS_TO_TEXT(ILL_FUNC);
178 STATUS_TO_TEXT(CMD_BUSY);
179 STATUS_TO_TEXT(CMDRESPEND);
180 STATUS_TO_TEXT(DATAEND);
181 STATUS_TO_TEXT(CRCFAIL);
182 STATUS_TO_TEXT(DATATIMEOUT);
183 STATUS_TO_TEXT(CMDTIMEOUT);
184 STATUS_TO_TEXT(RXOVERFLOW);
185 STATUS_TO_TEXT(TXUNDERRUN);
186 STATUS_TO_TEXT(RXRDY);
187 STATUS_TO_TEXT(TXRQ);
188 STATUS_TO_TEXT(ILL_ACCESS);
189 printk("\n");
190}
191
192#else
193#define pr_debug_status(s) do { } while (0)
194#endif
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
index cf32267263df..53664188fc47 100644
--- a/drivers/mtd/maps/autcpu12-nvram.c
+++ b/drivers/mtd/maps/autcpu12-nvram.c
@@ -25,8 +25,8 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/sizes.h> 27#include <asm/sizes.h>
28#include <asm/hardware.h> 28#include <mach/hardware.h>
29#include <asm/arch/autcpu12.h> 29#include <mach/autcpu12.h>
30#include <linux/mtd/mtd.h> 30#include <linux/mtd/mtd.h>
31#include <linux/mtd/map.h> 31#include <linux/mtd/map.h>
32#include <linux/mtd/partitions.h> 32#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c
index cb507da0a87d..e5059aa3c724 100644
--- a/drivers/mtd/maps/cdb89712.c
+++ b/drivers/mtd/maps/cdb89712.c
@@ -9,7 +9,7 @@
9#include <linux/ioport.h> 9#include <linux/ioport.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <asm/io.h> 11#include <asm/io.h>
12#include <asm/arch/hardware.h> 12#include <mach/hardware.h>
13#include <linux/mtd/mtd.h> 13#include <linux/mtd/mtd.h>
14#include <linux/mtd/map.h> 14#include <linux/mtd/map.h>
15#include <linux/mtd/partitions.h> 15#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
index 6464d487eb1a..60e68bde0fea 100644
--- a/drivers/mtd/maps/ceiva.c
+++ b/drivers/mtd/maps/ceiva.c
@@ -25,7 +25,7 @@
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26#include <linux/mtd/concat.h> 26#include <linux/mtd/concat.h>
27 27
28#include <asm/hardware.h> 28#include <mach/hardware.h>
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/sizes.h> 31#include <asm/sizes.h>
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
index ef8915474462..35fef655ccc4 100644
--- a/drivers/mtd/maps/h720x-flash.c
+++ b/drivers/mtd/maps/h720x-flash.c
@@ -16,7 +16,7 @@
16#include <linux/mtd/mtd.h> 16#include <linux/mtd/mtd.h>
17#include <linux/mtd/map.h> 17#include <linux/mtd/map.h>
18#include <linux/mtd/partitions.h> 18#include <linux/mtd/partitions.h>
19#include <asm/hardware.h> 19#include <mach/hardware.h>
20#include <asm/io.h> 20#include <asm/io.h>
21 21
22static struct mtd_info *mymtd; 22static struct mtd_info *mymtd;
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index ee361aaadb1e..7100ee3c7b01 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -37,7 +37,7 @@
37#include <linux/mtd/partitions.h> 37#include <linux/mtd/partitions.h>
38 38
39#include <asm/mach/flash.h> 39#include <asm/mach/flash.h>
40#include <asm/hardware.h> 40#include <mach/hardware.h>
41#include <asm/io.h> 41#include <asm/io.h>
42#include <asm/system.h> 42#include <asm/system.h>
43 43
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 113b1062020d..ed58f6a77bd9 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -24,8 +24,8 @@
24#include <linux/mtd/concat.h> 24#include <linux/mtd/concat.h>
25#endif 25#endif
26 26
27#include <asm/hardware.h> 27#include <mach/hardware.h>
28#include <asm/arch/h3600.h> 28#include <mach/h3600.h>
29#include <asm/io.h> 29#include <asm/io.h>
30 30
31 31
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index c2264792a20b..dcdb1f17577d 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -30,7 +30,7 @@
30#include <linux/mtd/partitions.h> 30#include <linux/mtd/partitions.h>
31 31
32#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/hardware.h> 33#include <mach/hardware.h>
34#include <asm/mach/flash.h> 34#include <asm/mach/flash.h>
35 35
36#include <linux/reboot.h> 36#include <linux/reboot.h>
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 68eec6c6c517..05f276af15da 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -43,9 +43,9 @@
43#include <linux/mtd/partitions.h> 43#include <linux/mtd/partitions.h>
44 44
45#include <asm/io.h> 45#include <asm/io.h>
46#include <asm/hardware.h> 46#include <mach/hardware.h>
47#include <asm/mach/flash.h> 47#include <asm/mach/flash.h>
48#include <asm/arch/tc.h> 48#include <mach/tc.h>
49 49
50#ifdef CONFIG_MTD_PARTITIONS 50#ifdef CONFIG_MTD_PARTITIONS
51static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL }; 51static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL };
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 82113295c266..771139c5bf87 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -19,7 +19,7 @@
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
20 20
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24 24
25#include <asm/mach/flash.h> 25#include <asm/mach/flash.h>
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index e177a43dfff0..7df6bbf0e4d9 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -18,7 +18,7 @@
18#include <linux/mtd/partitions.h> 18#include <linux/mtd/partitions.h>
19#include <linux/mtd/concat.h> 19#include <linux/mtd/concat.h>
20 20
21#include <asm/hardware.h> 21#include <mach/hardware.h>
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/sizes.h> 23#include <asm/sizes.h>
24#include <asm/mach/flash.h> 24#include <asm/mach/flash.h>
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 02f9cc30d77b..41f361c49b32 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -351,6 +351,13 @@ config MTD_NAND_PASEMI
351 Enables support for NAND Flash interface on PA Semi PWRficient 351 Enables support for NAND Flash interface on PA Semi PWRficient
352 based boards 352 based boards
353 353
354config MTD_NAND_TMIO
355 tristate "NAND Flash device on Toshiba Mobile IO Controller"
356 depends on MTD_NAND && MFD_TMIO
357 help
358 Support for NAND flash connected to a Toshiba Mobile IO
359 Controller in some PDAs, including the Sharp SL6000x.
360
354config MTD_NAND_NANDSIM 361config MTD_NAND_NANDSIM
355 tristate "Support for NAND Flash Simulator" 362 tristate "Support for NAND Flash Simulator"
356 depends on MTD_PARTITIONS 363 depends on MTD_PARTITIONS
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d772581de573..b786c5da82da 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o
27obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o 27obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
28obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o 28obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
29obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o 29obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
30obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
30obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o 31obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
31obj-$(CONFIG_MTD_ALAUDA) += alauda.o 32obj-$(CONFIG_MTD_ALAUDA) += alauda.o
32obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o 33obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index a0ba07c36ee9..26d42987971f 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -22,10 +22,10 @@
22#include <linux/mtd/nand.h> 22#include <linux/mtd/nand.h>
23#include <linux/mtd/partitions.h> 23#include <linux/mtd/partitions.h>
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/arch/hardware.h> 25#include <mach/hardware.h>
26#include <asm/sizes.h> 26#include <asm/sizes.h>
27#include <asm/arch/gpio.h> 27#include <mach/gpio.h>
28#include <asm/arch/board-ams-delta.h> 28#include <mach/board-ams-delta.h>
29 29
30/* 30/*
31 * MTD structure for E3 (Delta) 31 * MTD structure for E3 (Delta)
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 99aec46e2145..3387e0d5076b 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -32,8 +32,8 @@
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/io.h> 33#include <linux/io.h>
34 34
35#include <asm/arch/board.h> 35#include <mach/board.h>
36#include <asm/arch/cpu.h> 36#include <mach/cpu.h>
37 37
38#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW 38#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW
39#define hard_ecc 1 39#define hard_ecc 1
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 553dd7e9b41c..7c95da1f612c 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -32,9 +32,9 @@
32#include <linux/mtd/nand.h> 32#include <linux/mtd/nand.h>
33#include <linux/mtd/partitions.h> 33#include <linux/mtd/partitions.h>
34#include <asm/io.h> 34#include <asm/io.h>
35#include <asm/arch/hardware.h> 35#include <mach/hardware.h>
36#include <asm/sizes.h> 36#include <asm/sizes.h>
37#include <asm/arch/autcpu12.h> 37#include <mach/autcpu12.h>
38 38
39/* 39/*
40 * MTD structure for AUTCPU12 board 40 * MTD structure for AUTCPU12 board
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index fc8529bedfdf..9eba3f04783a 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -26,8 +26,8 @@
26#include <asm/irq.h> 26#include <asm/irq.h>
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28 28
29#include <asm/arch/hardware.h> 29#include <mach/hardware.h>
30#include <asm/arch/pxa-regs.h> 30#include <mach/pxa-regs.h>
31 31
32#define GPIO_NAND_CS (11) 32#define GPIO_NAND_CS (11)
33#define GPIO_NAND_RB (89) 33#define GPIO_NAND_RB (89)
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 387e4352903e..86366bfba9f8 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -23,7 +23,7 @@
23#include <linux/mtd/nand.h> 23#include <linux/mtd/nand.h>
24#include <linux/mtd/partitions.h> 24#include <linux/mtd/partitions.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */ 26#include <mach/hardware.h> /* for CLPS7111_VIRT_BASE */
27#include <asm/sizes.h> 27#include <asm/sizes.h>
28#include <asm/hardware/clps7111.h> 28#include <asm/hardware/clps7111.h>
29 29
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 9e59de501c2e..f8ce79b446ed 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -24,10 +24,10 @@
24#include <linux/mtd/nand.h> 24#include <linux/mtd/nand.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/arch/hardware.h> /* for CLPS7111_VIRT_BASE */ 27#include <mach/hardware.h> /* for CLPS7111_VIRT_BASE */
28#include <asm/sizes.h> 28#include <asm/sizes.h>
29#include <asm/arch/h1900-gpio.h> 29#include <mach/h1900-gpio.h>
30#include <asm/arch/ipaq.h> 30#include <mach/ipaq.h>
31 31
32/* 32/*
33 * MTD structure for EDB7312 board 33 * MTD structure for EDB7312 board
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index ee2ac3948cd8..917cf8d3ae95 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -18,8 +18,8 @@
18#include <linux/mtd/partitions.h> 18#include <linux/mtd/partitions.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/sizes.h> 20#include <asm/sizes.h>
21#include <asm/arch/hardware.h> 21#include <mach/hardware.h>
22#include <asm/plat-orion/orion_nand.h> 22#include <plat/orion_nand.h>
23 23
24#ifdef CONFIG_MTD_CMDLINE_PARTS 24#ifdef CONFIG_MTD_CMDLINE_PARTS
25static const char *part_probes[] = { "cmdlinepart", NULL }; 25static const char *part_probes[] = { "cmdlinepart", NULL };
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index fe2bc7e42119..a64ad15b8fdd 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -22,8 +22,8 @@
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <asm/dma.h> 23#include <asm/dma.h>
24 24
25#include <asm/arch/pxa-regs.h> 25#include <mach/pxa-regs.h>
26#include <asm/arch/pxa3xx_nand.h> 26#include <mach/pxa3xx_nand.h>
27 27
28#define CHIP_DELAY_TIMEOUT (2 * HZ/10) 28#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
29 29
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 6dba2fb66ae5..30a518e211bd 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -21,7 +21,7 @@
21#include <linux/mtd/partitions.h> 21#include <linux/mtd/partitions.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/hardware.h> 24#include <mach/hardware.h>
25#include <asm/mach-types.h> 25#include <asm/mach-types.h>
26 26
27static void __iomem *sharpsl_io_base; 27static void __iomem *sharpsl_io_base;
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
new file mode 100644
index 000000000000..cbab654b03c8
--- /dev/null
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -0,0 +1,556 @@
1/*
2 * Toshiba TMIO NAND flash controller driver
3 *
4 * Slightly murky pre-git history of the driver:
5 *
6 * Copyright (c) Ian Molton 2004, 2005, 2008
7 * Original work, independant of sharps code. Included hardware ECC support.
8 * Hard ECC did not work for writes in the early revisions.
9 * Copyright (c) Dirk Opfer 2005.
10 * Modifications developed from sharps code but
11 * NOT containing any, ported onto Ians base.
12 * Copyright (c) Chris Humbert 2005
13 * Copyright (c) Dmitry Baryshkov 2008
14 * Minor fixes
15 *
16 * Parts copyright Sebastian Carlier
17 *
18 * This file is licensed under
19 * the terms of the GNU General Public License version 2. This program
20 * is licensed "as is" without any warranty of any kind, whether express
21 * or implied.
22 *
23 */
24
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/mfd/core.h>
30#include <linux/mfd/tmio.h>
31#include <linux/delay.h>
32#include <linux/io.h>
33#include <linux/irq.h>
34#include <linux/interrupt.h>
35#include <linux/ioport.h>
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/nand.h>
38#include <linux/mtd/nand_ecc.h>
39#include <linux/mtd/partitions.h>
40
41/*--------------------------------------------------------------------------*/
42
43/*
44 * NAND Flash Host Controller Configuration Register
45 */
46#define CCR_COMMAND 0x04 /* w Command */
47#define CCR_BASE 0x10 /* l NAND Flash Control Reg Base Addr */
48#define CCR_INTP 0x3d /* b Interrupt Pin */
49#define CCR_INTE 0x48 /* b Interrupt Enable */
50#define CCR_EC 0x4a /* b Event Control */
51#define CCR_ICC 0x4c /* b Internal Clock Control */
52#define CCR_ECCC 0x5b /* b ECC Control */
53#define CCR_NFTC 0x60 /* b NAND Flash Transaction Control */
54#define CCR_NFM 0x61 /* b NAND Flash Monitor */
55#define CCR_NFPSC 0x62 /* b NAND Flash Power Supply Control */
56#define CCR_NFDC 0x63 /* b NAND Flash Detect Control */
57
58/*
59 * NAND Flash Control Register
60 */
61#define FCR_DATA 0x00 /* bwl Data Register */
62#define FCR_MODE 0x04 /* b Mode Register */
63#define FCR_STATUS 0x05 /* b Status Register */
64#define FCR_ISR 0x06 /* b Interrupt Status Register */
65#define FCR_IMR 0x07 /* b Interrupt Mask Register */
66
67/* FCR_MODE Register Command List */
68#define FCR_MODE_DATA 0x94 /* Data Data_Mode */
69#define FCR_MODE_COMMAND 0x95 /* Data Command_Mode */
70#define FCR_MODE_ADDRESS 0x96 /* Data Address_Mode */
71
72#define FCR_MODE_HWECC_CALC 0xB4 /* HW-ECC Data */
73#define FCR_MODE_HWECC_RESULT 0xD4 /* HW-ECC Calc result Read_Mode */
74#define FCR_MODE_HWECC_RESET 0xF4 /* HW-ECC Reset */
75
76#define FCR_MODE_POWER_ON 0x0C /* Power Supply ON to SSFDC card */
77#define FCR_MODE_POWER_OFF 0x08 /* Power Supply OFF to SSFDC card */
78
79#define FCR_MODE_LED_OFF 0x00 /* LED OFF */
80#define FCR_MODE_LED_ON 0x04 /* LED ON */
81
82#define FCR_MODE_EJECT_ON 0x68 /* Ejection events active */
83#define FCR_MODE_EJECT_OFF 0x08 /* Ejection events ignored */
84
85#define FCR_MODE_LOCK 0x6C /* Lock_Mode. Eject Switch Invalid */
86#define FCR_MODE_UNLOCK 0x0C /* UnLock_Mode. Eject Switch is valid */
87
88#define FCR_MODE_CONTROLLER_ID 0x40 /* Controller ID Read */
89#define FCR_MODE_STANDBY 0x00 /* SSFDC card Changes Standby State */
90
91#define FCR_MODE_WE 0x80
92#define FCR_MODE_ECC1 0x40
93#define FCR_MODE_ECC0 0x20
94#define FCR_MODE_CE 0x10
95#define FCR_MODE_PCNT1 0x08
96#define FCR_MODE_PCNT0 0x04
97#define FCR_MODE_ALE 0x02
98#define FCR_MODE_CLE 0x01
99
100#define FCR_STATUS_BUSY 0x80
101
102/*--------------------------------------------------------------------------*/
103
104struct tmio_nand {
105 struct mtd_info mtd;
106 struct nand_chip chip;
107
108 struct platform_device *dev;
109
110 void __iomem *ccr;
111 void __iomem *fcr;
112 unsigned long fcr_phys;
113
114 unsigned int irq;
115
116 /* for tmio_nand_read_byte */
117 u8 read;
118 unsigned read_good:1;
119};
120
121#define mtd_to_tmio(m) container_of(m, struct tmio_nand, mtd)
122
123#ifdef CONFIG_MTD_CMDLINE_PARTS
124static const char *part_probes[] = { "cmdlinepart", NULL };
125#endif
126
127/*--------------------------------------------------------------------------*/
128
129static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd,
130 unsigned int ctrl)
131{
132 struct tmio_nand *tmio = mtd_to_tmio(mtd);
133 struct nand_chip *chip = mtd->priv;
134
135 if (ctrl & NAND_CTRL_CHANGE) {
136 u8 mode;
137
138 if (ctrl & NAND_NCE) {
139 mode = FCR_MODE_DATA;
140
141 if (ctrl & NAND_CLE)
142 mode |= FCR_MODE_CLE;
143 else
144 mode &= ~FCR_MODE_CLE;
145
146 if (ctrl & NAND_ALE)
147 mode |= FCR_MODE_ALE;
148 else
149 mode &= ~FCR_MODE_ALE;
150 } else {
151 mode = FCR_MODE_STANDBY;
152 }
153
154 tmio_iowrite8(mode, tmio->fcr + FCR_MODE);
155 tmio->read_good = 0;
156 }
157
158 if (cmd != NAND_CMD_NONE)
159 tmio_iowrite8(cmd, chip->IO_ADDR_W);
160}
161
162static int tmio_nand_dev_ready(struct mtd_info *mtd)
163{
164 struct tmio_nand *tmio = mtd_to_tmio(mtd);
165
166 return !(tmio_ioread8(tmio->fcr + FCR_STATUS) & FCR_STATUS_BUSY);
167}
168
169static irqreturn_t tmio_irq(int irq, void *__tmio)
170{
171 struct tmio_nand *tmio = __tmio;
172 struct nand_chip *nand_chip = &tmio->chip;
173
174 /* disable RDYREQ interrupt */
175 tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
176
177 if (unlikely(!waitqueue_active(&nand_chip->controller->wq)))
178 dev_warn(&tmio->dev->dev, "spurious interrupt\n");
179
180 wake_up(&nand_chip->controller->wq);
181 return IRQ_HANDLED;
182}
183
184/*
185 *The TMIO core has a RDYREQ interrupt on the posedge of #SMRB.
186 *This interrupt is normally disabled, but for long operations like
187 *erase and write, we enable it to wake us up. The irq handler
188 *disables the interrupt.
189 */
190static int
191tmio_nand_wait(struct mtd_info *mtd, struct nand_chip *nand_chip)
192{
193 struct tmio_nand *tmio = mtd_to_tmio(mtd);
194 long timeout;
195
196 /* enable RDYREQ interrupt */
197 tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);
198 tmio_iowrite8(0x81, tmio->fcr + FCR_IMR);
199
200 timeout = wait_event_timeout(nand_chip->controller->wq,
201 tmio_nand_dev_ready(mtd),
202 msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20));
203
204 if (unlikely(!tmio_nand_dev_ready(mtd))) {
205 tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
206 dev_warn(&tmio->dev->dev, "still busy with %s after %d ms\n",
207 nand_chip->state == FL_ERASING ? "erase" : "program",
208 nand_chip->state == FL_ERASING ? 400 : 20);
209
210 } else if (unlikely(!timeout)) {
211 tmio_iowrite8(0x00, tmio->fcr + FCR_IMR);
212 dev_warn(&tmio->dev->dev, "timeout waiting for interrupt\n");
213 }
214
215 nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
216 return nand_chip->read_byte(mtd);
217}
218
219/*
220 *The TMIO controller combines two 8-bit data bytes into one 16-bit
221 *word. This function separates them so nand_base.c works as expected,
222 *especially its NAND_CMD_READID routines.
223 *
224 *To prevent stale data from being read, tmio_nand_hwcontrol() clears
225 *tmio->read_good.
226 */
227static u_char tmio_nand_read_byte(struct mtd_info *mtd)
228{
229 struct tmio_nand *tmio = mtd_to_tmio(mtd);
230 unsigned int data;
231
232 if (tmio->read_good--)
233 return tmio->read;
234
235 data = tmio_ioread16(tmio->fcr + FCR_DATA);
236 tmio->read = data >> 8;
237 return data;
238}
239
240/*
241 *The TMIO controller converts an 8-bit NAND interface to a 16-bit
242 *bus interface, so all data reads and writes must be 16-bit wide.
243 *Thus, we implement 16-bit versions of the read, write, and verify
244 *buffer functions.
245 */
246static void
247tmio_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
248{
249 struct tmio_nand *tmio = mtd_to_tmio(mtd);
250
251 tmio_iowrite16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
252}
253
254static void tmio_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
255{
256 struct tmio_nand *tmio = mtd_to_tmio(mtd);
257
258 tmio_ioread16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
259}
260
261static int
262tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
263{
264 struct tmio_nand *tmio = mtd_to_tmio(mtd);
265 u16 *p = (u16 *) buf;
266
267 for (len >>= 1; len; len--)
268 if (*(p++) != tmio_ioread16(tmio->fcr + FCR_DATA))
269 return -EFAULT;
270 return 0;
271}
272
273static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode)
274{
275 struct tmio_nand *tmio = mtd_to_tmio(mtd);
276
277 tmio_iowrite8(FCR_MODE_HWECC_RESET, tmio->fcr + FCR_MODE);
278 tmio_ioread8(tmio->fcr + FCR_DATA); /* dummy read */
279 tmio_iowrite8(FCR_MODE_HWECC_CALC, tmio->fcr + FCR_MODE);
280}
281
282static int tmio_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
283 u_char *ecc_code)
284{
285 struct tmio_nand *tmio = mtd_to_tmio(mtd);
286 unsigned int ecc;
287
288 tmio_iowrite8(FCR_MODE_HWECC_RESULT, tmio->fcr + FCR_MODE);
289
290 ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
291 ecc_code[1] = ecc; /* 000-255 LP7-0 */
292 ecc_code[0] = ecc >> 8; /* 000-255 LP15-8 */
293 ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
294 ecc_code[2] = ecc; /* 000-255 CP5-0,11b */
295 ecc_code[4] = ecc >> 8; /* 256-511 LP7-0 */
296 ecc = tmio_ioread16(tmio->fcr + FCR_DATA);
297 ecc_code[3] = ecc; /* 256-511 LP15-8 */
298 ecc_code[5] = ecc >> 8; /* 256-511 CP5-0,11b */
299
300 tmio_iowrite8(FCR_MODE_DATA, tmio->fcr + FCR_MODE);
301 return 0;
302}
303
304static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
305{
306 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
307 int ret;
308
309 if (cell->enable) {
310 ret = cell->enable(dev);
311 if (ret)
312 return ret;
313 }
314
315 /* (4Ch) CLKRUN Enable 1st spcrunc */
316 tmio_iowrite8(0x81, tmio->ccr + CCR_ICC);
317
318 /* (10h)BaseAddress 0x1000 spba.spba2 */
319 tmio_iowrite16(tmio->fcr_phys, tmio->ccr + CCR_BASE);
320 tmio_iowrite16(tmio->fcr_phys >> 16, tmio->ccr + CCR_BASE + 16);
321
322 /* (04h)Command Register I/O spcmd */
323 tmio_iowrite8(0x02, tmio->ccr + CCR_COMMAND);
324
325 /* (62h) Power Supply Control ssmpwc */
326 /* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */
327 tmio_iowrite8(0x02, tmio->ccr + CCR_NFPSC);
328
329 /* (63h) Detect Control ssmdtc */
330 tmio_iowrite8(0x02, tmio->ccr + CCR_NFDC);
331
332 /* Interrupt status register clear sintst */
333 tmio_iowrite8(0x0f, tmio->fcr + FCR_ISR);
334
335 /* After power supply, Media are reset smode */
336 tmio_iowrite8(FCR_MODE_POWER_ON, tmio->fcr + FCR_MODE);
337 tmio_iowrite8(FCR_MODE_COMMAND, tmio->fcr + FCR_MODE);
338 tmio_iowrite8(NAND_CMD_RESET, tmio->fcr + FCR_DATA);
339
340 /* Standby Mode smode */
341 tmio_iowrite8(FCR_MODE_STANDBY, tmio->fcr + FCR_MODE);
342
343 mdelay(5);
344
345 return 0;
346}
347
348static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
349{
350 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
351
352 tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE);
353 if (cell->disable)
354 cell->disable(dev);
355}
356
357static int tmio_probe(struct platform_device *dev)
358{
359 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
360 struct tmio_nand_data *data = cell->driver_data;
361 struct resource *fcr = platform_get_resource(dev,
362 IORESOURCE_MEM, 0);
363 struct resource *ccr = platform_get_resource(dev,
364 IORESOURCE_MEM, 1);
365 int irq = platform_get_irq(dev, 0);
366 struct tmio_nand *tmio;
367 struct mtd_info *mtd;
368 struct nand_chip *nand_chip;
369#ifdef CONFIG_MTD_PARTITIONS
370 struct mtd_partition *parts;
371 int nbparts = 0;
372#endif
373 int retval;
374
375 if (data == NULL)
376 dev_warn(&dev->dev, "NULL platform data!\n");
377
378 tmio = kzalloc(sizeof *tmio, GFP_KERNEL);
379 if (!tmio) {
380 retval = -ENOMEM;
381 goto err_kzalloc;
382 }
383
384 tmio->dev = dev;
385
386 platform_set_drvdata(dev, tmio);
387 mtd = &tmio->mtd;
388 nand_chip = &tmio->chip;
389 mtd->priv = nand_chip;
390 mtd->name = "tmio-nand";
391
392 tmio->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1);
393 if (!tmio->ccr) {
394 retval = -EIO;
395 goto err_iomap_ccr;
396 }
397
398 tmio->fcr_phys = (unsigned long)fcr->start;
399 tmio->fcr = ioremap(fcr->start, fcr->end - fcr->start + 1);
400 if (!tmio->fcr) {
401 retval = -EIO;
402 goto err_iomap_fcr;
403 }
404
405 retval = tmio_hw_init(dev, tmio);
406 if (retval)
407 goto err_hwinit;
408
409 /* Set address of NAND IO lines */
410 nand_chip->IO_ADDR_R = tmio->fcr;
411 nand_chip->IO_ADDR_W = tmio->fcr;
412
413 /* Set address of hardware control function */
414 nand_chip->cmd_ctrl = tmio_nand_hwcontrol;
415 nand_chip->dev_ready = tmio_nand_dev_ready;
416 nand_chip->read_byte = tmio_nand_read_byte;
417 nand_chip->write_buf = tmio_nand_write_buf;
418 nand_chip->read_buf = tmio_nand_read_buf;
419 nand_chip->verify_buf = tmio_nand_verify_buf;
420
421 /* set eccmode using hardware ECC */
422 nand_chip->ecc.mode = NAND_ECC_HW;
423 nand_chip->ecc.size = 512;
424 nand_chip->ecc.bytes = 6;
425 nand_chip->ecc.hwctl = tmio_nand_enable_hwecc;
426 nand_chip->ecc.calculate = tmio_nand_calculate_ecc;
427 nand_chip->ecc.correct = nand_correct_data;
428
429 if (data)
430 nand_chip->badblock_pattern = data->badblock_pattern;
431
432 /* 15 us command delay time */
433 nand_chip->chip_delay = 15;
434
435 retval = request_irq(irq, &tmio_irq,
436 IRQF_DISABLED, dev->dev.bus_id, tmio);
437 if (retval) {
438 dev_err(&dev->dev, "request_irq error %d\n", retval);
439 goto err_irq;
440 }
441
442 tmio->irq = irq;
443 nand_chip->waitfunc = tmio_nand_wait;
444
445 /* Scan to find existence of the device */
446 if (nand_scan(mtd, 1)) {
447 retval = -ENODEV;
448 goto err_scan;
449 }
450 /* Register the partitions */
451#ifdef CONFIG_MTD_PARTITIONS
452#ifdef CONFIG_MTD_CMDLINE_PARTS
453 nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
454#endif
455 if (nbparts <= 0 && data) {
456 parts = data->partition;
457 nbparts = data->num_partitions;
458 }
459
460 if (nbparts)
461 retval = add_mtd_partitions(mtd, parts, nbparts);
462 else
463#endif
464 retval = add_mtd_device(mtd);
465
466 if (!retval)
467 return retval;
468
469 nand_release(mtd);
470
471err_scan:
472 if (tmio->irq)
473 free_irq(tmio->irq, tmio);
474err_irq:
475 tmio_hw_stop(dev, tmio);
476err_hwinit:
477 iounmap(tmio->fcr);
478err_iomap_fcr:
479 iounmap(tmio->ccr);
480err_iomap_ccr:
481 kfree(tmio);
482err_kzalloc:
483 return retval;
484}
485
486static int tmio_remove(struct platform_device *dev)
487{
488 struct tmio_nand *tmio = platform_get_drvdata(dev);
489
490 nand_release(&tmio->mtd);
491 if (tmio->irq)
492 free_irq(tmio->irq, tmio);
493 tmio_hw_stop(dev, tmio);
494 iounmap(tmio->fcr);
495 iounmap(tmio->ccr);
496 kfree(tmio);
497 return 0;
498}
499
500#ifdef CONFIG_PM
501static int tmio_suspend(struct platform_device *dev, pm_message_t state)
502{
503 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
504
505 if (cell->suspend)
506 cell->suspend(dev);
507
508 tmio_hw_stop(dev, platform_get_drvdata(dev));
509 return 0;
510}
511
512static int tmio_resume(struct platform_device *dev)
513{
514 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
515
516 /* FIXME - is this required or merely another attack of the broken
517 * SHARP platform? Looks suspicious.
518 */
519 tmio_hw_init(dev, platform_get_drvdata(dev));
520
521 if (cell->resume)
522 cell->resume(dev);
523
524 return 0;
525}
526#else
527#define tmio_suspend NULL
528#define tmio_resume NULL
529#endif
530
531static struct platform_driver tmio_driver = {
532 .driver.name = "tmio-nand",
533 .driver.owner = THIS_MODULE,
534 .probe = tmio_probe,
535 .remove = tmio_remove,
536 .suspend = tmio_suspend,
537 .resume = tmio_resume,
538};
539
540static int __init tmio_init(void)
541{
542 return platform_driver_register(&tmio_driver);
543}
544
545static void __exit tmio_exit(void)
546{
547 platform_driver_unregister(&tmio_driver);
548}
549
550module_init(tmio_init);
551module_exit(tmio_exit);
552
553MODULE_LICENSE("GPL v2");
554MODULE_AUTHOR("Ian Molton, Dirk Opfer, Chris Humbert, Dmitry Baryshkov");
555MODULE_DESCRIPTION("NAND flash driver on Toshiba Mobile IO controller");
556MODULE_ALIAS("platform:tmio-nand");
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c
index 807a72752eeb..2c410a011317 100644
--- a/drivers/mtd/nand/ts7250.c
+++ b/drivers/mtd/nand/ts7250.c
@@ -25,7 +25,7 @@
25#include <linux/mtd/nand.h> 25#include <linux/mtd/nand.h>
26#include <linux/mtd/partitions.h> 26#include <linux/mtd/partitions.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/arch/hardware.h> 28#include <mach/hardware.h>
29#include <asm/sizes.h> 29#include <asm/sizes.h>
30#include <asm/mach-types.h> 30#include <asm/mach-types.h>
31 31
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index dc6e474229b1..e2ce41d3828e 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -640,10 +640,8 @@ static int init586(struct net_device *dev)
640 cfg_cmd->time_low = 0x00; 640 cfg_cmd->time_low = 0x00;
641 cfg_cmd->time_high = 0xf2; 641 cfg_cmd->time_high = 0xf2;
642 cfg_cmd->promisc = 0; 642 cfg_cmd->promisc = 0;
643 if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) { 643 if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC))
644 cfg_cmd->promisc = 1; 644 cfg_cmd->promisc = 1;
645 dev->flags |= IFF_PROMISC;
646 }
647 cfg_cmd->carr_coll = 0x00; 645 cfg_cmd->carr_coll = 0x00;
648 646
649 p->scb->cbl_offset = make16(cfg_cmd); 647 p->scb->cbl_offset = make16(cfg_cmd);
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index 6aca0c640f13..abc84f765973 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -1521,14 +1521,11 @@ static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
1521 struct mc32_local *lp = netdev_priv(dev); 1521 struct mc32_local *lp = netdev_priv(dev);
1522 u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */ 1522 u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */
1523 1523
1524 if (dev->flags&IFF_PROMISC) 1524 if ((dev->flags&IFF_PROMISC) ||
1525 (dev->flags&IFF_ALLMULTI) ||
1526 dev->mc_count > 10)
1525 /* Enable promiscuous mode */ 1527 /* Enable promiscuous mode */
1526 filt |= 1; 1528 filt |= 1;
1527 else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10)
1528 {
1529 dev->flags|=IFF_PROMISC;
1530 filt |= 1;
1531 }
1532 else if(dev->mc_count) 1529 else if(dev->mc_count)
1533 { 1530 {
1534 unsigned char block[62]; 1531 unsigned char block[62];
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 8db4e6b89482..491ee16da5c1 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1692,12 +1692,14 @@ vortex_open(struct net_device *dev)
1692 vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1)); 1692 vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
1693 vp->rx_ring[i].status = 0; /* Clear complete bit. */ 1693 vp->rx_ring[i].status = 0; /* Clear complete bit. */
1694 vp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG); 1694 vp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG);
1695 skb = dev_alloc_skb(PKT_BUF_SZ); 1695
1696 skb = __netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN,
1697 GFP_KERNEL);
1696 vp->rx_skbuff[i] = skb; 1698 vp->rx_skbuff[i] = skb;
1697 if (skb == NULL) 1699 if (skb == NULL)
1698 break; /* Bad news! */ 1700 break; /* Bad news! */
1699 skb->dev = dev; /* Mark as being used by this device. */ 1701
1700 skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ 1702 skb_reserve(skb, NET_IP_ALIGN); /* Align IP on 16 byte boundaries */
1701 vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); 1703 vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
1702 } 1704 }
1703 if (i != RX_RING_SIZE) { 1705 if (i != RX_RING_SIZE) {
@@ -2538,7 +2540,7 @@ boomerang_rx(struct net_device *dev)
2538 struct sk_buff *skb; 2540 struct sk_buff *skb;
2539 entry = vp->dirty_rx % RX_RING_SIZE; 2541 entry = vp->dirty_rx % RX_RING_SIZE;
2540 if (vp->rx_skbuff[entry] == NULL) { 2542 if (vp->rx_skbuff[entry] == NULL) {
2541 skb = dev_alloc_skb(PKT_BUF_SZ); 2543 skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
2542 if (skb == NULL) { 2544 if (skb == NULL) {
2543 static unsigned long last_jif; 2545 static unsigned long last_jif;
2544 if (time_after(jiffies, last_jif + 10 * HZ)) { 2546 if (time_after(jiffies, last_jif + 10 * HZ)) {
@@ -2549,8 +2551,8 @@ boomerang_rx(struct net_device *dev)
2549 mod_timer(&vp->rx_oom_timer, RUN_AT(HZ * 1)); 2551 mod_timer(&vp->rx_oom_timer, RUN_AT(HZ * 1));
2550 break; /* Bad news! */ 2552 break; /* Bad news! */
2551 } 2553 }
2552 skb->dev = dev; /* Mark as being used by this device. */ 2554
2553 skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ 2555 skb_reserve(skb, NET_IP_ALIGN);
2554 vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); 2556 vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
2555 vp->rx_skbuff[entry] = skb; 2557 vp->rx_skbuff[entry] = skb;
2556 } 2558 }
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index dc5d2584bd0c..f72a2e87d569 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -9,42 +9,39 @@ int ei_open(struct net_device *dev)
9{ 9{
10 return __ei_open(dev); 10 return __ei_open(dev);
11} 11}
12EXPORT_SYMBOL(ei_open);
12 13
13int ei_close(struct net_device *dev) 14int ei_close(struct net_device *dev)
14{ 15{
15 return __ei_close(dev); 16 return __ei_close(dev);
16} 17}
18EXPORT_SYMBOL(ei_close);
17 19
18irqreturn_t ei_interrupt(int irq, void *dev_id) 20irqreturn_t ei_interrupt(int irq, void *dev_id)
19{ 21{
20 return __ei_interrupt(irq, dev_id); 22 return __ei_interrupt(irq, dev_id);
21} 23}
24EXPORT_SYMBOL(ei_interrupt);
22 25
23#ifdef CONFIG_NET_POLL_CONTROLLER 26#ifdef CONFIG_NET_POLL_CONTROLLER
24void ei_poll(struct net_device *dev) 27void ei_poll(struct net_device *dev)
25{ 28{
26 __ei_poll(dev); 29 __ei_poll(dev);
27} 30}
31EXPORT_SYMBOL(ei_poll);
28#endif 32#endif
29 33
30struct net_device *__alloc_ei_netdev(int size) 34struct net_device *__alloc_ei_netdev(int size)
31{ 35{
32 return ____alloc_ei_netdev(size); 36 return ____alloc_ei_netdev(size);
33} 37}
38EXPORT_SYMBOL(__alloc_ei_netdev);
34 39
35void NS8390_init(struct net_device *dev, int startp) 40void NS8390_init(struct net_device *dev, int startp)
36{ 41{
37 __NS8390_init(dev, startp); 42 __NS8390_init(dev, startp);
38} 43}
39
40EXPORT_SYMBOL(ei_open);
41EXPORT_SYMBOL(ei_close);
42EXPORT_SYMBOL(ei_interrupt);
43#ifdef CONFIG_NET_POLL_CONTROLLER
44EXPORT_SYMBOL(ei_poll);
45#endif
46EXPORT_SYMBOL(NS8390_init); 44EXPORT_SYMBOL(NS8390_init);
47EXPORT_SYMBOL(__alloc_ei_netdev);
48 45
49#if defined(MODULE) 46#if defined(MODULE)
50 47
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
index 71f19884c4b1..4c6eea4611a2 100644
--- a/drivers/net/8390p.c
+++ b/drivers/net/8390p.c
@@ -4,9 +4,9 @@ static const char version[] =
4 "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; 4 "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
5 5
6#define ei_inb(_p) inb(_p) 6#define ei_inb(_p) inb(_p)
7#define ei_outb(_v,_p) outb(_v,_p) 7#define ei_outb(_v, _p) outb(_v, _p)
8#define ei_inb_p(_p) inb_p(_p) 8#define ei_inb_p(_p) inb_p(_p)
9#define ei_outb_p(_v,_p) outb_p(_v,_p) 9#define ei_outb_p(_v, _p) outb_p(_v, _p)
10 10
11#include "lib8390.c" 11#include "lib8390.c"
12 12
@@ -14,42 +14,39 @@ int eip_open(struct net_device *dev)
14{ 14{
15 return __ei_open(dev); 15 return __ei_open(dev);
16} 16}
17EXPORT_SYMBOL(eip_open);
17 18
18int eip_close(struct net_device *dev) 19int eip_close(struct net_device *dev)
19{ 20{
20 return __ei_close(dev); 21 return __ei_close(dev);
21} 22}
23EXPORT_SYMBOL(eip_close);
22 24
23irqreturn_t eip_interrupt(int irq, void *dev_id) 25irqreturn_t eip_interrupt(int irq, void *dev_id)
24{ 26{
25 return __ei_interrupt(irq, dev_id); 27 return __ei_interrupt(irq, dev_id);
26} 28}
29EXPORT_SYMBOL(eip_interrupt);
27 30
28#ifdef CONFIG_NET_POLL_CONTROLLER 31#ifdef CONFIG_NET_POLL_CONTROLLER
29void eip_poll(struct net_device *dev) 32void eip_poll(struct net_device *dev)
30{ 33{
31 __ei_poll(dev); 34 __ei_poll(dev);
32} 35}
36EXPORT_SYMBOL(eip_poll);
33#endif 37#endif
34 38
35struct net_device *__alloc_eip_netdev(int size) 39struct net_device *__alloc_eip_netdev(int size)
36{ 40{
37 return ____alloc_ei_netdev(size); 41 return ____alloc_ei_netdev(size);
38} 42}
43EXPORT_SYMBOL(__alloc_eip_netdev);
39 44
40void NS8390p_init(struct net_device *dev, int startp) 45void NS8390p_init(struct net_device *dev, int startp)
41{ 46{
42 return __NS8390_init(dev, startp); 47 __NS8390_init(dev, startp);
43} 48}
44
45EXPORT_SYMBOL(eip_open);
46EXPORT_SYMBOL(eip_close);
47EXPORT_SYMBOL(eip_interrupt);
48#ifdef CONFIG_NET_POLL_CONTROLLER
49EXPORT_SYMBOL(eip_poll);
50#endif
51EXPORT_SYMBOL(NS8390p_init); 49EXPORT_SYMBOL(NS8390p_init);
52EXPORT_SYMBOL(__alloc_eip_netdev);
53 50
54#if defined(MODULE) 51#if defined(MODULE)
55 52
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8a03875ec877..a5c141cecd4e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -510,14 +510,15 @@ config STNIC
510config SH_ETH 510config SH_ETH
511 tristate "Renesas SuperH Ethernet support" 511 tristate "Renesas SuperH Ethernet support"
512 depends on SUPERH && \ 512 depends on SUPERH && \
513 (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763) 513 (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763 || \
514 CPU_SUBTYPE_SH7619)
514 select CRC32 515 select CRC32
515 select MII 516 select MII
516 select MDIO_BITBANG 517 select MDIO_BITBANG
517 select PHYLIB 518 select PHYLIB
518 help 519 help
519 Renesas SuperH Ethernet device driver. 520 Renesas SuperH Ethernet device driver.
520 This driver support SH7710, SH7712 and SH7763. 521 This driver support SH7710, SH7712, SH7763 and SH7619.
521 522
522config SUNLANCE 523config SUNLANCE
523 tristate "Sun LANCE support" 524 tristate "Sun LANCE support"
@@ -1171,7 +1172,7 @@ config ETH16I
1171 1172
1172config NE2000 1173config NE2000
1173 tristate "NE2000/NE1000 support" 1174 tristate "NE2000/NE1000 support"
1174 depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938 1175 depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
1175 select CRC32 1176 select CRC32
1176 ---help--- 1177 ---help---
1177 If you have a network (Ethernet) card of this type, say Y and read 1178 If you have a network (Ethernet) card of this type, say Y and read
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index e4483de84e7f..66de80b64b92 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -52,7 +52,6 @@
52 52
53#include <linux/module.h> 53#include <linux/module.h>
54#include <linux/moduleparam.h> 54#include <linux/moduleparam.h>
55#include <linux/version.h>
56#include <linux/types.h> 55#include <linux/types.h>
57#include <linux/errno.h> 56#include <linux/errno.h>
58#include <linux/ioport.h> 57#include <linux/ioport.h>
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index a637910b02dd..aa4a5246be53 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -28,7 +28,7 @@
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30 30
31#include <asm/hardware.h> 31#include <mach/hardware.h>
32#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/system.h> 33#include <asm/system.h>
34 34
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index ffae266e2d7f..0fa53464efb2 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -32,9 +32,9 @@
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34 34
35#include <asm/arch/at91rm9200_emac.h> 35#include <mach/at91rm9200_emac.h>
36#include <asm/arch/gpio.h> 36#include <mach/gpio.h>
37#include <asm/arch/board.h> 37#include <mach/board.h>
38 38
39#include "at91_ether.h" 39#include "at91_ether.h"
40 40
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 18d3eeb7eab2..1267444d79da 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -20,8 +20,8 @@
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <asm/arch/ep93xx-regs.h> 23#include <mach/ep93xx-regs.h>
24#include <asm/arch/platform.h> 24#include <mach/platform.h>
25#include <asm/io.h> 25#include <asm/io.h>
26 26
27#define DRV_MODULE_NAME "ep93xx-eth" 27#define DRV_MODULE_NAME "ep93xx-eth"
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 9b777d9433cd..e2d702b8b2e4 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -32,8 +32,8 @@
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/mii.h> 33#include <linux/mii.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <asm/arch/npe.h> 35#include <mach/npe.h>
36#include <asm/arch/qmgr.h> 36#include <mach/qmgr.h>
37 37
38#define DEBUG_QUEUES 0 38#define DEBUG_QUEUES 0
39#define DEBUG_DESC 0 39#define DEBUG_DESC 0
@@ -551,7 +551,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
551 if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) { 551 if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) {
552 phys = dma_map_single(&dev->dev, skb->data, 552 phys = dma_map_single(&dev->dev, skb->data,
553 RX_BUFF_SIZE, DMA_FROM_DEVICE); 553 RX_BUFF_SIZE, DMA_FROM_DEVICE);
554 if (dma_mapping_error(phys)) { 554 if (dma_mapping_error(&dev->dev, phys)) {
555 dev_kfree_skb(skb); 555 dev_kfree_skb(skb);
556 skb = NULL; 556 skb = NULL;
557 } 557 }
@@ -698,7 +698,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
698#endif 698#endif
699 699
700 phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE); 700 phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
701 if (dma_mapping_error(phys)) { 701 if (dma_mapping_error(&dev->dev, phys)) {
702#ifdef __ARMEB__ 702#ifdef __ARMEB__
703 dev_kfree_skb(skb); 703 dev_kfree_skb(skb);
704#else 704#else
@@ -883,7 +883,7 @@ static int init_queues(struct port *port)
883 desc->buf_len = MAX_MRU; 883 desc->buf_len = MAX_MRU;
884 desc->data = dma_map_single(&port->netdev->dev, data, 884 desc->data = dma_map_single(&port->netdev->dev, data,
885 RX_BUFF_SIZE, DMA_FROM_DEVICE); 885 RX_BUFF_SIZE, DMA_FROM_DEVICE);
886 if (dma_mapping_error(desc->data)) { 886 if (dma_mapping_error(&port->netdev->dev, desc->data)) {
887 free_buffer(buff); 887 free_buffer(buff);
888 return -EIO; 888 return -EIO;
889 } 889 }
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index cdc3b85b10b9..619c6583e1aa 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -355,7 +355,7 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
355 struct atl1e_adapter *adapter = netdev_priv(netdev); 355 struct atl1e_adapter *adapter = netdev_priv(netdev);
356 356
357 if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | 357 if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
358 WAKE_MCAST | WAKE_BCAST | WAKE_MCAST)) 358 WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
359 return -EOPNOTSUPP; 359 return -EOPNOTSUPP;
360 /* these settings will always override what we currently have */ 360 /* these settings will always override what we currently have */
361 adapter->wol = 0; 361 adapter->wol = 0;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 35264c244cfd..82d7be1655d3 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -47,7 +47,7 @@ MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
47MODULE_LICENSE("GPL"); 47MODULE_LICENSE("GPL");
48MODULE_VERSION(DRV_VERSION); 48MODULE_VERSION(DRV_VERSION);
49 49
50static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter); 50static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter);
51 51
52static const u16 52static const u16
53atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] = 53atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
@@ -1037,7 +1037,7 @@ static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
1037 return; 1037 return;
1038} 1038}
1039 1039
1040static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter) 1040static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
1041{ 1041{
1042 u32 value; 1042 u32 value;
1043 struct atl1e_hw *hw = &adapter->hw; 1043 struct atl1e_hw *hw = &adapter->hw;
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index f12e3d12474b..e6a7bb79d4df 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1790,6 +1790,17 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
1790{ 1790{
1791 struct pci_dev *pdev = adapter->pdev; 1791 struct pci_dev *pdev = adapter->pdev;
1792 1792
1793 /*
1794 * The L1 hardware contains a bug that erroneously sets the
1795 * PACKET_FLAG_ERR and ERR_FLAG_L4_CHKSUM bits whenever a
1796 * fragmented IP packet is received, even though the packet
1797 * is perfectly valid and its checksum is correct. There's
1798 * no way to distinguish between one of these good packets
1799 * and a packet that actually contains a TCP/UDP checksum
1800 * error, so all we can do is allow it to be handed up to
1801 * the higher layers and let it be sorted out there.
1802 */
1803
1793 skb->ip_summed = CHECKSUM_NONE; 1804 skb->ip_summed = CHECKSUM_NONE;
1794 1805
1795 if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { 1806 if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
@@ -1816,14 +1827,6 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
1816 return; 1827 return;
1817 } 1828 }
1818 1829
1819 /* IPv4, but hardware thinks its checksum is wrong */
1820 if (netif_msg_rx_err(adapter))
1821 dev_printk(KERN_DEBUG, &pdev->dev,
1822 "hw csum wrong, pkt_flag:%x, err_flag:%x\n",
1823 rrd->pkt_flg, rrd->err_flg);
1824 skb->ip_summed = CHECKSUM_COMPLETE;
1825 skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
1826 adapter->hw_csum_err++;
1827 return; 1830 return;
1828} 1831}
1829 1832
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index 3d4433358a36..c10cd8058e23 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -854,14 +854,9 @@ static void set_rx_mode_8002(struct net_device *dev)
854 struct net_local *lp = netdev_priv(dev); 854 struct net_local *lp = netdev_priv(dev);
855 long ioaddr = dev->base_addr; 855 long ioaddr = dev->base_addr;
856 856
857 if ( dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC))) { 857 if (dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
858 /* We must make the kernel realise we had to move
859 * into promisc mode or we start all out war on
860 * the cable. - AC
861 */
862 dev->flags|=IFF_PROMISC;
863 lp->addr_mode = CMR2h_PROMISC; 858 lp->addr_mode = CMR2h_PROMISC;
864 } else 859 else
865 lp->addr_mode = CMR2h_Normal; 860 lp->addr_mode = CMR2h_Normal;
866 write_reg_high(ioaddr, CMR2, lp->addr_mode); 861 write_reg_high(ioaddr, CMR2, lp->addr_mode);
867} 862}
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index cb8be490e5ae..5ee1b0557a02 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -807,7 +807,7 @@ err_out:
807static int au1000_init(struct net_device *dev) 807static int au1000_init(struct net_device *dev)
808{ 808{
809 struct au1000_private *aup = (struct au1000_private *) dev->priv; 809 struct au1000_private *aup = (struct au1000_private *) dev->priv;
810 u32 flags; 810 unsigned long flags;
811 int i; 811 int i;
812 u32 control; 812 u32 control;
813 813
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 0b4adf4a0f7d..a886a4b9f7e5 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -554,7 +554,7 @@ static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
554 554
555 spin_lock_irqsave(&ax->mii_lock, flags); 555 spin_lock_irqsave(&ax->mii_lock, flags);
556 mii_ethtool_gset(&ax->mii, cmd); 556 mii_ethtool_gset(&ax->mii, cmd);
557 spin_lock_irqsave(&ax->mii_lock, flags); 557 spin_unlock_irqrestore(&ax->mii_lock, flags);
558 558
559 return 0; 559 return 0;
560} 560}
@@ -567,7 +567,7 @@ static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
567 567
568 spin_lock_irqsave(&ax->mii_lock, flags); 568 spin_lock_irqsave(&ax->mii_lock, flags);
569 rc = mii_ethtool_sset(&ax->mii, cmd); 569 rc = mii_ethtool_sset(&ax->mii, cmd);
570 spin_lock_irqsave(&ax->mii_lock, flags); 570 spin_unlock_irqrestore(&ax->mii_lock, flags);
571 571
572 return rc; 572 return rc;
573} 573}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 5ebde67d4297..2486a656f12d 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -35,8 +35,8 @@
35#include <linux/time.h> 35#include <linux/time.h>
36#include <linux/ethtool.h> 36#include <linux/ethtool.h>
37#include <linux/mii.h> 37#include <linux/mii.h>
38#ifdef NETIF_F_HW_VLAN_TX
39#include <linux/if_vlan.h> 38#include <linux/if_vlan.h>
39#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
40#define BCM_VLAN 1 40#define BCM_VLAN 1
41#endif 41#endif
42#include <net/ip.h> 42#include <net/ip.h>
@@ -57,8 +57,8 @@
57 57
58#define DRV_MODULE_NAME "bnx2" 58#define DRV_MODULE_NAME "bnx2"
59#define PFX DRV_MODULE_NAME ": " 59#define PFX DRV_MODULE_NAME ": "
60#define DRV_MODULE_VERSION "1.7.9" 60#define DRV_MODULE_VERSION "1.8.0"
61#define DRV_MODULE_RELDATE "July 18, 2008" 61#define DRV_MODULE_RELDATE "Aug 14, 2008"
62 62
63#define RUN_AT(x) (jiffies + (x)) 63#define RUN_AT(x) (jiffies + (x))
64 64
@@ -2876,6 +2876,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2876 struct sw_bd *rx_buf; 2876 struct sw_bd *rx_buf;
2877 struct sk_buff *skb; 2877 struct sk_buff *skb;
2878 dma_addr_t dma_addr; 2878 dma_addr_t dma_addr;
2879 u16 vtag = 0;
2880 int hw_vlan __maybe_unused = 0;
2879 2881
2880 sw_ring_cons = RX_RING_IDX(sw_cons); 2882 sw_ring_cons = RX_RING_IDX(sw_cons);
2881 sw_ring_prod = RX_RING_IDX(sw_prod); 2883 sw_ring_prod = RX_RING_IDX(sw_prod);
@@ -2919,7 +2921,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2919 if (len <= bp->rx_copy_thresh) { 2921 if (len <= bp->rx_copy_thresh) {
2920 struct sk_buff *new_skb; 2922 struct sk_buff *new_skb;
2921 2923
2922 new_skb = netdev_alloc_skb(bp->dev, len + 2); 2924 new_skb = netdev_alloc_skb(bp->dev, len + 6);
2923 if (new_skb == NULL) { 2925 if (new_skb == NULL) {
2924 bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons, 2926 bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
2925 sw_ring_prod); 2927 sw_ring_prod);
@@ -2928,9 +2930,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2928 2930
2929 /* aligned copy */ 2931 /* aligned copy */
2930 skb_copy_from_linear_data_offset(skb, 2932 skb_copy_from_linear_data_offset(skb,
2931 BNX2_RX_OFFSET - 2, 2933 BNX2_RX_OFFSET - 6,
2932 new_skb->data, len + 2); 2934 new_skb->data, len + 6);
2933 skb_reserve(new_skb, 2); 2935 skb_reserve(new_skb, 6);
2934 skb_put(new_skb, len); 2936 skb_put(new_skb, len);
2935 2937
2936 bnx2_reuse_rx_skb(bp, rxr, skb, 2938 bnx2_reuse_rx_skb(bp, rxr, skb,
@@ -2941,6 +2943,25 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2941 dma_addr, (sw_ring_cons << 16) | sw_ring_prod))) 2943 dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
2942 goto next_rx; 2944 goto next_rx;
2943 2945
2946 if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
2947 !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
2948 vtag = rx_hdr->l2_fhdr_vlan_tag;
2949#ifdef BCM_VLAN
2950 if (bp->vlgrp)
2951 hw_vlan = 1;
2952 else
2953#endif
2954 {
2955 struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
2956 __skb_push(skb, 4);
2957
2958 memmove(ve, skb->data + 4, ETH_ALEN * 2);
2959 ve->h_vlan_proto = htons(ETH_P_8021Q);
2960 ve->h_vlan_TCI = htons(vtag);
2961 len += 4;
2962 }
2963 }
2964
2944 skb->protocol = eth_type_trans(skb, bp->dev); 2965 skb->protocol = eth_type_trans(skb, bp->dev);
2945 2966
2946 if ((len > (bp->dev->mtu + ETH_HLEN)) && 2967 if ((len > (bp->dev->mtu + ETH_HLEN)) &&
@@ -2962,10 +2983,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
2962 } 2983 }
2963 2984
2964#ifdef BCM_VLAN 2985#ifdef BCM_VLAN
2965 if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) { 2986 if (hw_vlan)
2966 vlan_hwaccel_receive_skb(skb, bp->vlgrp, 2987 vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
2967 rx_hdr->l2_fhdr_vlan_tag);
2968 }
2969 else 2988 else
2970#endif 2989#endif
2971 netif_receive_skb(skb); 2990 netif_receive_skb(skb);
@@ -3237,10 +3256,10 @@ bnx2_set_rx_mode(struct net_device *dev)
3237 BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); 3256 BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
3238 sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; 3257 sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
3239#ifdef BCM_VLAN 3258#ifdef BCM_VLAN
3240 if (!bp->vlgrp && !(bp->flags & BNX2_FLAG_ASF_ENABLE)) 3259 if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
3241 rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; 3260 rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
3242#else 3261#else
3243 if (!(bp->flags & BNX2_FLAG_ASF_ENABLE)) 3262 if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
3244 rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; 3263 rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
3245#endif 3264#endif
3246 if (dev->flags & IFF_PROMISC) { 3265 if (dev->flags & IFF_PROMISC) {
@@ -5963,10 +5982,12 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
5963 vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; 5982 vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
5964 } 5983 }
5965 5984
5985#ifdef BCM_VLAN
5966 if (bp->vlgrp && vlan_tx_tag_present(skb)) { 5986 if (bp->vlgrp && vlan_tx_tag_present(skb)) {
5967 vlan_tag_flags |= 5987 vlan_tag_flags |=
5968 (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); 5988 (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
5969 } 5989 }
5990#endif
5970 if ((mss = skb_shinfo(skb)->gso_size)) { 5991 if ((mss = skb_shinfo(skb)->gso_size)) {
5971 u32 tcp_opt_len, ip_tcp_len; 5992 u32 tcp_opt_len, ip_tcp_len;
5972 struct iphdr *iph; 5993 struct iphdr *iph;
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 4bf4f7b205f2..b468f904c7f8 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -40,20 +40,20 @@
40#define DP(__mask, __fmt, __args...) do { \ 40#define DP(__mask, __fmt, __args...) do { \
41 if (bp->msglevel & (__mask)) \ 41 if (bp->msglevel & (__mask)) \
42 printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __func__, __LINE__, \ 42 printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
43 bp->dev?(bp->dev->name):"?", ##__args); \ 43 bp->dev ? (bp->dev->name) : "?", ##__args); \
44 } while (0) 44 } while (0)
45 45
46/* errors debug print */ 46/* errors debug print */
47#define BNX2X_DBG_ERR(__fmt, __args...) do { \ 47#define BNX2X_DBG_ERR(__fmt, __args...) do { \
48 if (bp->msglevel & NETIF_MSG_PROBE) \ 48 if (bp->msglevel & NETIF_MSG_PROBE) \
49 printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \ 49 printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
50 bp->dev?(bp->dev->name):"?", ##__args); \ 50 bp->dev ? (bp->dev->name) : "?", ##__args); \
51 } while (0) 51 } while (0)
52 52
53/* for errors (never masked) */ 53/* for errors (never masked) */
54#define BNX2X_ERR(__fmt, __args...) do { \ 54#define BNX2X_ERR(__fmt, __args...) do { \
55 printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \ 55 printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
56 bp->dev?(bp->dev->name):"?", ##__args); \ 56 bp->dev ? (bp->dev->name) : "?", ##__args); \
57 } while (0) 57 } while (0)
58 58
59/* before we have a dev->name use dev_info() */ 59/* before we have a dev->name use dev_info() */
@@ -120,16 +120,8 @@
120#define SHMEM_RD(bp, field) REG_RD(bp, SHMEM_ADDR(bp, field)) 120#define SHMEM_RD(bp, field) REG_RD(bp, SHMEM_ADDR(bp, field))
121#define SHMEM_WR(bp, field, val) REG_WR(bp, SHMEM_ADDR(bp, field), val) 121#define SHMEM_WR(bp, field, val) REG_WR(bp, SHMEM_ADDR(bp, field), val)
122 122
123#define NIG_WR(reg, val) REG_WR(bp, reg, val) 123#define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg)
124#define EMAC_WR(reg, val) REG_WR(bp, emac_base + reg, val) 124#define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val)
125#define BMAC_WR(reg, val) REG_WR(bp, GRCBASE_NIG + bmac_addr + reg, val)
126
127
128#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
129
130#define for_each_nondefault_queue(bp, var) \
131 for (var = 1; var < bp->num_queues; var++)
132#define is_multi(bp) (bp->num_queues > 1)
133 125
134 126
135/* fast path */ 127/* fast path */
@@ -163,7 +155,7 @@ struct sw_rx_page {
163#define NUM_RX_SGE_PAGES 2 155#define NUM_RX_SGE_PAGES 2
164#define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge)) 156#define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
165#define MAX_RX_SGE_CNT (RX_SGE_CNT - 2) 157#define MAX_RX_SGE_CNT (RX_SGE_CNT - 2)
166/* RX_SGE_CNT is promissed to be a power of 2 */ 158/* RX_SGE_CNT is promised to be a power of 2 */
167#define RX_SGE_MASK (RX_SGE_CNT - 1) 159#define RX_SGE_MASK (RX_SGE_CNT - 1)
168#define NUM_RX_SGE (RX_SGE_CNT * NUM_RX_SGE_PAGES) 160#define NUM_RX_SGE (RX_SGE_CNT * NUM_RX_SGE_PAGES)
169#define MAX_RX_SGE (NUM_RX_SGE - 1) 161#define MAX_RX_SGE (NUM_RX_SGE - 1)
@@ -258,8 +250,7 @@ struct bnx2x_fastpath {
258 250
259 unsigned long tx_pkt, 251 unsigned long tx_pkt,
260 rx_pkt, 252 rx_pkt,
261 rx_calls, 253 rx_calls;
262 rx_alloc_failed;
263 /* TPA related */ 254 /* TPA related */
264 struct sw_rx_bd tpa_pool[ETH_MAX_AGGREGATION_QUEUES_E1H]; 255 struct sw_rx_bd tpa_pool[ETH_MAX_AGGREGATION_QUEUES_E1H];
265 u8 tpa_state[ETH_MAX_AGGREGATION_QUEUES_E1H]; 256 u8 tpa_state[ETH_MAX_AGGREGATION_QUEUES_E1H];
@@ -275,6 +266,15 @@ struct bnx2x_fastpath {
275 266
276#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) 267#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
277 268
269#define BNX2X_HAS_TX_WORK(fp) \
270 ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \
271 (fp->tx_pkt_prod != fp->tx_pkt_cons))
272
273#define BNX2X_HAS_RX_WORK(fp) \
274 (fp->rx_comp_cons != le16_to_cpu(*fp->rx_cons_sb))
275
276#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
277
278 278
279/* MC hsi */ 279/* MC hsi */
280#define MAX_FETCH_BD 13 /* HW max BDs per packet */ 280#define MAX_FETCH_BD 13 /* HW max BDs per packet */
@@ -317,7 +317,7 @@ struct bnx2x_fastpath {
317#define RCQ_BD(x) ((x) & MAX_RCQ_BD) 317#define RCQ_BD(x) ((x) & MAX_RCQ_BD)
318 318
319 319
320/* This is needed for determening of last_max */ 320/* This is needed for determining of last_max */
321#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b)) 321#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b))
322 322
323#define __SGE_MASK_SET_BIT(el, bit) \ 323#define __SGE_MASK_SET_BIT(el, bit) \
@@ -386,20 +386,28 @@ struct bnx2x_fastpath {
386#define TPA_TYPE(cqe_fp_flags) ((cqe_fp_flags) & \ 386#define TPA_TYPE(cqe_fp_flags) ((cqe_fp_flags) & \
387 (TPA_TYPE_START | TPA_TYPE_END)) 387 (TPA_TYPE_START | TPA_TYPE_END))
388 388
389#define BNX2X_RX_SUM_OK(cqe) \ 389#define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG
390 (!(cqe->fast_path_cqe.status_flags & \ 390
391 (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | \ 391#define BNX2X_IP_CSUM_ERR(cqe) \
392 ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG))) 392 (!((cqe)->fast_path_cqe.status_flags & \
393 ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG) && \
394 ((cqe)->fast_path_cqe.type_error_flags & \
395 ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG))
396
397#define BNX2X_L4_CSUM_ERR(cqe) \
398 (!((cqe)->fast_path_cqe.status_flags & \
399 ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) && \
400 ((cqe)->fast_path_cqe.type_error_flags & \
401 ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG))
402
403#define BNX2X_RX_CSUM_OK(cqe) \
404 (!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe)))
393 405
394#define BNX2X_RX_SUM_FIX(cqe) \ 406#define BNX2X_RX_SUM_FIX(cqe) \
395 ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \ 407 ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
396 PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \ 408 PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
397 (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT)) 409 (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
398 410
399#define ETH_RX_ERROR_FALGS (ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG | \
400 ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | \
401 ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)
402
403 411
404#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES) 412#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES)
405#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES) 413#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES)
@@ -647,6 +655,8 @@ struct bnx2x_eth_stats {
647 655
648 u32 brb_drop_hi; 656 u32 brb_drop_hi;
649 u32 brb_drop_lo; 657 u32 brb_drop_lo;
658 u32 brb_truncate_hi;
659 u32 brb_truncate_lo;
650 660
651 u32 jabber_packets_received; 661 u32 jabber_packets_received;
652 662
@@ -663,6 +673,9 @@ struct bnx2x_eth_stats {
663 u32 mac_discard; 673 u32 mac_discard;
664 674
665 u32 driver_xoff; 675 u32 driver_xoff;
676 u32 rx_err_discard_pkt;
677 u32 rx_skb_alloc_failed;
678 u32 hw_csum_err;
666}; 679};
667 680
668#define STATS_OFFSET32(stat_name) \ 681#define STATS_OFFSET32(stat_name) \
@@ -753,7 +766,6 @@ struct bnx2x {
753 u16 def_att_idx; 766 u16 def_att_idx;
754 u32 attn_state; 767 u32 attn_state;
755 struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS]; 768 struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
756 u32 aeu_mask;
757 u32 nig_mask; 769 u32 nig_mask;
758 770
759 /* slow path ring */ 771 /* slow path ring */
@@ -772,7 +784,7 @@ struct bnx2x {
772 u8 stats_pending; 784 u8 stats_pending;
773 u8 set_mac_pending; 785 u8 set_mac_pending;
774 786
775 /* End of fileds used in the performance code paths */ 787 /* End of fields used in the performance code paths */
776 788
777 int panic; 789 int panic;
778 int msglevel; 790 int msglevel;
@@ -794,9 +806,6 @@ struct bnx2x {
794#define BP_FUNC(bp) (bp->func) 806#define BP_FUNC(bp) (bp->func)
795#define BP_E1HVN(bp) (bp->func >> 1) 807#define BP_E1HVN(bp) (bp->func >> 1)
796#define BP_L_ID(bp) (BP_E1HVN(bp) << 2) 808#define BP_L_ID(bp) (BP_E1HVN(bp) << 2)
797/* assorted E1HVN */
798#define IS_E1HMF(bp) (bp->e1hmf != 0)
799#define BP_MAX_QUEUES(bp) (IS_E1HMF(bp) ? 4 : 16)
800 809
801 int pm_cap; 810 int pm_cap;
802 int pcie_cap; 811 int pcie_cap;
@@ -821,6 +830,7 @@ struct bnx2x {
821 u32 mf_config; 830 u32 mf_config;
822 u16 e1hov; 831 u16 e1hov;
823 u8 e1hmf; 832 u8 e1hmf;
833#define IS_E1HMF(bp) (bp->e1hmf != 0)
824 834
825 u8 wol; 835 u8 wol;
826 836
@@ -836,7 +846,6 @@ struct bnx2x {
836 u16 rx_ticks_int; 846 u16 rx_ticks_int;
837 u16 rx_ticks; 847 u16 rx_ticks;
838 848
839 u32 stats_ticks;
840 u32 lin_cnt; 849 u32 lin_cnt;
841 850
842 int state; 851 int state;
@@ -852,6 +861,7 @@ struct bnx2x {
852#define BNX2X_STATE_ERROR 0xf000 861#define BNX2X_STATE_ERROR 0xf000
853 862
854 int num_queues; 863 int num_queues;
864#define BP_MAX_QUEUES(bp) (IS_E1HMF(bp) ? 4 : 16)
855 865
856 u32 rx_mode; 866 u32 rx_mode;
857#define BNX2X_RX_MODE_NONE 0 867#define BNX2X_RX_MODE_NONE 0
@@ -902,10 +912,17 @@ struct bnx2x {
902}; 912};
903 913
904 914
915#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
916
917#define for_each_nondefault_queue(bp, var) \
918 for (var = 1; var < bp->num_queues; var++)
919#define is_multi(bp) (bp->num_queues > 1)
920
921
905void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); 922void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
906void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, 923void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
907 u32 len32); 924 u32 len32);
908int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode); 925int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
909 926
910static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, 927static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
911 int wait) 928 int wait)
@@ -976,7 +993,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
976#define PCICFG_LINK_SPEED_SHIFT 16 993#define PCICFG_LINK_SPEED_SHIFT 16
977 994
978 995
979#define BNX2X_NUM_STATS 39 996#define BNX2X_NUM_STATS 42
980#define BNX2X_NUM_TESTS 8 997#define BNX2X_NUM_TESTS 8
981 998
982#define BNX2X_MAC_LOOPBACK 0 999#define BNX2X_MAC_LOOPBACK 0
@@ -1007,10 +1024,10 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
1007/* resolution of the rate shaping timer - 100 usec */ 1024/* resolution of the rate shaping timer - 100 usec */
1008#define RS_PERIODIC_TIMEOUT_USEC 100 1025#define RS_PERIODIC_TIMEOUT_USEC 100
1009/* resolution of fairness algorithm in usecs - 1026/* resolution of fairness algorithm in usecs -
1010 coefficient for clauclating the actuall t fair */ 1027 coefficient for calculating the actual t fair */
1011#define T_FAIR_COEF 10000000 1028#define T_FAIR_COEF 10000000
1012/* number of bytes in single QM arbitration cycle - 1029/* number of bytes in single QM arbitration cycle -
1013 coeffiecnt for calculating the fairness timer */ 1030 coefficient for calculating the fairness timer */
1014#define QM_ARB_BYTES 40000 1031#define QM_ARB_BYTES 40000
1015#define FAIR_MEM 2 1032#define FAIR_MEM 2
1016 1033
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
index e3da7f69d27b..192fa981b930 100644
--- a/drivers/net/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x_fw_defs.h
@@ -9,165 +9,171 @@
9 9
10 10
11#define CSTORM_ASSERT_LIST_INDEX_OFFSET \ 11#define CSTORM_ASSERT_LIST_INDEX_OFFSET \
12 (IS_E1H_OFFSET? 0x7000 : 0x1000) 12 (IS_E1H_OFFSET ? 0x7000 : 0x1000)
13#define CSTORM_ASSERT_LIST_OFFSET(idx) \ 13#define CSTORM_ASSERT_LIST_OFFSET(idx) \
14 (IS_E1H_OFFSET? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) 14 (IS_E1H_OFFSET ? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
15#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ 15#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
16 (IS_E1H_OFFSET? (0x8522 + ((function>>1) * 0x40) + ((function&1) \ 16 (IS_E1H_OFFSET ? (0x8522 + ((function>>1) * 0x40) + \
17 * 0x100) + (index * 0x4)) : (0x1922 + (function * 0x40) + (index \ 17 ((function&1) * 0x100) + (index * 0x4)) : (0x1922 + (function * \
18 * 0x4))) 18 0x40) + (index * 0x4)))
19#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ 19#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
20 (IS_E1H_OFFSET? (0x8500 + ((function>>1) * 0x40) + ((function&1) \ 20 (IS_E1H_OFFSET ? (0x8500 + ((function>>1) * 0x40) + \
21 * 0x100)) : (0x1900 + (function * 0x40))) 21 ((function&1) * 0x100)) : (0x1900 + (function * 0x40)))
22#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ 22#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
23 (IS_E1H_OFFSET? (0x8508 + ((function>>1) * 0x40) + ((function&1) \ 23 (IS_E1H_OFFSET ? (0x8508 + ((function>>1) * 0x40) + \
24 * 0x100)) : (0x1908 + (function * 0x40))) 24 ((function&1) * 0x100)) : (0x1908 + (function * 0x40)))
25#define CSTORM_FUNCTION_MODE_OFFSET \ 25#define CSTORM_FUNCTION_MODE_OFFSET \
26 (IS_E1H_OFFSET? 0x11e8 : 0xffffffff) 26 (IS_E1H_OFFSET ? 0x11e8 : 0xffffffff)
27#define CSTORM_HC_BTR_OFFSET(port) \ 27#define CSTORM_HC_BTR_OFFSET(port) \
28 (IS_E1H_OFFSET? (0x8704 + (port * 0xf0)) : (0x1984 + (port * 0xc0))) 28 (IS_E1H_OFFSET ? (0x8704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
29#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \ 29#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
30 (IS_E1H_OFFSET? (0x801a + (port * 0x280) + (cpu_id * 0x28) + \ 30 (IS_E1H_OFFSET ? (0x801a + (port * 0x280) + (cpu_id * 0x28) + \
31 (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \ 31 (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
32 (index * 0x4))) 32 (index * 0x4)))
33#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \ 33#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
34 (IS_E1H_OFFSET? (0x8018 + (port * 0x280) + (cpu_id * 0x28) + \ 34 (IS_E1H_OFFSET ? (0x8018 + (port * 0x280) + (cpu_id * 0x28) + \
35 (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \ 35 (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
36 (index * 0x4))) 36 (index * 0x4)))
37#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \ 37#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
38 (IS_E1H_OFFSET? (0x8000 + (port * 0x280) + (cpu_id * 0x28)) : \ 38 (IS_E1H_OFFSET ? (0x8000 + (port * 0x280) + (cpu_id * 0x28)) : \
39 (0x1400 + (port * 0x280) + (cpu_id * 0x28))) 39 (0x1400 + (port * 0x280) + (cpu_id * 0x28)))
40#define CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \ 40#define CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
41 (IS_E1H_OFFSET? (0x8008 + (port * 0x280) + (cpu_id * 0x28)) : \ 41 (IS_E1H_OFFSET ? (0x8008 + (port * 0x280) + (cpu_id * 0x28)) : \
42 (0x1408 + (port * 0x280) + (cpu_id * 0x28))) 42 (0x1408 + (port * 0x280) + (cpu_id * 0x28)))
43#define CSTORM_STATS_FLAGS_OFFSET(function) \ 43#define CSTORM_STATS_FLAGS_OFFSET(function) \
44 (IS_E1H_OFFSET? (0x1108 + (function * 0x8)) : (0x5108 + \ 44 (IS_E1H_OFFSET ? (0x1108 + (function * 0x8)) : (0x5108 + \
45 (function * 0x8))) 45 (function * 0x8)))
46#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \ 46#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \
47 (IS_E1H_OFFSET? (0x31c0 + (function * 0x20)) : 0xffffffff) 47 (IS_E1H_OFFSET ? (0x31c0 + (function * 0x20)) : 0xffffffff)
48#define TSTORM_ASSERT_LIST_INDEX_OFFSET \ 48#define TSTORM_ASSERT_LIST_INDEX_OFFSET \
49 (IS_E1H_OFFSET? 0xa000 : 0x1000) 49 (IS_E1H_OFFSET ? 0xa000 : 0x1000)
50#define TSTORM_ASSERT_LIST_OFFSET(idx) \ 50#define TSTORM_ASSERT_LIST_OFFSET(idx) \
51 (IS_E1H_OFFSET? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) 51 (IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
52#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \ 52#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
53 (IS_E1H_OFFSET? (0x3358 + (port * 0x3e8) + (client_id * 0x28)) : \ 53 (IS_E1H_OFFSET ? (0x3358 + (port * 0x3e8) + (client_id * 0x28)) \
54 (0x9c8 + (port * 0x2f8) + (client_id * 0x28))) 54 : (0x9c8 + (port * 0x2f8) + (client_id * 0x28)))
55#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ 55#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
56 (IS_E1H_OFFSET? (0xb01a + ((function>>1) * 0x28) + ((function&1) \ 56 (IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \
57 * 0xa0) + (index * 0x4)) : (0x141a + (function * 0x28) + (index * \ 57 ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
58 0x4))) 58 0x28) + (index * 0x4)))
59#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ 59#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
60 (IS_E1H_OFFSET? (0xb000 + ((function>>1) * 0x28) + ((function&1) \ 60 (IS_E1H_OFFSET ? (0xb000 + ((function>>1) * 0x28) + \
61 * 0xa0)) : (0x1400 + (function * 0x28))) 61 ((function&1) * 0xa0)) : (0x1400 + (function * 0x28)))
62#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ 62#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
63 (IS_E1H_OFFSET? (0xb008 + ((function>>1) * 0x28) + ((function&1) \ 63 (IS_E1H_OFFSET ? (0xb008 + ((function>>1) * 0x28) + \
64 * 0xa0)) : (0x1408 + (function * 0x28))) 64 ((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
65#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ 65#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
66 (IS_E1H_OFFSET? (0x2b80 + (function * 0x8)) : (0x4b68 + \ 66 (IS_E1H_OFFSET ? (0x2b80 + (function * 0x8)) : (0x4b68 + \
67 (function * 0x8))) 67 (function * 0x8)))
68#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \ 68#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \
69 (IS_E1H_OFFSET? (0x3000 + (function * 0x38)) : (0x1500 + \ 69 (IS_E1H_OFFSET ? (0x3000 + (function * 0x38)) : (0x1500 + \
70 (function * 0x38))) 70 (function * 0x38)))
71#define TSTORM_FUNCTION_MODE_OFFSET \ 71#define TSTORM_FUNCTION_MODE_OFFSET \
72 (IS_E1H_OFFSET? 0x1ad0 : 0xffffffff) 72 (IS_E1H_OFFSET ? 0x1ad0 : 0xffffffff)
73#define TSTORM_HC_BTR_OFFSET(port) \ 73#define TSTORM_HC_BTR_OFFSET(port) \
74 (IS_E1H_OFFSET? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18))) 74 (IS_E1H_OFFSET ? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
75#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \ 75#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \
76 (IS_E1H_OFFSET? (0x12c8 + (function * 0x80)) : (0x22c8 + \ 76 (IS_E1H_OFFSET ? (0x12c8 + (function * 0x80)) : (0x22c8 + \
77 (function * 0x80))) 77 (function * 0x80)))
78#define TSTORM_INDIRECTION_TABLE_SIZE 0x80 78#define TSTORM_INDIRECTION_TABLE_SIZE 0x80
79#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \ 79#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \
80 (IS_E1H_OFFSET? (0x3008 + (function * 0x38)) : (0x1508 + \ 80 (IS_E1H_OFFSET ? (0x3008 + (function * 0x38)) : (0x1508 + \
81 (function * 0x38))) 81 (function * 0x38)))
82#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
83 (IS_E1H_OFFSET ? (0x2010 + (port * 0x5b0) + (stats_counter_id * \
84 0x50)) : (0x4000 + (port * 0x3f0) + (stats_counter_id * 0x38)))
82#define TSTORM_RX_PRODS_OFFSET(port, client_id) \ 85#define TSTORM_RX_PRODS_OFFSET(port, client_id) \
83 (IS_E1H_OFFSET? (0x3350 + (port * 0x3e8) + (client_id * 0x28)) : \ 86 (IS_E1H_OFFSET ? (0x3350 + (port * 0x3e8) + (client_id * 0x28)) \
84 (0x9c0 + (port * 0x2f8) + (client_id * 0x28))) 87 : (0x9c0 + (port * 0x2f8) + (client_id * 0x28)))
85#define TSTORM_STATS_FLAGS_OFFSET(function) \ 88#define TSTORM_STATS_FLAGS_OFFSET(function) \
86 (IS_E1H_OFFSET? (0x2c00 + (function * 0x8)) : (0x4b88 + \ 89 (IS_E1H_OFFSET ? (0x2c00 + (function * 0x8)) : (0x4b88 + \
87 (function * 0x8))) 90 (function * 0x8)))
88#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET? 0x3b30 : 0x1c20) 91#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3b30 : 0x1c20)
89#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET? 0xa040 : 0x2c10) 92#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa040 : 0x2c10)
90#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET? 0x2440 : 0x1200) 93#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2440 : 0x1200)
91#define USTORM_ASSERT_LIST_INDEX_OFFSET \ 94#define USTORM_ASSERT_LIST_INDEX_OFFSET \
92 (IS_E1H_OFFSET? 0x8000 : 0x1000) 95 (IS_E1H_OFFSET ? 0x8000 : 0x1000)
93#define USTORM_ASSERT_LIST_OFFSET(idx) \ 96#define USTORM_ASSERT_LIST_OFFSET(idx) \
94 (IS_E1H_OFFSET? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) 97 (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
95#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \ 98#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
96 (IS_E1H_OFFSET? (0x3298 + (port * 0x258) + (clientId * 0x18)) : \ 99 (IS_E1H_OFFSET ? (0x3298 + (port * 0x258) + (clientId * 0x18)) : \
97 (0x5450 + (port * 0x1c8) + (clientId * 0x18))) 100 (0x5450 + (port * 0x1c8) + (clientId * 0x18)))
98#define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ 101#define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
99 (IS_E1H_OFFSET? (0x951a + ((function>>1) * 0x28) + ((function&1) \ 102 (IS_E1H_OFFSET ? (0x951a + ((function>>1) * 0x28) + \
100 * 0xa0) + (index * 0x4)) : (0x191a + (function * 0x28) + (index * \ 103 ((function&1) * 0xa0) + (index * 0x4)) : (0x191a + (function * \
101 0x4))) 104 0x28) + (index * 0x4)))
102#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ 105#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
103 (IS_E1H_OFFSET? (0x9500 + ((function>>1) * 0x28) + ((function&1) \ 106 (IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x28) + \
104 * 0xa0)) : (0x1900 + (function * 0x28))) 107 ((function&1) * 0xa0)) : (0x1900 + (function * 0x28)))
105#define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ 108#define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
106 (IS_E1H_OFFSET? (0x9508 + ((function>>1) * 0x28) + ((function&1) \ 109 (IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x28) + \
107 * 0xa0)) : (0x1908 + (function * 0x28))) 110 ((function&1) * 0xa0)) : (0x1908 + (function * 0x28)))
108#define USTORM_FUNCTION_MODE_OFFSET \ 111#define USTORM_FUNCTION_MODE_OFFSET \
109 (IS_E1H_OFFSET? 0x2448 : 0xffffffff) 112 (IS_E1H_OFFSET ? 0x2448 : 0xffffffff)
110#define USTORM_HC_BTR_OFFSET(port) \ 113#define USTORM_HC_BTR_OFFSET(port) \
111 (IS_E1H_OFFSET? (0x9644 + (port * 0xd0)) : (0x1954 + (port * 0xb8))) 114 (IS_E1H_OFFSET ? (0x9644 + (port * 0xd0)) : (0x1954 + (port * 0xb8)))
112#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \ 115#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
113 (IS_E1H_OFFSET? (0x3290 + (port * 0x258) + (clientId * 0x18)) : \ 116 (IS_E1H_OFFSET ? (0x3290 + (port * 0x258) + (clientId * 0x18)) : \
114 (0x5448 + (port * 0x1c8) + (clientId * 0x18))) 117 (0x5448 + (port * 0x1c8) + (clientId * 0x18)))
115#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \ 118#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
116 (IS_E1H_OFFSET? (0x2408 + (function * 0x8)) : (0x5408 + \ 119 (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5408 + \
117 (function * 0x8))) 120 (function * 0x8)))
118#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \ 121#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
119 (IS_E1H_OFFSET? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \ 122 (IS_E1H_OFFSET ? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \
120 (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \ 123 (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
121 (index * 0x4))) 124 (index * 0x4)))
122#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \ 125#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
123 (IS_E1H_OFFSET? (0x9018 + (port * 0x280) + (cpu_id * 0x28) + \ 126 (IS_E1H_OFFSET ? (0x9018 + (port * 0x280) + (cpu_id * 0x28) + \
124 (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \ 127 (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
125 (index * 0x4))) 128 (index * 0x4)))
126#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \ 129#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
127 (IS_E1H_OFFSET? (0x9000 + (port * 0x280) + (cpu_id * 0x28)) : \ 130 (IS_E1H_OFFSET ? (0x9000 + (port * 0x280) + (cpu_id * 0x28)) : \
128 (0x1400 + (port * 0x280) + (cpu_id * 0x28))) 131 (0x1400 + (port * 0x280) + (cpu_id * 0x28)))
129#define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \ 132#define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
130 (IS_E1H_OFFSET? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \ 133 (IS_E1H_OFFSET ? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \
131 (0x1408 + (port * 0x280) + (cpu_id * 0x28))) 134 (0x1408 + (port * 0x280) + (cpu_id * 0x28)))
132#define XSTORM_ASSERT_LIST_INDEX_OFFSET \ 135#define XSTORM_ASSERT_LIST_INDEX_OFFSET \
133 (IS_E1H_OFFSET? 0x9000 : 0x1000) 136 (IS_E1H_OFFSET ? 0x9000 : 0x1000)
134#define XSTORM_ASSERT_LIST_OFFSET(idx) \ 137#define XSTORM_ASSERT_LIST_OFFSET(idx) \
135 (IS_E1H_OFFSET? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) 138 (IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
136#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \ 139#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
137 (IS_E1H_OFFSET? (0x24a8 + (port * 0x40)) : (0x3ba0 + (port * 0x40))) 140 (IS_E1H_OFFSET ? (0x24a8 + (port * 0x40)) : (0x3ba0 + (port * 0x40)))
138#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ 141#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
139 (IS_E1H_OFFSET? (0xa01a + ((function>>1) * 0x28) + ((function&1) \ 142 (IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \
140 * 0xa0) + (index * 0x4)) : (0x141a + (function * 0x28) + (index * \ 143 ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
141 0x4))) 144 0x28) + (index * 0x4)))
142#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ 145#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
143 (IS_E1H_OFFSET? (0xa000 + ((function>>1) * 0x28) + ((function&1) \ 146 (IS_E1H_OFFSET ? (0xa000 + ((function>>1) * 0x28) + \
144 * 0xa0)) : (0x1400 + (function * 0x28))) 147 ((function&1) * 0xa0)) : (0x1400 + (function * 0x28)))
145#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ 148#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
146 (IS_E1H_OFFSET? (0xa008 + ((function>>1) * 0x28) + ((function&1) \ 149 (IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \
147 * 0xa0)) : (0x1408 + (function * 0x28))) 150 ((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
148#define XSTORM_E1HOV_OFFSET(function) \ 151#define XSTORM_E1HOV_OFFSET(function) \
149 (IS_E1H_OFFSET? (0x2ab8 + (function * 0x2)) : 0xffffffff) 152 (IS_E1H_OFFSET ? (0x2ab8 + (function * 0x2)) : 0xffffffff)
150#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ 153#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
151 (IS_E1H_OFFSET? (0x2418 + (function * 0x8)) : (0x3b70 + \ 154 (IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3b70 + \
152 (function * 0x8))) 155 (function * 0x8)))
153#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \ 156#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
154 (IS_E1H_OFFSET? (0x2568 + (function * 0x70)) : (0x3c60 + \ 157 (IS_E1H_OFFSET ? (0x2568 + (function * 0x70)) : (0x3c60 + \
155 (function * 0x70))) 158 (function * 0x70)))
156#define XSTORM_FUNCTION_MODE_OFFSET \ 159#define XSTORM_FUNCTION_MODE_OFFSET \
157 (IS_E1H_OFFSET? 0x2ac8 : 0xffffffff) 160 (IS_E1H_OFFSET ? 0x2ac8 : 0xffffffff)
158#define XSTORM_HC_BTR_OFFSET(port) \ 161#define XSTORM_HC_BTR_OFFSET(port) \
159 (IS_E1H_OFFSET? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18))) 162 (IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
163#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
164 (IS_E1H_OFFSET ? (0xc000 + (port * 0x3f0) + (stats_counter_id * \
165 0x38)) : (0x3378 + (port * 0x3f0) + (stats_counter_id * 0x38)))
160#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \ 166#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
161 (IS_E1H_OFFSET? (0x2528 + (function * 0x70)) : (0x3c20 + \ 167 (IS_E1H_OFFSET ? (0x2528 + (function * 0x70)) : (0x3c20 + \
162 (function * 0x70))) 168 (function * 0x70)))
163#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \ 169#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
164 (IS_E1H_OFFSET? (0x2000 + (function * 0x10)) : (0x3328 + \ 170 (IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \
165 (function * 0x10))) 171 (function * 0x10)))
166#define XSTORM_SPQ_PROD_OFFSET(function) \ 172#define XSTORM_SPQ_PROD_OFFSET(function) \
167 (IS_E1H_OFFSET? (0x2008 + (function * 0x10)) : (0x3330 + \ 173 (IS_E1H_OFFSET ? (0x2008 + (function * 0x10)) : (0x3330 + \
168 (function * 0x10))) 174 (function * 0x10)))
169#define XSTORM_STATS_FLAGS_OFFSET(function) \ 175#define XSTORM_STATS_FLAGS_OFFSET(function) \
170 (IS_E1H_OFFSET? (0x23d8 + (function * 0x8)) : (0x3b60 + \ 176 (IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3b60 + \
171 (function * 0x8))) 177 (function * 0x8)))
172#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0 178#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
173 179
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index d3e8198d7dba..efd764427fa1 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -1268,7 +1268,7 @@ struct doorbell {
1268 1268
1269 1269
1270/* 1270/*
1271 * IGU driver acknowlegement register 1271 * IGU driver acknowledgement register
1272 */ 1272 */
1273struct igu_ack_register { 1273struct igu_ack_register {
1274#if defined(__BIG_ENDIAN) 1274#if defined(__BIG_ENDIAN)
@@ -1882,7 +1882,7 @@ struct timers_block_context {
1882}; 1882};
1883 1883
1884/* 1884/*
1885 * structure for easy accessability to assembler 1885 * structure for easy accessibility to assembler
1886 */ 1886 */
1887struct eth_tx_bd_flags { 1887struct eth_tx_bd_flags {
1888 u8 as_bitfield; 1888 u8 as_bitfield;
@@ -2044,7 +2044,7 @@ struct eth_context {
2044 2044
2045 2045
2046/* 2046/*
2047 * ethernet doorbell 2047 * Ethernet doorbell
2048 */ 2048 */
2049struct eth_tx_doorbell { 2049struct eth_tx_doorbell {
2050#if defined(__BIG_ENDIAN) 2050#if defined(__BIG_ENDIAN)
@@ -2256,7 +2256,7 @@ struct ramrod_data {
2256}; 2256};
2257 2257
2258/* 2258/*
2259 * union for ramrod data for ethernet protocol (CQE) (force size of 16 bits) 2259 * union for ramrod data for Ethernet protocol (CQE) (force size of 16 bits)
2260 */ 2260 */
2261union eth_ramrod_data { 2261union eth_ramrod_data {
2262 struct ramrod_data general; 2262 struct ramrod_data general;
@@ -2330,7 +2330,7 @@ struct spe_hdr {
2330}; 2330};
2331 2331
2332/* 2332/*
2333 * ethernet slow path element 2333 * Ethernet slow path element
2334 */ 2334 */
2335union eth_specific_data { 2335union eth_specific_data {
2336 u8 protocol_data[8]; 2336 u8 protocol_data[8];
@@ -2343,7 +2343,7 @@ union eth_specific_data {
2343}; 2343};
2344 2344
2345/* 2345/*
2346 * ethernet slow path element 2346 * Ethernet slow path element
2347 */ 2347 */
2348struct eth_spe { 2348struct eth_spe {
2349 struct spe_hdr hdr; 2349 struct spe_hdr hdr;
@@ -2615,7 +2615,7 @@ struct tstorm_eth_rx_producers {
2615 2615
2616 2616
2617/* 2617/*
2618 * common flag to indicate existance of TPA. 2618 * common flag to indicate existence of TPA.
2619 */ 2619 */
2620struct tstorm_eth_tpa_exist { 2620struct tstorm_eth_tpa_exist {
2621#if defined(__BIG_ENDIAN) 2621#if defined(__BIG_ENDIAN)
@@ -2765,7 +2765,7 @@ struct tstorm_common_stats {
2765}; 2765};
2766 2766
2767/* 2767/*
2768 * Eth statistics query sturcture for the eth_stats_quesry ramrod 2768 * Eth statistics query structure for the eth_stats_query ramrod
2769 */ 2769 */
2770struct eth_stats_query { 2770struct eth_stats_query {
2771 struct xstorm_common_stats xstorm_common; 2771 struct xstorm_common_stats xstorm_common;
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 4c7750789b62..130927cfc75b 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -72,26 +72,26 @@
72 72
73 73
74struct raw_op { 74struct raw_op {
75 u32 op :8; 75 u32 op:8;
76 u32 offset :24; 76 u32 offset:24;
77 u32 raw_data; 77 u32 raw_data;
78}; 78};
79 79
80struct op_read { 80struct op_read {
81 u32 op :8; 81 u32 op:8;
82 u32 offset :24; 82 u32 offset:24;
83 u32 pad; 83 u32 pad;
84}; 84};
85 85
86struct op_write { 86struct op_write {
87 u32 op :8; 87 u32 op:8;
88 u32 offset :24; 88 u32 offset:24;
89 u32 val; 89 u32 val;
90}; 90};
91 91
92struct op_string_write { 92struct op_string_write {
93 u32 op :8; 93 u32 op:8;
94 u32 offset :24; 94 u32 offset:24;
95#ifdef __LITTLE_ENDIAN 95#ifdef __LITTLE_ENDIAN
96 u16 data_off; 96 u16 data_off;
97 u16 data_len; 97 u16 data_len;
@@ -102,8 +102,8 @@ struct op_string_write {
102}; 102};
103 103
104struct op_zero { 104struct op_zero {
105 u32 op :8; 105 u32 op:8;
106 u32 offset :24; 106 u32 offset:24;
107 u32 len; 107 u32 len;
108}; 108};
109 109
@@ -208,7 +208,7 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
208/********************************************************* 208/*********************************************************
209 There are different blobs for each PRAM section. 209 There are different blobs for each PRAM section.
210 In addition, each blob write operation is divided into a few operations 210 In addition, each blob write operation is divided into a few operations
211 in order to decrease the amount of phys. contigious buffer needed. 211 in order to decrease the amount of phys. contiguous buffer needed.
212 Thus, when we select a blob the address may be with some offset 212 Thus, when we select a blob the address may be with some offset
213 from the beginning of PRAM section. 213 from the beginning of PRAM section.
214 The same holds for the INT_TABLE sections. 214 The same holds for the INT_TABLE sections.
@@ -336,7 +336,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
336 len = op->str_wr.data_len; 336 len = op->str_wr.data_len;
337 data = data_base + op->str_wr.data_off; 337 data = data_base + op->str_wr.data_off;
338 338
339 /* carefull! it must be in order */ 339 /* careful! it must be in order */
340 if (unlikely(op_type > OP_WB)) { 340 if (unlikely(op_type > OP_WB)) {
341 341
342 /* If E1 only */ 342 /* If E1 only */
@@ -740,7 +740,7 @@ static u8 calc_crc8(u32 data, u8 crc)
740 return crc_res; 740 return crc_res;
741} 741}
742 742
743/* regiesers addresses are not in order 743/* registers addresses are not in order
744 so these arrays help simplify the code */ 744 so these arrays help simplify the code */
745static const int cm_start[E1H_FUNC_MAX][9] = { 745static const int cm_start[E1H_FUNC_MAX][9] = {
746 {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START, 746 {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START,
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
index 63019055e4bb..9755bf6b08dd 100644
--- a/drivers/net/bnx2x_init_values.h
+++ b/drivers/net/bnx2x_init_values.h
@@ -901,31 +901,28 @@ static const struct raw_op init_ops[] = {
901 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3760, 0x4}, 901 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3760, 0x4},
902 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1e20, 0x42}, 902 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1e20, 0x42},
903 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3738, 0x9}, 903 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3738, 0x9},
904 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3000, 0x400}, 904 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
905 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3738 + 0x24, 0x10293}, 905 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3738 + 0x24, 0x10293},
906 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x2c00, 0x2}, 906 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x20278},
907 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x42}, 907 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x42},
908 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2c00 + 0x8, 0x20278}, 908 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
909 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400}, 909 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
910 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b68, 0x2}, 910 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x2027a},
911 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2}, 911 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
912 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x2027a},
913 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x20294}, 912 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x20294},
914 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
915 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2}, 913 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
916 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x2027c},
917 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x20296}, 914 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x20296},
918 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2}, 915 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
919 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x20298}, 916 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x20298},
920 {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000}, 917 {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
921 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x10027e}, 918 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x10027c},
922 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x10029a}, 919 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x10029a},
923 {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0}, 920 {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
924 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x10028e}, 921 {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x10028c},
925 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002aa}, 922 {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002aa},
926 {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc20000}, 923 {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc20000},
927 {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xc40000}, 924 {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xc40000},
928 {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x13029e}, 925 {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x13029c},
929 {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x368, 0x1302ba}, 926 {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x368, 0x1302ba},
930 {OP_ZP_E1, USEM_REG_PRAM, 0x311c0000}, 927 {OP_ZP_E1, USEM_REG_PRAM, 0x311c0000},
931 {OP_ZP_E1H, USEM_REG_PRAM, 0x31070000}, 928 {OP_ZP_E1H, USEM_REG_PRAM, 0x31070000},
@@ -933,11 +930,11 @@ static const struct raw_op init_ops[] = {
933 {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x330e0c42}, 930 {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x330e0c42},
934 {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x38561919}, 931 {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x38561919},
935 {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x389b1906}, 932 {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x389b1906},
936 {OP_WR_64_E1, USEM_REG_PRAM + 0x17fe0, 0x500402a0}, 933 {OP_WR_64_E1, USEM_REG_PRAM + 0x17fe0, 0x5004029e},
937 {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x132272d}, 934 {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x132272d},
938 {OP_WR_64_E1H, USEM_REG_PRAM + 0x18250, 0x4fb602bc}, 935 {OP_WR_64_E1H, USEM_REG_PRAM + 0x18250, 0x4fb602bc},
939#define USEM_COMMON_END 790 936#define USEM_COMMON_END 787
940#define USEM_PORT0_START 790 937#define USEM_PORT0_START 787
941 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0}, 938 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
942 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0}, 939 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
943 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0xa}, 940 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0xa},
@@ -950,44 +947,27 @@ static const struct raw_op init_ops[] = {
950 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3288, 0x96}, 947 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3288, 0x96},
951 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5440, 0x72}, 948 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5440, 0x72},
952 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20}, 949 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
953 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3000, 0x20}, 950 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
954 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20}, 951 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
955 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3100, 0x20}, 952 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
956 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20}, 953 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
957 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3200, 0x20},
958 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20}, 954 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
959 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3300, 0x20},
960 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20}, 955 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
961 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3400, 0x20},
962 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20}, 956 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20},
963 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3500, 0x20},
964 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20}, 957 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20},
965 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3600, 0x20},
966 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20}, 958 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20},
967 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3700, 0x20},
968 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20}, 959 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20},
969 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3800, 0x20},
970 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20}, 960 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20},
971 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3900, 0x20},
972 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20}, 961 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20},
973 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3a00, 0x20},
974 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20}, 962 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20},
975 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3b00, 0x20},
976 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20}, 963 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20},
977 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3c00, 0x20},
978 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20}, 964 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20},
979 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3d00, 0x20},
980 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20}, 965 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20},
981 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3e00, 0x20},
982 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20}, 966 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
983 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3f00, 0x20},
984 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52}, 967 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
985 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x2c10, 0x2},
986 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc}, 968 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
987 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b78, 0x52}, 969#define USEM_PORT0_END 818
988 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e08, 0xc}, 970#define USEM_PORT1_START 818
989#define USEM_PORT0_END 838
990#define USEM_PORT1_START 838
991 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0}, 971 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
992 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0}, 972 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
993 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1928, 0xa}, 973 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1928, 0xa},
@@ -1000,76 +980,59 @@ static const struct raw_op init_ops[] = {
1000 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x34e0, 0x96}, 980 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x34e0, 0x96},
1001 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5608, 0x72}, 981 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5608, 0x72},
1002 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20}, 982 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
1003 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3080, 0x20}, 983 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
1004 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20}, 984 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
1005 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3180, 0x20}, 985 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
1006 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20}, 986 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
1007 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3280, 0x20},
1008 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20}, 987 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
1009 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3380, 0x20},
1010 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20}, 988 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
1011 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3480, 0x20},
1012 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20}, 989 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20},
1013 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3580, 0x20},
1014 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20}, 990 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20},
1015 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3680, 0x20},
1016 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20}, 991 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20},
1017 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3780, 0x20},
1018 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20}, 992 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20},
1019 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3880, 0x20},
1020 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20}, 993 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20},
1021 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3980, 0x20},
1022 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20}, 994 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20},
1023 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3a80, 0x20},
1024 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20}, 995 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20},
1025 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3b80, 0x20},
1026 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20}, 996 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20},
1027 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3c80, 0x20},
1028 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20}, 997 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20},
1029 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3d80, 0x20},
1030 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20}, 998 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20},
1031 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3e80, 0x20},
1032 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20}, 999 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
1033 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3f80, 0x20},
1034 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52}, 1000 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
1035 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x2c20, 0x2},
1036 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc}, 1001 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
1037 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52}, 1002#define USEM_PORT1_END 849
1038 {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e38, 0xc}, 1003#define USEM_FUNC0_START 849
1039#define USEM_PORT1_END 886
1040#define USEM_FUNC0_START 886
1041 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4}, 1004 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
1042 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4010, 0x2}, 1005 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4010, 0x2},
1043#define USEM_FUNC0_END 888 1006#define USEM_FUNC0_END 851
1044#define USEM_FUNC1_START 888 1007#define USEM_FUNC1_START 851
1045 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4}, 1008 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
1046 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4020, 0x2}, 1009 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4020, 0x2},
1047#define USEM_FUNC1_END 890 1010#define USEM_FUNC1_END 853
1048#define USEM_FUNC2_START 890 1011#define USEM_FUNC2_START 853
1049 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4}, 1012 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
1050 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4030, 0x2}, 1013 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4030, 0x2},
1051#define USEM_FUNC2_END 892 1014#define USEM_FUNC2_END 855
1052#define USEM_FUNC3_START 892 1015#define USEM_FUNC3_START 855
1053 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4}, 1016 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
1054 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4040, 0x2}, 1017 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4040, 0x2},
1055#define USEM_FUNC3_END 894 1018#define USEM_FUNC3_END 857
1056#define USEM_FUNC4_START 894 1019#define USEM_FUNC4_START 857
1057 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4}, 1020 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
1058 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4050, 0x2}, 1021 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4050, 0x2},
1059#define USEM_FUNC4_END 896 1022#define USEM_FUNC4_END 859
1060#define USEM_FUNC5_START 896 1023#define USEM_FUNC5_START 859
1061 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4}, 1024 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
1062 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4060, 0x2}, 1025 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4060, 0x2},
1063#define USEM_FUNC5_END 898 1026#define USEM_FUNC5_END 861
1064#define USEM_FUNC6_START 898 1027#define USEM_FUNC6_START 861
1065 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4}, 1028 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
1066 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4070, 0x2}, 1029 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4070, 0x2},
1067#define USEM_FUNC6_END 900 1030#define USEM_FUNC6_END 863
1068#define USEM_FUNC7_START 900 1031#define USEM_FUNC7_START 863
1069 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4}, 1032 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
1070 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4080, 0x2}, 1033 {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4080, 0x2},
1071#define USEM_FUNC7_END 902 1034#define USEM_FUNC7_END 865
1072#define CSEM_COMMON_START 902 1035#define CSEM_COMMON_START 865
1073 {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0}, 1036 {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
1074 {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0}, 1037 {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
1075 {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0}, 1038 {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -1128,29 +1091,29 @@ static const struct raw_op init_ops[] = {
1128 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0}, 1091 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
1129 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240}, 1092 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
1130 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0}, 1093 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
1131 {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a2}, 1094 {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a0},
1132 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80}, 1095 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
1133 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4}, 1096 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
1134 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x240}, 1097 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x240},
1135 {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b88, 0x2002be}, 1098 {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b88, 0x2002be},
1136 {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff}, 1099 {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
1137 {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002aa}, 1100 {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002a8},
1138 {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002de}, 1101 {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002de},
1139 {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0}, 1102 {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
1140 {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ba}, 1103 {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002b8},
1141 {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ee}, 1104 {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ee},
1142 {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x6e0000}, 1105 {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x6e0000},
1143 {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x6f0000}, 1106 {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x6f0000},
1144 {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002ca}, 1107 {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002c8},
1145 {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x1002fe}, 1108 {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x1002fe},
1146 {OP_ZP_E1, CSEM_REG_PRAM, 0x32580000}, 1109 {OP_ZP_E1, CSEM_REG_PRAM, 0x32580000},
1147 {OP_ZP_E1H, CSEM_REG_PRAM, 0x31fa0000}, 1110 {OP_ZP_E1H, CSEM_REG_PRAM, 0x31fa0000},
1148 {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x18270c96}, 1111 {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x18270c96},
1149 {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x19040c7f}, 1112 {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x19040c7f},
1150 {OP_WR_64_E1, CSEM_REG_PRAM + 0xb210, 0x682402cc}, 1113 {OP_WR_64_E1, CSEM_REG_PRAM + 0xb210, 0x682402ca},
1151 {OP_WR_64_E1H, CSEM_REG_PRAM + 0xb430, 0x67e00300}, 1114 {OP_WR_64_E1H, CSEM_REG_PRAM + 0xb430, 0x67e00300},
1152#define CSEM_COMMON_END 981 1115#define CSEM_COMMON_END 944
1153#define CSEM_PORT0_START 981 1116#define CSEM_PORT0_START 944
1154 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0}, 1117 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
1155 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0}, 1118 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
1156 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10}, 1119 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
@@ -1163,8 +1126,8 @@ static const struct raw_op init_ops[] = {
1163 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30}, 1126 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
1164 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6}, 1127 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
1165 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30}, 1128 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
1166#define CSEM_PORT0_END 993 1129#define CSEM_PORT0_END 956
1167#define CSEM_PORT1_START 993 1130#define CSEM_PORT1_START 956
1168 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0}, 1131 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
1169 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0}, 1132 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
1170 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10}, 1133 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
@@ -1177,43 +1140,43 @@ static const struct raw_op init_ops[] = {
1177 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30}, 1140 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
1178 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6}, 1141 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
1179 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30}, 1142 {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
1180#define CSEM_PORT1_END 1005 1143#define CSEM_PORT1_END 968
1181#define CSEM_FUNC0_START 1005 1144#define CSEM_FUNC0_START 968
1182 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0}, 1145 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
1183 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2}, 1146 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
1184#define CSEM_FUNC0_END 1007 1147#define CSEM_FUNC0_END 970
1185#define CSEM_FUNC1_START 1007 1148#define CSEM_FUNC1_START 970
1186 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0}, 1149 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
1187 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2}, 1150 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
1188#define CSEM_FUNC1_END 1009 1151#define CSEM_FUNC1_END 972
1189#define CSEM_FUNC2_START 1009 1152#define CSEM_FUNC2_START 972
1190 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0}, 1153 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
1191 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2}, 1154 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
1192#define CSEM_FUNC2_END 1011 1155#define CSEM_FUNC2_END 974
1193#define CSEM_FUNC3_START 1011 1156#define CSEM_FUNC3_START 974
1194 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0}, 1157 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
1195 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2}, 1158 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
1196#define CSEM_FUNC3_END 1013 1159#define CSEM_FUNC3_END 976
1197#define CSEM_FUNC4_START 1013 1160#define CSEM_FUNC4_START 976
1198 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0}, 1161 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
1199 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2}, 1162 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
1200#define CSEM_FUNC4_END 1015 1163#define CSEM_FUNC4_END 978
1201#define CSEM_FUNC5_START 1015 1164#define CSEM_FUNC5_START 978
1202 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0}, 1165 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
1203 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2}, 1166 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
1204#define CSEM_FUNC5_END 1017 1167#define CSEM_FUNC5_END 980
1205#define CSEM_FUNC6_START 1017 1168#define CSEM_FUNC6_START 980
1206 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0}, 1169 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
1207 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2}, 1170 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
1208#define CSEM_FUNC6_END 1019 1171#define CSEM_FUNC6_END 982
1209#define CSEM_FUNC7_START 1019 1172#define CSEM_FUNC7_START 982
1210 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0}, 1173 {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
1211 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2}, 1174 {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
1212#define CSEM_FUNC7_END 1021 1175#define CSEM_FUNC7_END 984
1213#define XPB_COMMON_START 1021 1176#define XPB_COMMON_START 984
1214 {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20}, 1177 {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
1215#define XPB_COMMON_END 1022 1178#define XPB_COMMON_END 985
1216#define DQ_COMMON_START 1022 1179#define DQ_COMMON_START 985
1217 {OP_WR, DORQ_REG_MODE_ACT, 0x2}, 1180 {OP_WR, DORQ_REG_MODE_ACT, 0x2},
1218 {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3}, 1181 {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
1219 {OP_WR, DORQ_REG_OUTST_REQ, 0x4}, 1182 {OP_WR, DORQ_REG_OUTST_REQ, 0x4},
@@ -1232,8 +1195,8 @@ static const struct raw_op init_ops[] = {
1232 {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c}, 1195 {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
1233 {OP_WR, DORQ_REG_REGN, 0x7c1004}, 1196 {OP_WR, DORQ_REG_REGN, 0x7c1004},
1234 {OP_WR, DORQ_REG_IF_EN, 0xf}, 1197 {OP_WR, DORQ_REG_IF_EN, 0xf},
1235#define DQ_COMMON_END 1040 1198#define DQ_COMMON_END 1003
1236#define TIMERS_COMMON_START 1040 1199#define TIMERS_COMMON_START 1003
1237 {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2}, 1200 {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
1238 {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c}, 1201 {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
1239 {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1}, 1202 {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
@@ -1256,14 +1219,14 @@ static const struct raw_op init_ops[] = {
1256 {OP_WR, TM_REG_EN_CL0_INPUT, 0x1}, 1219 {OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
1257 {OP_WR, TM_REG_EN_CL1_INPUT, 0x1}, 1220 {OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
1258 {OP_WR, TM_REG_EN_CL2_INPUT, 0x1}, 1221 {OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
1259#define TIMERS_COMMON_END 1062 1222#define TIMERS_COMMON_END 1025
1260#define TIMERS_PORT0_START 1062 1223#define TIMERS_PORT0_START 1025
1261 {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2}, 1224 {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
1262#define TIMERS_PORT0_END 1063 1225#define TIMERS_PORT0_END 1026
1263#define TIMERS_PORT1_START 1063 1226#define TIMERS_PORT1_START 1026
1264 {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2}, 1227 {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
1265#define TIMERS_PORT1_END 1064 1228#define TIMERS_PORT1_END 1027
1266#define XSDM_COMMON_START 1064 1229#define XSDM_COMMON_START 1027
1267 {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614}, 1230 {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
1268 {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424}, 1231 {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
1269 {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600}, 1232 {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
@@ -1311,8 +1274,8 @@ static const struct raw_op init_ops[] = {
1311 {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8}, 1274 {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
1312 {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1}, 1275 {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
1313 {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa}, 1276 {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
1314#define XSDM_COMMON_END 1111 1277#define XSDM_COMMON_END 1074
1315#define QM_COMMON_START 1111 1278#define QM_COMMON_START 1074
1316 {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6}, 1279 {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
1317 {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5}, 1280 {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
1318 {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa}, 1281 {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
@@ -1613,8 +1576,8 @@ static const struct raw_op init_ops[] = {
1613 {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5}, 1576 {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
1614 {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7}, 1577 {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
1615 {OP_WR, QM_REG_CMINTEN, 0xff}, 1578 {OP_WR, QM_REG_CMINTEN, 0xff},
1616#define QM_COMMON_END 1411 1579#define QM_COMMON_END 1374
1617#define PBF_COMMON_START 1411 1580#define PBF_COMMON_START 1374
1618 {OP_WR, PBF_REG_INIT, 0x1}, 1581 {OP_WR, PBF_REG_INIT, 0x1},
1619 {OP_WR, PBF_REG_INIT_P4, 0x1}, 1582 {OP_WR, PBF_REG_INIT_P4, 0x1},
1620 {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1}, 1583 {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
@@ -1622,20 +1585,20 @@ static const struct raw_op init_ops[] = {
1622 {OP_WR, PBF_REG_INIT_P4, 0x0}, 1585 {OP_WR, PBF_REG_INIT_P4, 0x0},
1623 {OP_WR, PBF_REG_INIT, 0x0}, 1586 {OP_WR, PBF_REG_INIT, 0x0},
1624 {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0}, 1587 {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
1625#define PBF_COMMON_END 1418 1588#define PBF_COMMON_END 1381
1626#define PBF_PORT0_START 1418 1589#define PBF_PORT0_START 1381
1627 {OP_WR, PBF_REG_INIT_P0, 0x1}, 1590 {OP_WR, PBF_REG_INIT_P0, 0x1},
1628 {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1}, 1591 {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
1629 {OP_WR, PBF_REG_INIT_P0, 0x0}, 1592 {OP_WR, PBF_REG_INIT_P0, 0x0},
1630 {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0}, 1593 {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
1631#define PBF_PORT0_END 1422 1594#define PBF_PORT0_END 1385
1632#define PBF_PORT1_START 1422 1595#define PBF_PORT1_START 1385
1633 {OP_WR, PBF_REG_INIT_P1, 0x1}, 1596 {OP_WR, PBF_REG_INIT_P1, 0x1},
1634 {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1}, 1597 {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
1635 {OP_WR, PBF_REG_INIT_P1, 0x0}, 1598 {OP_WR, PBF_REG_INIT_P1, 0x0},
1636 {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0}, 1599 {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
1637#define PBF_PORT1_END 1426 1600#define PBF_PORT1_END 1389
1638#define XCM_COMMON_START 1426 1601#define XCM_COMMON_START 1389
1639 {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32}, 1602 {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
1640 {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020}, 1603 {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
1641 {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020}, 1604 {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
@@ -1670,7 +1633,7 @@ static const struct raw_op init_ops[] = {
1670 {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f}, 1633 {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
1671 {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20}, 1634 {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
1672 {OP_ZR, XCM_REG_XX_TABLE, 0x12}, 1635 {OP_ZR, XCM_REG_XX_TABLE, 0x12},
1673 {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02ce}, 1636 {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02cc},
1674 {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0302}, 1637 {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0302},
1675 {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf}, 1638 {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
1676 {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7}, 1639 {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
@@ -1700,8 +1663,8 @@ static const struct raw_op init_ops[] = {
1700 {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1}, 1663 {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
1701 {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1}, 1664 {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
1702 {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1}, 1665 {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
1703#define XCM_COMMON_END 1490 1666#define XCM_COMMON_END 1453
1704#define XCM_PORT0_START 1490 1667#define XCM_PORT0_START 1453
1705 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, 1668 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
1706 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, 1669 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
1707 {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, 1670 {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1710,8 +1673,8 @@ static const struct raw_op init_ops[] = {
1710 {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2}, 1673 {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
1711 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, 1674 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
1712 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, 1675 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
1713#define XCM_PORT0_END 1498 1676#define XCM_PORT0_END 1461
1714#define XCM_PORT1_START 1498 1677#define XCM_PORT1_START 1461
1715 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, 1678 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
1716 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, 1679 {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
1717 {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, 1680 {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1720,8 +1683,8 @@ static const struct raw_op init_ops[] = {
1720 {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2}, 1683 {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
1721 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, 1684 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
1722 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, 1685 {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
1723#define XCM_PORT1_END 1506 1686#define XCM_PORT1_END 1469
1724#define XCM_FUNC0_START 1506 1687#define XCM_FUNC0_START 1469
1725 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, 1688 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
1726 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, 1689 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
1727 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, 1690 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1731,8 +1694,8 @@ static const struct raw_op init_ops[] = {
1731 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, 1694 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
1732 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, 1695 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
1733 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, 1696 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
1734#define XCM_FUNC0_END 1515 1697#define XCM_FUNC0_END 1478
1735#define XCM_FUNC1_START 1515 1698#define XCM_FUNC1_START 1478
1736 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, 1699 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
1737 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, 1700 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
1738 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, 1701 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1742,8 +1705,8 @@ static const struct raw_op init_ops[] = {
1742 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, 1705 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
1743 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, 1706 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
1744 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, 1707 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
1745#define XCM_FUNC1_END 1524 1708#define XCM_FUNC1_END 1487
1746#define XCM_FUNC2_START 1524 1709#define XCM_FUNC2_START 1487
1747 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, 1710 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
1748 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, 1711 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
1749 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, 1712 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1753,8 +1716,8 @@ static const struct raw_op init_ops[] = {
1753 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, 1716 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
1754 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, 1717 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
1755 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, 1718 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
1756#define XCM_FUNC2_END 1533 1719#define XCM_FUNC2_END 1496
1757#define XCM_FUNC3_START 1533 1720#define XCM_FUNC3_START 1496
1758 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, 1721 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
1759 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, 1722 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
1760 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, 1723 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1764,8 +1727,8 @@ static const struct raw_op init_ops[] = {
1764 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, 1727 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
1765 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, 1728 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
1766 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, 1729 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
1767#define XCM_FUNC3_END 1542 1730#define XCM_FUNC3_END 1505
1768#define XCM_FUNC4_START 1542 1731#define XCM_FUNC4_START 1505
1769 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, 1732 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
1770 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, 1733 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
1771 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, 1734 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1775,8 +1738,8 @@ static const struct raw_op init_ops[] = {
1775 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, 1738 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
1776 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, 1739 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
1777 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, 1740 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
1778#define XCM_FUNC4_END 1551 1741#define XCM_FUNC4_END 1514
1779#define XCM_FUNC5_START 1551 1742#define XCM_FUNC5_START 1514
1780 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, 1743 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
1781 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, 1744 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
1782 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, 1745 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1786,8 +1749,8 @@ static const struct raw_op init_ops[] = {
1786 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, 1749 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
1787 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, 1750 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
1788 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, 1751 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
1789#define XCM_FUNC5_END 1560 1752#define XCM_FUNC5_END 1523
1790#define XCM_FUNC6_START 1560 1753#define XCM_FUNC6_START 1523
1791 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, 1754 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
1792 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, 1755 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
1793 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, 1756 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1797,8 +1760,8 @@ static const struct raw_op init_ops[] = {
1797 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, 1760 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
1798 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, 1761 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
1799 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, 1762 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
1800#define XCM_FUNC6_END 1569 1763#define XCM_FUNC6_END 1532
1801#define XCM_FUNC7_START 1569 1764#define XCM_FUNC7_START 1532
1802 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, 1765 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
1803 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, 1766 {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
1804 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, 1767 {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1808,8 +1771,8 @@ static const struct raw_op init_ops[] = {
1808 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, 1771 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
1809 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, 1772 {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
1810 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, 1773 {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
1811#define XCM_FUNC7_END 1578 1774#define XCM_FUNC7_END 1541
1812#define XSEM_COMMON_START 1578 1775#define XSEM_COMMON_START 1541
1813 {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0}, 1776 {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
1814 {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0}, 1777 {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
1815 {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0}, 1778 {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -1876,9 +1839,9 @@ static const struct raw_op init_ops[] = {
1876 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2}, 1839 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
1877 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0}, 1840 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
1878 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86}, 1841 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
1879 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202ed}, 1842 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202eb},
1880 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20}, 1843 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
1881 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402ef}, 1844 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402ed},
1882 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0}, 1845 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
1883 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1}, 1846 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
1884 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x20321}, 1847 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x20321},
@@ -1886,29 +1849,29 @@ static const struct raw_op init_ops[] = {
1886 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x40323}, 1849 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x40323},
1887 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0}, 1850 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
1888 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ac8, 0x0}, 1851 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ac8, 0x0},
1889 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202f3}, 1852 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202f1},
1890 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ab8, 0x0}, 1853 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ab8, 0x0},
1891 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2}, 1854 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
1892 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1}, 1855 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
1893 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4}, 1856 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
1894 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10}, 1857 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
1895 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f50, 0x202f5}, 1858 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f50, 0x202f3},
1896 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100327}, 1859 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100327},
1897 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2}, 1860 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
1898 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4}, 1861 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
1899 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x83b0, 0x20337}, 1862 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x83b0, 0x20337},
1900 {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0}, 1863 {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
1901 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x1002f7}, 1864 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x1002f5},
1902 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100339}, 1865 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100339},
1903 {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000}, 1866 {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
1904 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80307}, 1867 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80305},
1905 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80349}, 1868 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80349},
1906 {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000}, 1869 {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
1907 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8030f}, 1870 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8030d},
1908 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80351}, 1871 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80351},
1909 {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xa90000}, 1872 {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xa90000},
1910 {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xac0000}, 1873 {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xac0000},
1911 {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130317}, 1874 {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130315},
1912 {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x368, 0x130359}, 1875 {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x368, 0x130359},
1913 {OP_ZP_E1, XSEM_REG_PRAM, 0x344e0000}, 1876 {OP_ZP_E1, XSEM_REG_PRAM, 0x344e0000},
1914 {OP_ZP_E1H, XSEM_REG_PRAM, 0x34620000}, 1877 {OP_ZP_E1H, XSEM_REG_PRAM, 0x34620000},
@@ -1918,10 +1881,10 @@ static const struct raw_op init_ops[] = {
1918 {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3e971b22}, 1881 {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3e971b22},
1919 {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x1dd02ad2}, 1882 {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x1dd02ad2},
1920 {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x21542ac8}, 1883 {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x21542ac8},
1921 {OP_WR_64_E1, XSEM_REG_PRAM + 0x1c0d0, 0x47e60319}, 1884 {OP_WR_64_E1, XSEM_REG_PRAM + 0x1c0d0, 0x47e60317},
1922 {OP_WR_64_E1H, XSEM_REG_PRAM + 0x1c8d0, 0x46e6035b}, 1885 {OP_WR_64_E1H, XSEM_REG_PRAM + 0x1c8d0, 0x46e6035b},
1923#define XSEM_COMMON_END 1688 1886#define XSEM_COMMON_END 1651
1924#define XSEM_PORT0_START 1688 1887#define XSEM_PORT0_START 1651
1925 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x10}, 1888 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x10},
1926 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc}, 1889 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
1927 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c20, 0x1c}, 1890 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c20, 0x1c},
@@ -1934,7 +1897,7 @@ static const struct raw_op init_ops[] = {
1934 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26e8, 0x1c}, 1897 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26e8, 0x1c},
1935 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0}, 1898 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
1936 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x27c8, 0x1c}, 1899 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x27c8, 0x1c},
1937 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d10, 0x10031b}, 1900 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d10, 0x100319},
1938 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28}, 1901 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
1939 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0}, 1902 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
1940 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc}, 1903 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
@@ -1950,12 +1913,12 @@ static const struct raw_op init_ops[] = {
1950 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2035d}, 1913 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2035d},
1951 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1}, 1914 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
1952 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42}, 1915 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
1953 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x2032b}, 1916 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20329},
1954 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4}, 1917 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
1955 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42}, 1918 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
1956 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4}, 1919 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
1957#define XSEM_PORT0_END 1720 1920#define XSEM_PORT0_END 1683
1958#define XSEM_PORT1_START 1720 1921#define XSEM_PORT1_START 1683
1959 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3be0, 0x10}, 1922 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3be0, 0x10},
1960 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc}, 1923 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
1961 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c90, 0x1c}, 1924 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c90, 0x1c},
@@ -1968,7 +1931,7 @@ static const struct raw_op init_ops[] = {
1968 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2758, 0x1c}, 1931 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2758, 0x1c},
1969 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0}, 1932 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
1970 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2838, 0x1c}, 1933 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2838, 0x1c},
1971 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d50, 0x10032d}, 1934 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d50, 0x10032b},
1972 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28}, 1935 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
1973 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0}, 1936 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
1974 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc}, 1937 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
@@ -1984,65 +1947,65 @@ static const struct raw_op init_ops[] = {
1984 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2035f}, 1947 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2035f},
1985 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1}, 1948 {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
1986 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42}, 1949 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
1987 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2033d}, 1950 {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2033b},
1988 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4}, 1951 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
1989 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42}, 1952 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
1990 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4}, 1953 {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
1991#define XSEM_PORT1_END 1752 1954#define XSEM_PORT1_END 1715
1992#define XSEM_FUNC0_START 1752 1955#define XSEM_FUNC0_START 1715
1993 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0}, 1956 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
1994 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28b8, 0x100361}, 1957 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28b8, 0x100361},
1995 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe}, 1958 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
1996#define XSEM_FUNC0_END 1755 1959#define XSEM_FUNC0_END 1718
1997#define XSEM_FUNC1_START 1755 1960#define XSEM_FUNC1_START 1718
1998 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0}, 1961 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
1999 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28f8, 0x100371}, 1962 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28f8, 0x100371},
2000 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe}, 1963 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
2001#define XSEM_FUNC1_END 1758 1964#define XSEM_FUNC1_END 1721
2002#define XSEM_FUNC2_START 1758 1965#define XSEM_FUNC2_START 1721
2003 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0}, 1966 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
2004 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x100381}, 1967 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x100381},
2005 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe}, 1968 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
2006#define XSEM_FUNC2_END 1761 1969#define XSEM_FUNC2_END 1724
2007#define XSEM_FUNC3_START 1761 1970#define XSEM_FUNC3_START 1724
2008 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0}, 1971 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
2009 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2978, 0x100391}, 1972 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2978, 0x100391},
2010 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe}, 1973 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
2011#define XSEM_FUNC3_END 1764 1974#define XSEM_FUNC3_END 1727
2012#define XSEM_FUNC4_START 1764 1975#define XSEM_FUNC4_START 1727
2013 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0}, 1976 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
2014 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29b8, 0x1003a1}, 1977 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29b8, 0x1003a1},
2015 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe}, 1978 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
2016#define XSEM_FUNC4_END 1767 1979#define XSEM_FUNC4_END 1730
2017#define XSEM_FUNC5_START 1767 1980#define XSEM_FUNC5_START 1730
2018 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0}, 1981 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
2019 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f8, 0x1003b1}, 1982 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f8, 0x1003b1},
2020 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe}, 1983 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
2021#define XSEM_FUNC5_END 1770 1984#define XSEM_FUNC5_END 1733
2022#define XSEM_FUNC6_START 1770 1985#define XSEM_FUNC6_START 1733
2023 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0}, 1986 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
2024 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a38, 0x1003c1}, 1987 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a38, 0x1003c1},
2025 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe}, 1988 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
2026#define XSEM_FUNC6_END 1773 1989#define XSEM_FUNC6_END 1736
2027#define XSEM_FUNC7_START 1773 1990#define XSEM_FUNC7_START 1736
2028 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0}, 1991 {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
2029 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a78, 0x1003d1}, 1992 {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a78, 0x1003d1},
2030 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe}, 1993 {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
2031#define XSEM_FUNC7_END 1776 1994#define XSEM_FUNC7_END 1739
2032#define CDU_COMMON_START 1776 1995#define CDU_COMMON_START 1739
2033 {OP_WR, CDU_REG_CDU_CONTROL0, 0x1}, 1996 {OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
2034 {OP_WR_E1H, CDU_REG_MF_MODE, 0x1}, 1997 {OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
2035 {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000}, 1998 {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
2036 {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d}, 1999 {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
2037 {OP_WB_E1, CDU_REG_L1TT, 0x200033f}, 2000 {OP_WB_E1, CDU_REG_L1TT, 0x200033d},
2038 {OP_WB_E1H, CDU_REG_L1TT, 0x20003e1}, 2001 {OP_WB_E1H, CDU_REG_L1TT, 0x20003e1},
2039 {OP_WB_E1, CDU_REG_MATT, 0x20053f}, 2002 {OP_WB_E1, CDU_REG_MATT, 0x20053d},
2040 {OP_WB_E1H, CDU_REG_MATT, 0x2805e1}, 2003 {OP_WB_E1H, CDU_REG_MATT, 0x2805e1},
2041 {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2}, 2004 {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
2042 {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6055f}, 2005 {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6055d},
2043 {OP_ZR, CDU_REG_MATT + 0xa0, 0x18}, 2006 {OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
2044#define CDU_COMMON_END 1787 2007#define CDU_COMMON_END 1750
2045#define DMAE_COMMON_START 1787 2008#define DMAE_COMMON_START 1750
2046 {OP_ZR, DMAE_REG_CMD_MEM, 0xe0}, 2009 {OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
2047 {OP_WR, DMAE_REG_CRC16C_INIT, 0x0}, 2010 {OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
2048 {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1}, 2011 {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
@@ -2050,24 +2013,24 @@ static const struct raw_op init_ops[] = {
2050 {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2}, 2013 {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
2051 {OP_WR, DMAE_REG_PCI_IFEN, 0x1}, 2014 {OP_WR, DMAE_REG_PCI_IFEN, 0x1},
2052 {OP_WR, DMAE_REG_GRC_IFEN, 0x1}, 2015 {OP_WR, DMAE_REG_GRC_IFEN, 0x1},
2053#define DMAE_COMMON_END 1794 2016#define DMAE_COMMON_END 1757
2054#define PXP_COMMON_START 1794 2017#define PXP_COMMON_START 1757
2055 {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50565}, 2018 {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50563},
2056 {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50609}, 2019 {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50609},
2057 {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x5056a}, 2020 {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50568},
2058 {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5060e}, 2021 {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5060e},
2059 {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5056f}, 2022 {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5056d},
2060#define PXP_COMMON_END 1799 2023#define PXP_COMMON_END 1762
2061#define CFC_COMMON_START 1799 2024#define CFC_COMMON_START 1762
2062 {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100}, 2025 {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
2063 {OP_WR, CFC_REG_CONTROL0, 0x10}, 2026 {OP_WR, CFC_REG_CONTROL0, 0x10},
2064 {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff}, 2027 {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
2065 {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a}, 2028 {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
2066#define CFC_COMMON_END 1803 2029#define CFC_COMMON_END 1766
2067#define HC_COMMON_START 1803 2030#define HC_COMMON_START 1766
2068 {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4}, 2031 {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
2069#define HC_COMMON_END 1804 2032#define HC_COMMON_END 1767
2070#define HC_PORT0_START 1804 2033#define HC_PORT0_START 1767
2071 {OP_WR_E1, HC_REG_CONFIG_0, 0x1080}, 2034 {OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
2072 {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2}, 2035 {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
2073 {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10}, 2036 {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2086,8 +2049,8 @@ static const struct raw_op init_ops[] = {
2086 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, 2049 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
2087 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, 2050 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
2088 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, 2051 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
2089#define HC_PORT0_END 1822 2052#define HC_PORT0_END 1785
2090#define HC_PORT1_START 1822 2053#define HC_PORT1_START 1785
2091 {OP_WR_E1, HC_REG_CONFIG_1, 0x1080}, 2054 {OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
2092 {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2}, 2055 {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
2093 {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10}, 2056 {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2106,8 +2069,8 @@ static const struct raw_op init_ops[] = {
2106 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, 2069 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
2107 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, 2070 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
2108 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, 2071 {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
2109#define HC_PORT1_END 1840 2072#define HC_PORT1_END 1803
2110#define HC_FUNC0_START 1840 2073#define HC_FUNC0_START 1803
2111 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, 2074 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
2112 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0}, 2075 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
2113 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, 2076 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2123,8 +2086,8 @@ static const struct raw_op init_ops[] = {
2123 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, 2086 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
2124 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, 2087 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
2125 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, 2088 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
2126#define HC_FUNC0_END 1855 2089#define HC_FUNC0_END 1818
2127#define HC_FUNC1_START 1855 2090#define HC_FUNC1_START 1818
2128 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, 2091 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
2129 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1}, 2092 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
2130 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, 2093 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2140,8 +2103,8 @@ static const struct raw_op init_ops[] = {
2140 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, 2103 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
2141 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, 2104 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
2142 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, 2105 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
2143#define HC_FUNC1_END 1870 2106#define HC_FUNC1_END 1833
2144#define HC_FUNC2_START 1870 2107#define HC_FUNC2_START 1833
2145 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, 2108 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
2146 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2}, 2109 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
2147 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, 2110 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2157,8 +2120,8 @@ static const struct raw_op init_ops[] = {
2157 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, 2120 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
2158 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, 2121 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
2159 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, 2122 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
2160#define HC_FUNC2_END 1885 2123#define HC_FUNC2_END 1848
2161#define HC_FUNC3_START 1885 2124#define HC_FUNC3_START 1848
2162 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, 2125 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
2163 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3}, 2126 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
2164 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, 2127 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2174,8 +2137,8 @@ static const struct raw_op init_ops[] = {
2174 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, 2137 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
2175 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, 2138 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
2176 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, 2139 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
2177#define HC_FUNC3_END 1900 2140#define HC_FUNC3_END 1863
2178#define HC_FUNC4_START 1900 2141#define HC_FUNC4_START 1863
2179 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, 2142 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
2180 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4}, 2143 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
2181 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, 2144 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2191,8 +2154,8 @@ static const struct raw_op init_ops[] = {
2191 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, 2154 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
2192 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, 2155 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
2193 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, 2156 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
2194#define HC_FUNC4_END 1915 2157#define HC_FUNC4_END 1878
2195#define HC_FUNC5_START 1915 2158#define HC_FUNC5_START 1878
2196 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, 2159 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
2197 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5}, 2160 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
2198 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, 2161 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2208,8 +2171,8 @@ static const struct raw_op init_ops[] = {
2208 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, 2171 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
2209 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, 2172 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
2210 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, 2173 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
2211#define HC_FUNC5_END 1930 2174#define HC_FUNC5_END 1893
2212#define HC_FUNC6_START 1930 2175#define HC_FUNC6_START 1893
2213 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, 2176 {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
2214 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6}, 2177 {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
2215 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, 2178 {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2225,8 +2188,8 @@ static const struct raw_op init_ops[] = {
2225 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, 2188 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
2226 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, 2189 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
2227 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, 2190 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
2228#define HC_FUNC6_END 1945 2191#define HC_FUNC6_END 1908
2229#define HC_FUNC7_START 1945 2192#define HC_FUNC7_START 1908
2230 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, 2193 {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
2231 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7}, 2194 {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
2232 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, 2195 {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2242,8 +2205,8 @@ static const struct raw_op init_ops[] = {
2242 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, 2205 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
2243 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, 2206 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
2244 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, 2207 {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
2245#define HC_FUNC7_END 1960 2208#define HC_FUNC7_END 1923
2246#define PXP2_COMMON_START 1960 2209#define PXP2_COMMON_START 1923
2247 {OP_WR_E1, PXP2_REG_PGL_CONTROL0, 0xe38340}, 2210 {OP_WR_E1, PXP2_REG_PGL_CONTROL0, 0xe38340},
2248 {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1}, 2211 {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
2249 {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10}, 2212 {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
@@ -2361,8 +2324,8 @@ static const struct raw_op init_ops[] = {
2361 {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1}, 2324 {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
2362 {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1}, 2325 {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
2363 {OP_WR_E1H, PXP2_REG_PGL_CONTROL0, 0xe38340}, 2326 {OP_WR_E1H, PXP2_REG_PGL_CONTROL0, 0xe38340},
2364#define PXP2_COMMON_END 2077 2327#define PXP2_COMMON_END 2040
2365#define MISC_AEU_COMMON_START 2077 2328#define MISC_AEU_COMMON_START 2040
2366 {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16}, 2329 {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
2367 {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000}, 2330 {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
2368 {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555}, 2331 {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
@@ -2382,8 +2345,8 @@ static const struct raw_op init_ops[] = {
2382 {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0}, 2345 {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
2383 {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00}, 2346 {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
2384 {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3}, 2347 {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
2385#define MISC_AEU_COMMON_END 2096 2348#define MISC_AEU_COMMON_END 2059
2386#define MISC_AEU_PORT0_START 2096 2349#define MISC_AEU_PORT0_START 2059
2387 {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000}, 2350 {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
2388 {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000}, 2351 {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
2389 {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef}, 2352 {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
@@ -2416,8 +2379,8 @@ static const struct raw_op init_ops[] = {
2416 {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0}, 2379 {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
2417 {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3}, 2380 {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
2418 {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7}, 2381 {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
2419#define MISC_AEU_PORT0_END 2128 2382#define MISC_AEU_PORT0_END 2091
2420#define MISC_AEU_PORT1_START 2128 2383#define MISC_AEU_PORT1_START 2091
2421 {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000}, 2384 {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
2422 {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000}, 2385 {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
2423 {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef}, 2386 {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
@@ -2450,7 +2413,7 @@ static const struct raw_op init_ops[] = {
2450 {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0}, 2413 {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
2451 {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3}, 2414 {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
2452 {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7}, 2415 {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
2453#define MISC_AEU_PORT1_END 2160 2416#define MISC_AEU_PORT1_END 2123
2454 2417
2455}; 2418};
2456 2419
@@ -2560,103 +2523,92 @@ static const u32 init_data_e1[] = {
2560 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 2523 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80,
2561 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 2524 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280,
2562 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 2525 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780,
2563 0x000ddb00, 0x00001900, 0x00000028, 0x00000000, 0x00100000, 0x00000000, 2526 0x000ddb00, 0x00001900, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
2564 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2565 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2527 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2566 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2528 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2567 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2529 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2568 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2530 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2569 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
2570 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2571 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, 0x40000000,
2572 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2531 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2532 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500,
2533 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2534 0xffffffff, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2573 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2535 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2574 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2536 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2575 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2537 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2576 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2538 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2577 0x00000000, 0x00007ff8, 0x00000000, 0x00003500, 0x00001000, 0x00002080, 2539 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
2578 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380, 2540 0x00000000, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
2579 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 2541 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
2580 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980, 2542 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
2581 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 2543 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
2582 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 2544 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
2583 0x00010001, 0x00000604, 0xccccccc1, 0xffffffff, 0xffffffff, 0xcccc0201, 2545 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
2584 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 2546 0xccccccc1, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, 0x00000000,
2547 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2585 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2548 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2586 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2549 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2587 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2550 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2588 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 2551 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
2589 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 2552 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000,
2590 0x00007ff8, 0x00000000, 0x00003500, 0x0000ffff, 0x00000000, 0x0000ffff, 2553 0x00003500, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
2591 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 2554 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
2555 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x00100000,
2592 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 2556 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
2593 0x00000000, 0x00100000, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
2594 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 2557 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
2595 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 2558 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x00100000,
2596 0x00000000, 0x00100000, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 2559 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2597 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 2560 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c,
2598 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
2599 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2600 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
2601 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
2602 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
2603 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2604 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c,
2605 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
2606 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
2607 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2608 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
2609 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 2561 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
2610 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 2562 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
2611 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 2563 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
2612 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 2564 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
2613 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 2565 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
2614 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 2566 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
2615 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 2567 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2616 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 2568 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c,
2617 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 2569 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
2618 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 2570 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
2619 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 2571 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2620 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 2572 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
2621 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 2573 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
2622 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 2574 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
2623 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 2575 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2624 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 2576 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
2625 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 2577 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7,
2626 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 2578 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
2627 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 2579 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2628 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 2580 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c,
2629 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 2581 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
2630 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 2582 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
2631 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 2583 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2632 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 2584 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
2633 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 2585 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
2634 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 2586 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
2635 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 2587 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2636 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 2588 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c,
2637 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 2589 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
2638 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 2590 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
2639 0xcdcdcdcd, 0xfffffff3, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 2591 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2640 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c, 2592 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
2641 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 2593 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
2642 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 2594 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
2643 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 2595 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
2644 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 2596 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
2645 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 2597 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a,
2646 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 2598 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c,
2647 0xcdcdcdcd, 0xffffff97, 0x040fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 2599 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
2648 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c, 2600 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c,
2649 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 2601 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
2650 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 2602 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
2651 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 2603 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2652 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 2604 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
2653 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 2605 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
2654 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 2606 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
2655 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 2607 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2656 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 2608 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
2657 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 2609 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
2658 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 2610 0x040fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
2659 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 2611 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
2660 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 2612 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
2661 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 2613 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
2662 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 2614 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
@@ -2678,16 +2630,27 @@ static const u32 init_data_e1[] = {
2678 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 2630 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
2679 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 2631 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
2680 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 2632 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
2681 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 2633 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
2682 0x00070100, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 2634 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
2683 0x00010370, 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 2635 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
2684 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 2636 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
2685 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 2637 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
2686 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 2638 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
2687 0x00080380, 0x00028000, 0x000b8028, 0x000200e0, 0x00010100, 0x00008110, 2639 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
2688 0x00000118, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, 2640 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
2689 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc, 2641 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
2690 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000 2642 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
2643 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
2644 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170,
2645 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370, 0x00080000,
2646 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200, 0x00070210,
2647 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198, 0x00020250,
2648 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100, 0x00028180,
2649 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380, 0x00028000,
2650 0x000b8028, 0x000200e0, 0x00010100, 0x00008110, 0x00000118, 0xcccccccc,
2651 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc,
2652 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc,
2653 0xcccccccc, 0x00002000
2691}; 2654};
2692 2655
2693static const u32 init_data_e1h[] = { 2656static const u32 init_data_e1h[] = {
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index ff2743db10d9..4ce7fe9c5251 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -21,7 +21,6 @@
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/ethtool.h> 22#include <linux/ethtool.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/version.h>
25 24
26#include "bnx2x_reg.h" 25#include "bnx2x_reg.h"
27#include "bnx2x_fw_defs.h" 26#include "bnx2x_fw_defs.h"
@@ -31,17 +30,16 @@
31 30
32/********************************************************/ 31/********************************************************/
33#define SUPPORT_CL73 0 /* Currently no */ 32#define SUPPORT_CL73 0 /* Currently no */
34#define ETH_HLEN 14 33#define ETH_HLEN 14
35#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/ 34#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
36#define ETH_MIN_PACKET_SIZE 60 35#define ETH_MIN_PACKET_SIZE 60
37#define ETH_MAX_PACKET_SIZE 1500 36#define ETH_MAX_PACKET_SIZE 1500
38#define ETH_MAX_JUMBO_PACKET_SIZE 9600 37#define ETH_MAX_JUMBO_PACKET_SIZE 9600
39#define MDIO_ACCESS_TIMEOUT 1000 38#define MDIO_ACCESS_TIMEOUT 1000
40#define BMAC_CONTROL_RX_ENABLE 2 39#define BMAC_CONTROL_RX_ENABLE 2
41#define MAX_MTU_SIZE 5000
42 40
43/***********************************************************/ 41/***********************************************************/
44/* Shortcut definitions */ 42/* Shortcut definitions */
45/***********************************************************/ 43/***********************************************************/
46 44
47#define NIG_STATUS_XGXS0_LINK10G \ 45#define NIG_STATUS_XGXS0_LINK10G \
@@ -80,12 +78,12 @@
80 78
81#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37 79#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
82#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73 80#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
83#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM 81#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
84#define AUTONEG_PARALLEL \ 82#define AUTONEG_PARALLEL \
85 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION 83 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
86#define AUTONEG_SGMII_FIBER_AUTODET \ 84#define AUTONEG_SGMII_FIBER_AUTODET \
87 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT 85 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
88#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY 86#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
89 87
90#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \ 88#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
91 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE 89 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
@@ -202,11 +200,10 @@ static void bnx2x_emac_init(struct link_params *params,
202 /* init emac - use read-modify-write */ 200 /* init emac - use read-modify-write */
203 /* self clear reset */ 201 /* self clear reset */
204 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 202 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
205 EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET)); 203 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
206 204
207 timeout = 200; 205 timeout = 200;
208 do 206 do {
209 {
210 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 207 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
211 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val); 208 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
212 if (!timeout) { 209 if (!timeout) {
@@ -214,18 +211,18 @@ static void bnx2x_emac_init(struct link_params *params,
214 return; 211 return;
215 } 212 }
216 timeout--; 213 timeout--;
217 }while (val & EMAC_MODE_RESET); 214 } while (val & EMAC_MODE_RESET);
218 215
219 /* Set mac address */ 216 /* Set mac address */
220 val = ((params->mac_addr[0] << 8) | 217 val = ((params->mac_addr[0] << 8) |
221 params->mac_addr[1]); 218 params->mac_addr[1]);
222 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val); 219 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
223 220
224 val = ((params->mac_addr[2] << 24) | 221 val = ((params->mac_addr[2] << 24) |
225 (params->mac_addr[3] << 16) | 222 (params->mac_addr[3] << 16) |
226 (params->mac_addr[4] << 8) | 223 (params->mac_addr[4] << 8) |
227 params->mac_addr[5]); 224 params->mac_addr[5]);
228 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val); 225 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
229} 226}
230 227
231static u8 bnx2x_emac_enable(struct link_params *params, 228static u8 bnx2x_emac_enable(struct link_params *params,
@@ -286,7 +283,7 @@ static u8 bnx2x_emac_enable(struct link_params *params,
286 if (CHIP_REV_IS_SLOW(bp)) { 283 if (CHIP_REV_IS_SLOW(bp)) {
287 /* config GMII mode */ 284 /* config GMII mode */
288 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 285 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
289 EMAC_WR(EMAC_REG_EMAC_MODE, 286 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
290 (val | EMAC_MODE_PORT_GMII)); 287 (val | EMAC_MODE_PORT_GMII));
291 } else { /* ASIC */ 288 } else { /* ASIC */
292 /* pause enable/disable */ 289 /* pause enable/disable */
@@ -298,17 +295,19 @@ static u8 bnx2x_emac_enable(struct link_params *params,
298 EMAC_RX_MODE_FLOW_EN); 295 EMAC_RX_MODE_FLOW_EN);
299 296
300 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, 297 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
301 EMAC_TX_MODE_EXT_PAUSE_EN); 298 (EMAC_TX_MODE_EXT_PAUSE_EN |
299 EMAC_TX_MODE_FLOW_EN));
302 if (vars->flow_ctrl & FLOW_CTRL_TX) 300 if (vars->flow_ctrl & FLOW_CTRL_TX)
303 bnx2x_bits_en(bp, emac_base + 301 bnx2x_bits_en(bp, emac_base +
304 EMAC_REG_EMAC_TX_MODE, 302 EMAC_REG_EMAC_TX_MODE,
305 EMAC_TX_MODE_EXT_PAUSE_EN); 303 (EMAC_TX_MODE_EXT_PAUSE_EN |
304 EMAC_TX_MODE_FLOW_EN));
306 } 305 }
307 306
308 /* KEEP_VLAN_TAG, promiscuous */ 307 /* KEEP_VLAN_TAG, promiscuous */
309 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); 308 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
310 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; 309 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
311 EMAC_WR(EMAC_REG_EMAC_RX_MODE, val); 310 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
312 311
313 /* Set Loopback */ 312 /* Set Loopback */
314 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 313 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
@@ -316,10 +315,10 @@ static u8 bnx2x_emac_enable(struct link_params *params,
316 val |= 0x810; 315 val |= 0x810;
317 else 316 else
318 val &= ~0x810; 317 val &= ~0x810;
319 EMAC_WR(EMAC_REG_EMAC_MODE, val); 318 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
320 319
321 /* enable emac for jumbo packets */ 320 /* enable emac for jumbo packets */
322 EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE, 321 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
323 (EMAC_RX_MTU_SIZE_JUMBO_ENA | 322 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
324 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); 323 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
325 324
@@ -591,9 +590,9 @@ void bnx2x_link_status_update(struct link_params *params,
591 vars->flow_ctrl &= ~FLOW_CTRL_RX; 590 vars->flow_ctrl &= ~FLOW_CTRL_RX;
592 591
593 if (vars->phy_flags & PHY_XGXS_FLAG) { 592 if (vars->phy_flags & PHY_XGXS_FLAG) {
594 if (params->req_line_speed && 593 if (vars->line_speed &&
595 ((params->req_line_speed == SPEED_10) || 594 ((vars->line_speed == SPEED_10) ||
596 (params->req_line_speed == SPEED_100))) { 595 (vars->line_speed == SPEED_100))) {
597 vars->phy_flags |= PHY_SGMII_FLAG; 596 vars->phy_flags |= PHY_SGMII_FLAG;
598 } else { 597 } else {
599 vars->phy_flags &= ~PHY_SGMII_FLAG; 598 vars->phy_flags &= ~PHY_SGMII_FLAG;
@@ -645,7 +644,7 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
645 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : 644 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
646 NIG_REG_INGRESS_BMAC0_MEM; 645 NIG_REG_INGRESS_BMAC0_MEM;
647 u32 wb_data[2]; 646 u32 wb_data[2];
648 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4); 647 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
649 648
650 /* Only if the bmac is out of reset */ 649 /* Only if the bmac is out of reset */
651 if (REG_RD(bp, MISC_REG_RESET_REG_2) & 650 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
@@ -670,7 +669,6 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
670 u8 port = params->port; 669 u8 port = params->port;
671 u32 init_crd, crd; 670 u32 init_crd, crd;
672 u32 count = 1000; 671 u32 count = 1000;
673 u32 pause = 0;
674 672
675 /* disable port */ 673 /* disable port */
676 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); 674 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
@@ -693,33 +691,25 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
693 return -EINVAL; 691 return -EINVAL;
694 } 692 }
695 693
696 if (flow_ctrl & FLOW_CTRL_RX) 694 if (flow_ctrl & FLOW_CTRL_RX ||
697 pause = 1; 695 line_speed == SPEED_10 ||
698 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, pause); 696 line_speed == SPEED_100 ||
699 if (pause) { 697 line_speed == SPEED_1000 ||
698 line_speed == SPEED_2500) {
699 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
700 /* update threshold */ 700 /* update threshold */
701 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); 701 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
702 /* update init credit */ 702 /* update init credit */
703 init_crd = 778; /* (800-18-4) */ 703 init_crd = 778; /* (800-18-4) */
704 704
705 } else { 705 } else {
706 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + 706 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
707 ETH_OVREHEAD)/16; 707 ETH_OVREHEAD)/16;
708 708 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
709 /* update threshold */ 709 /* update threshold */
710 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh); 710 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
711 /* update init credit */ 711 /* update init credit */
712 switch (line_speed) { 712 switch (line_speed) {
713 case SPEED_10:
714 case SPEED_100:
715 case SPEED_1000:
716 init_crd = thresh + 55 - 22;
717 break;
718
719 case SPEED_2500:
720 init_crd = thresh + 138 - 22;
721 break;
722
723 case SPEED_10000: 713 case SPEED_10000:
724 init_crd = thresh + 553 - 22; 714 init_crd = thresh + 553 - 22;
725 break; 715 break;
@@ -764,10 +754,10 @@ static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
764 emac_base = GRCBASE_EMAC0; 754 emac_base = GRCBASE_EMAC0;
765 break; 755 break;
766 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 756 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
767 emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1; 757 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
768 break; 758 break;
769 default: 759 default:
770 emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0; 760 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
771 break; 761 break;
772 } 762 }
773 return emac_base; 763 return emac_base;
@@ -1044,7 +1034,7 @@ static void bnx2x_set_swap_lanes(struct link_params *params)
1044} 1034}
1045 1035
1046static void bnx2x_set_parallel_detection(struct link_params *params, 1036static void bnx2x_set_parallel_detection(struct link_params *params,
1047 u8 phy_flags) 1037 u8 phy_flags)
1048{ 1038{
1049 struct bnx2x *bp = params->bp; 1039 struct bnx2x *bp = params->bp;
1050 u16 control2; 1040 u16 control2;
@@ -1114,7 +1104,7 @@ static void bnx2x_set_autoneg(struct link_params *params,
1114 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val); 1104 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1115 1105
1116 /* CL37 Autoneg Enabled */ 1106 /* CL37 Autoneg Enabled */
1117 if (params->req_line_speed == SPEED_AUTO_NEG) 1107 if (vars->line_speed == SPEED_AUTO_NEG)
1118 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN; 1108 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1119 else /* CL37 Autoneg Disabled */ 1109 else /* CL37 Autoneg Disabled */
1120 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 1110 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
@@ -1132,7 +1122,7 @@ static void bnx2x_set_autoneg(struct link_params *params,
1132 MDIO_REG_BANK_SERDES_DIGITAL, 1122 MDIO_REG_BANK_SERDES_DIGITAL,
1133 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val); 1123 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1134 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN; 1124 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1135 if (params->req_line_speed == SPEED_AUTO_NEG) 1125 if (vars->line_speed == SPEED_AUTO_NEG)
1136 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; 1126 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1137 else 1127 else
1138 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; 1128 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
@@ -1148,7 +1138,7 @@ static void bnx2x_set_autoneg(struct link_params *params,
1148 MDIO_REG_BANK_BAM_NEXT_PAGE, 1138 MDIO_REG_BANK_BAM_NEXT_PAGE,
1149 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, 1139 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1150 &reg_val); 1140 &reg_val);
1151 if (params->req_line_speed == SPEED_AUTO_NEG) { 1141 if (vars->line_speed == SPEED_AUTO_NEG) {
1152 /* Enable BAM aneg Mode and TetonII aneg Mode */ 1142 /* Enable BAM aneg Mode and TetonII aneg Mode */
1153 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | 1143 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1154 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); 1144 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
@@ -1164,7 +1154,7 @@ static void bnx2x_set_autoneg(struct link_params *params,
1164 reg_val); 1154 reg_val);
1165 1155
1166 /* Enable Clause 73 Aneg */ 1156 /* Enable Clause 73 Aneg */
1167 if ((params->req_line_speed == SPEED_AUTO_NEG) && 1157 if ((vars->line_speed == SPEED_AUTO_NEG) &&
1168 (SUPPORT_CL73)) { 1158 (SUPPORT_CL73)) {
1169 /* Enable BAM Station Manager */ 1159 /* Enable BAM Station Manager */
1170 1160
@@ -1226,7 +1216,8 @@ static void bnx2x_set_autoneg(struct link_params *params,
1226} 1216}
1227 1217
1228/* program SerDes, forced speed */ 1218/* program SerDes, forced speed */
1229static void bnx2x_program_serdes(struct link_params *params) 1219static void bnx2x_program_serdes(struct link_params *params,
1220 struct link_vars *vars)
1230{ 1221{
1231 struct bnx2x *bp = params->bp; 1222 struct bnx2x *bp = params->bp;
1232 u16 reg_val; 1223 u16 reg_val;
@@ -1248,28 +1239,35 @@ static void bnx2x_program_serdes(struct link_params *params)
1248 1239
1249 /* program speed 1240 /* program speed
1250 - needed only if the speed is greater than 1G (2.5G or 10G) */ 1241 - needed only if the speed is greater than 1G (2.5G or 10G) */
1251 if (!((params->req_line_speed == SPEED_1000) || 1242 CL45_RD_OVER_CL22(bp, params->port,
1252 (params->req_line_speed == SPEED_100) ||
1253 (params->req_line_speed == SPEED_10))) {
1254 CL45_RD_OVER_CL22(bp, params->port,
1255 params->phy_addr, 1243 params->phy_addr,
1256 MDIO_REG_BANK_SERDES_DIGITAL, 1244 MDIO_REG_BANK_SERDES_DIGITAL,
1257 MDIO_SERDES_DIGITAL_MISC1, &reg_val); 1245 MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1258 /* clearing the speed value before setting the right speed */ 1246 /* clearing the speed value before setting the right speed */
1259 reg_val &= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK; 1247 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1248
1249 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1250 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1251
1252 if (!((vars->line_speed == SPEED_1000) ||
1253 (vars->line_speed == SPEED_100) ||
1254 (vars->line_speed == SPEED_10))) {
1255
1260 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M | 1256 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1261 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL); 1257 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1262 if (params->req_line_speed == SPEED_10000) 1258 if (vars->line_speed == SPEED_10000)
1263 reg_val |= 1259 reg_val |=
1264 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; 1260 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1265 if (params->req_line_speed == SPEED_13000) 1261 if (vars->line_speed == SPEED_13000)
1266 reg_val |= 1262 reg_val |=
1267 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; 1263 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1268 CL45_WR_OVER_CL22(bp, params->port, 1264 }
1265
1266 CL45_WR_OVER_CL22(bp, params->port,
1269 params->phy_addr, 1267 params->phy_addr,
1270 MDIO_REG_BANK_SERDES_DIGITAL, 1268 MDIO_REG_BANK_SERDES_DIGITAL,
1271 MDIO_SERDES_DIGITAL_MISC1, reg_val); 1269 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1272 } 1270
1273} 1271}
1274 1272
1275static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) 1273static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
@@ -1295,48 +1293,49 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1295 MDIO_OVER_1G_UP3, 0); 1293 MDIO_OVER_1G_UP3, 0);
1296} 1294}
1297 1295
1298static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params, 1296static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1299 u32 *ieee_fc)
1300{ 1297{
1301 struct bnx2x *bp = params->bp; 1298 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1302 /* for AN, we are always publishing full duplex */
1303 u16 an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1304
1305 /* resolve pause mode and advertisement 1299 /* resolve pause mode and advertisement
1306 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ 1300 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1307 1301
1308 switch (params->req_flow_ctrl) { 1302 switch (params->req_flow_ctrl) {
1309 case FLOW_CTRL_AUTO: 1303 case FLOW_CTRL_AUTO:
1310 if (params->mtu <= MAX_MTU_SIZE) { 1304 if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) {
1311 an_adv |= 1305 *ieee_fc |=
1312 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 1306 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1313 } else { 1307 } else {
1314 an_adv |= 1308 *ieee_fc |=
1315 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; 1309 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1316 } 1310 }
1317 break; 1311 break;
1318 case FLOW_CTRL_TX: 1312 case FLOW_CTRL_TX:
1319 an_adv |= 1313 *ieee_fc |=
1320 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; 1314 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1321 break; 1315 break;
1322 1316
1323 case FLOW_CTRL_RX: 1317 case FLOW_CTRL_RX:
1324 case FLOW_CTRL_BOTH: 1318 case FLOW_CTRL_BOTH:
1325 an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 1319 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1326 break; 1320 break;
1327 1321
1328 case FLOW_CTRL_NONE: 1322 case FLOW_CTRL_NONE:
1329 default: 1323 default:
1330 an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; 1324 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1331 break; 1325 break;
1332 } 1326 }
1327}
1333 1328
1334 *ieee_fc = an_adv; 1329static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1330 u32 ieee_fc)
1331{
1332 struct bnx2x *bp = params->bp;
1333 /* for AN, we are always publishing full duplex */
1335 1334
1336 CL45_WR_OVER_CL22(bp, params->port, 1335 CL45_WR_OVER_CL22(bp, params->port,
1337 params->phy_addr, 1336 params->phy_addr,
1338 MDIO_REG_BANK_COMBO_IEEE0, 1337 MDIO_REG_BANK_COMBO_IEEE0,
1339 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, an_adv); 1338 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1340} 1339}
1341 1340
1342static void bnx2x_restart_autoneg(struct link_params *params) 1341static void bnx2x_restart_autoneg(struct link_params *params)
@@ -1382,7 +1381,8 @@ static void bnx2x_restart_autoneg(struct link_params *params)
1382 } 1381 }
1383} 1382}
1384 1383
1385static void bnx2x_initialize_sgmii_process(struct link_params *params) 1384static void bnx2x_initialize_sgmii_process(struct link_params *params,
1385 struct link_vars *vars)
1386{ 1386{
1387 struct bnx2x *bp = params->bp; 1387 struct bnx2x *bp = params->bp;
1388 u16 control1; 1388 u16 control1;
@@ -1406,7 +1406,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params)
1406 control1); 1406 control1);
1407 1407
1408 /* if forced speed */ 1408 /* if forced speed */
1409 if (!(params->req_line_speed == SPEED_AUTO_NEG)) { 1409 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1410 /* set speed, disable autoneg */ 1410 /* set speed, disable autoneg */
1411 u16 mii_control; 1411 u16 mii_control;
1412 1412
@@ -1419,7 +1419,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params)
1419 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK| 1419 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1420 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX); 1420 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1421 1421
1422 switch (params->req_line_speed) { 1422 switch (vars->line_speed) {
1423 case SPEED_100: 1423 case SPEED_100:
1424 mii_control |= 1424 mii_control |=
1425 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100; 1425 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
@@ -1433,8 +1433,8 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params)
1433 break; 1433 break;
1434 default: 1434 default:
1435 /* invalid speed for SGMII */ 1435 /* invalid speed for SGMII */
1436 DP(NETIF_MSG_LINK, "Invalid req_line_speed 0x%x\n", 1436 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1437 params->req_line_speed); 1437 vars->line_speed);
1438 break; 1438 break;
1439 } 1439 }
1440 1440
@@ -1460,20 +1460,20 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params)
1460 */ 1460 */
1461 1461
1462static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) 1462static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1463{ 1463{ /* LD LP */
1464 switch (pause_result) { /* ASYM P ASYM P */ 1464 switch (pause_result) { /* ASYM P ASYM P */
1465 case 0xb: /* 1 0 1 1 */ 1465 case 0xb: /* 1 0 1 1 */
1466 vars->flow_ctrl = FLOW_CTRL_TX; 1466 vars->flow_ctrl = FLOW_CTRL_TX;
1467 break; 1467 break;
1468 1468
1469 case 0xe: /* 1 1 1 0 */ 1469 case 0xe: /* 1 1 1 0 */
1470 vars->flow_ctrl = FLOW_CTRL_RX; 1470 vars->flow_ctrl = FLOW_CTRL_RX;
1471 break; 1471 break;
1472 1472
1473 case 0x5: /* 0 1 0 1 */ 1473 case 0x5: /* 0 1 0 1 */
1474 case 0x7: /* 0 1 1 1 */ 1474 case 0x7: /* 0 1 1 1 */
1475 case 0xd: /* 1 1 0 1 */ 1475 case 0xd: /* 1 1 0 1 */
1476 case 0xf: /* 1 1 1 1 */ 1476 case 0xf: /* 1 1 1 1 */
1477 vars->flow_ctrl = FLOW_CTRL_BOTH; 1477 vars->flow_ctrl = FLOW_CTRL_BOTH;
1478 break; 1478 break;
1479 1479
@@ -1531,6 +1531,28 @@ static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1531 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n", 1531 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1532 pause_result); 1532 pause_result);
1533 bnx2x_pause_resolve(vars, pause_result); 1533 bnx2x_pause_resolve(vars, pause_result);
1534 if (vars->flow_ctrl == FLOW_CTRL_NONE &&
1535 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1536 bnx2x_cl45_read(bp, port,
1537 ext_phy_type,
1538 ext_phy_addr,
1539 MDIO_AN_DEVAD,
1540 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1541
1542 bnx2x_cl45_read(bp, port,
1543 ext_phy_type,
1544 ext_phy_addr,
1545 MDIO_AN_DEVAD,
1546 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1547 pause_result = (ld_pause &
1548 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1549 pause_result |= (lp_pause &
1550 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1551
1552 bnx2x_pause_resolve(vars, pause_result);
1553 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1554 pause_result);
1555 }
1534 } 1556 }
1535 return ret; 1557 return ret;
1536} 1558}
@@ -1541,8 +1563,8 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1541 u32 gp_status) 1563 u32 gp_status)
1542{ 1564{
1543 struct bnx2x *bp = params->bp; 1565 struct bnx2x *bp = params->bp;
1544 u16 ld_pause; /* local driver */ 1566 u16 ld_pause; /* local driver */
1545 u16 lp_pause; /* link partner */ 1567 u16 lp_pause; /* link partner */
1546 u16 pause_result; 1568 u16 pause_result;
1547 1569
1548 vars->flow_ctrl = FLOW_CTRL_NONE; 1570 vars->flow_ctrl = FLOW_CTRL_NONE;
@@ -1573,13 +1595,10 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1573 (bnx2x_ext_phy_resove_fc(params, vars))) { 1595 (bnx2x_ext_phy_resove_fc(params, vars))) {
1574 return; 1596 return;
1575 } else { 1597 } else {
1576 vars->flow_ctrl = params->req_flow_ctrl; 1598 if (params->req_flow_ctrl == FLOW_CTRL_AUTO)
1577 if (vars->flow_ctrl == FLOW_CTRL_AUTO) { 1599 vars->flow_ctrl = params->req_fc_auto_adv;
1578 if (params->mtu <= MAX_MTU_SIZE) 1600 else
1579 vars->flow_ctrl = FLOW_CTRL_BOTH; 1601 vars->flow_ctrl = params->req_flow_ctrl;
1580 else
1581 vars->flow_ctrl = FLOW_CTRL_TX;
1582 }
1583 } 1602 }
1584 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); 1603 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1585} 1604}
@@ -1590,6 +1609,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1590 u32 gp_status) 1609 u32 gp_status)
1591{ 1610{
1592 struct bnx2x *bp = params->bp; 1611 struct bnx2x *bp = params->bp;
1612
1593 u8 rc = 0; 1613 u8 rc = 0;
1594 vars->link_status = 0; 1614 vars->link_status = 0;
1595 1615
@@ -1690,7 +1710,11 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1690 1710
1691 vars->link_status |= LINK_STATUS_SERDES_LINK; 1711 vars->link_status |= LINK_STATUS_SERDES_LINK;
1692 1712
1693 if (params->req_line_speed == SPEED_AUTO_NEG) { 1713 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1714 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1715 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1716 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1717 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1694 vars->autoneg = AUTO_NEG_ENABLED; 1718 vars->autoneg = AUTO_NEG_ENABLED;
1695 1719
1696 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { 1720 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
@@ -1705,18 +1729,18 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1705 1729
1706 } 1730 }
1707 if (vars->flow_ctrl & FLOW_CTRL_TX) 1731 if (vars->flow_ctrl & FLOW_CTRL_TX)
1708 vars->link_status |= 1732 vars->link_status |=
1709 LINK_STATUS_TX_FLOW_CONTROL_ENABLED; 1733 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1710 1734
1711 if (vars->flow_ctrl & FLOW_CTRL_RX) 1735 if (vars->flow_ctrl & FLOW_CTRL_RX)
1712 vars->link_status |= 1736 vars->link_status |=
1713 LINK_STATUS_RX_FLOW_CONTROL_ENABLED; 1737 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1714 1738
1715 } else { /* link_down */ 1739 } else { /* link_down */
1716 DP(NETIF_MSG_LINK, "phy link down\n"); 1740 DP(NETIF_MSG_LINK, "phy link down\n");
1717 1741
1718 vars->phy_link_up = 0; 1742 vars->phy_link_up = 0;
1719 vars->line_speed = 0; 1743
1720 vars->duplex = DUPLEX_FULL; 1744 vars->duplex = DUPLEX_FULL;
1721 vars->flow_ctrl = FLOW_CTRL_NONE; 1745 vars->flow_ctrl = FLOW_CTRL_NONE;
1722 vars->autoneg = AUTO_NEG_DISABLED; 1746 vars->autoneg = AUTO_NEG_DISABLED;
@@ -1817,15 +1841,15 @@ static u8 bnx2x_emac_program(struct link_params *params,
1817} 1841}
1818 1842
1819/*****************************************************************************/ 1843/*****************************************************************************/
1820/* External Phy section */ 1844/* External Phy section */
1821/*****************************************************************************/ 1845/*****************************************************************************/
1822static void bnx2x_hw_reset(struct bnx2x *bp) 1846static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1823{ 1847{
1824 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 1848 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1825 MISC_REGISTERS_GPIO_OUTPUT_LOW); 1849 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1826 msleep(1); 1850 msleep(1);
1827 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 1851 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1828 MISC_REGISTERS_GPIO_OUTPUT_HIGH); 1852 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1829} 1853}
1830 1854
1831static void bnx2x_ext_phy_reset(struct link_params *params, 1855static void bnx2x_ext_phy_reset(struct link_params *params,
@@ -1854,10 +1878,11 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
1854 1878
1855 /* Restore normal power mode*/ 1879 /* Restore normal power mode*/
1856 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 1880 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1857 MISC_REGISTERS_GPIO_OUTPUT_HIGH); 1881 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1882 params->port);
1858 1883
1859 /* HW reset */ 1884 /* HW reset */
1860 bnx2x_hw_reset(bp); 1885 bnx2x_hw_reset(bp, params->port);
1861 1886
1862 bnx2x_cl45_write(bp, params->port, 1887 bnx2x_cl45_write(bp, params->port,
1863 ext_phy_type, 1888 ext_phy_type,
@@ -1869,7 +1894,8 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
1869 /* Unset Low Power Mode and SW reset */ 1894 /* Unset Low Power Mode and SW reset */
1870 /* Restore normal power mode*/ 1895 /* Restore normal power mode*/
1871 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 1896 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1872 MISC_REGISTERS_GPIO_OUTPUT_HIGH); 1897 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1898 params->port);
1873 1899
1874 DP(NETIF_MSG_LINK, "XGXS 8072\n"); 1900 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1875 bnx2x_cl45_write(bp, params->port, 1901 bnx2x_cl45_write(bp, params->port,
@@ -1887,19 +1913,14 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
1887 1913
1888 /* Restore normal power mode*/ 1914 /* Restore normal power mode*/
1889 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 1915 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1890 MISC_REGISTERS_GPIO_OUTPUT_HIGH); 1916 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1917 params->port);
1891 1918
1892 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 1919 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1893 MISC_REGISTERS_GPIO_OUTPUT_HIGH); 1920 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1921 params->port);
1894 1922
1895 DP(NETIF_MSG_LINK, "XGXS 8073\n"); 1923 DP(NETIF_MSG_LINK, "XGXS 8073\n");
1896 bnx2x_cl45_write(bp,
1897 params->port,
1898 ext_phy_type,
1899 ext_phy_addr,
1900 MDIO_PMA_DEVAD,
1901 MDIO_PMA_REG_CTRL,
1902 1<<15);
1903 } 1924 }
1904 break; 1925 break;
1905 1926
@@ -1908,10 +1929,11 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
1908 1929
1909 /* Restore normal power mode*/ 1930 /* Restore normal power mode*/
1910 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 1931 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1911 MISC_REGISTERS_GPIO_OUTPUT_HIGH); 1932 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1933 params->port);
1912 1934
1913 /* HW reset */ 1935 /* HW reset */
1914 bnx2x_hw_reset(bp); 1936 bnx2x_hw_reset(bp, params->port);
1915 1937
1916 break; 1938 break;
1917 1939
@@ -1934,7 +1956,7 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
1934 1956
1935 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: 1957 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1936 DP(NETIF_MSG_LINK, "SerDes 5482\n"); 1958 DP(NETIF_MSG_LINK, "SerDes 5482\n");
1937 bnx2x_hw_reset(bp); 1959 bnx2x_hw_reset(bp, params->port);
1938 break; 1960 break;
1939 1961
1940 default: 1962 default:
@@ -2098,42 +2120,45 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2098 2120
2099} 2121}
2100 2122
2101static void bnx2x_bcm8073_external_rom_boot(struct link_params *params) 2123static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2124 u8 ext_phy_addr)
2102{ 2125{
2103 struct bnx2x *bp = params->bp; 2126 u16 fw_ver1, fw_ver2;
2104 u8 port = params->port; 2127 /* Boot port from external ROM */
2105 u8 ext_phy_addr = ((params->ext_phy_config &
2106 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2107 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2108 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2109 u16 fw_ver1, fw_ver2, val;
2110 /* Need to wait 100ms after reset */
2111 msleep(100);
2112 /* Boot port from external ROM */
2113 /* EDC grst */ 2128 /* EDC grst */
2114 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2129 bnx2x_cl45_write(bp, port,
2130 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2131 ext_phy_addr,
2115 MDIO_PMA_DEVAD, 2132 MDIO_PMA_DEVAD,
2116 MDIO_PMA_REG_GEN_CTRL, 2133 MDIO_PMA_REG_GEN_CTRL,
2117 0x0001); 2134 0x0001);
2118 2135
2119 /* ucode reboot and rst */ 2136 /* ucode reboot and rst */
2120 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2137 bnx2x_cl45_write(bp, port,
2138 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2139 ext_phy_addr,
2121 MDIO_PMA_DEVAD, 2140 MDIO_PMA_DEVAD,
2122 MDIO_PMA_REG_GEN_CTRL, 2141 MDIO_PMA_REG_GEN_CTRL,
2123 0x008c); 2142 0x008c);
2124 2143
2125 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2144 bnx2x_cl45_write(bp, port,
2145 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2146 ext_phy_addr,
2126 MDIO_PMA_DEVAD, 2147 MDIO_PMA_DEVAD,
2127 MDIO_PMA_REG_MISC_CTRL1, 0x0001); 2148 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2128 2149
2129 /* Reset internal microprocessor */ 2150 /* Reset internal microprocessor */
2130 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2151 bnx2x_cl45_write(bp, port,
2152 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2153 ext_phy_addr,
2131 MDIO_PMA_DEVAD, 2154 MDIO_PMA_DEVAD,
2132 MDIO_PMA_REG_GEN_CTRL, 2155 MDIO_PMA_REG_GEN_CTRL,
2133 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); 2156 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2134 2157
2135 /* Release srst bit */ 2158 /* Release srst bit */
2136 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2159 bnx2x_cl45_write(bp, port,
2160 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2161 ext_phy_addr,
2137 MDIO_PMA_DEVAD, 2162 MDIO_PMA_DEVAD,
2138 MDIO_PMA_REG_GEN_CTRL, 2163 MDIO_PMA_REG_GEN_CTRL,
2139 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); 2164 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
@@ -2142,35 +2167,52 @@ static void bnx2x_bcm8073_external_rom_boot(struct link_params *params)
2142 msleep(100); 2167 msleep(100);
2143 2168
2144 /* Clear ser_boot_ctl bit */ 2169 /* Clear ser_boot_ctl bit */
2145 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2170 bnx2x_cl45_write(bp, port,
2171 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2172 ext_phy_addr,
2146 MDIO_PMA_DEVAD, 2173 MDIO_PMA_DEVAD,
2147 MDIO_PMA_REG_MISC_CTRL1, 0x0000); 2174 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2148 2175
2149 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, 2176 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2150 MDIO_PMA_DEVAD, 2177 ext_phy_addr,
2151 MDIO_PMA_REG_ROM_VER1, &fw_ver1); 2178 MDIO_PMA_DEVAD,
2152 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, 2179 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2153 MDIO_PMA_DEVAD, 2180 bnx2x_cl45_read(bp, port,
2154 MDIO_PMA_REG_ROM_VER2, &fw_ver2); 2181 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2182 ext_phy_addr,
2183 MDIO_PMA_DEVAD,
2184 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2155 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2); 2185 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2156 2186
2157 /* Only set bit 10 = 1 (Tx power down) */ 2187}
2158 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2159 MDIO_PMA_DEVAD,
2160 MDIO_PMA_REG_TX_POWER_DOWN, &val);
2161 2188
2189static void bnx2x_bcm807x_force_10G(struct link_params *params)
2190{
2191 struct bnx2x *bp = params->bp;
2192 u8 port = params->port;
2193 u8 ext_phy_addr = ((params->ext_phy_config &
2194 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2195 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2196 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2197
2198 /* Force KR or KX */
2162 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2199 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2163 MDIO_PMA_DEVAD, 2200 MDIO_PMA_DEVAD,
2164 MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10)); 2201 MDIO_PMA_REG_CTRL,
2165 2202 0x2040);
2166 msleep(600);
2167 /* Release bit 10 (Release Tx power down) */
2168 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2203 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2169 MDIO_PMA_DEVAD, 2204 MDIO_PMA_DEVAD,
2170 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); 2205 MDIO_PMA_REG_10G_CTRL2,
2171 2206 0x000b);
2207 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2208 MDIO_PMA_DEVAD,
2209 MDIO_PMA_REG_BCM_CTRL,
2210 0x0000);
2211 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2212 MDIO_AN_DEVAD,
2213 MDIO_AN_REG_CTRL,
2214 0x0000);
2172} 2215}
2173
2174static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) 2216static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2175{ 2217{
2176 struct bnx2x *bp = params->bp; 2218 struct bnx2x *bp = params->bp;
@@ -2236,32 +2278,51 @@ static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2236 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2278 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2237 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); 2279 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2238} 2280}
2239static void bnx2x_bcm807x_force_10G(struct link_params *params) 2281
2282static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2283 struct link_vars *vars)
2240{ 2284{
2285
2241 struct bnx2x *bp = params->bp; 2286 struct bnx2x *bp = params->bp;
2242 u8 port = params->port; 2287 u16 cl37_val;
2243 u8 ext_phy_addr = ((params->ext_phy_config & 2288 u8 ext_phy_addr = ((params->ext_phy_config &
2244 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> 2289 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2245 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); 2290 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2246 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 2291 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2247 2292
2248 /* Force KR or KX */ 2293 bnx2x_cl45_read(bp, params->port,
2249 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2294 ext_phy_type,
2250 MDIO_PMA_DEVAD, 2295 ext_phy_addr,
2251 MDIO_PMA_REG_CTRL, 2296 MDIO_AN_DEVAD,
2252 0x2040); 2297 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2253 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2298
2254 MDIO_PMA_DEVAD, 2299 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2255 MDIO_PMA_REG_10G_CTRL2, 2300 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2256 0x000b); 2301
2257 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2302 if ((vars->ieee_fc &
2258 MDIO_PMA_DEVAD, 2303 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2259 MDIO_PMA_REG_BCM_CTRL, 2304 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2260 0x0000); 2305 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2261 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 2306 }
2307 if ((vars->ieee_fc &
2308 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2309 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2310 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2311 }
2312 if ((vars->ieee_fc &
2313 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2314 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2315 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2316 }
2317 DP(NETIF_MSG_LINK,
2318 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2319
2320 bnx2x_cl45_write(bp, params->port,
2321 ext_phy_type,
2322 ext_phy_addr,
2262 MDIO_AN_DEVAD, 2323 MDIO_AN_DEVAD,
2263 MDIO_AN_REG_CTRL, 2324 MDIO_AN_REG_CL37_FC_LD, cl37_val);
2264 0x0000); 2325 msleep(500);
2265} 2326}
2266 2327
2267static void bnx2x_ext_phy_set_pause(struct link_params *params, 2328static void bnx2x_ext_phy_set_pause(struct link_params *params,
@@ -2282,13 +2343,16 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
2282 MDIO_AN_REG_ADV_PAUSE, &val); 2343 MDIO_AN_REG_ADV_PAUSE, &val);
2283 2344
2284 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; 2345 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2346
2285 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ 2347 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2286 2348
2287 if (vars->ieee_fc & 2349 if ((vars->ieee_fc &
2350 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2288 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { 2351 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2289 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; 2352 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2290 } 2353 }
2291 if (vars->ieee_fc & 2354 if ((vars->ieee_fc &
2355 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2292 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { 2356 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2293 val |= 2357 val |=
2294 MDIO_AN_REG_ADV_PAUSE_PAUSE; 2358 MDIO_AN_REG_ADV_PAUSE_PAUSE;
@@ -2302,6 +2366,65 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
2302 MDIO_AN_REG_ADV_PAUSE, val); 2366 MDIO_AN_REG_ADV_PAUSE, val);
2303} 2367}
2304 2368
2369
2370static void bnx2x_init_internal_phy(struct link_params *params,
2371 struct link_vars *vars)
2372{
2373 struct bnx2x *bp = params->bp;
2374 u8 port = params->port;
2375 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2376 u16 bank, rx_eq;
2377
2378 rx_eq = ((params->serdes_config &
2379 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2380 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2381
2382 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2383 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2384 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2385 CL45_WR_OVER_CL22(bp, port,
2386 params->phy_addr,
2387 bank ,
2388 MDIO_RX0_RX_EQ_BOOST,
2389 ((rx_eq &
2390 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2391 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2392 }
2393
2394 /* forced speed requested? */
2395 if (vars->line_speed != SPEED_AUTO_NEG) {
2396 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2397
2398 /* disable autoneg */
2399 bnx2x_set_autoneg(params, vars);
2400
2401 /* program speed and duplex */
2402 bnx2x_program_serdes(params, vars);
2403
2404 } else { /* AN_mode */
2405 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2406
2407 /* AN enabled */
2408 bnx2x_set_brcm_cl37_advertisment(params);
2409
2410 /* program duplex & pause advertisement (for aneg) */
2411 bnx2x_set_ieee_aneg_advertisment(params,
2412 vars->ieee_fc);
2413
2414 /* enable autoneg */
2415 bnx2x_set_autoneg(params, vars);
2416
2417 /* enable and restart AN */
2418 bnx2x_restart_autoneg(params);
2419 }
2420
2421 } else { /* SGMII mode */
2422 DP(NETIF_MSG_LINK, "SGMII\n");
2423
2424 bnx2x_initialize_sgmii_process(params, vars);
2425 }
2426}
2427
2305static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) 2428static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2306{ 2429{
2307 struct bnx2x *bp = params->bp; 2430 struct bnx2x *bp = params->bp;
@@ -2343,7 +2466,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2343 2466
2344 switch (ext_phy_type) { 2467 switch (ext_phy_type) {
2345 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 2468 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2346 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2347 break; 2469 break;
2348 2470
2349 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 2471 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
@@ -2419,7 +2541,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2419 ext_phy_type, 2541 ext_phy_type,
2420 ext_phy_addr, 2542 ext_phy_addr,
2421 MDIO_AN_DEVAD, 2543 MDIO_AN_DEVAD,
2422 MDIO_AN_REG_CL37_FD, 2544 MDIO_AN_REG_CL37_FC_LP,
2423 0x0020); 2545 0x0020);
2424 /* Enable CL37 AN */ 2546 /* Enable CL37 AN */
2425 bnx2x_cl45_write(bp, params->port, 2547 bnx2x_cl45_write(bp, params->port,
@@ -2458,54 +2580,43 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2458 rx_alarm_ctrl_val = 0x400; 2580 rx_alarm_ctrl_val = 0x400;
2459 lasi_ctrl_val = 0x0004; 2581 lasi_ctrl_val = 0x0004;
2460 } else { 2582 } else {
2461 /* In 8073, port1 is directed through emac0 and
2462 * port0 is directed through emac1
2463 */
2464 rx_alarm_ctrl_val = (1<<2); 2583 rx_alarm_ctrl_val = (1<<2);
2465 /*lasi_ctrl_val = 0x0005;*/
2466 lasi_ctrl_val = 0x0004; 2584 lasi_ctrl_val = 0x0004;
2467 } 2585 }
2468 2586
2469 /* Wait for soft reset to get cleared upto 1 sec */ 2587 /* enable LASI */
2470 for (cnt = 0; cnt < 1000; cnt++) { 2588 bnx2x_cl45_write(bp, params->port,
2471 bnx2x_cl45_read(bp, params->port, 2589 ext_phy_type,
2472 ext_phy_type, 2590 ext_phy_addr,
2473 ext_phy_addr, 2591 MDIO_PMA_DEVAD,
2474 MDIO_PMA_DEVAD, 2592 MDIO_PMA_REG_RX_ALARM_CTRL,
2475 MDIO_PMA_REG_CTRL, 2593 rx_alarm_ctrl_val);
2476 &ctrl); 2594
2477 if (!(ctrl & (1<<15))) 2595 bnx2x_cl45_write(bp, params->port,
2478 break; 2596 ext_phy_type,
2479 msleep(1); 2597 ext_phy_addr,
2480 } 2598 MDIO_PMA_DEVAD,
2481 DP(NETIF_MSG_LINK, 2599 MDIO_PMA_REG_LASI_CTRL,
2482 "807x control reg 0x%x (after %d ms)\n", 2600 lasi_ctrl_val);
2483 ctrl, cnt); 2601
2602 bnx2x_8073_set_pause_cl37(params, vars);
2484 2603
2485 if (ext_phy_type == 2604 if (ext_phy_type ==
2486 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){ 2605 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2487 bnx2x_bcm8072_external_rom_boot(params); 2606 bnx2x_bcm8072_external_rom_boot(params);
2488 } else { 2607 } else {
2489 bnx2x_bcm8073_external_rom_boot(params); 2608
2490 /* In case of 8073 with long xaui lines, 2609 /* In case of 8073 with long xaui lines,
2491 don't set the 8073 xaui low power*/ 2610 don't set the 8073 xaui low power*/
2492 bnx2x_bcm8073_set_xaui_low_power_mode(params); 2611 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2493 } 2612 }
2494 2613
2495 /* enable LASI */ 2614 bnx2x_cl45_read(bp, params->port,
2496 bnx2x_cl45_write(bp, params->port, 2615 ext_phy_type,
2497 ext_phy_type, 2616 ext_phy_addr,
2498 ext_phy_addr, 2617 MDIO_PMA_DEVAD,
2499 MDIO_PMA_DEVAD, 2618 0xca13,
2500 MDIO_PMA_REG_RX_ALARM_CTRL, 2619 &tmp1);
2501 rx_alarm_ctrl_val);
2502
2503 bnx2x_cl45_write(bp, params->port,
2504 ext_phy_type,
2505 ext_phy_addr,
2506 MDIO_PMA_DEVAD,
2507 MDIO_PMA_REG_LASI_CTRL,
2508 lasi_ctrl_val);
2509 2620
2510 bnx2x_cl45_read(bp, params->port, 2621 bnx2x_cl45_read(bp, params->port,
2511 ext_phy_type, 2622 ext_phy_type,
@@ -2519,12 +2630,21 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2519 /* If this is forced speed, set to KR or KX 2630 /* If this is forced speed, set to KR or KX
2520 * (all other are not supported) 2631 * (all other are not supported)
2521 */ 2632 */
2522 if (!(params->req_line_speed == SPEED_AUTO_NEG)) { 2633 if (params->loopback_mode == LOOPBACK_EXT) {
2523 if (params->req_line_speed == SPEED_10000) { 2634 bnx2x_bcm807x_force_10G(params);
2524 bnx2x_bcm807x_force_10G(params); 2635 DP(NETIF_MSG_LINK,
2525 DP(NETIF_MSG_LINK, 2636 "Forced speed 10G on 807X\n");
2526 "Forced speed 10G on 807X\n"); 2637 break;
2527 break; 2638 } else {
2639 bnx2x_cl45_write(bp, params->port,
2640 ext_phy_type, ext_phy_addr,
2641 MDIO_PMA_DEVAD,
2642 MDIO_PMA_REG_BCM_CTRL,
2643 0x0002);
2644 }
2645 if (params->req_line_speed != SPEED_AUTO_NEG) {
2646 if (params->req_line_speed == SPEED_10000) {
2647 val = (1<<7);
2528 } else if (params->req_line_speed == 2648 } else if (params->req_line_speed ==
2529 SPEED_2500) { 2649 SPEED_2500) {
2530 val = (1<<5); 2650 val = (1<<5);
@@ -2539,11 +2659,14 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2539 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) 2659 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2540 val |= (1<<7); 2660 val |= (1<<7);
2541 2661
2662 /* Note that 2.5G works only when
2663 used with 1G advertisment */
2542 if (params->speed_cap_mask & 2664 if (params->speed_cap_mask &
2543 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) 2665 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
2666 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
2544 val |= (1<<5); 2667 val |= (1<<5);
2545 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); 2668 DP(NETIF_MSG_LINK,
2546 /*val = ((1<<5)|(1<<7));*/ 2669 "807x autoneg val = 0x%x\n", val);
2547 } 2670 }
2548 2671
2549 bnx2x_cl45_write(bp, params->port, 2672 bnx2x_cl45_write(bp, params->port,
@@ -2554,20 +2677,19 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2554 2677
2555 if (ext_phy_type == 2678 if (ext_phy_type ==
2556 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { 2679 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2557 /* Disable 2.5Ghz */ 2680
2558 bnx2x_cl45_read(bp, params->port, 2681 bnx2x_cl45_read(bp, params->port,
2559 ext_phy_type, 2682 ext_phy_type,
2560 ext_phy_addr, 2683 ext_phy_addr,
2561 MDIO_AN_DEVAD, 2684 MDIO_AN_DEVAD,
2562 0x8329, &tmp1); 2685 0x8329, &tmp1);
2563/* SUPPORT_SPEED_CAPABILITY 2686
2564 (Due to the nature of the link order, its not 2687 if (((params->speed_cap_mask &
2565 possible to enable 2.5G within the autoneg 2688 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
2566 capabilities) 2689 (params->req_line_speed ==
2567 if (params->speed_cap_mask & 2690 SPEED_AUTO_NEG)) ||
2568 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) 2691 (params->req_line_speed ==
2569*/ 2692 SPEED_2500)) {
2570 if (params->req_line_speed == SPEED_2500) {
2571 u16 phy_ver; 2693 u16 phy_ver;
2572 /* Allow 2.5G for A1 and above */ 2694 /* Allow 2.5G for A1 and above */
2573 bnx2x_cl45_read(bp, params->port, 2695 bnx2x_cl45_read(bp, params->port,
@@ -2575,49 +2697,53 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2575 ext_phy_addr, 2697 ext_phy_addr,
2576 MDIO_PMA_DEVAD, 2698 MDIO_PMA_DEVAD,
2577 0xc801, &phy_ver); 2699 0xc801, &phy_ver);
2578 2700 DP(NETIF_MSG_LINK, "Add 2.5G\n");
2579 if (phy_ver > 0) 2701 if (phy_ver > 0)
2580 tmp1 |= 1; 2702 tmp1 |= 1;
2581 else 2703 else
2582 tmp1 &= 0xfffe; 2704 tmp1 &= 0xfffe;
2583 } 2705 } else {
2584 else 2706 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
2585 tmp1 &= 0xfffe; 2707 tmp1 &= 0xfffe;
2708 }
2586 2709
2587 bnx2x_cl45_write(bp, params->port, 2710 bnx2x_cl45_write(bp, params->port,
2588 ext_phy_type, 2711 ext_phy_type,
2589 ext_phy_addr, 2712 ext_phy_addr,
2590 MDIO_AN_DEVAD, 2713 MDIO_AN_DEVAD,
2591 0x8329, tmp1); 2714 0x8329, tmp1);
2592 } 2715 }
2593 /* Add support for CL37 (passive mode) I */ 2716
2594 bnx2x_cl45_write(bp, params->port, 2717 /* Add support for CL37 (passive mode) II */
2718
2719 bnx2x_cl45_read(bp, params->port,
2595 ext_phy_type, 2720 ext_phy_type,
2596 ext_phy_addr, 2721 ext_phy_addr,
2597 MDIO_AN_DEVAD, 2722 MDIO_AN_DEVAD,
2598 MDIO_AN_REG_CL37_CL73, 0x040c); 2723 MDIO_AN_REG_CL37_FC_LD,
2599 /* Add support for CL37 (passive mode) II */ 2724 &tmp1);
2725
2600 bnx2x_cl45_write(bp, params->port, 2726 bnx2x_cl45_write(bp, params->port,
2601 ext_phy_type, 2727 ext_phy_type,
2602 ext_phy_addr, 2728 ext_phy_addr,
2603 MDIO_AN_DEVAD, 2729 MDIO_AN_DEVAD,
2604 MDIO_AN_REG_CL37_FD, 0x20); 2730 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
2731 ((params->req_duplex == DUPLEX_FULL) ?
2732 0x20 : 0x40)));
2733
2605 /* Add support for CL37 (passive mode) III */ 2734 /* Add support for CL37 (passive mode) III */
2606 bnx2x_cl45_write(bp, params->port, 2735 bnx2x_cl45_write(bp, params->port,
2607 ext_phy_type, 2736 ext_phy_type,
2608 ext_phy_addr, 2737 ext_phy_addr,
2609 MDIO_AN_DEVAD, 2738 MDIO_AN_DEVAD,
2610 MDIO_AN_REG_CL37_AN, 0x1000); 2739 MDIO_AN_REG_CL37_AN, 0x1000);
2611 /* Restart autoneg */
2612 msleep(500);
2613 2740
2614 if (ext_phy_type == 2741 if (ext_phy_type ==
2615 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { 2742 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2616 2743 /* The SNR will improve about 2db by changing
2617 /* The SNR will improve about 2db by changing the
2618 BW and FEE main tap. Rest commands are executed 2744 BW and FEE main tap. Rest commands are executed
2619 after link is up*/ 2745 after link is up*/
2620 /* Change FFE main cursor to 5 in EDC register */ 2746 /*Change FFE main cursor to 5 in EDC register*/
2621 if (bnx2x_8073_is_snr_needed(params)) 2747 if (bnx2x_8073_is_snr_needed(params))
2622 bnx2x_cl45_write(bp, params->port, 2748 bnx2x_cl45_write(bp, params->port,
2623 ext_phy_type, 2749 ext_phy_type,
@@ -2626,25 +2752,28 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2626 MDIO_PMA_REG_EDC_FFE_MAIN, 2752 MDIO_PMA_REG_EDC_FFE_MAIN,
2627 0xFB0C); 2753 0xFB0C);
2628 2754
2629 /* Enable FEC (Forware Error Correction) 2755 /* Enable FEC (Forware Error Correction)
2630 Request in the AN */ 2756 Request in the AN */
2631 bnx2x_cl45_read(bp, params->port, 2757 bnx2x_cl45_read(bp, params->port,
2632 ext_phy_type, 2758 ext_phy_type,
2633 ext_phy_addr, 2759 ext_phy_addr,
2634 MDIO_AN_DEVAD, 2760 MDIO_AN_DEVAD,
2635 MDIO_AN_REG_ADV2, &tmp1); 2761 MDIO_AN_REG_ADV2, &tmp1);
2636 2762
2637 tmp1 |= (1<<15); 2763 tmp1 |= (1<<15);
2764
2765 bnx2x_cl45_write(bp, params->port,
2766 ext_phy_type,
2767 ext_phy_addr,
2768 MDIO_AN_DEVAD,
2769 MDIO_AN_REG_ADV2, tmp1);
2638 2770
2639 bnx2x_cl45_write(bp, params->port,
2640 ext_phy_type,
2641 ext_phy_addr,
2642 MDIO_AN_DEVAD,
2643 MDIO_AN_REG_ADV2, tmp1);
2644 } 2771 }
2645 2772
2646 bnx2x_ext_phy_set_pause(params, vars); 2773 bnx2x_ext_phy_set_pause(params, vars);
2647 2774
2775 /* Restart autoneg */
2776 msleep(500);
2648 bnx2x_cl45_write(bp, params->port, 2777 bnx2x_cl45_write(bp, params->port,
2649 ext_phy_type, 2778 ext_phy_type,
2650 ext_phy_addr, 2779 ext_phy_addr,
@@ -2701,10 +2830,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2701 } 2830 }
2702 2831
2703 } else { /* SerDes */ 2832 } else { /* SerDes */
2704/* ext_phy_addr = ((bp->ext_phy_config & 2833
2705 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
2706 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
2707*/
2708 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); 2834 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2709 switch (ext_phy_type) { 2835 switch (ext_phy_type) {
2710 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: 2836 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
@@ -2726,7 +2852,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2726 2852
2727 2853
2728static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, 2854static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2729 struct link_vars *vars) 2855 struct link_vars *vars)
2730{ 2856{
2731 struct bnx2x *bp = params->bp; 2857 struct bnx2x *bp = params->bp;
2732 u32 ext_phy_type; 2858 u32 ext_phy_type;
@@ -2767,6 +2893,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2767 MDIO_PMA_REG_RX_SD, &rx_sd); 2893 MDIO_PMA_REG_RX_SD, &rx_sd);
2768 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd); 2894 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2769 ext_phy_link_up = (rx_sd & 0x1); 2895 ext_phy_link_up = (rx_sd & 0x1);
2896 if (ext_phy_link_up)
2897 vars->line_speed = SPEED_10000;
2770 break; 2898 break;
2771 2899
2772 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 2900 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
@@ -2810,6 +2938,13 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2810 */ 2938 */
2811 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || 2939 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2812 (val2 & (1<<1))); 2940 (val2 & (1<<1)));
2941 if (ext_phy_link_up) {
2942 if (val2 & (1<<1))
2943 vars->line_speed = SPEED_1000;
2944 else
2945 vars->line_speed = SPEED_10000;
2946 }
2947
2813 /* clear LASI indication*/ 2948 /* clear LASI indication*/
2814 bnx2x_cl45_read(bp, params->port, ext_phy_type, 2949 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2815 ext_phy_addr, 2950 ext_phy_addr,
@@ -2820,6 +2955,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2820 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 2955 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2821 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 2956 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2822 { 2957 {
2958 u16 link_status = 0;
2959 u16 an1000_status = 0;
2823 if (ext_phy_type == 2960 if (ext_phy_type ==
2824 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { 2961 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2825 bnx2x_cl45_read(bp, params->port, 2962 bnx2x_cl45_read(bp, params->port,
@@ -2846,14 +2983,9 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2846 MDIO_PMA_DEVAD, 2983 MDIO_PMA_DEVAD,
2847 MDIO_PMA_REG_LASI_STATUS, &val1); 2984 MDIO_PMA_REG_LASI_STATUS, &val1);
2848 2985
2849 bnx2x_cl45_read(bp, params->port,
2850 ext_phy_type,
2851 ext_phy_addr,
2852 MDIO_PMA_DEVAD,
2853 MDIO_PMA_REG_LASI_STATUS, &val2);
2854 DP(NETIF_MSG_LINK, 2986 DP(NETIF_MSG_LINK,
2855 "8703 LASI status 0x%x->0x%x\n", 2987 "8703 LASI status 0x%x\n",
2856 val1, val2); 2988 val1);
2857 } 2989 }
2858 2990
2859 /* clear the interrupt LASI status register */ 2991 /* clear the interrupt LASI status register */
@@ -2869,20 +3001,23 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2869 MDIO_PCS_REG_STATUS, &val1); 3001 MDIO_PCS_REG_STATUS, &val1);
2870 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", 3002 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
2871 val2, val1); 3003 val2, val1);
2872 /* Check the LASI */ 3004 /* Clear MSG-OUT */
2873 bnx2x_cl45_read(bp, params->port, 3005 bnx2x_cl45_read(bp, params->port,
2874 ext_phy_type, 3006 ext_phy_type,
2875 ext_phy_addr, 3007 ext_phy_addr,
2876 MDIO_PMA_DEVAD, 3008 MDIO_PMA_DEVAD,
2877 MDIO_PMA_REG_RX_ALARM, &val2); 3009 0xca13,
3010 &val1);
3011
3012 /* Check the LASI */
2878 bnx2x_cl45_read(bp, params->port, 3013 bnx2x_cl45_read(bp, params->port,
2879 ext_phy_type, 3014 ext_phy_type,
2880 ext_phy_addr, 3015 ext_phy_addr,
2881 MDIO_PMA_DEVAD, 3016 MDIO_PMA_DEVAD,
2882 MDIO_PMA_REG_RX_ALARM, 3017 MDIO_PMA_REG_RX_ALARM, &val2);
2883 &val1); 3018
2884 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n", 3019 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
2885 val2, val1); 3020
2886 /* Check the link status */ 3021 /* Check the link status */
2887 bnx2x_cl45_read(bp, params->port, 3022 bnx2x_cl45_read(bp, params->port,
2888 ext_phy_type, 3023 ext_phy_type,
@@ -2905,29 +3040,29 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2905 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); 3040 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
2906 if (ext_phy_type == 3041 if (ext_phy_type ==
2907 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { 3042 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2908 u16 an1000_status = 0; 3043
2909 if (ext_phy_link_up && 3044 if (ext_phy_link_up &&
2910 ( 3045 ((params->req_line_speed !=
2911 (params->req_line_speed != SPEED_10000) 3046 SPEED_10000))) {
2912 )) {
2913 if (bnx2x_bcm8073_xaui_wa(params) 3047 if (bnx2x_bcm8073_xaui_wa(params)
2914 != 0) { 3048 != 0) {
2915 ext_phy_link_up = 0; 3049 ext_phy_link_up = 0;
2916 break; 3050 break;
2917 } 3051 }
2918 bnx2x_cl45_read(bp, params->port, 3052 }
3053 bnx2x_cl45_read(bp, params->port,
2919 ext_phy_type, 3054 ext_phy_type,
2920 ext_phy_addr, 3055 ext_phy_addr,
2921 MDIO_XS_DEVAD, 3056 MDIO_AN_DEVAD,
2922 0x8304, 3057 0x8304,
2923 &an1000_status); 3058 &an1000_status);
2924 bnx2x_cl45_read(bp, params->port, 3059 bnx2x_cl45_read(bp, params->port,
2925 ext_phy_type, 3060 ext_phy_type,
2926 ext_phy_addr, 3061 ext_phy_addr,
2927 MDIO_XS_DEVAD, 3062 MDIO_AN_DEVAD,
2928 0x8304, 3063 0x8304,
2929 &an1000_status); 3064 &an1000_status);
2930 } 3065
2931 /* Check the link status on 1.1.2 */ 3066 /* Check the link status on 1.1.2 */
2932 bnx2x_cl45_read(bp, params->port, 3067 bnx2x_cl45_read(bp, params->port,
2933 ext_phy_type, 3068 ext_phy_type,
@@ -2943,8 +3078,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2943 "an_link_status=0x%x\n", 3078 "an_link_status=0x%x\n",
2944 val2, val1, an1000_status); 3079 val2, val1, an1000_status);
2945 3080
2946 ext_phy_link_up = (((val1 & 4) == 4) || 3081 ext_phy_link_up = (((val1 & 4) == 4) ||
2947 (an1000_status & (1<<1))); 3082 (an1000_status & (1<<1)));
2948 if (ext_phy_link_up && 3083 if (ext_phy_link_up &&
2949 bnx2x_8073_is_snr_needed(params)) { 3084 bnx2x_8073_is_snr_needed(params)) {
2950 /* The SNR will improve about 2dbby 3085 /* The SNR will improve about 2dbby
@@ -2968,8 +3103,74 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2968 MDIO_PMA_REG_CDR_BANDWIDTH, 3103 MDIO_PMA_REG_CDR_BANDWIDTH,
2969 0x0333); 3104 0x0333);
2970 3105
3106
3107 }
3108 bnx2x_cl45_read(bp, params->port,
3109 ext_phy_type,
3110 ext_phy_addr,
3111 MDIO_PMA_DEVAD,
3112 0xc820,
3113 &link_status);
3114
3115 /* Bits 0..2 --> speed detected,
3116 bits 13..15--> link is down */
3117 if ((link_status & (1<<2)) &&
3118 (!(link_status & (1<<15)))) {
3119 ext_phy_link_up = 1;
3120 vars->line_speed = SPEED_10000;
3121 DP(NETIF_MSG_LINK,
3122 "port %x: External link"
3123 " up in 10G\n", params->port);
3124 } else if ((link_status & (1<<1)) &&
3125 (!(link_status & (1<<14)))) {
3126 ext_phy_link_up = 1;
3127 vars->line_speed = SPEED_2500;
3128 DP(NETIF_MSG_LINK,
3129 "port %x: External link"
3130 " up in 2.5G\n", params->port);
3131 } else if ((link_status & (1<<0)) &&
3132 (!(link_status & (1<<13)))) {
3133 ext_phy_link_up = 1;
3134 vars->line_speed = SPEED_1000;
3135 DP(NETIF_MSG_LINK,
3136 "port %x: External link"
3137 " up in 1G\n", params->port);
3138 } else {
3139 ext_phy_link_up = 0;
3140 DP(NETIF_MSG_LINK,
3141 "port %x: External link"
3142 " is down\n", params->port);
3143 }
3144 } else {
3145 /* See if 1G link is up for the 8072 */
3146 bnx2x_cl45_read(bp, params->port,
3147 ext_phy_type,
3148 ext_phy_addr,
3149 MDIO_AN_DEVAD,
3150 0x8304,
3151 &an1000_status);
3152 bnx2x_cl45_read(bp, params->port,
3153 ext_phy_type,
3154 ext_phy_addr,
3155 MDIO_AN_DEVAD,
3156 0x8304,
3157 &an1000_status);
3158 if (an1000_status & (1<<1)) {
3159 ext_phy_link_up = 1;
3160 vars->line_speed = SPEED_1000;
3161 DP(NETIF_MSG_LINK,
3162 "port %x: External link"
3163 " up in 1G\n", params->port);
3164 } else if (ext_phy_link_up) {
3165 ext_phy_link_up = 1;
3166 vars->line_speed = SPEED_10000;
3167 DP(NETIF_MSG_LINK,
3168 "port %x: External link"
3169 " up in 10G\n", params->port);
2971 } 3170 }
2972 } 3171 }
3172
3173
2973 break; 3174 break;
2974 } 3175 }
2975 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 3176 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
@@ -3006,6 +3207,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3006 MDIO_AN_DEVAD, 3207 MDIO_AN_DEVAD,
3007 MDIO_AN_REG_MASTER_STATUS, 3208 MDIO_AN_REG_MASTER_STATUS,
3008 &val2); 3209 &val2);
3210 vars->line_speed = SPEED_10000;
3009 DP(NETIF_MSG_LINK, 3211 DP(NETIF_MSG_LINK,
3010 "SFX7101 AN status 0x%x->Master=%x\n", 3212 "SFX7101 AN status 0x%x->Master=%x\n",
3011 val2, 3213 val2,
@@ -3100,7 +3302,7 @@ static void bnx2x_link_int_enable(struct link_params *params)
3100 * link management 3302 * link management
3101 */ 3303 */
3102static void bnx2x_link_int_ack(struct link_params *params, 3304static void bnx2x_link_int_ack(struct link_params *params,
3103 struct link_vars *vars, u16 is_10g) 3305 struct link_vars *vars, u8 is_10g)
3104{ 3306{
3105 struct bnx2x *bp = params->bp; 3307 struct bnx2x *bp = params->bp;
3106 u8 port = params->port; 3308 u8 port = params->port;
@@ -3181,7 +3383,8 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3181} 3383}
3182 3384
3183 3385
3184static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr) 3386static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3387 u32 ext_phy_type)
3185{ 3388{
3186 u32 cnt = 0; 3389 u32 cnt = 0;
3187 u16 ctrl = 0; 3390 u16 ctrl = 0;
@@ -3192,12 +3395,14 @@ static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
3192 3395
3193 /* take ext phy out of reset */ 3396 /* take ext phy out of reset */
3194 bnx2x_set_gpio(bp, 3397 bnx2x_set_gpio(bp,
3195 MISC_REGISTERS_GPIO_2, 3398 MISC_REGISTERS_GPIO_2,
3196 MISC_REGISTERS_GPIO_HIGH); 3399 MISC_REGISTERS_GPIO_HIGH,
3400 port);
3197 3401
3198 bnx2x_set_gpio(bp, 3402 bnx2x_set_gpio(bp,
3199 MISC_REGISTERS_GPIO_1, 3403 MISC_REGISTERS_GPIO_1,
3200 MISC_REGISTERS_GPIO_HIGH); 3404 MISC_REGISTERS_GPIO_HIGH,
3405 port);
3201 3406
3202 /* wait for 5ms */ 3407 /* wait for 5ms */
3203 msleep(5); 3408 msleep(5);
@@ -3205,7 +3410,7 @@ static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
3205 for (cnt = 0; cnt < 1000; cnt++) { 3410 for (cnt = 0; cnt < 1000; cnt++) {
3206 msleep(1); 3411 msleep(1);
3207 bnx2x_cl45_read(bp, port, 3412 bnx2x_cl45_read(bp, port,
3208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, 3413 ext_phy_type,
3209 ext_phy_addr, 3414 ext_phy_addr,
3210 MDIO_PMA_DEVAD, 3415 MDIO_PMA_DEVAD,
3211 MDIO_PMA_REG_CTRL, 3416 MDIO_PMA_REG_CTRL,
@@ -3217,13 +3422,17 @@ static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
3217 } 3422 }
3218} 3423}
3219 3424
3220static void bnx2x_turn_off_sf(struct bnx2x *bp) 3425static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
3221{ 3426{
3222 /* put sf to reset */ 3427 /* put sf to reset */
3223 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_LOW);
3224 bnx2x_set_gpio(bp, 3428 bnx2x_set_gpio(bp,
3225 MISC_REGISTERS_GPIO_2, 3429 MISC_REGISTERS_GPIO_1,
3226 MISC_REGISTERS_GPIO_LOW); 3430 MISC_REGISTERS_GPIO_LOW,
3431 port);
3432 bnx2x_set_gpio(bp,
3433 MISC_REGISTERS_GPIO_2,
3434 MISC_REGISTERS_GPIO_LOW,
3435 port);
3227} 3436}
3228 3437
3229u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, 3438u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
@@ -3253,7 +3462,8 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3253 3462
3254 /* Take ext phy out of reset */ 3463 /* Take ext phy out of reset */
3255 if (!driver_loaded) 3464 if (!driver_loaded)
3256 bnx2x_turn_on_sf(bp, params->port, ext_phy_addr); 3465 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3466 ext_phy_type);
3257 3467
3258 /* wait for 1ms */ 3468 /* wait for 1ms */
3259 msleep(1); 3469 msleep(1);
@@ -3276,11 +3486,16 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3276 version[4] = '\0'; 3486 version[4] = '\0';
3277 3487
3278 if (!driver_loaded) 3488 if (!driver_loaded)
3279 bnx2x_turn_off_sf(bp); 3489 bnx2x_turn_off_sf(bp, params->port);
3280 break; 3490 break;
3281 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 3491 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3282 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 3492 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3283 { 3493 {
3494 /* Take ext phy out of reset */
3495 if (!driver_loaded)
3496 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3497 ext_phy_type);
3498
3284 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3499 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3285 ext_phy_addr, 3500 ext_phy_addr,
3286 MDIO_PMA_DEVAD, 3501 MDIO_PMA_DEVAD,
@@ -3333,7 +3548,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params,
3333 struct bnx2x *bp = params->bp; 3548 struct bnx2x *bp = params->bp;
3334 3549
3335 if (is_10g) { 3550 if (is_10g) {
3336 u32 md_devad; 3551 u32 md_devad;
3337 3552
3338 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); 3553 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3339 3554
@@ -3553,6 +3768,8 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3553 u16 hw_led_mode, u32 chip_id) 3768 u16 hw_led_mode, u32 chip_id)
3554{ 3769{
3555 u8 rc = 0; 3770 u8 rc = 0;
3771 u32 tmp;
3772 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3556 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); 3773 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3557 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", 3774 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3558 speed, hw_led_mode); 3775 speed, hw_led_mode);
@@ -3561,6 +3778,9 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3561 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); 3778 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3562 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 3779 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3563 SHARED_HW_CFG_LED_MAC1); 3780 SHARED_HW_CFG_LED_MAC1);
3781
3782 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3783 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3564 break; 3784 break;
3565 3785
3566 case LED_MODE_OPER: 3786 case LED_MODE_OPER:
@@ -3572,6 +3792,10 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3572 LED_BLINK_RATE_VAL); 3792 LED_BLINK_RATE_VAL);
3573 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + 3793 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3574 port*4, 1); 3794 port*4, 1);
3795 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3796 EMAC_WR(bp, EMAC_REG_EMAC_LED,
3797 (tmp & (~EMAC_LED_OVERRIDE)));
3798
3575 if (!CHIP_IS_E1H(bp) && 3799 if (!CHIP_IS_E1H(bp) &&
3576 ((speed == SPEED_2500) || 3800 ((speed == SPEED_2500) ||
3577 (speed == SPEED_1000) || 3801 (speed == SPEED_1000) ||
@@ -3622,7 +3846,8 @@ static u8 bnx2x_link_initialize(struct link_params *params,
3622 struct bnx2x *bp = params->bp; 3846 struct bnx2x *bp = params->bp;
3623 u8 port = params->port; 3847 u8 port = params->port;
3624 u8 rc = 0; 3848 u8 rc = 0;
3625 3849 u8 non_ext_phy;
3850 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3626 /* Activate the external PHY */ 3851 /* Activate the external PHY */
3627 bnx2x_ext_phy_reset(params, vars); 3852 bnx2x_ext_phy_reset(params, vars);
3628 3853
@@ -3644,10 +3869,6 @@ static u8 bnx2x_link_initialize(struct link_params *params,
3644 bnx2x_set_swap_lanes(params); 3869 bnx2x_set_swap_lanes(params);
3645 } 3870 }
3646 3871
3647 /* Set Parallel Detect */
3648 if (params->req_line_speed == SPEED_AUTO_NEG)
3649 bnx2x_set_parallel_detection(params, vars->phy_flags);
3650
3651 if (vars->phy_flags & PHY_XGXS_FLAG) { 3872 if (vars->phy_flags & PHY_XGXS_FLAG) {
3652 if (params->req_line_speed && 3873 if (params->req_line_speed &&
3653 ((params->req_line_speed == SPEED_100) || 3874 ((params->req_line_speed == SPEED_100) ||
@@ -3657,68 +3878,33 @@ static u8 bnx2x_link_initialize(struct link_params *params,
3657 vars->phy_flags &= ~PHY_SGMII_FLAG; 3878 vars->phy_flags &= ~PHY_SGMII_FLAG;
3658 } 3879 }
3659 } 3880 }
3881 /* In case of external phy existance, the line speed would be the
3882 line speed linked up by the external phy. In case it is direct only,
3883 then the line_speed during initialization will be equal to the
3884 req_line_speed*/
3885 vars->line_speed = params->req_line_speed;
3660 3886
3661 if (!(vars->phy_flags & PHY_SGMII_FLAG)) { 3887 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
3662 u16 bank, rx_eq;
3663
3664 rx_eq = ((params->serdes_config &
3665 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
3666 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
3667 3888
3668 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq); 3889 /* init ext phy and enable link state int */
3669 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL; 3890 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3670 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) { 3891 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3671 CL45_WR_OVER_CL22(bp, port, 3892 (params->loopback_mode == LOOPBACK_EXT_PHY));
3672 params->phy_addr, 3893
3673 bank , 3894 if (non_ext_phy ||
3674 MDIO_RX0_RX_EQ_BOOST, 3895 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3675 ((rx_eq & 3896 if (params->req_line_speed == SPEED_AUTO_NEG)
3676 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) | 3897 bnx2x_set_parallel_detection(params, vars->phy_flags);
3677 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL)); 3898 bnx2x_init_internal_phy(params, vars);
3678 }
3679
3680 /* forced speed requested? */
3681 if (params->req_line_speed != SPEED_AUTO_NEG) {
3682 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3683
3684 /* disable autoneg */
3685 bnx2x_set_autoneg(params, vars);
3686
3687 /* program speed and duplex */
3688 bnx2x_program_serdes(params);
3689 vars->ieee_fc =
3690 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3691
3692 } else { /* AN_mode */
3693 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3694
3695 /* AN enabled */
3696 bnx2x_set_brcm_cl37_advertisment(params);
3697
3698 /* program duplex & pause advertisement (for aneg) */
3699 bnx2x_set_ieee_aneg_advertisment(params,
3700 &vars->ieee_fc);
3701
3702 /* enable autoneg */
3703 bnx2x_set_autoneg(params, vars);
3704
3705 /* enable and restart AN */
3706 bnx2x_restart_autoneg(params);
3707 }
3708
3709 } else { /* SGMII mode */
3710 DP(NETIF_MSG_LINK, "SGMII\n");
3711
3712 bnx2x_initialize_sgmii_process(params);
3713 } 3899 }
3714 3900
3715 /* init ext phy and enable link state int */ 3901 if (!non_ext_phy)
3716 rc |= bnx2x_ext_phy_init(params, vars); 3902 rc |= bnx2x_ext_phy_init(params, vars);
3717 3903
3718 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, 3904 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3719 (NIG_STATUS_XGXS0_LINK10G | 3905 (NIG_STATUS_XGXS0_LINK10G |
3720 NIG_STATUS_XGXS0_LINK_STATUS | 3906 NIG_STATUS_XGXS0_LINK_STATUS |
3721 NIG_STATUS_SERDES0_LINK_STATUS)); 3907 NIG_STATUS_SERDES0_LINK_STATUS));
3722 3908
3723 return rc; 3909 return rc;
3724 3910
@@ -3730,15 +3916,23 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3730 struct bnx2x *bp = params->bp; 3916 struct bnx2x *bp = params->bp;
3731 3917
3732 u32 val; 3918 u32 val;
3733 DP(NETIF_MSG_LINK, "Phy Initialization started\n"); 3919 DP(NETIF_MSG_LINK, "Phy Initialization started \n");
3734 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n", 3920 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3735 params->req_line_speed, params->req_flow_ctrl); 3921 params->req_line_speed, params->req_flow_ctrl);
3736 vars->link_status = 0; 3922 vars->link_status = 0;
3923 vars->phy_link_up = 0;
3924 vars->link_up = 0;
3925 vars->line_speed = 0;
3926 vars->duplex = DUPLEX_FULL;
3927 vars->flow_ctrl = FLOW_CTRL_NONE;
3928 vars->mac_type = MAC_TYPE_NONE;
3929
3737 if (params->switch_cfg == SWITCH_CFG_1G) 3930 if (params->switch_cfg == SWITCH_CFG_1G)
3738 vars->phy_flags = PHY_SERDES_FLAG; 3931 vars->phy_flags = PHY_SERDES_FLAG;
3739 else 3932 else
3740 vars->phy_flags = PHY_XGXS_FLAG; 3933 vars->phy_flags = PHY_XGXS_FLAG;
3741 3934
3935
3742 /* disable attentions */ 3936 /* disable attentions */
3743 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, 3937 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3744 (NIG_MASK_XGXS0_LINK_STATUS | 3938 (NIG_MASK_XGXS0_LINK_STATUS |
@@ -3894,6 +4088,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3894 } 4088 }
3895 4089
3896 bnx2x_link_initialize(params, vars); 4090 bnx2x_link_initialize(params, vars);
4091 msleep(30);
3897 bnx2x_link_int_enable(params); 4092 bnx2x_link_int_enable(params);
3898 } 4093 }
3899 return 0; 4094 return 0;
@@ -3943,39 +4138,22 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3943 /* HW reset */ 4138 /* HW reset */
3944 4139
3945 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 4140 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3946 MISC_REGISTERS_GPIO_OUTPUT_LOW); 4141 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4142 port);
3947 4143
3948 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 4144 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3949 MISC_REGISTERS_GPIO_OUTPUT_LOW); 4145 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4146 port);
3950 4147
3951 DP(NETIF_MSG_LINK, "reset external PHY\n"); 4148 DP(NETIF_MSG_LINK, "reset external PHY\n");
3952 } else { 4149 } else if (ext_phy_type ==
3953 4150 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3954 u8 ext_phy_addr = ((ext_phy_config & 4151 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
3955 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3956 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3957
3958 /* SW reset */
3959 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3960 MDIO_PMA_DEVAD,
3961 MDIO_PMA_REG_CTRL,
3962 1<<15);
3963
3964 /* Set Low Power Mode */
3965 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3966 MDIO_PMA_DEVAD,
3967 MDIO_PMA_REG_CTRL,
3968 1<<11);
3969
3970
3971 if (ext_phy_type ==
3972 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3973 DP(NETIF_MSG_LINK, "Setting 8073 port %d into"
3974 "low power mode\n", 4152 "low power mode\n",
3975 port); 4153 port);
3976 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 4154 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3977 MISC_REGISTERS_GPIO_OUTPUT_LOW); 4155 MISC_REGISTERS_GPIO_OUTPUT_LOW,
3978 } 4156 port);
3979 } 4157 }
3980 } 4158 }
3981 /* reset the SerDes/XGXS */ 4159 /* reset the SerDes/XGXS */
@@ -3995,6 +4173,73 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3995 return 0; 4173 return 0;
3996} 4174}
3997 4175
4176static u8 bnx2x_update_link_down(struct link_params *params,
4177 struct link_vars *vars)
4178{
4179 struct bnx2x *bp = params->bp;
4180 u8 port = params->port;
4181 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4182 bnx2x_set_led(bp, port, LED_MODE_OFF,
4183 0, params->hw_led_mode,
4184 params->chip_id);
4185
4186 /* indicate no mac active */
4187 vars->mac_type = MAC_TYPE_NONE;
4188
4189 /* update shared memory */
4190 vars->link_status = 0;
4191 vars->line_speed = 0;
4192 bnx2x_update_mng(params, vars->link_status);
4193
4194 /* activate nig drain */
4195 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4196
4197 /* reset BigMac */
4198 bnx2x_bmac_rx_disable(bp, params->port);
4199 REG_WR(bp, GRCBASE_MISC +
4200 MISC_REGISTERS_RESET_REG_2_CLEAR,
4201 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4202 return 0;
4203}
4204
4205static u8 bnx2x_update_link_up(struct link_params *params,
4206 struct link_vars *vars,
4207 u8 link_10g, u32 gp_status)
4208{
4209 struct bnx2x *bp = params->bp;
4210 u8 port = params->port;
4211 u8 rc = 0;
4212 vars->link_status |= LINK_STATUS_LINK_UP;
4213 if (link_10g) {
4214 bnx2x_bmac_enable(params, vars, 0);
4215 bnx2x_set_led(bp, port, LED_MODE_OPER,
4216 SPEED_10000, params->hw_led_mode,
4217 params->chip_id);
4218
4219 } else {
4220 bnx2x_emac_enable(params, vars, 0);
4221 rc = bnx2x_emac_program(params, vars->line_speed,
4222 vars->duplex);
4223
4224 /* AN complete? */
4225 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4226 if (!(vars->phy_flags &
4227 PHY_SGMII_FLAG))
4228 bnx2x_set_sgmii_tx_driver(params);
4229 }
4230 }
4231
4232 /* PBF - link up */
4233 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4234 vars->line_speed);
4235
4236 /* disable drain */
4237 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4238
4239 /* update shared memory */
4240 bnx2x_update_mng(params, vars->link_status);
4241 return rc;
4242}
3998/* This function should called upon link interrupt */ 4243/* This function should called upon link interrupt */
3999/* In case vars->link_up, driver needs to 4244/* In case vars->link_up, driver needs to
4000 1. Update the pbf 4245 1. Update the pbf
@@ -4012,10 +4257,10 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4012{ 4257{
4013 struct bnx2x *bp = params->bp; 4258 struct bnx2x *bp = params->bp;
4014 u8 port = params->port; 4259 u8 port = params->port;
4015 u16 i;
4016 u16 gp_status; 4260 u16 gp_status;
4017 u16 link_10g; 4261 u8 link_10g;
4018 u8 rc = 0; 4262 u8 ext_phy_link_up, rc = 0;
4263 u32 ext_phy_type;
4019 4264
4020 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", 4265 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4021 port, 4266 port,
@@ -4031,15 +4276,16 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4031 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), 4276 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4032 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); 4277 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4033 4278
4279 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4034 4280
4035 /* avoid fast toggling */ 4281 /* Check external link change only for non-direct */
4036 for (i = 0; i < 10; i++) { 4282 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4037 msleep(10); 4283
4038 CL45_RD_OVER_CL22(bp, port, params->phy_addr, 4284 /* Read gp_status */
4039 MDIO_REG_BANK_GP_STATUS, 4285 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4040 MDIO_GP_STATUS_TOP_AN_STATUS1, 4286 MDIO_REG_BANK_GP_STATUS,
4041 &gp_status); 4287 MDIO_GP_STATUS_TOP_AN_STATUS1,
4042 } 4288 &gp_status);
4043 4289
4044 rc = bnx2x_link_settings_status(params, vars, gp_status); 4290 rc = bnx2x_link_settings_status(params, vars, gp_status);
4045 if (rc != 0) 4291 if (rc != 0)
@@ -4055,73 +4301,177 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4055 4301
4056 bnx2x_link_int_ack(params, vars, link_10g); 4302 bnx2x_link_int_ack(params, vars, link_10g);
4057 4303
4304 /* In case external phy link is up, and internal link is down
4305 ( not initialized yet probably after link initialization, it needs
4306 to be initialized.
4307 Note that after link down-up as result of cable plug,
4308 the xgxs link would probably become up again without the need to
4309 initialize it*/
4310
4311 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4312 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4313 (ext_phy_link_up && !vars->phy_link_up))
4314 bnx2x_init_internal_phy(params, vars);
4315
4058 /* link is up only if both local phy and external phy are up */ 4316 /* link is up only if both local phy and external phy are up */
4059 vars->link_up = (vars->phy_link_up && 4317 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4060 bnx2x_ext_phy_is_link_up(params, vars));
4061 4318
4062 if (!vars->phy_link_up && 4319 if (vars->link_up)
4063 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18)) { 4320 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4064 bnx2x_ext_phy_is_link_up(params, vars); /* Clear interrupt */ 4321 else
4322 rc = bnx2x_update_link_down(params, vars);
4323
4324 return rc;
4325}
4326
4327static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4328{
4329 u8 ext_phy_addr[PORT_MAX];
4330 u16 val;
4331 s8 port;
4332
4333 /* PART1 - Reset both phys */
4334 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4335 /* Extract the ext phy address for the port */
4336 u32 ext_phy_config = REG_RD(bp, shmem_base +
4337 offsetof(struct shmem_region,
4338 dev_info.port_hw_config[port].external_phy_config));
4339
4340 /* disable attentions */
4341 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4342 (NIG_MASK_XGXS0_LINK_STATUS |
4343 NIG_MASK_XGXS0_LINK10G |
4344 NIG_MASK_SERDES0_LINK_STATUS |
4345 NIG_MASK_MI_INT));
4346
4347 ext_phy_addr[port] =
4348 ((ext_phy_config &
4349 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4350 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4351
4352 /* Need to take the phy out of low power mode in order
4353 to write to access its registers */
4354 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4355 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
4356
4357 /* Reset the phy */
4358 bnx2x_cl45_write(bp, port,
4359 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4360 ext_phy_addr[port],
4361 MDIO_PMA_DEVAD,
4362 MDIO_PMA_REG_CTRL,
4363 1<<15);
4065 } 4364 }
4066 4365
4067 if (vars->link_up) { 4366 /* Add delay of 150ms after reset */
4068 vars->link_status |= LINK_STATUS_LINK_UP; 4367 msleep(150);
4069 if (link_10g) {
4070 bnx2x_bmac_enable(params, vars, 0);
4071 bnx2x_set_led(bp, port, LED_MODE_OPER,
4072 SPEED_10000, params->hw_led_mode,
4073 params->chip_id);
4074 4368
4075 } else { 4369 /* PART2 - Download firmware to both phys */
4076 bnx2x_emac_enable(params, vars, 0); 4370 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4077 rc = bnx2x_emac_program(params, vars->line_speed, 4371 u16 fw_ver1;
4078 vars->duplex);
4079 4372
4080 /* AN complete? */ 4373 bnx2x_bcm8073_external_rom_boot(bp, port,
4081 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { 4374 ext_phy_addr[port]);
4082 if (!(vars->phy_flags & 4375
4083 PHY_SGMII_FLAG)) 4376 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4084 bnx2x_set_sgmii_tx_driver(params); 4377 ext_phy_addr[port],
4085 } 4378 MDIO_PMA_DEVAD,
4379 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
4380 if (fw_ver1 == 0) {
4381 DP(NETIF_MSG_LINK,
4382 "bnx2x_8073_common_init_phy port %x "
4383 "fw Download failed\n", port);
4384 return -EINVAL;
4086 } 4385 }
4087 4386
4088 /* PBF - link up */ 4387 /* Only set bit 10 = 1 (Tx power down) */
4089 rc |= bnx2x_pbf_update(params, vars->flow_ctrl, 4388 bnx2x_cl45_read(bp, port,
4090 vars->line_speed); 4389 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4390 ext_phy_addr[port],
4391 MDIO_PMA_DEVAD,
4392 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4091 4393
4092 /* disable drain */ 4394 /* Phase1 of TX_POWER_DOWN reset */
4093 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); 4395 bnx2x_cl45_write(bp, port,
4396 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4397 ext_phy_addr[port],
4398 MDIO_PMA_DEVAD,
4399 MDIO_PMA_REG_TX_POWER_DOWN,
4400 (val | 1<<10));
4401 }
4094 4402
4095 /* update shared memory */ 4403 /* Toggle Transmitter: Power down and then up with 600ms
4096 bnx2x_update_mng(params, vars->link_status); 4404 delay between */
4405 msleep(600);
4097 4406
4098 } else { /* link down */ 4407 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4099 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", params->port); 4408 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4100 bnx2x_set_led(bp, port, LED_MODE_OFF, 4409 /* Phase2 of POWER_DOWN_RESET*/
4101 0, params->hw_led_mode, 4410 /* Release bit 10 (Release Tx power down) */
4102 params->chip_id); 4411 bnx2x_cl45_read(bp, port,
4412 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4413 ext_phy_addr[port],
4414 MDIO_PMA_DEVAD,
4415 MDIO_PMA_REG_TX_POWER_DOWN, &val);
4103 4416
4104 /* indicate no mac active */ 4417 bnx2x_cl45_write(bp, port,
4105 vars->mac_type = MAC_TYPE_NONE; 4418 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4419 ext_phy_addr[port],
4420 MDIO_PMA_DEVAD,
4421 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
4422 msleep(15);
4106 4423
4107 /* update shared memory */ 4424 /* Read modify write the SPI-ROM version select register */
4108 vars->link_status = 0; 4425 bnx2x_cl45_read(bp, port,
4109 bnx2x_update_mng(params, vars->link_status); 4426 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4427 ext_phy_addr[port],
4428 MDIO_PMA_DEVAD,
4429 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
4430 bnx2x_cl45_write(bp, port,
4431 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4432 ext_phy_addr[port],
4433 MDIO_PMA_DEVAD,
4434 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
4110 4435
4111 /* activate nig drain */ 4436 /* set GPIO2 back to LOW */
4112 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); 4437 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4438 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4439 }
4440 return 0;
4113 4441
4114 /* reset BigMac */ 4442}
4115 bnx2x_bmac_rx_disable(bp, params->port);
4116 REG_WR(bp, GRCBASE_MISC +
4117 MISC_REGISTERS_RESET_REG_2_CLEAR,
4118 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4119 4443
4444u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4445{
4446 u8 rc = 0;
4447 u32 ext_phy_type;
4448
4449 DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
4450
4451 /* Read the ext_phy_type for arbitrary port(0) */
4452 ext_phy_type = XGXS_EXT_PHY_TYPE(
4453 REG_RD(bp, shmem_base +
4454 offsetof(struct shmem_region,
4455 dev_info.port_hw_config[0].external_phy_config)));
4456
4457 switch (ext_phy_type) {
4458 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4459 {
4460 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
4461 break;
4462 }
4463 default:
4464 DP(NETIF_MSG_LINK,
4465 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4466 ext_phy_type);
4467 break;
4120 } 4468 }
4121 4469
4122 return rc; 4470 return rc;
4123} 4471}
4124 4472
4473
4474
4125static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) 4475static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4126{ 4476{
4127 u16 val, cnt; 4477 u16 val, cnt;
@@ -4154,7 +4504,7 @@ static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4154} 4504}
4155#define RESERVED_SIZE 256 4505#define RESERVED_SIZE 256
4156/* max application is 160K bytes - data at end of RAM */ 4506/* max application is 160K bytes - data at end of RAM */
4157#define MAX_APP_SIZE 160*1024 - RESERVED_SIZE 4507#define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
4158 4508
4159/* Header is 14 bytes */ 4509/* Header is 14 bytes */
4160#define HEADER_SIZE 14 4510#define HEADER_SIZE 14
@@ -4192,12 +4542,12 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4192 size = MAX_APP_SIZE+HEADER_SIZE; 4542 size = MAX_APP_SIZE+HEADER_SIZE;
4193 } 4543 }
4194 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]); 4544 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4195 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]); 4545 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
4196 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1 4546 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4197 and issuing a reset.*/ 4547 and issuing a reset.*/
4198 4548
4199 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, 4549 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4200 MISC_REGISTERS_GPIO_HIGH); 4550 MISC_REGISTERS_GPIO_HIGH, port);
4201 4551
4202 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); 4552 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4203 4553
@@ -4429,7 +4779,8 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4429 } 4779 }
4430 4780
4431 /* DSP Remove Download Mode */ 4781 /* DSP Remove Download Mode */
4432 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_LOW); 4782 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4783 MISC_REGISTERS_GPIO_LOW, port);
4433 4784
4434 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); 4785 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4435 4786
@@ -4437,7 +4788,7 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4437 for (cnt = 0; cnt < 100; cnt++) 4788 for (cnt = 0; cnt < 100; cnt++)
4438 msleep(5); 4789 msleep(5);
4439 4790
4440 bnx2x_hw_reset(bp); 4791 bnx2x_hw_reset(bp, port);
4441 4792
4442 for (cnt = 0; cnt < 100; cnt++) 4793 for (cnt = 0; cnt < 100; cnt++)
4443 msleep(5); 4794 msleep(5);
@@ -4473,7 +4824,7 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4473 MDIO_PMA_REG_7101_VER2, 4824 MDIO_PMA_REG_7101_VER2,
4474 &image_revision2); 4825 &image_revision2);
4475 4826
4476 if (data[0x14e] != (image_revision2&0xFF) || 4827 if (data[0x14e] != (image_revision2&0xFF) ||
4477 data[0x14f] != ((image_revision2&0xFF00)>>8) || 4828 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4478 data[0x150] != (image_revision1&0xFF) || 4829 data[0x150] != (image_revision1&0xFF) ||
4479 data[0x151] != ((image_revision1&0xFF00)>>8)) { 4830 data[0x151] != ((image_revision1&0xFF00)>>8)) {
@@ -4508,11 +4859,11 @@ u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4508 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 4859 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4509 /* Take ext phy out of reset */ 4860 /* Take ext phy out of reset */
4510 if (!driver_loaded) 4861 if (!driver_loaded)
4511 bnx2x_turn_on_sf(bp, port, ext_phy_addr); 4862 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4512 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr, 4863 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4513 data, size); 4864 data, size);
4514 if (!driver_loaded) 4865 if (!driver_loaded)
4515 bnx2x_turn_off_sf(bp); 4866 bnx2x_turn_off_sf(bp, port);
4516 break; 4867 break;
4517 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 4868 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4518 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: 4869 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h
index 714d37ac95de..86d54a17b411 100644
--- a/drivers/net/bnx2x_link.h
+++ b/drivers/net/bnx2x_link.h
@@ -55,14 +55,17 @@ struct link_params {
55#define LOOPBACK_BMAC 2 55#define LOOPBACK_BMAC 2
56#define LOOPBACK_XGXS_10 3 56#define LOOPBACK_XGXS_10 3
57#define LOOPBACK_EXT_PHY 4 57#define LOOPBACK_EXT_PHY 4
58#define LOOPBACK_EXT 5
58 59
59 u16 req_duplex; 60 u16 req_duplex;
60 u16 req_flow_ctrl; 61 u16 req_flow_ctrl;
62 u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
63 req_flow_ctrl is set to AUTO */
61 u16 req_line_speed; /* Also determine AutoNeg */ 64 u16 req_line_speed; /* Also determine AutoNeg */
62 65
63 /* Device parameters */ 66 /* Device parameters */
64 u8 mac_addr[6]; 67 u8 mac_addr[6];
65 u16 mtu; 68
66 69
67 70
68 /* shmem parameters */ 71 /* shmem parameters */
@@ -140,7 +143,7 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
140 u8 phy_addr, u8 devad, u16 reg, u16 val); 143 u8 phy_addr, u8 devad, u16 reg, u16 val);
141 144
142/* Reads the link_status from the shmem, 145/* Reads the link_status from the shmem,
143 and update the link vars accordinaly */ 146 and update the link vars accordingly */
144void bnx2x_link_status_update(struct link_params *input, 147void bnx2x_link_status_update(struct link_params *input,
145 struct link_vars *output); 148 struct link_vars *output);
146/* returns string representing the fw_version of the external phy */ 149/* returns string representing the fw_version of the external phy */
@@ -149,7 +152,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
149 152
150/* Set/Unset the led 153/* Set/Unset the led
151 Basically, the CLC takes care of the led for the link, but in case one needs 154 Basically, the CLC takes care of the led for the link, but in case one needs
152 to set/unset the led unnatually, set the "mode" to LED_MODE_OPER to 155 to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to
153 blink the led, and LED_MODE_OFF to set the led off.*/ 156 blink the led, and LED_MODE_OFF to set the led off.*/
154u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed, 157u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
155 u16 hw_led_mode, u32 chip_id); 158 u16 hw_led_mode, u32 chip_id);
@@ -164,5 +167,7 @@ u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
164 otherwise link is down*/ 167 otherwise link is down*/
165u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); 168u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
166 169
170/* One-time initialization for external phy after power up */
171u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
167 172
168#endif /* BNX2X_LINK_H */ 173#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index af251a5df844..971576b43687 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -44,7 +44,6 @@
44#include <net/ip.h> 44#include <net/ip.h>
45#include <net/tcp.h> 45#include <net/tcp.h>
46#include <net/checksum.h> 46#include <net/checksum.h>
47#include <linux/version.h>
48#include <net/ip6_checksum.h> 47#include <net/ip6_checksum.h>
49#include <linux/workqueue.h> 48#include <linux/workqueue.h>
50#include <linux/crc32.h> 49#include <linux/crc32.h>
@@ -60,8 +59,8 @@
60#include "bnx2x.h" 59#include "bnx2x.h"
61#include "bnx2x_init.h" 60#include "bnx2x_init.h"
62 61
63#define DRV_MODULE_VERSION "1.45.6" 62#define DRV_MODULE_VERSION "1.45.17"
64#define DRV_MODULE_RELDATE "2008/06/23" 63#define DRV_MODULE_RELDATE "2008/08/13"
65#define BNX2X_BC_VER 0x040200 64#define BNX2X_BC_VER 0x040200
66 65
67/* Time in jiffies before concluding the transmitter is hung */ 66/* Time in jiffies before concluding the transmitter is hung */
@@ -76,23 +75,21 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
76MODULE_LICENSE("GPL"); 75MODULE_LICENSE("GPL");
77MODULE_VERSION(DRV_MODULE_VERSION); 76MODULE_VERSION(DRV_MODULE_VERSION);
78 77
78static int disable_tpa;
79static int use_inta; 79static int use_inta;
80static int poll; 80static int poll;
81static int debug; 81static int debug;
82static int disable_tpa;
83static int nomcp;
84static int load_count[3]; /* 0-common, 1-port0, 2-port1 */ 82static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
85static int use_multi; 83static int use_multi;
86 84
85module_param(disable_tpa, int, 0);
87module_param(use_inta, int, 0); 86module_param(use_inta, int, 0);
88module_param(poll, int, 0); 87module_param(poll, int, 0);
89module_param(debug, int, 0); 88module_param(debug, int, 0);
90module_param(disable_tpa, int, 0); 89MODULE_PARM_DESC(disable_tpa, "disable the TPA (LRO) feature");
91module_param(nomcp, int, 0);
92MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X"); 90MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
93MODULE_PARM_DESC(poll, "use polling (for debug)"); 91MODULE_PARM_DESC(poll, "use polling (for debug)");
94MODULE_PARM_DESC(debug, "default debug msglevel"); 92MODULE_PARM_DESC(debug, "default debug msglevel");
95MODULE_PARM_DESC(nomcp, "ignore management CPU");
96 93
97#ifdef BNX2X_MULTI 94#ifdef BNX2X_MULTI
98module_param(use_multi, int, 0); 95module_param(use_multi, int, 0);
@@ -237,17 +234,16 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
237 while (*wb_comp != DMAE_COMP_VAL) { 234 while (*wb_comp != DMAE_COMP_VAL) {
238 DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); 235 DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
239 236
240 /* adjust delay for emulation/FPGA */
241 if (CHIP_REV_IS_SLOW(bp))
242 msleep(100);
243 else
244 udelay(5);
245
246 if (!cnt) { 237 if (!cnt) {
247 BNX2X_ERR("dmae timeout!\n"); 238 BNX2X_ERR("dmae timeout!\n");
248 break; 239 break;
249 } 240 }
250 cnt--; 241 cnt--;
242 /* adjust delay for emulation/FPGA */
243 if (CHIP_REV_IS_SLOW(bp))
244 msleep(100);
245 else
246 udelay(5);
251 } 247 }
252 248
253 mutex_unlock(&bp->dmae_mutex); 249 mutex_unlock(&bp->dmae_mutex);
@@ -310,17 +306,16 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
310 306
311 while (*wb_comp != DMAE_COMP_VAL) { 307 while (*wb_comp != DMAE_COMP_VAL) {
312 308
313 /* adjust delay for emulation/FPGA */
314 if (CHIP_REV_IS_SLOW(bp))
315 msleep(100);
316 else
317 udelay(5);
318
319 if (!cnt) { 309 if (!cnt) {
320 BNX2X_ERR("dmae timeout!\n"); 310 BNX2X_ERR("dmae timeout!\n");
321 break; 311 break;
322 } 312 }
323 cnt--; 313 cnt--;
314 /* adjust delay for emulation/FPGA */
315 if (CHIP_REV_IS_SLOW(bp))
316 msleep(100);
317 else
318 udelay(5);
324 } 319 }
325 DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n", 320 DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
326 bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], 321 bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
@@ -503,6 +498,9 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
503 int i; 498 int i;
504 u16 j, start, end; 499 u16 j, start, end;
505 500
501 bp->stats_state = STATS_STATE_DISABLED;
502 DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
503
506 BNX2X_ERR("begin crash dump -----------------\n"); 504 BNX2X_ERR("begin crash dump -----------------\n");
507 505
508 for_each_queue(bp, i) { 506 for_each_queue(bp, i) {
@@ -513,17 +511,20 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
513 " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n", 511 " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n",
514 i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, 512 i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
515 fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); 513 fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
516 BNX2X_ERR(" rx_comp_prod(%x) rx_comp_cons(%x)" 514 BNX2X_ERR(" rx_bd_prod(%x) rx_bd_cons(%x)"
517 " *rx_cons_sb(%x) *rx_bd_cons_sb(%x)" 515 " *rx_bd_cons_sb(%x) rx_comp_prod(%x)"
518 " rx_sge_prod(%x) last_max_sge(%x)\n", 516 " rx_comp_cons(%x) *rx_cons_sb(%x)\n",
519 fp->rx_comp_prod, fp->rx_comp_cons, 517 fp->rx_bd_prod, fp->rx_bd_cons,
520 le16_to_cpu(*fp->rx_cons_sb), 518 le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod,
521 le16_to_cpu(*fp->rx_bd_cons_sb), 519 fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb));
522 fp->rx_sge_prod, fp->last_max_sge); 520 BNX2X_ERR(" rx_sge_prod(%x) last_max_sge(%x)"
523 BNX2X_ERR(" fp_c_idx(%x) fp_u_idx(%x)" 521 " fp_c_idx(%x) *sb_c_idx(%x) fp_u_idx(%x)"
524 " bd data(%x,%x) rx_alloc_failed(%lx)\n", 522 " *sb_u_idx(%x) bd data(%x,%x)\n",
525 fp->fp_c_idx, fp->fp_u_idx, hw_prods->packets_prod, 523 fp->rx_sge_prod, fp->last_max_sge, fp->fp_c_idx,
526 hw_prods->bds_prod, fp->rx_alloc_failed); 524 fp->status_blk->c_status_block.status_block_index,
525 fp->fp_u_idx,
526 fp->status_blk->u_status_block.status_block_index,
527 hw_prods->packets_prod, hw_prods->bds_prod);
527 528
528 start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10); 529 start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
529 end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245); 530 end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
@@ -553,8 +554,8 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
553 j, rx_bd[1], rx_bd[0], sw_bd->skb); 554 j, rx_bd[1], rx_bd[0], sw_bd->skb);
554 } 555 }
555 556
556 start = 0; 557 start = RX_SGE(fp->rx_sge_prod);
557 end = RX_SGE_CNT*NUM_RX_SGE_PAGES; 558 end = RX_SGE(fp->last_max_sge);
558 for (j = start; j < end; j++) { 559 for (j = start; j < end; j++) {
559 u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j]; 560 u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j];
560 struct sw_rx_page *sw_page = &fp->rx_page_ring[j]; 561 struct sw_rx_page *sw_page = &fp->rx_page_ring[j];
@@ -582,9 +583,6 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
582 bnx2x_fw_dump(bp); 583 bnx2x_fw_dump(bp);
583 bnx2x_mc_assert(bp); 584 bnx2x_mc_assert(bp);
584 BNX2X_ERR("end crash dump -----------------\n"); 585 BNX2X_ERR("end crash dump -----------------\n");
585
586 bp->stats_state = STATS_STATE_DISABLED;
587 DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
588} 586}
589 587
590static void bnx2x_int_enable(struct bnx2x *bp) 588static void bnx2x_int_enable(struct bnx2x *bp)
@@ -684,7 +682,8 @@ static void bnx2x_int_disable_sync(struct bnx2x *bp)
684static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, 682static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
685 u8 storm, u16 index, u8 op, u8 update) 683 u8 storm, u16 index, u8 op, u8 update)
686{ 684{
687 u32 igu_addr = (IGU_ADDR_INT_ACK + IGU_FUNC_BASE * BP_FUNC(bp)) * 8; 685 u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
686 COMMAND_REG_INT_ACK);
688 struct igu_ack_register igu_ack; 687 struct igu_ack_register igu_ack;
689 688
690 igu_ack.status_block_index = index; 689 igu_ack.status_block_index = index;
@@ -694,9 +693,9 @@ static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
694 (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) | 693 (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
695 (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT)); 694 (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
696 695
697 DP(BNX2X_MSG_OFF, "write 0x%08x to IGU addr 0x%x\n", 696 DP(BNX2X_MSG_OFF, "write 0x%08x to HC addr 0x%x\n",
698 (*(u32 *)&igu_ack), BAR_IGU_INTMEM + igu_addr); 697 (*(u32 *)&igu_ack), hc_addr);
699 REG_WR(bp, BAR_IGU_INTMEM + igu_addr, (*(u32 *)&igu_ack)); 698 REG_WR(bp, hc_addr, (*(u32 *)&igu_ack));
700} 699}
701 700
702static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) 701static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
@@ -716,36 +715,15 @@ static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
716 return rc; 715 return rc;
717} 716}
718 717
719static inline int bnx2x_has_work(struct bnx2x_fastpath *fp)
720{
721 u16 rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
722
723 if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
724 rx_cons_sb++;
725
726 if ((fp->rx_comp_cons != rx_cons_sb) ||
727 (fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) ||
728 (fp->tx_pkt_prod != fp->tx_pkt_cons))
729 return 1;
730
731 return 0;
732}
733
734static u16 bnx2x_ack_int(struct bnx2x *bp) 718static u16 bnx2x_ack_int(struct bnx2x *bp)
735{ 719{
736 u32 igu_addr = (IGU_ADDR_SIMD_MASK + IGU_FUNC_BASE * BP_FUNC(bp)) * 8; 720 u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
737 u32 result = REG_RD(bp, BAR_IGU_INTMEM + igu_addr); 721 COMMAND_REG_SIMD_MASK);
722 u32 result = REG_RD(bp, hc_addr);
738 723
739 DP(BNX2X_MSG_OFF, "read 0x%08x from IGU addr 0x%x\n", 724 DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n",
740 result, BAR_IGU_INTMEM + igu_addr); 725 result, hc_addr);
741 726
742#ifdef IGU_DEBUG
743#warning IGU_DEBUG active
744 if (result == 0) {
745 BNX2X_ERR("read %x from IGU\n", result);
746 REG_WR(bp, TM_REG_TIMER_SOFT_RST, 0);
747 }
748#endif
749 return result; 727 return result;
750} 728}
751 729
@@ -898,6 +876,7 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
898 netif_tx_lock(bp->dev); 876 netif_tx_lock(bp->dev);
899 877
900 if (netif_queue_stopped(bp->dev) && 878 if (netif_queue_stopped(bp->dev) &&
879 (bp->state == BNX2X_STATE_OPEN) &&
901 (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)) 880 (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
902 netif_wake_queue(bp->dev); 881 netif_wake_queue(bp->dev);
903 882
@@ -905,6 +884,7 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
905 } 884 }
906} 885}
907 886
887
908static void bnx2x_sp_event(struct bnx2x_fastpath *fp, 888static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
909 union eth_rx_cqe *rr_cqe) 889 union eth_rx_cqe *rr_cqe)
910{ 890{
@@ -960,6 +940,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
960 bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; 940 bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
961 break; 941 break;
962 942
943
963 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): 944 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
964 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): 945 case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
965 DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); 946 DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
@@ -1169,8 +1150,8 @@ static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp)
1169 memset(fp->sge_mask, 0xff, 1150 memset(fp->sge_mask, 0xff,
1170 (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); 1151 (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64));
1171 1152
1172 /* Clear the two last indeces in the page to 1: 1153 /* Clear the two last indices in the page to 1:
1173 these are the indeces that correspond to the "next" element, 1154 these are the indices that correspond to the "next" element,
1174 hence will never be indicated and should be removed from 1155 hence will never be indicated and should be removed from
1175 the calculations. */ 1156 the calculations. */
1176 bnx2x_clear_sge_mask_next_elems(fp); 1157 bnx2x_clear_sge_mask_next_elems(fp);
@@ -1261,7 +1242,7 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
1261 where we are and drop the whole packet */ 1242 where we are and drop the whole packet */
1262 err = bnx2x_alloc_rx_sge(bp, fp, sge_idx); 1243 err = bnx2x_alloc_rx_sge(bp, fp, sge_idx);
1263 if (unlikely(err)) { 1244 if (unlikely(err)) {
1264 fp->rx_alloc_failed++; 1245 bp->eth_stats.rx_skb_alloc_failed++;
1265 return err; 1246 return err;
1266 } 1247 }
1267 1248
@@ -1297,14 +1278,13 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
1297 pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), 1278 pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
1298 bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); 1279 bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
1299 1280
1300 /* if alloc failed drop the packet and keep the buffer in the bin */
1301 if (likely(new_skb)) { 1281 if (likely(new_skb)) {
1282 /* fix ip xsum and give it to the stack */
1283 /* (no need to map the new skb) */
1302 1284
1303 prefetch(skb); 1285 prefetch(skb);
1304 prefetch(((char *)(skb)) + 128); 1286 prefetch(((char *)(skb)) + 128);
1305 1287
1306 /* else fix ip xsum and give it to the stack */
1307 /* (no need to map the new skb) */
1308#ifdef BNX2X_STOP_ON_ERROR 1288#ifdef BNX2X_STOP_ON_ERROR
1309 if (pad + len > bp->rx_buf_size) { 1289 if (pad + len > bp->rx_buf_size) {
1310 BNX2X_ERR("skb_put is about to fail... " 1290 BNX2X_ERR("skb_put is about to fail... "
@@ -1353,9 +1333,10 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
1353 fp->tpa_pool[queue].skb = new_skb; 1333 fp->tpa_pool[queue].skb = new_skb;
1354 1334
1355 } else { 1335 } else {
1336 /* else drop the packet and keep the buffer in the bin */
1356 DP(NETIF_MSG_RX_STATUS, 1337 DP(NETIF_MSG_RX_STATUS,
1357 "Failed to allocate new skb - dropping packet!\n"); 1338 "Failed to allocate new skb - dropping packet!\n");
1358 fp->rx_alloc_failed++; 1339 bp->eth_stats.rx_skb_alloc_failed++;
1359 } 1340 }
1360 1341
1361 fp->tpa_state[queue] = BNX2X_TPA_STOP; 1342 fp->tpa_state[queue] = BNX2X_TPA_STOP;
@@ -1390,7 +1371,6 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
1390 u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons; 1371 u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons;
1391 u16 hw_comp_cons, sw_comp_cons, sw_comp_prod; 1372 u16 hw_comp_cons, sw_comp_cons, sw_comp_prod;
1392 int rx_pkt = 0; 1373 int rx_pkt = 0;
1393 u16 queue;
1394 1374
1395#ifdef BNX2X_STOP_ON_ERROR 1375#ifdef BNX2X_STOP_ON_ERROR
1396 if (unlikely(bp->panic)) 1376 if (unlikely(bp->panic))
@@ -1456,7 +1436,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
1456 if ((!fp->disable_tpa) && 1436 if ((!fp->disable_tpa) &&
1457 (TPA_TYPE(cqe_fp_flags) != 1437 (TPA_TYPE(cqe_fp_flags) !=
1458 (TPA_TYPE_START | TPA_TYPE_END))) { 1438 (TPA_TYPE_START | TPA_TYPE_END))) {
1459 queue = cqe->fast_path_cqe.queue_index; 1439 u16 queue = cqe->fast_path_cqe.queue_index;
1460 1440
1461 if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_START) { 1441 if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_START) {
1462 DP(NETIF_MSG_RX_STATUS, 1442 DP(NETIF_MSG_RX_STATUS,
@@ -1503,11 +1483,10 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
1503 1483
1504 /* is this an error packet? */ 1484 /* is this an error packet? */
1505 if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { 1485 if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
1506 /* do we sometimes forward error packets anyway? */
1507 DP(NETIF_MSG_RX_ERR, 1486 DP(NETIF_MSG_RX_ERR,
1508 "ERROR flags %x rx packet %u\n", 1487 "ERROR flags %x rx packet %u\n",
1509 cqe_fp_flags, sw_comp_cons); 1488 cqe_fp_flags, sw_comp_cons);
1510 /* TBD make sure MC counts this as a drop */ 1489 bp->eth_stats.rx_err_discard_pkt++;
1511 goto reuse_rx; 1490 goto reuse_rx;
1512 } 1491 }
1513 1492
@@ -1524,7 +1503,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
1524 DP(NETIF_MSG_RX_ERR, 1503 DP(NETIF_MSG_RX_ERR,
1525 "ERROR packet dropped " 1504 "ERROR packet dropped "
1526 "because of alloc failure\n"); 1505 "because of alloc failure\n");
1527 fp->rx_alloc_failed++; 1506 bp->eth_stats.rx_skb_alloc_failed++;
1528 goto reuse_rx; 1507 goto reuse_rx;
1529 } 1508 }
1530 1509
@@ -1550,7 +1529,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
1550 DP(NETIF_MSG_RX_ERR, 1529 DP(NETIF_MSG_RX_ERR,
1551 "ERROR packet dropped because " 1530 "ERROR packet dropped because "
1552 "of alloc failure\n"); 1531 "of alloc failure\n");
1553 fp->rx_alloc_failed++; 1532 bp->eth_stats.rx_skb_alloc_failed++;
1554reuse_rx: 1533reuse_rx:
1555 bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); 1534 bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
1556 goto next_rx; 1535 goto next_rx;
@@ -1559,10 +1538,12 @@ reuse_rx:
1559 skb->protocol = eth_type_trans(skb, bp->dev); 1538 skb->protocol = eth_type_trans(skb, bp->dev);
1560 1539
1561 skb->ip_summed = CHECKSUM_NONE; 1540 skb->ip_summed = CHECKSUM_NONE;
1562 if (bp->rx_csum && BNX2X_RX_SUM_OK(cqe)) 1541 if (bp->rx_csum) {
1563 skb->ip_summed = CHECKSUM_UNNECESSARY; 1542 if (likely(BNX2X_RX_CSUM_OK(cqe)))
1564 1543 skb->ip_summed = CHECKSUM_UNNECESSARY;
1565 /* TBD do we pass bad csum packets in promisc */ 1544 else
1545 bp->eth_stats.hw_csum_err++;
1546 }
1566 } 1547 }
1567 1548
1568#ifdef BCM_VLAN 1549#ifdef BCM_VLAN
@@ -1615,6 +1596,12 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
1615 struct net_device *dev = bp->dev; 1596 struct net_device *dev = bp->dev;
1616 int index = FP_IDX(fp); 1597 int index = FP_IDX(fp);
1617 1598
1599 /* Return here if interrupt is disabled */
1600 if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
1601 DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
1602 return IRQ_HANDLED;
1603 }
1604
1618 DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n", 1605 DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
1619 index, FP_SB_ID(fp)); 1606 index, FP_SB_ID(fp));
1620 bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0); 1607 bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0);
@@ -1648,17 +1635,17 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
1648 } 1635 }
1649 DP(NETIF_MSG_INTR, "got an interrupt status %u\n", status); 1636 DP(NETIF_MSG_INTR, "got an interrupt status %u\n", status);
1650 1637
1651#ifdef BNX2X_STOP_ON_ERROR
1652 if (unlikely(bp->panic))
1653 return IRQ_HANDLED;
1654#endif
1655
1656 /* Return here if interrupt is disabled */ 1638 /* Return here if interrupt is disabled */
1657 if (unlikely(atomic_read(&bp->intr_sem) != 0)) { 1639 if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
1658 DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); 1640 DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
1659 return IRQ_HANDLED; 1641 return IRQ_HANDLED;
1660 } 1642 }
1661 1643
1644#ifdef BNX2X_STOP_ON_ERROR
1645 if (unlikely(bp->panic))
1646 return IRQ_HANDLED;
1647#endif
1648
1662 mask = 0x2 << bp->fp[0].sb_id; 1649 mask = 0x2 << bp->fp[0].sb_id;
1663 if (status & mask) { 1650 if (status & mask) {
1664 struct bnx2x_fastpath *fp = &bp->fp[0]; 1651 struct bnx2x_fastpath *fp = &bp->fp[0];
@@ -1699,11 +1686,12 @@ static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
1699 * General service functions 1686 * General service functions
1700 */ 1687 */
1701 1688
1702static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource) 1689static int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource)
1703{ 1690{
1704 u32 lock_status; 1691 u32 lock_status;
1705 u32 resource_bit = (1 << resource); 1692 u32 resource_bit = (1 << resource);
1706 u8 port = BP_PORT(bp); 1693 int func = BP_FUNC(bp);
1694 u32 hw_lock_control_reg;
1707 int cnt; 1695 int cnt;
1708 1696
1709 /* Validating that the resource is within range */ 1697 /* Validating that the resource is within range */
@@ -1714,8 +1702,15 @@ static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
1714 return -EINVAL; 1702 return -EINVAL;
1715 } 1703 }
1716 1704
1705 if (func <= 5) {
1706 hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8);
1707 } else {
1708 hw_lock_control_reg =
1709 (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8);
1710 }
1711
1717 /* Validating that the resource is not already taken */ 1712 /* Validating that the resource is not already taken */
1718 lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8); 1713 lock_status = REG_RD(bp, hw_lock_control_reg);
1719 if (lock_status & resource_bit) { 1714 if (lock_status & resource_bit) {
1720 DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", 1715 DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
1721 lock_status, resource_bit); 1716 lock_status, resource_bit);
@@ -1725,9 +1720,8 @@ static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
1725 /* Try for 1 second every 5ms */ 1720 /* Try for 1 second every 5ms */
1726 for (cnt = 0; cnt < 200; cnt++) { 1721 for (cnt = 0; cnt < 200; cnt++) {
1727 /* Try to acquire the lock */ 1722 /* Try to acquire the lock */
1728 REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + port*8 + 4, 1723 REG_WR(bp, hw_lock_control_reg + 4, resource_bit);
1729 resource_bit); 1724 lock_status = REG_RD(bp, hw_lock_control_reg);
1730 lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8);
1731 if (lock_status & resource_bit) 1725 if (lock_status & resource_bit)
1732 return 0; 1726 return 0;
1733 1727
@@ -1737,11 +1731,12 @@ static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
1737 return -EAGAIN; 1731 return -EAGAIN;
1738} 1732}
1739 1733
1740static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource) 1734static int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource)
1741{ 1735{
1742 u32 lock_status; 1736 u32 lock_status;
1743 u32 resource_bit = (1 << resource); 1737 u32 resource_bit = (1 << resource);
1744 u8 port = BP_PORT(bp); 1738 int func = BP_FUNC(bp);
1739 u32 hw_lock_control_reg;
1745 1740
1746 /* Validating that the resource is within range */ 1741 /* Validating that the resource is within range */
1747 if (resource > HW_LOCK_MAX_RESOURCE_VALUE) { 1742 if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
@@ -1751,20 +1746,27 @@ static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
1751 return -EINVAL; 1746 return -EINVAL;
1752 } 1747 }
1753 1748
1749 if (func <= 5) {
1750 hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8);
1751 } else {
1752 hw_lock_control_reg =
1753 (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8);
1754 }
1755
1754 /* Validating that the resource is currently taken */ 1756 /* Validating that the resource is currently taken */
1755 lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8); 1757 lock_status = REG_RD(bp, hw_lock_control_reg);
1756 if (!(lock_status & resource_bit)) { 1758 if (!(lock_status & resource_bit)) {
1757 DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n", 1759 DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
1758 lock_status, resource_bit); 1760 lock_status, resource_bit);
1759 return -EFAULT; 1761 return -EFAULT;
1760 } 1762 }
1761 1763
1762 REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + port*8, resource_bit); 1764 REG_WR(bp, hw_lock_control_reg, resource_bit);
1763 return 0; 1765 return 0;
1764} 1766}
1765 1767
1766/* HW Lock for shared dual port PHYs */ 1768/* HW Lock for shared dual port PHYs */
1767static void bnx2x_phy_hw_lock(struct bnx2x *bp) 1769static void bnx2x_acquire_phy_lock(struct bnx2x *bp)
1768{ 1770{
1769 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); 1771 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
1770 1772
@@ -1772,25 +1774,25 @@ static void bnx2x_phy_hw_lock(struct bnx2x *bp)
1772 1774
1773 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) || 1775 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
1774 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) 1776 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
1775 bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO); 1777 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
1776} 1778}
1777 1779
1778static void bnx2x_phy_hw_unlock(struct bnx2x *bp) 1780static void bnx2x_release_phy_lock(struct bnx2x *bp)
1779{ 1781{
1780 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); 1782 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
1781 1783
1782 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) || 1784 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
1783 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) 1785 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
1784 bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO); 1786 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
1785 1787
1786 mutex_unlock(&bp->port.phy_mutex); 1788 mutex_unlock(&bp->port.phy_mutex);
1787} 1789}
1788 1790
1789int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode) 1791int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
1790{ 1792{
1791 /* The GPIO should be swapped if swap register is set and active */ 1793 /* The GPIO should be swapped if swap register is set and active */
1792 int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && 1794 int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
1793 REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ BP_PORT(bp); 1795 REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
1794 int gpio_shift = gpio_num + 1796 int gpio_shift = gpio_num +
1795 (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); 1797 (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
1796 u32 gpio_mask = (1 << gpio_shift); 1798 u32 gpio_mask = (1 << gpio_shift);
@@ -1801,7 +1803,7 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
1801 return -EINVAL; 1803 return -EINVAL;
1802 } 1804 }
1803 1805
1804 bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); 1806 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
1805 /* read GPIO and mask except the float bits */ 1807 /* read GPIO and mask except the float bits */
1806 gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT); 1808 gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
1807 1809
@@ -1822,7 +1824,7 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
1822 gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS); 1824 gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
1823 break; 1825 break;
1824 1826
1825 case MISC_REGISTERS_GPIO_INPUT_HI_Z : 1827 case MISC_REGISTERS_GPIO_INPUT_HI_Z:
1826 DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n", 1828 DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
1827 gpio_num, gpio_shift); 1829 gpio_num, gpio_shift);
1828 /* set FLOAT */ 1830 /* set FLOAT */
@@ -1834,7 +1836,7 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
1834 } 1836 }
1835 1837
1836 REG_WR(bp, MISC_REG_GPIO, gpio_reg); 1838 REG_WR(bp, MISC_REG_GPIO, gpio_reg);
1837 bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO); 1839 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
1838 1840
1839 return 0; 1841 return 0;
1840} 1842}
@@ -1850,19 +1852,19 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
1850 return -EINVAL; 1852 return -EINVAL;
1851 } 1853 }
1852 1854
1853 bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); 1855 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
1854 /* read SPIO and mask except the float bits */ 1856 /* read SPIO and mask except the float bits */
1855 spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT); 1857 spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
1856 1858
1857 switch (mode) { 1859 switch (mode) {
1858 case MISC_REGISTERS_SPIO_OUTPUT_LOW : 1860 case MISC_REGISTERS_SPIO_OUTPUT_LOW:
1859 DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num); 1861 DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
1860 /* clear FLOAT and set CLR */ 1862 /* clear FLOAT and set CLR */
1861 spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); 1863 spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
1862 spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS); 1864 spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
1863 break; 1865 break;
1864 1866
1865 case MISC_REGISTERS_SPIO_OUTPUT_HIGH : 1867 case MISC_REGISTERS_SPIO_OUTPUT_HIGH:
1866 DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num); 1868 DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
1867 /* clear FLOAT and set SET */ 1869 /* clear FLOAT and set SET */
1868 spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS); 1870 spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
@@ -1880,7 +1882,7 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
1880 } 1882 }
1881 1883
1882 REG_WR(bp, MISC_REG_SPIO, spio_reg); 1884 REG_WR(bp, MISC_REG_SPIO, spio_reg);
1883 bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO); 1885 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
1884 1886
1885 return 0; 1887 return 0;
1886} 1888}
@@ -1940,46 +1942,63 @@ static void bnx2x_link_report(struct bnx2x *bp)
1940 1942
1941static u8 bnx2x_initial_phy_init(struct bnx2x *bp) 1943static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
1942{ 1944{
1943 u8 rc; 1945 if (!BP_NOMCP(bp)) {
1946 u8 rc;
1944 1947
1945 /* Initialize link parameters structure variables */ 1948 /* Initialize link parameters structure variables */
1946 bp->link_params.mtu = bp->dev->mtu; 1949 /* It is recommended to turn off RX FC for jumbo frames
1950 for better performance */
1951 if (IS_E1HMF(bp))
1952 bp->link_params.req_fc_auto_adv = FLOW_CTRL_BOTH;
1953 else if (bp->dev->mtu > 5000)
1954 bp->link_params.req_fc_auto_adv = FLOW_CTRL_TX;
1955 else
1956 bp->link_params.req_fc_auto_adv = FLOW_CTRL_BOTH;
1947 1957
1948 bnx2x_phy_hw_lock(bp); 1958 bnx2x_acquire_phy_lock(bp);
1949 rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); 1959 rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
1950 bnx2x_phy_hw_unlock(bp); 1960 bnx2x_release_phy_lock(bp);
1951 1961
1952 if (bp->link_vars.link_up) 1962 if (bp->link_vars.link_up)
1953 bnx2x_link_report(bp); 1963 bnx2x_link_report(bp);
1954 1964
1955 bnx2x_calc_fc_adv(bp); 1965 bnx2x_calc_fc_adv(bp);
1956 1966
1957 return rc; 1967 return rc;
1968 }
1969 BNX2X_ERR("Bootcode is missing -not initializing link\n");
1970 return -EINVAL;
1958} 1971}
1959 1972
1960static void bnx2x_link_set(struct bnx2x *bp) 1973static void bnx2x_link_set(struct bnx2x *bp)
1961{ 1974{
1962 bnx2x_phy_hw_lock(bp); 1975 if (!BP_NOMCP(bp)) {
1963 bnx2x_phy_init(&bp->link_params, &bp->link_vars); 1976 bnx2x_acquire_phy_lock(bp);
1964 bnx2x_phy_hw_unlock(bp); 1977 bnx2x_phy_init(&bp->link_params, &bp->link_vars);
1978 bnx2x_release_phy_lock(bp);
1965 1979
1966 bnx2x_calc_fc_adv(bp); 1980 bnx2x_calc_fc_adv(bp);
1981 } else
1982 BNX2X_ERR("Bootcode is missing -not setting link\n");
1967} 1983}
1968 1984
1969static void bnx2x__link_reset(struct bnx2x *bp) 1985static void bnx2x__link_reset(struct bnx2x *bp)
1970{ 1986{
1971 bnx2x_phy_hw_lock(bp); 1987 if (!BP_NOMCP(bp)) {
1972 bnx2x_link_reset(&bp->link_params, &bp->link_vars); 1988 bnx2x_acquire_phy_lock(bp);
1973 bnx2x_phy_hw_unlock(bp); 1989 bnx2x_link_reset(&bp->link_params, &bp->link_vars);
1990 bnx2x_release_phy_lock(bp);
1991 } else
1992 BNX2X_ERR("Bootcode is missing -not resetting link\n");
1974} 1993}
1975 1994
1976static u8 bnx2x_link_test(struct bnx2x *bp) 1995static u8 bnx2x_link_test(struct bnx2x *bp)
1977{ 1996{
1978 u8 rc; 1997 u8 rc;
1979 1998
1980 bnx2x_phy_hw_lock(bp); 1999 bnx2x_acquire_phy_lock(bp);
1981 rc = bnx2x_test_link(&bp->link_params, &bp->link_vars); 2000 rc = bnx2x_test_link(&bp->link_params, &bp->link_vars);
1982 bnx2x_phy_hw_unlock(bp); 2001 bnx2x_release_phy_lock(bp);
1983 2002
1984 return rc; 2003 return rc;
1985} 2004}
@@ -1991,7 +2010,7 @@ static u8 bnx2x_link_test(struct bnx2x *bp)
1991 sum of vn_min_rates 2010 sum of vn_min_rates
1992 or 2011 or
1993 0 - if all the min_rates are 0. 2012 0 - if all the min_rates are 0.
1994 In the later case fainess algorithm should be deactivated. 2013 In the later case fairness algorithm should be deactivated.
1995 If not all min_rates are zero then those that are zeroes will 2014 If not all min_rates are zero then those that are zeroes will
1996 be set to 1. 2015 be set to 1.
1997 */ 2016 */
@@ -2114,7 +2133,7 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
2114 FUNC_MF_CFG_MIN_BW_SHIFT) * 100; 2133 FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
2115 /* If FAIRNESS is enabled (not all min rates are zeroes) and 2134 /* If FAIRNESS is enabled (not all min rates are zeroes) and
2116 if current min rate is zero - set it to 1. 2135 if current min rate is zero - set it to 1.
2117 This is a requirment of the algorithm. */ 2136 This is a requirement of the algorithm. */
2118 if ((vn_min_rate == 0) && wsum) 2137 if ((vn_min_rate == 0) && wsum)
2119 vn_min_rate = DEF_MIN_RATE; 2138 vn_min_rate = DEF_MIN_RATE;
2120 vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> 2139 vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
@@ -2203,9 +2222,9 @@ static void bnx2x_link_attn(struct bnx2x *bp)
2203 /* Make sure that we are synced with the current statistics */ 2222 /* Make sure that we are synced with the current statistics */
2204 bnx2x_stats_handle(bp, STATS_EVENT_STOP); 2223 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
2205 2224
2206 bnx2x_phy_hw_lock(bp); 2225 bnx2x_acquire_phy_lock(bp);
2207 bnx2x_link_update(&bp->link_params, &bp->link_vars); 2226 bnx2x_link_update(&bp->link_params, &bp->link_vars);
2208 bnx2x_phy_hw_unlock(bp); 2227 bnx2x_release_phy_lock(bp);
2209 2228
2210 if (bp->link_vars.link_up) { 2229 if (bp->link_vars.link_up) {
2211 2230
@@ -2357,7 +2376,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
2357} 2376}
2358 2377
2359/* acquire split MCP access lock register */ 2378/* acquire split MCP access lock register */
2360static int bnx2x_lock_alr(struct bnx2x *bp) 2379static int bnx2x_acquire_alr(struct bnx2x *bp)
2361{ 2380{
2362 u32 i, j, val; 2381 u32 i, j, val;
2363 int rc = 0; 2382 int rc = 0;
@@ -2374,15 +2393,15 @@ static int bnx2x_lock_alr(struct bnx2x *bp)
2374 msleep(5); 2393 msleep(5);
2375 } 2394 }
2376 if (!(val & (1L << 31))) { 2395 if (!(val & (1L << 31))) {
2377 BNX2X_ERR("Cannot acquire nvram interface\n"); 2396 BNX2X_ERR("Cannot acquire MCP access lock register\n");
2378 rc = -EBUSY; 2397 rc = -EBUSY;
2379 } 2398 }
2380 2399
2381 return rc; 2400 return rc;
2382} 2401}
2383 2402
2384/* Release split MCP access lock register */ 2403/* release split MCP access lock register */
2385static void bnx2x_unlock_alr(struct bnx2x *bp) 2404static void bnx2x_release_alr(struct bnx2x *bp)
2386{ 2405{
2387 u32 val = 0; 2406 u32 val = 0;
2388 2407
@@ -2395,7 +2414,6 @@ static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
2395 u16 rc = 0; 2414 u16 rc = 0;
2396 2415
2397 barrier(); /* status block is written to by the chip */ 2416 barrier(); /* status block is written to by the chip */
2398
2399 if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) { 2417 if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) {
2400 bp->def_att_idx = def_sb->atten_status_block.attn_bits_index; 2418 bp->def_att_idx = def_sb->atten_status_block.attn_bits_index;
2401 rc |= 1; 2419 rc |= 1;
@@ -2426,26 +2444,31 @@ static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
2426static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) 2444static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
2427{ 2445{
2428 int port = BP_PORT(bp); 2446 int port = BP_PORT(bp);
2429 int func = BP_FUNC(bp); 2447 u32 hc_addr = (HC_REG_COMMAND_REG + port*32 +
2430 u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_FUNC_BASE * func) * 8; 2448 COMMAND_REG_ATTN_BITS_SET);
2431 u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : 2449 u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
2432 MISC_REG_AEU_MASK_ATTN_FUNC_0; 2450 MISC_REG_AEU_MASK_ATTN_FUNC_0;
2433 u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : 2451 u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
2434 NIG_REG_MASK_INTERRUPT_PORT0; 2452 NIG_REG_MASK_INTERRUPT_PORT0;
2453 u32 aeu_mask;
2435 2454
2436 if (~bp->aeu_mask & (asserted & 0xff))
2437 BNX2X_ERR("IGU ERROR\n");
2438 if (bp->attn_state & asserted) 2455 if (bp->attn_state & asserted)
2439 BNX2X_ERR("IGU ERROR\n"); 2456 BNX2X_ERR("IGU ERROR\n");
2440 2457
2458 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
2459 aeu_mask = REG_RD(bp, aeu_addr);
2460
2441 DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n", 2461 DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n",
2442 bp->aeu_mask, asserted); 2462 aeu_mask, asserted);
2443 bp->aeu_mask &= ~(asserted & 0xff); 2463 aeu_mask &= ~(asserted & 0xff);
2444 DP(NETIF_MSG_HW, "after masking: aeu_mask %x\n", bp->aeu_mask); 2464 DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask);
2445 2465
2446 REG_WR(bp, aeu_addr, bp->aeu_mask); 2466 REG_WR(bp, aeu_addr, aeu_mask);
2467 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
2447 2468
2469 DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state);
2448 bp->attn_state |= asserted; 2470 bp->attn_state |= asserted;
2471 DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state);
2449 2472
2450 if (asserted & ATTN_HARD_WIRED_MASK) { 2473 if (asserted & ATTN_HARD_WIRED_MASK) {
2451 if (asserted & ATTN_NIG_FOR_FUNC) { 2474 if (asserted & ATTN_NIG_FOR_FUNC) {
@@ -2500,9 +2523,9 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
2500 2523
2501 } /* if hardwired */ 2524 } /* if hardwired */
2502 2525
2503 DP(NETIF_MSG_HW, "about to mask 0x%08x at IGU addr 0x%x\n", 2526 DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n",
2504 asserted, BAR_IGU_INTMEM + igu_addr); 2527 asserted, hc_addr);
2505 REG_WR(bp, BAR_IGU_INTMEM + igu_addr, asserted); 2528 REG_WR(bp, hc_addr, asserted);
2506 2529
2507 /* now set back the mask */ 2530 /* now set back the mask */
2508 if (asserted & ATTN_NIG_FOR_FUNC) 2531 if (asserted & ATTN_NIG_FOR_FUNC)
@@ -2530,12 +2553,12 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
2530 case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G: 2553 case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
2531 /* Fan failure attention */ 2554 /* Fan failure attention */
2532 2555
2533 /* The PHY reset is controled by GPIO 1 */ 2556 /* The PHY reset is controlled by GPIO 1 */
2534 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2557 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2535 MISC_REGISTERS_GPIO_OUTPUT_LOW); 2558 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
2536 /* Low power mode is controled by GPIO 2 */ 2559 /* Low power mode is controlled by GPIO 2 */
2537 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 2560 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2538 MISC_REGISTERS_GPIO_OUTPUT_LOW); 2561 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
2539 /* mark the failure */ 2562 /* mark the failure */
2540 bp->link_params.ext_phy_config &= 2563 bp->link_params.ext_phy_config &=
2541 ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; 2564 ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
@@ -2699,10 +2722,11 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
2699 int index; 2722 int index;
2700 u32 reg_addr; 2723 u32 reg_addr;
2701 u32 val; 2724 u32 val;
2725 u32 aeu_mask;
2702 2726
2703 /* need to take HW lock because MCP or other port might also 2727 /* need to take HW lock because MCP or other port might also
2704 try to handle this event */ 2728 try to handle this event */
2705 bnx2x_lock_alr(bp); 2729 bnx2x_acquire_alr(bp);
2706 2730
2707 attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4); 2731 attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4);
2708 attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); 2732 attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4);
@@ -2734,32 +2758,35 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
2734 HW_PRTY_ASSERT_SET_1) || 2758 HW_PRTY_ASSERT_SET_1) ||
2735 (attn.sig[2] & group_mask.sig[2] & 2759 (attn.sig[2] & group_mask.sig[2] &
2736 HW_PRTY_ASSERT_SET_2)) 2760 HW_PRTY_ASSERT_SET_2))
2737 BNX2X_ERR("FATAL HW block parity attention\n"); 2761 BNX2X_ERR("FATAL HW block parity attention\n");
2738 } 2762 }
2739 } 2763 }
2740 2764
2741 bnx2x_unlock_alr(bp); 2765 bnx2x_release_alr(bp);
2742 2766
2743 reg_addr = (IGU_ADDR_ATTN_BITS_CLR + IGU_FUNC_BASE * BP_FUNC(bp)) * 8; 2767 reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR);
2744 2768
2745 val = ~deasserted; 2769 val = ~deasserted;
2746/* DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n", 2770 DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n",
2747 val, BAR_IGU_INTMEM + reg_addr); */ 2771 val, reg_addr);
2748 REG_WR(bp, BAR_IGU_INTMEM + reg_addr, val); 2772 REG_WR(bp, reg_addr, val);
2749 2773
2750 if (bp->aeu_mask & (deasserted & 0xff))
2751 BNX2X_ERR("IGU BUG!\n");
2752 if (~bp->attn_state & deasserted) 2774 if (~bp->attn_state & deasserted)
2753 BNX2X_ERR("IGU BUG!\n"); 2775 BNX2X_ERR("IGU ERROR\n");
2754 2776
2755 reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : 2777 reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
2756 MISC_REG_AEU_MASK_ATTN_FUNC_0; 2778 MISC_REG_AEU_MASK_ATTN_FUNC_0;
2757 2779
2758 DP(NETIF_MSG_HW, "aeu_mask %x\n", bp->aeu_mask); 2780 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
2759 bp->aeu_mask |= (deasserted & 0xff); 2781 aeu_mask = REG_RD(bp, reg_addr);
2782
2783 DP(NETIF_MSG_HW, "aeu_mask %x newly deasserted %x\n",
2784 aeu_mask, deasserted);
2785 aeu_mask |= (deasserted & 0xff);
2786 DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask);
2760 2787
2761 DP(NETIF_MSG_HW, "new mask %x\n", bp->aeu_mask); 2788 REG_WR(bp, reg_addr, aeu_mask);
2762 REG_WR(bp, reg_addr, bp->aeu_mask); 2789 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
2763 2790
2764 DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state); 2791 DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state);
2765 bp->attn_state &= ~deasserted; 2792 bp->attn_state &= ~deasserted;
@@ -2800,7 +2827,7 @@ static void bnx2x_sp_task(struct work_struct *work)
2800 2827
2801 /* Return here if interrupt is disabled */ 2828 /* Return here if interrupt is disabled */
2802 if (unlikely(atomic_read(&bp->intr_sem) != 0)) { 2829 if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
2803 DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n"); 2830 DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
2804 return; 2831 return;
2805 } 2832 }
2806 2833
@@ -2808,7 +2835,7 @@ static void bnx2x_sp_task(struct work_struct *work)
2808/* if (status == 0) */ 2835/* if (status == 0) */
2809/* BNX2X_ERR("spurious slowpath interrupt!\n"); */ 2836/* BNX2X_ERR("spurious slowpath interrupt!\n"); */
2810 2837
2811 DP(BNX2X_MSG_SP, "got a slowpath interrupt (updated %x)\n", status); 2838 DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status);
2812 2839
2813 /* HW attentions */ 2840 /* HW attentions */
2814 if (status & 0x1) 2841 if (status & 0x1)
@@ -2838,7 +2865,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
2838 2865
2839 /* Return here if interrupt is disabled */ 2866 /* Return here if interrupt is disabled */
2840 if (unlikely(atomic_read(&bp->intr_sem) != 0)) { 2867 if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
2841 DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n"); 2868 DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
2842 return IRQ_HANDLED; 2869 return IRQ_HANDLED;
2843 } 2870 }
2844 2871
@@ -2876,11 +2903,11 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
2876 /* underflow */ \ 2903 /* underflow */ \
2877 d_hi = m_hi - s_hi; \ 2904 d_hi = m_hi - s_hi; \
2878 if (d_hi > 0) { \ 2905 if (d_hi > 0) { \
2879 /* we can 'loan' 1 */ \ 2906 /* we can 'loan' 1 */ \
2880 d_hi--; \ 2907 d_hi--; \
2881 d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ 2908 d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
2882 } else { \ 2909 } else { \
2883 /* m_hi <= s_hi */ \ 2910 /* m_hi <= s_hi */ \
2884 d_hi = 0; \ 2911 d_hi = 0; \
2885 d_lo = 0; \ 2912 d_lo = 0; \
2886 } \ 2913 } \
@@ -2890,7 +2917,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
2890 d_hi = 0; \ 2917 d_hi = 0; \
2891 d_lo = 0; \ 2918 d_lo = 0; \
2892 } else { \ 2919 } else { \
2893 /* m_hi >= s_hi */ \ 2920 /* m_hi >= s_hi */ \
2894 d_hi = m_hi - s_hi; \ 2921 d_hi = m_hi - s_hi; \
2895 d_lo = m_lo - s_lo; \ 2922 d_lo = m_lo - s_lo; \
2896 } \ 2923 } \
@@ -2963,37 +2990,6 @@ static inline long bnx2x_hilo(u32 *hiref)
2963 * Init service functions 2990 * Init service functions
2964 */ 2991 */
2965 2992
2966static void bnx2x_storm_stats_init(struct bnx2x *bp)
2967{
2968 int func = BP_FUNC(bp);
2969
2970 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), 1);
2971 REG_WR(bp, BAR_XSTRORM_INTMEM +
2972 XSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
2973
2974 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), 1);
2975 REG_WR(bp, BAR_TSTRORM_INTMEM +
2976 TSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
2977
2978 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), 0);
2979 REG_WR(bp, BAR_CSTRORM_INTMEM +
2980 CSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
2981
2982 REG_WR(bp, BAR_XSTRORM_INTMEM +
2983 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
2984 U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
2985 REG_WR(bp, BAR_XSTRORM_INTMEM +
2986 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
2987 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
2988
2989 REG_WR(bp, BAR_TSTRORM_INTMEM +
2990 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
2991 U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
2992 REG_WR(bp, BAR_TSTRORM_INTMEM +
2993 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
2994 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
2995}
2996
2997static void bnx2x_storm_stats_post(struct bnx2x *bp) 2993static void bnx2x_storm_stats_post(struct bnx2x *bp)
2998{ 2994{
2999 if (!bp->stats_pending) { 2995 if (!bp->stats_pending) {
@@ -3032,6 +3028,8 @@ static void bnx2x_stats_init(struct bnx2x *bp)
3032 memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats)); 3028 memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
3033 bp->port.old_nig_stats.brb_discard = 3029 bp->port.old_nig_stats.brb_discard =
3034 REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38); 3030 REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
3031 bp->port.old_nig_stats.brb_truncate =
3032 REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
3035 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50, 3033 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
3036 &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2); 3034 &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
3037 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50, 3035 REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
@@ -3101,12 +3099,12 @@ static int bnx2x_stats_comp(struct bnx2x *bp)
3101 3099
3102 might_sleep(); 3100 might_sleep();
3103 while (*stats_comp != DMAE_COMP_VAL) { 3101 while (*stats_comp != DMAE_COMP_VAL) {
3104 msleep(1);
3105 if (!cnt) { 3102 if (!cnt) {
3106 BNX2X_ERR("timeout waiting for stats finished\n"); 3103 BNX2X_ERR("timeout waiting for stats finished\n");
3107 break; 3104 break;
3108 } 3105 }
3109 cnt--; 3106 cnt--;
3107 msleep(1);
3110 } 3108 }
3111 return 1; 3109 return 1;
3112} 3110}
@@ -3451,8 +3449,7 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
3451 UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); 3449 UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
3452 UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); 3450 UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
3453 UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); 3451 UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
3454 UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); 3452 UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
3455 UPDATE_STAT64(rx_stat_grxcf, rx_stat_bmac_xcf);
3456 UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); 3453 UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
3457 UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived); 3454 UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
3458 UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); 3455 UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
@@ -3536,6 +3533,8 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
3536 3533
3537 ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo, 3534 ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
3538 new->brb_discard - old->brb_discard); 3535 new->brb_discard - old->brb_discard);
3536 ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo,
3537 new->brb_truncate - old->brb_truncate);
3539 3538
3540 UPDATE_STAT64_NIG(egress_mac_pkt0, 3539 UPDATE_STAT64_NIG(egress_mac_pkt0,
3541 etherstatspkts1024octetsto1522octets); 3540 etherstatspkts1024octetsto1522octets);
@@ -3713,8 +3712,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
3713 nstats->rx_length_errors = 3712 nstats->rx_length_errors =
3714 estats->rx_stat_etherstatsundersizepkts_lo + 3713 estats->rx_stat_etherstatsundersizepkts_lo +
3715 estats->jabber_packets_received; 3714 estats->jabber_packets_received;
3716 nstats->rx_over_errors = estats->brb_drop_lo + 3715 nstats->rx_over_errors = estats->brb_drop_lo + estats->brb_truncate_lo;
3717 estats->brb_truncate_discard;
3718 nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo; 3716 nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
3719 nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo; 3717 nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
3720 nstats->rx_fifo_errors = old_tclient->no_buff_discard; 3718 nstats->rx_fifo_errors = old_tclient->no_buff_discard;
@@ -3783,7 +3781,7 @@ static void bnx2x_stats_update(struct bnx2x *bp)
3783 bp->fp->rx_comp_cons), 3781 bp->fp->rx_comp_cons),
3784 le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets); 3782 le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets);
3785 printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n", 3783 printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
3786 netif_queue_stopped(bp->dev)? "Xoff" : "Xon", 3784 netif_queue_stopped(bp->dev) ? "Xoff" : "Xon",
3787 estats->driver_xoff, estats->brb_drop_lo); 3785 estats->driver_xoff, estats->brb_drop_lo);
3788 printk(KERN_DEBUG "tstats: checksum_discard %u " 3786 printk(KERN_DEBUG "tstats: checksum_discard %u "
3789 "packets_too_big_discard %u no_buff_discard %u " 3787 "packets_too_big_discard %u no_buff_discard %u "
@@ -3994,14 +3992,14 @@ static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id)
3994 3992
3995 bnx2x_init_fill(bp, BAR_USTRORM_INTMEM + 3993 bnx2x_init_fill(bp, BAR_USTRORM_INTMEM +
3996 USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0, 3994 USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
3997 sizeof(struct ustorm_def_status_block)/4); 3995 sizeof(struct ustorm_status_block)/4);
3998 bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM + 3996 bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM +
3999 CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0, 3997 CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
4000 sizeof(struct cstorm_def_status_block)/4); 3998 sizeof(struct cstorm_status_block)/4);
4001} 3999}
4002 4000
4003static void bnx2x_init_sb(struct bnx2x *bp, int sb_id, 4001static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
4004 struct host_status_block *sb, dma_addr_t mapping) 4002 dma_addr_t mapping, int sb_id)
4005{ 4003{
4006 int port = BP_PORT(bp); 4004 int port = BP_PORT(bp);
4007 int func = BP_FUNC(bp); 4005 int func = BP_FUNC(bp);
@@ -4077,7 +4075,6 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
4077 atten_status_block); 4075 atten_status_block);
4078 def_sb->atten_status_block.status_block_id = sb_id; 4076 def_sb->atten_status_block.status_block_id = sb_id;
4079 4077
4080 bp->def_att_idx = 0;
4081 bp->attn_state = 0; 4078 bp->attn_state = 0;
4082 4079
4083 reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : 4080 reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
@@ -4094,9 +4091,6 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
4094 reg_offset + 0xc + 0x10*index); 4091 reg_offset + 0xc + 0x10*index);
4095 } 4092 }
4096 4093
4097 bp->aeu_mask = REG_RD(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
4098 MISC_REG_AEU_MASK_ATTN_FUNC_0));
4099
4100 reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : 4094 reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L :
4101 HC_REG_ATTN_MSG0_ADDR_L); 4095 HC_REG_ATTN_MSG0_ADDR_L);
4102 4096
@@ -4114,17 +4108,13 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
4114 u_def_status_block); 4108 u_def_status_block);
4115 def_sb->u_def_status_block.status_block_id = sb_id; 4109 def_sb->u_def_status_block.status_block_id = sb_id;
4116 4110
4117 bp->def_u_idx = 0;
4118
4119 REG_WR(bp, BAR_USTRORM_INTMEM + 4111 REG_WR(bp, BAR_USTRORM_INTMEM +
4120 USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); 4112 USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
4121 REG_WR(bp, BAR_USTRORM_INTMEM + 4113 REG_WR(bp, BAR_USTRORM_INTMEM +
4122 ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), 4114 ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
4123 U64_HI(section)); 4115 U64_HI(section));
4124 REG_WR8(bp, BAR_USTRORM_INTMEM + DEF_USB_FUNC_OFF + 4116 REG_WR8(bp, BAR_USTRORM_INTMEM + DEF_USB_FUNC_OFF +
4125 USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); 4117 USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
4126 REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(func),
4127 BNX2X_BTR);
4128 4118
4129 for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++) 4119 for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++)
4130 REG_WR16(bp, BAR_USTRORM_INTMEM + 4120 REG_WR16(bp, BAR_USTRORM_INTMEM +
@@ -4135,17 +4125,13 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
4135 c_def_status_block); 4125 c_def_status_block);
4136 def_sb->c_def_status_block.status_block_id = sb_id; 4126 def_sb->c_def_status_block.status_block_id = sb_id;
4137 4127
4138 bp->def_c_idx = 0;
4139
4140 REG_WR(bp, BAR_CSTRORM_INTMEM + 4128 REG_WR(bp, BAR_CSTRORM_INTMEM +
4141 CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); 4129 CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
4142 REG_WR(bp, BAR_CSTRORM_INTMEM + 4130 REG_WR(bp, BAR_CSTRORM_INTMEM +
4143 ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), 4131 ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
4144 U64_HI(section)); 4132 U64_HI(section));
4145 REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF + 4133 REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF +
4146 CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); 4134 CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
4147 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(func),
4148 BNX2X_BTR);
4149 4135
4150 for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++) 4136 for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++)
4151 REG_WR16(bp, BAR_CSTRORM_INTMEM + 4137 REG_WR16(bp, BAR_CSTRORM_INTMEM +
@@ -4156,17 +4142,13 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
4156 t_def_status_block); 4142 t_def_status_block);
4157 def_sb->t_def_status_block.status_block_id = sb_id; 4143 def_sb->t_def_status_block.status_block_id = sb_id;
4158 4144
4159 bp->def_t_idx = 0;
4160
4161 REG_WR(bp, BAR_TSTRORM_INTMEM + 4145 REG_WR(bp, BAR_TSTRORM_INTMEM +
4162 TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); 4146 TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
4163 REG_WR(bp, BAR_TSTRORM_INTMEM + 4147 REG_WR(bp, BAR_TSTRORM_INTMEM +
4164 ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), 4148 ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
4165 U64_HI(section)); 4149 U64_HI(section));
4166 REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF + 4150 REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF +
4167 TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); 4151 TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
4168 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(func),
4169 BNX2X_BTR);
4170 4152
4171 for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++) 4153 for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++)
4172 REG_WR16(bp, BAR_TSTRORM_INTMEM + 4154 REG_WR16(bp, BAR_TSTRORM_INTMEM +
@@ -4177,23 +4159,20 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
4177 x_def_status_block); 4159 x_def_status_block);
4178 def_sb->x_def_status_block.status_block_id = sb_id; 4160 def_sb->x_def_status_block.status_block_id = sb_id;
4179 4161
4180 bp->def_x_idx = 0;
4181
4182 REG_WR(bp, BAR_XSTRORM_INTMEM + 4162 REG_WR(bp, BAR_XSTRORM_INTMEM +
4183 XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); 4163 XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
4184 REG_WR(bp, BAR_XSTRORM_INTMEM + 4164 REG_WR(bp, BAR_XSTRORM_INTMEM +
4185 ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), 4165 ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
4186 U64_HI(section)); 4166 U64_HI(section));
4187 REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF + 4167 REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF +
4188 XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); 4168 XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
4189 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(func),
4190 BNX2X_BTR);
4191 4169
4192 for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++) 4170 for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++)
4193 REG_WR16(bp, BAR_XSTRORM_INTMEM + 4171 REG_WR16(bp, BAR_XSTRORM_INTMEM +
4194 XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); 4172 XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
4195 4173
4196 bp->stats_pending = 0; 4174 bp->stats_pending = 0;
4175 bp->set_mac_pending = 0;
4197 4176
4198 bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); 4177 bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
4199} 4178}
@@ -4209,21 +4188,25 @@ static void bnx2x_update_coalesce(struct bnx2x *bp)
4209 /* HC_INDEX_U_ETH_RX_CQ_CONS */ 4188 /* HC_INDEX_U_ETH_RX_CQ_CONS */
4210 REG_WR8(bp, BAR_USTRORM_INTMEM + 4189 REG_WR8(bp, BAR_USTRORM_INTMEM +
4211 USTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id, 4190 USTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
4212 HC_INDEX_U_ETH_RX_CQ_CONS), 4191 U_SB_ETH_RX_CQ_INDEX),
4213 bp->rx_ticks/12); 4192 bp->rx_ticks/12);
4214 REG_WR16(bp, BAR_USTRORM_INTMEM + 4193 REG_WR16(bp, BAR_USTRORM_INTMEM +
4215 USTORM_SB_HC_DISABLE_OFFSET(port, sb_id, 4194 USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
4216 HC_INDEX_U_ETH_RX_CQ_CONS), 4195 U_SB_ETH_RX_CQ_INDEX),
4196 bp->rx_ticks ? 0 : 1);
4197 REG_WR16(bp, BAR_USTRORM_INTMEM +
4198 USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
4199 U_SB_ETH_RX_BD_INDEX),
4217 bp->rx_ticks ? 0 : 1); 4200 bp->rx_ticks ? 0 : 1);
4218 4201
4219 /* HC_INDEX_C_ETH_TX_CQ_CONS */ 4202 /* HC_INDEX_C_ETH_TX_CQ_CONS */
4220 REG_WR8(bp, BAR_CSTRORM_INTMEM + 4203 REG_WR8(bp, BAR_CSTRORM_INTMEM +
4221 CSTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id, 4204 CSTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
4222 HC_INDEX_C_ETH_TX_CQ_CONS), 4205 C_SB_ETH_TX_CQ_INDEX),
4223 bp->tx_ticks/12); 4206 bp->tx_ticks/12);
4224 REG_WR16(bp, BAR_CSTRORM_INTMEM + 4207 REG_WR16(bp, BAR_CSTRORM_INTMEM +
4225 CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id, 4208 CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
4226 HC_INDEX_C_ETH_TX_CQ_CONS), 4209 C_SB_ETH_TX_CQ_INDEX),
4227 bp->tx_ticks ? 0 : 1); 4210 bp->tx_ticks ? 0 : 1);
4228 } 4211 }
4229} 4212}
@@ -4256,7 +4239,9 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
4256static void bnx2x_init_rx_rings(struct bnx2x *bp) 4239static void bnx2x_init_rx_rings(struct bnx2x *bp)
4257{ 4240{
4258 int func = BP_FUNC(bp); 4241 int func = BP_FUNC(bp);
4259 u16 ring_prod, cqe_ring_prod = 0; 4242 int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 :
4243 ETH_MAX_AGGREGATION_QUEUES_E1H;
4244 u16 ring_prod, cqe_ring_prod;
4260 int i, j; 4245 int i, j;
4261 4246
4262 bp->rx_buf_use_size = bp->dev->mtu; 4247 bp->rx_buf_use_size = bp->dev->mtu;
@@ -4270,9 +4255,9 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
4270 bp->dev->mtu + ETH_OVREHEAD); 4255 bp->dev->mtu + ETH_OVREHEAD);
4271 4256
4272 for_each_queue(bp, j) { 4257 for_each_queue(bp, j) {
4273 for (i = 0; i < ETH_MAX_AGGREGATION_QUEUES_E1H; i++) { 4258 struct bnx2x_fastpath *fp = &bp->fp[j];
4274 struct bnx2x_fastpath *fp = &bp->fp[j];
4275 4259
4260 for (i = 0; i < max_agg_queues; i++) {
4276 fp->tpa_pool[i].skb = 4261 fp->tpa_pool[i].skb =
4277 netdev_alloc_skb(bp->dev, bp->rx_buf_size); 4262 netdev_alloc_skb(bp->dev, bp->rx_buf_size);
4278 if (!fp->tpa_pool[i].skb) { 4263 if (!fp->tpa_pool[i].skb) {
@@ -4352,8 +4337,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
4352 BNX2X_ERR("disabling TPA for queue[%d]\n", j); 4337 BNX2X_ERR("disabling TPA for queue[%d]\n", j);
4353 /* Cleanup already allocated elements */ 4338 /* Cleanup already allocated elements */
4354 bnx2x_free_rx_sge_range(bp, fp, ring_prod); 4339 bnx2x_free_rx_sge_range(bp, fp, ring_prod);
4355 bnx2x_free_tpa_pool(bp, fp, 4340 bnx2x_free_tpa_pool(bp, fp, max_agg_queues);
4356 ETH_MAX_AGGREGATION_QUEUES_E1H);
4357 fp->disable_tpa = 1; 4341 fp->disable_tpa = 1;
4358 ring_prod = 0; 4342 ring_prod = 0;
4359 break; 4343 break;
@@ -4363,13 +4347,13 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
4363 fp->rx_sge_prod = ring_prod; 4347 fp->rx_sge_prod = ring_prod;
4364 4348
4365 /* Allocate BDs and initialize BD ring */ 4349 /* Allocate BDs and initialize BD ring */
4366 fp->rx_comp_cons = fp->rx_alloc_failed = 0; 4350 fp->rx_comp_cons = 0;
4367 cqe_ring_prod = ring_prod = 0; 4351 cqe_ring_prod = ring_prod = 0;
4368 for (i = 0; i < bp->rx_ring_size; i++) { 4352 for (i = 0; i < bp->rx_ring_size; i++) {
4369 if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { 4353 if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
4370 BNX2X_ERR("was only able to allocate " 4354 BNX2X_ERR("was only able to allocate "
4371 "%d rx skbs\n", i); 4355 "%d rx skbs\n", i);
4372 fp->rx_alloc_failed++; 4356 bp->eth_stats.rx_skb_alloc_failed++;
4373 break; 4357 break;
4374 } 4358 }
4375 ring_prod = NEXT_RX_IDX(ring_prod); 4359 ring_prod = NEXT_RX_IDX(ring_prod);
@@ -4497,7 +4481,7 @@ static void bnx2x_init_context(struct bnx2x *bp)
4497 } 4481 }
4498 4482
4499 context->cstorm_st_context.sb_index_number = 4483 context->cstorm_st_context.sb_index_number =
4500 HC_INDEX_C_ETH_TX_CQ_CONS; 4484 C_SB_ETH_TX_CQ_INDEX;
4501 context->cstorm_st_context.status_block_id = sb_id; 4485 context->cstorm_st_context.status_block_id = sb_id;
4502 4486
4503 context->xstorm_ag_context.cdu_reserved = 4487 context->xstorm_ag_context.cdu_reserved =
@@ -4535,7 +4519,7 @@ static void bnx2x_set_client_config(struct bnx2x *bp)
4535 int i; 4519 int i;
4536 4520
4537 tstorm_client.mtu = bp->dev->mtu + ETH_OVREHEAD; 4521 tstorm_client.mtu = bp->dev->mtu + ETH_OVREHEAD;
4538 tstorm_client.statistics_counter_id = 0; 4522 tstorm_client.statistics_counter_id = BP_CL_ID(bp);
4539 tstorm_client.config_flags = 4523 tstorm_client.config_flags =
4540 TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; 4524 TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
4541#ifdef BCM_VLAN 4525#ifdef BCM_VLAN
@@ -4579,7 +4563,7 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
4579 int func = BP_FUNC(bp); 4563 int func = BP_FUNC(bp);
4580 int i; 4564 int i;
4581 4565
4582 DP(NETIF_MSG_RX_STATUS, "rx mode is %d\n", mode); 4566 DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask);
4583 4567
4584 switch (mode) { 4568 switch (mode) {
4585 case BNX2X_RX_MODE_NONE: /* no Rx */ 4569 case BNX2X_RX_MODE_NONE: /* no Rx */
@@ -4617,13 +4601,35 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
4617 bnx2x_set_client_config(bp); 4601 bnx2x_set_client_config(bp);
4618} 4602}
4619 4603
4620static void bnx2x_init_internal(struct bnx2x *bp) 4604static void bnx2x_init_internal_common(struct bnx2x *bp)
4605{
4606 int i;
4607
4608 /* Zero this manually as its initialization is
4609 currently missing in the initTool */
4610 for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++)
4611 REG_WR(bp, BAR_USTRORM_INTMEM +
4612 USTORM_AGG_DATA_OFFSET + i * 4, 0);
4613}
4614
4615static void bnx2x_init_internal_port(struct bnx2x *bp)
4616{
4617 int port = BP_PORT(bp);
4618
4619 REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
4620 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
4621 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
4622 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
4623}
4624
4625static void bnx2x_init_internal_func(struct bnx2x *bp)
4621{ 4626{
4622 struct tstorm_eth_function_common_config tstorm_config = {0}; 4627 struct tstorm_eth_function_common_config tstorm_config = {0};
4623 struct stats_indication_flags stats_flags = {0}; 4628 struct stats_indication_flags stats_flags = {0};
4624 int port = BP_PORT(bp); 4629 int port = BP_PORT(bp);
4625 int func = BP_FUNC(bp); 4630 int func = BP_FUNC(bp);
4626 int i; 4631 int i;
4632 u16 max_agg_size;
4627 4633
4628 if (is_multi(bp)) { 4634 if (is_multi(bp)) {
4629 tstorm_config.config_flags = MULTI_FLAGS; 4635 tstorm_config.config_flags = MULTI_FLAGS;
@@ -4636,31 +4642,53 @@ static void bnx2x_init_internal(struct bnx2x *bp)
4636 TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func), 4642 TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func),
4637 (*(u32 *)&tstorm_config)); 4643 (*(u32 *)&tstorm_config));
4638 4644
4639/* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n",
4640 (*(u32 *)&tstorm_config)); */
4641
4642 bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ 4645 bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
4643 bnx2x_set_storm_rx_mode(bp); 4646 bnx2x_set_storm_rx_mode(bp);
4644 4647
4648 /* reset xstorm per client statistics */
4649 for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) {
4650 REG_WR(bp, BAR_XSTRORM_INTMEM +
4651 XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
4652 i*4, 0);
4653 }
4654 /* reset tstorm per client statistics */
4655 for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) {
4656 REG_WR(bp, BAR_TSTRORM_INTMEM +
4657 TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
4658 i*4, 0);
4659 }
4660
4661 /* Init statistics related context */
4645 stats_flags.collect_eth = 1; 4662 stats_flags.collect_eth = 1;
4646 4663
4647 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), 4664 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func),
4648 ((u32 *)&stats_flags)[0]); 4665 ((u32 *)&stats_flags)[0]);
4649 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port) + 4, 4666 REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4,
4650 ((u32 *)&stats_flags)[1]); 4667 ((u32 *)&stats_flags)[1]);
4651 4668
4652 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port), 4669 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func),
4653 ((u32 *)&stats_flags)[0]); 4670 ((u32 *)&stats_flags)[0]);
4654 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port) + 4, 4671 REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4,
4655 ((u32 *)&stats_flags)[1]); 4672 ((u32 *)&stats_flags)[1]);
4656 4673
4657 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port), 4674 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func),
4658 ((u32 *)&stats_flags)[0]); 4675 ((u32 *)&stats_flags)[0]);
4659 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port) + 4, 4676 REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4,
4660 ((u32 *)&stats_flags)[1]); 4677 ((u32 *)&stats_flags)[1]);
4661 4678
4662/* DP(NETIF_MSG_IFUP, "stats_flags: 0x%08x 0x%08x\n", 4679 REG_WR(bp, BAR_XSTRORM_INTMEM +
4663 ((u32 *)&stats_flags)[0], ((u32 *)&stats_flags)[1]); */ 4680 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
4681 U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
4682 REG_WR(bp, BAR_XSTRORM_INTMEM +
4683 XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
4684 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
4685
4686 REG_WR(bp, BAR_TSTRORM_INTMEM +
4687 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
4688 U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
4689 REG_WR(bp, BAR_TSTRORM_INTMEM +
4690 TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
4691 U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
4664 4692
4665 if (CHIP_IS_E1H(bp)) { 4693 if (CHIP_IS_E1H(bp)) {
4666 REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, 4694 REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET,
@@ -4676,15 +4704,12 @@ static void bnx2x_init_internal(struct bnx2x *bp)
4676 bp->e1hov); 4704 bp->e1hov);
4677 } 4705 }
4678 4706
4679 /* Zero this manualy as its initialization is 4707 /* Init CQ ring mapping and aggregation size */
4680 currently missing in the initTool */ 4708 max_agg_size = min((u32)(bp->rx_buf_use_size +
4681 for (i = 0; i < USTORM_AGG_DATA_SIZE >> 2; i++) 4709 8*BCM_PAGE_SIZE*PAGES_PER_SGE),
4682 REG_WR(bp, BAR_USTRORM_INTMEM + 4710 (u32)0xffff);
4683 USTORM_AGG_DATA_OFFSET + 4*i, 0);
4684
4685 for_each_queue(bp, i) { 4711 for_each_queue(bp, i) {
4686 struct bnx2x_fastpath *fp = &bp->fp[i]; 4712 struct bnx2x_fastpath *fp = &bp->fp[i];
4687 u16 max_agg_size;
4688 4713
4689 REG_WR(bp, BAR_USTRORM_INTMEM + 4714 REG_WR(bp, BAR_USTRORM_INTMEM +
4690 USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)), 4715 USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)),
@@ -4693,16 +4718,34 @@ static void bnx2x_init_internal(struct bnx2x *bp)
4693 USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4, 4718 USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4,
4694 U64_HI(fp->rx_comp_mapping)); 4719 U64_HI(fp->rx_comp_mapping));
4695 4720
4696 max_agg_size = min((u32)(bp->rx_buf_use_size +
4697 8*BCM_PAGE_SIZE*PAGES_PER_SGE),
4698 (u32)0xffff);
4699 REG_WR16(bp, BAR_USTRORM_INTMEM + 4721 REG_WR16(bp, BAR_USTRORM_INTMEM +
4700 USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)), 4722 USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
4701 max_agg_size); 4723 max_agg_size);
4702 } 4724 }
4703} 4725}
4704 4726
4705static void bnx2x_nic_init(struct bnx2x *bp) 4727static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
4728{
4729 switch (load_code) {
4730 case FW_MSG_CODE_DRV_LOAD_COMMON:
4731 bnx2x_init_internal_common(bp);
4732 /* no break */
4733
4734 case FW_MSG_CODE_DRV_LOAD_PORT:
4735 bnx2x_init_internal_port(bp);
4736 /* no break */
4737
4738 case FW_MSG_CODE_DRV_LOAD_FUNCTION:
4739 bnx2x_init_internal_func(bp);
4740 break;
4741
4742 default:
4743 BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code);
4744 break;
4745 }
4746}
4747
4748static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
4706{ 4749{
4707 int i; 4750 int i;
4708 4751
@@ -4717,19 +4760,20 @@ static void bnx2x_nic_init(struct bnx2x *bp)
4717 DP(NETIF_MSG_IFUP, 4760 DP(NETIF_MSG_IFUP,
4718 "bnx2x_init_sb(%p,%p) index %d cl_id %d sb %d\n", 4761 "bnx2x_init_sb(%p,%p) index %d cl_id %d sb %d\n",
4719 bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp)); 4762 bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp));
4720 bnx2x_init_sb(bp, FP_SB_ID(fp), fp->status_blk, 4763 bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping,
4721 fp->status_blk_mapping); 4764 FP_SB_ID(fp));
4765 bnx2x_update_fpsb_idx(fp);
4722 } 4766 }
4723 4767
4724 bnx2x_init_def_sb(bp, bp->def_status_blk, 4768 bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping,
4725 bp->def_status_blk_mapping, DEF_SB_ID); 4769 DEF_SB_ID);
4770 bnx2x_update_dsb_idx(bp);
4726 bnx2x_update_coalesce(bp); 4771 bnx2x_update_coalesce(bp);
4727 bnx2x_init_rx_rings(bp); 4772 bnx2x_init_rx_rings(bp);
4728 bnx2x_init_tx_ring(bp); 4773 bnx2x_init_tx_ring(bp);
4729 bnx2x_init_sp_ring(bp); 4774 bnx2x_init_sp_ring(bp);
4730 bnx2x_init_context(bp); 4775 bnx2x_init_context(bp);
4731 bnx2x_init_internal(bp); 4776 bnx2x_init_internal(bp, load_code);
4732 bnx2x_storm_stats_init(bp);
4733 bnx2x_init_ind_table(bp); 4777 bnx2x_init_ind_table(bp);
4734 bnx2x_int_enable(bp); 4778 bnx2x_int_enable(bp);
4735} 4779}
@@ -4878,7 +4922,7 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
4878 REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); 4922 REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
4879 REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); 4923 REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
4880 REG_WR(bp, CFC_REG_DEBUG0, 0x1); 4924 REG_WR(bp, CFC_REG_DEBUG0, 0x1);
4881 NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0); 4925 REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0);
4882 4926
4883 /* Write 0 to parser credits for CFC search request */ 4927 /* Write 0 to parser credits for CFC search request */
4884 REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); 4928 REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
@@ -4933,7 +4977,7 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
4933 REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); 4977 REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
4934 REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); 4978 REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
4935 REG_WR(bp, CFC_REG_DEBUG0, 0x1); 4979 REG_WR(bp, CFC_REG_DEBUG0, 0x1);
4936 NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0); 4980 REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0);
4937 4981
4938 /* Write 0 to parser credits for CFC search request */ 4982 /* Write 0 to parser credits for CFC search request */
4939 REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); 4983 REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
@@ -5000,7 +5044,7 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
5000 REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff); 5044 REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff);
5001 REG_WR(bp, TCM_REG_PRS_IFEN, 0x1); 5045 REG_WR(bp, TCM_REG_PRS_IFEN, 0x1);
5002 REG_WR(bp, CFC_REG_DEBUG0, 0x0); 5046 REG_WR(bp, CFC_REG_DEBUG0, 0x0);
5003 NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x1); 5047 REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x1);
5004 5048
5005 DP(NETIF_MSG_HW, "done\n"); 5049 DP(NETIF_MSG_HW, "done\n");
5006 5050
@@ -5089,11 +5133,6 @@ static int bnx2x_init_common(struct bnx2x *bp)
5089 REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); 5133 REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
5090#endif 5134#endif
5091 5135
5092#ifndef BCM_ISCSI
5093 /* set NIC mode */
5094 REG_WR(bp, PRS_REG_NIC_MODE, 1);
5095#endif
5096
5097 REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2); 5136 REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2);
5098#ifdef BCM_ISCSI 5137#ifdef BCM_ISCSI
5099 REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5); 5138 REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5);
@@ -5163,6 +5202,8 @@ static int bnx2x_init_common(struct bnx2x *bp)
5163 } 5202 }
5164 5203
5165 bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); 5204 bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
5205 /* set NIC mode */
5206 REG_WR(bp, PRS_REG_NIC_MODE, 1);
5166 if (CHIP_IS_E1H(bp)) 5207 if (CHIP_IS_E1H(bp))
5167 REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); 5208 REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
5168 5209
@@ -5333,6 +5374,13 @@ static int bnx2x_init_common(struct bnx2x *bp)
5333 ((u32 *)&tmp)[1]); 5374 ((u32 *)&tmp)[1]);
5334 } 5375 }
5335 5376
5377 if (!BP_NOMCP(bp)) {
5378 bnx2x_acquire_phy_lock(bp);
5379 bnx2x_common_init_phy(bp, bp->common.shmem_base);
5380 bnx2x_release_phy_lock(bp);
5381 } else
5382 BNX2X_ERR("Bootcode is missing - can not initialize link\n");
5383
5336 return 0; 5384 return 0;
5337} 5385}
5338 5386
@@ -5638,18 +5686,23 @@ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
5638 int func = BP_FUNC(bp); 5686 int func = BP_FUNC(bp);
5639 u32 seq = ++bp->fw_seq; 5687 u32 seq = ++bp->fw_seq;
5640 u32 rc = 0; 5688 u32 rc = 0;
5689 u32 cnt = 1;
5690 u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
5641 5691
5642 SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); 5692 SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
5643 DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); 5693 DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
5644 5694
5645 /* let the FW do it's magic ... */ 5695 do {
5646 msleep(100); /* TBD */ 5696 /* let the FW do it's magic ... */
5697 msleep(delay);
5647 5698
5648 if (CHIP_REV_IS_SLOW(bp)) 5699 rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
5649 msleep(900);
5650 5700
5651 rc = SHMEM_RD(bp, func_mb[func].fw_mb_header); 5701 /* Give the FW up to 2 second (200*10ms) */
5652 DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq); 5702 } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 200));
5703
5704 DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n",
5705 cnt*delay, rc, seq);
5653 5706
5654 /* is this a reply to our command? */ 5707 /* is this a reply to our command? */
5655 if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) { 5708 if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
@@ -5713,6 +5766,7 @@ static void bnx2x_free_mem(struct bnx2x *bp)
5713 NUM_RCQ_BD); 5766 NUM_RCQ_BD);
5714 5767
5715 /* SGE ring */ 5768 /* SGE ring */
5769 BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring));
5716 BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring), 5770 BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring),
5717 bnx2x_fp(bp, i, rx_sge_mapping), 5771 bnx2x_fp(bp, i, rx_sge_mapping),
5718 BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); 5772 BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
@@ -5890,7 +5944,8 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
5890 dev_kfree_skb(skb); 5944 dev_kfree_skb(skb);
5891 } 5945 }
5892 if (!fp->disable_tpa) 5946 if (!fp->disable_tpa)
5893 bnx2x_free_tpa_pool(bp, fp, 5947 bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ?
5948 ETH_MAX_AGGREGATION_QUEUES_E1 :
5894 ETH_MAX_AGGREGATION_QUEUES_E1H); 5949 ETH_MAX_AGGREGATION_QUEUES_E1H);
5895 } 5950 }
5896} 5951}
@@ -5976,8 +6031,8 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
5976 bnx2x_msix_fp_int, 0, 6031 bnx2x_msix_fp_int, 0,
5977 bp->dev->name, &bp->fp[i]); 6032 bp->dev->name, &bp->fp[i]);
5978 if (rc) { 6033 if (rc) {
5979 BNX2X_ERR("request fp #%d irq failed rc %d\n", 6034 BNX2X_ERR("request fp #%d irq failed rc -%d\n",
5980 i + offset, rc); 6035 i + offset, -rc);
5981 bnx2x_free_msix_irqs(bp); 6036 bnx2x_free_msix_irqs(bp);
5982 return -EBUSY; 6037 return -EBUSY;
5983 } 6038 }
@@ -6004,7 +6059,7 @@ static int bnx2x_req_irq(struct bnx2x *bp)
6004 * Init service functions 6059 * Init service functions
6005 */ 6060 */
6006 6061
6007static void bnx2x_set_mac_addr_e1(struct bnx2x *bp) 6062static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
6008{ 6063{
6009 struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); 6064 struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
6010 int port = BP_PORT(bp); 6065 int port = BP_PORT(bp);
@@ -6026,11 +6081,15 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp)
6026 config->config_table[0].cam_entry.lsb_mac_addr = 6081 config->config_table[0].cam_entry.lsb_mac_addr =
6027 swab16(*(u16 *)&bp->dev->dev_addr[4]); 6082 swab16(*(u16 *)&bp->dev->dev_addr[4]);
6028 config->config_table[0].cam_entry.flags = cpu_to_le16(port); 6083 config->config_table[0].cam_entry.flags = cpu_to_le16(port);
6029 config->config_table[0].target_table_entry.flags = 0; 6084 if (set)
6085 config->config_table[0].target_table_entry.flags = 0;
6086 else
6087 CAM_INVALIDATE(config->config_table[0]);
6030 config->config_table[0].target_table_entry.client_id = 0; 6088 config->config_table[0].target_table_entry.client_id = 0;
6031 config->config_table[0].target_table_entry.vlan_id = 0; 6089 config->config_table[0].target_table_entry.vlan_id = 0;
6032 6090
6033 DP(NETIF_MSG_IFUP, "setting MAC (%04x:%04x:%04x)\n", 6091 DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n",
6092 (set ? "setting" : "clearing"),
6034 config->config_table[0].cam_entry.msb_mac_addr, 6093 config->config_table[0].cam_entry.msb_mac_addr,
6035 config->config_table[0].cam_entry.middle_mac_addr, 6094 config->config_table[0].cam_entry.middle_mac_addr,
6036 config->config_table[0].cam_entry.lsb_mac_addr); 6095 config->config_table[0].cam_entry.lsb_mac_addr);
@@ -6040,8 +6099,11 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp)
6040 config->config_table[1].cam_entry.middle_mac_addr = 0xffff; 6099 config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
6041 config->config_table[1].cam_entry.lsb_mac_addr = 0xffff; 6100 config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
6042 config->config_table[1].cam_entry.flags = cpu_to_le16(port); 6101 config->config_table[1].cam_entry.flags = cpu_to_le16(port);
6043 config->config_table[1].target_table_entry.flags = 6102 if (set)
6103 config->config_table[1].target_table_entry.flags =
6044 TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST; 6104 TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
6105 else
6106 CAM_INVALIDATE(config->config_table[1]);
6045 config->config_table[1].target_table_entry.client_id = 0; 6107 config->config_table[1].target_table_entry.client_id = 0;
6046 config->config_table[1].target_table_entry.vlan_id = 0; 6108 config->config_table[1].target_table_entry.vlan_id = 0;
6047 6109
@@ -6050,12 +6112,12 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp)
6050 U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); 6112 U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
6051} 6113}
6052 6114
6053static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp) 6115static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
6054{ 6116{
6055 struct mac_configuration_cmd_e1h *config = 6117 struct mac_configuration_cmd_e1h *config =
6056 (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config); 6118 (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config);
6057 6119
6058 if (bp->state != BNX2X_STATE_OPEN) { 6120 if (set && (bp->state != BNX2X_STATE_OPEN)) {
6059 DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state); 6121 DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
6060 return; 6122 return;
6061 } 6123 }
@@ -6079,9 +6141,14 @@ static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp)
6079 config->config_table[0].client_id = BP_L_ID(bp); 6141 config->config_table[0].client_id = BP_L_ID(bp);
6080 config->config_table[0].vlan_id = 0; 6142 config->config_table[0].vlan_id = 0;
6081 config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov); 6143 config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov);
6082 config->config_table[0].flags = BP_PORT(bp); 6144 if (set)
6145 config->config_table[0].flags = BP_PORT(bp);
6146 else
6147 config->config_table[0].flags =
6148 MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE;
6083 6149
6084 DP(NETIF_MSG_IFUP, "setting MAC (%04x:%04x:%04x) E1HOV %d CLID %d\n", 6150 DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID %d\n",
6151 (set ? "setting" : "clearing"),
6085 config->config_table[0].msb_mac_addr, 6152 config->config_table[0].msb_mac_addr,
6086 config->config_table[0].middle_mac_addr, 6153 config->config_table[0].middle_mac_addr,
6087 config->config_table[0].lsb_mac_addr, bp->e1hov, BP_L_ID(bp)); 6154 config->config_table[0].lsb_mac_addr, bp->e1hov, BP_L_ID(bp));
@@ -6106,13 +6173,13 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
6106 bnx2x_rx_int(bp->fp, 10); 6173 bnx2x_rx_int(bp->fp, 10);
6107 /* if index is different from 0 6174 /* if index is different from 0
6108 * the reply for some commands will 6175 * the reply for some commands will
6109 * be on the none default queue 6176 * be on the non default queue
6110 */ 6177 */
6111 if (idx) 6178 if (idx)
6112 bnx2x_rx_int(&bp->fp[idx], 10); 6179 bnx2x_rx_int(&bp->fp[idx], 10);
6113 } 6180 }
6114 mb(); /* state is changed by bnx2x_sp_event() */
6115 6181
6182 mb(); /* state is changed by bnx2x_sp_event() */
6116 if (*state_p == state) 6183 if (*state_p == state)
6117 return 0; 6184 return 0;
6118 6185
@@ -6167,7 +6234,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
6167{ 6234{
6168 u32 load_code; 6235 u32 load_code;
6169 int i, rc; 6236 int i, rc;
6170
6171#ifdef BNX2X_STOP_ON_ERROR 6237#ifdef BNX2X_STOP_ON_ERROR
6172 if (unlikely(bp->panic)) 6238 if (unlikely(bp->panic))
6173 return -EPERM; 6239 return -EPERM;
@@ -6183,22 +6249,24 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
6183 if (!BP_NOMCP(bp)) { 6249 if (!BP_NOMCP(bp)) {
6184 load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); 6250 load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
6185 if (!load_code) { 6251 if (!load_code) {
6186 BNX2X_ERR("MCP response failure, unloading\n"); 6252 BNX2X_ERR("MCP response failure, aborting\n");
6187 return -EBUSY; 6253 return -EBUSY;
6188 } 6254 }
6189 if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) 6255 if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
6190 return -EBUSY; /* other port in diagnostic mode */ 6256 return -EBUSY; /* other port in diagnostic mode */
6191 6257
6192 } else { 6258 } else {
6259 int port = BP_PORT(bp);
6260
6193 DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n", 6261 DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
6194 load_count[0], load_count[1], load_count[2]); 6262 load_count[0], load_count[1], load_count[2]);
6195 load_count[0]++; 6263 load_count[0]++;
6196 load_count[1 + BP_PORT(bp)]++; 6264 load_count[1 + port]++;
6197 DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n", 6265 DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
6198 load_count[0], load_count[1], load_count[2]); 6266 load_count[0], load_count[1], load_count[2]);
6199 if (load_count[0] == 1) 6267 if (load_count[0] == 1)
6200 load_code = FW_MSG_CODE_DRV_LOAD_COMMON; 6268 load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
6201 else if (load_count[1 + BP_PORT(bp)] == 1) 6269 else if (load_count[1 + port] == 1)
6202 load_code = FW_MSG_CODE_DRV_LOAD_PORT; 6270 load_code = FW_MSG_CODE_DRV_LOAD_PORT;
6203 else 6271 else
6204 load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; 6272 load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
@@ -6247,9 +6315,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
6247 bnx2x_fp(bp, i, disable_tpa) = 6315 bnx2x_fp(bp, i, disable_tpa) =
6248 ((bp->flags & TPA_ENABLE_FLAG) == 0); 6316 ((bp->flags & TPA_ENABLE_FLAG) == 0);
6249 6317
6250 /* Disable interrupt handling until HW is initialized */
6251 atomic_set(&bp->intr_sem, 1);
6252
6253 if (bp->flags & USING_MSIX_FLAG) { 6318 if (bp->flags & USING_MSIX_FLAG) {
6254 rc = bnx2x_req_msix_irqs(bp); 6319 rc = bnx2x_req_msix_irqs(bp);
6255 if (rc) { 6320 if (rc) {
@@ -6276,17 +6341,14 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
6276 goto load_error; 6341 goto load_error;
6277 } 6342 }
6278 6343
6279 /* Enable interrupt handling */
6280 atomic_set(&bp->intr_sem, 0);
6281
6282 /* Setup NIC internals and enable interrupts */ 6344 /* Setup NIC internals and enable interrupts */
6283 bnx2x_nic_init(bp); 6345 bnx2x_nic_init(bp, load_code);
6284 6346
6285 /* Send LOAD_DONE command to MCP */ 6347 /* Send LOAD_DONE command to MCP */
6286 if (!BP_NOMCP(bp)) { 6348 if (!BP_NOMCP(bp)) {
6287 load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); 6349 load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
6288 if (!load_code) { 6350 if (!load_code) {
6289 BNX2X_ERR("MCP response failure, unloading\n"); 6351 BNX2X_ERR("MCP response failure, aborting\n");
6290 rc = -EBUSY; 6352 rc = -EBUSY;
6291 goto load_int_disable; 6353 goto load_int_disable;
6292 } 6354 }
@@ -6301,11 +6363,12 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
6301 for_each_queue(bp, i) 6363 for_each_queue(bp, i)
6302 napi_enable(&bnx2x_fp(bp, i, napi)); 6364 napi_enable(&bnx2x_fp(bp, i, napi));
6303 6365
6366 /* Enable interrupt handling */
6367 atomic_set(&bp->intr_sem, 0);
6368
6304 rc = bnx2x_setup_leading(bp); 6369 rc = bnx2x_setup_leading(bp);
6305 if (rc) { 6370 if (rc) {
6306#ifdef BNX2X_STOP_ON_ERROR 6371 BNX2X_ERR("Setup leading failed!\n");
6307 bp->panic = 1;
6308#endif
6309 goto load_stop_netif; 6372 goto load_stop_netif;
6310 } 6373 }
6311 6374
@@ -6323,9 +6386,9 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
6323 } 6386 }
6324 6387
6325 if (CHIP_IS_E1(bp)) 6388 if (CHIP_IS_E1(bp))
6326 bnx2x_set_mac_addr_e1(bp); 6389 bnx2x_set_mac_addr_e1(bp, 1);
6327 else 6390 else
6328 bnx2x_set_mac_addr_e1h(bp); 6391 bnx2x_set_mac_addr_e1h(bp, 1);
6329 6392
6330 if (bp->port.pmf) 6393 if (bp->port.pmf)
6331 bnx2x_initial_phy_init(bp); 6394 bnx2x_initial_phy_init(bp);
@@ -6339,7 +6402,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
6339 break; 6402 break;
6340 6403
6341 case LOAD_OPEN: 6404 case LOAD_OPEN:
6342 /* IRQ is only requested from bnx2x_open */
6343 netif_start_queue(bp->dev); 6405 netif_start_queue(bp->dev);
6344 bnx2x_set_rx_mode(bp->dev); 6406 bnx2x_set_rx_mode(bp->dev);
6345 if (bp->flags & USING_MSIX_FLAG) 6407 if (bp->flags & USING_MSIX_FLAG)
@@ -6378,8 +6440,7 @@ load_int_disable:
6378 /* Free SKBs, SGEs, TPA pool and driver internals */ 6440 /* Free SKBs, SGEs, TPA pool and driver internals */
6379 bnx2x_free_skbs(bp); 6441 bnx2x_free_skbs(bp);
6380 for_each_queue(bp, i) 6442 for_each_queue(bp, i)
6381 bnx2x_free_rx_sge_range(bp, bp->fp + i, 6443 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
6382 RX_SGE_CNT*NUM_RX_SGE_PAGES);
6383load_error: 6444load_error:
6384 bnx2x_free_mem(bp); 6445 bnx2x_free_mem(bp);
6385 6446
@@ -6411,7 +6472,7 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
6411 return rc; 6472 return rc;
6412} 6473}
6413 6474
6414static void bnx2x_stop_leading(struct bnx2x *bp) 6475static int bnx2x_stop_leading(struct bnx2x *bp)
6415{ 6476{
6416 u16 dsb_sp_prod_idx; 6477 u16 dsb_sp_prod_idx;
6417 /* if the other port is handling traffic, 6478 /* if the other port is handling traffic,
@@ -6429,7 +6490,7 @@ static void bnx2x_stop_leading(struct bnx2x *bp)
6429 rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0, 6490 rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
6430 &(bp->fp[0].state), 1); 6491 &(bp->fp[0].state), 1);
6431 if (rc) /* timeout */ 6492 if (rc) /* timeout */
6432 return; 6493 return rc;
6433 6494
6434 dsb_sp_prod_idx = *bp->dsb_sp_prod; 6495 dsb_sp_prod_idx = *bp->dsb_sp_prod;
6435 6496
@@ -6441,20 +6502,24 @@ static void bnx2x_stop_leading(struct bnx2x *bp)
6441 so there is not much to do if this times out 6502 so there is not much to do if this times out
6442 */ 6503 */
6443 while (dsb_sp_prod_idx == *bp->dsb_sp_prod) { 6504 while (dsb_sp_prod_idx == *bp->dsb_sp_prod) {
6444 msleep(1);
6445 if (!cnt) { 6505 if (!cnt) {
6446 DP(NETIF_MSG_IFDOWN, "timeout waiting for port del " 6506 DP(NETIF_MSG_IFDOWN, "timeout waiting for port del "
6447 "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", 6507 "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
6448 *bp->dsb_sp_prod, dsb_sp_prod_idx); 6508 *bp->dsb_sp_prod, dsb_sp_prod_idx);
6449#ifdef BNX2X_STOP_ON_ERROR 6509#ifdef BNX2X_STOP_ON_ERROR
6450 bnx2x_panic(); 6510 bnx2x_panic();
6511#else
6512 rc = -EBUSY;
6451#endif 6513#endif
6452 break; 6514 break;
6453 } 6515 }
6454 cnt--; 6516 cnt--;
6517 msleep(1);
6455 } 6518 }
6456 bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; 6519 bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
6457 bp->fp[0].state = BNX2X_FP_STATE_CLOSED; 6520 bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
6521
6522 return rc;
6458} 6523}
6459 6524
6460static void bnx2x_reset_func(struct bnx2x *bp) 6525static void bnx2x_reset_func(struct bnx2x *bp)
@@ -6496,7 +6561,7 @@ static void bnx2x_reset_port(struct bnx2x *bp)
6496 val = REG_RD(bp, BRB1_REG_PORT_NUM_OCC_BLOCKS_0 + port*4); 6561 val = REG_RD(bp, BRB1_REG_PORT_NUM_OCC_BLOCKS_0 + port*4);
6497 if (val) 6562 if (val)
6498 DP(NETIF_MSG_IFDOWN, 6563 DP(NETIF_MSG_IFDOWN,
6499 "BRB1 is not empty %d blooks are occupied\n", val); 6564 "BRB1 is not empty %d blocks are occupied\n", val);
6500 6565
6501 /* TODO: Close Doorbell port? */ 6566 /* TODO: Close Doorbell port? */
6502} 6567}
@@ -6536,11 +6601,12 @@ static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
6536 } 6601 }
6537} 6602}
6538 6603
6539/* msut be called with rtnl_lock */ 6604/* must be called with rtnl_lock */
6540static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) 6605static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
6541{ 6606{
6607 int port = BP_PORT(bp);
6542 u32 reset_code = 0; 6608 u32 reset_code = 0;
6543 int i, cnt; 6609 int i, cnt, rc;
6544 6610
6545 bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; 6611 bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
6546 6612
@@ -6557,22 +6623,17 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
6557 (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); 6623 (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
6558 bnx2x_stats_handle(bp, STATS_EVENT_STOP); 6624 bnx2x_stats_handle(bp, STATS_EVENT_STOP);
6559 6625
6560 /* Wait until all fast path tasks complete */ 6626 /* Wait until tx fast path tasks complete */
6561 for_each_queue(bp, i) { 6627 for_each_queue(bp, i) {
6562 struct bnx2x_fastpath *fp = &bp->fp[i]; 6628 struct bnx2x_fastpath *fp = &bp->fp[i];
6563 6629
6564#ifdef BNX2X_STOP_ON_ERROR
6565#ifdef __powerpc64__
6566 DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n",
6567#else
6568 DP(NETIF_MSG_IFDOWN, "fp->tpa_queue_used = 0x%llx\n",
6569#endif
6570 fp->tpa_queue_used);
6571#endif
6572 cnt = 1000; 6630 cnt = 1000;
6573 smp_rmb(); 6631 smp_rmb();
6574 while (bnx2x_has_work(fp)) { 6632 while (BNX2X_HAS_TX_WORK(fp)) {
6575 msleep(1); 6633
6634 if (!netif_running(bp->dev))
6635 bnx2x_tx_int(fp, 1000);
6636
6576 if (!cnt) { 6637 if (!cnt) {
6577 BNX2X_ERR("timeout waiting for queue[%d]\n", 6638 BNX2X_ERR("timeout waiting for queue[%d]\n",
6578 i); 6639 i);
@@ -6584,14 +6645,13 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
6584#endif 6645#endif
6585 } 6646 }
6586 cnt--; 6647 cnt--;
6648 msleep(1);
6587 smp_rmb(); 6649 smp_rmb();
6588 } 6650 }
6589 } 6651 }
6590 6652
6591 /* Wait until all slow path tasks complete */ 6653 /* Give HW time to discard old tx messages */
6592 cnt = 1000; 6654 msleep(1);
6593 while ((bp->spq_left != MAX_SPQ_PENDING) && cnt--)
6594 msleep(1);
6595 6655
6596 for_each_queue(bp, i) 6656 for_each_queue(bp, i)
6597 napi_disable(&bnx2x_fp(bp, i, napi)); 6657 napi_disable(&bnx2x_fp(bp, i, napi));
@@ -6601,52 +6661,79 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
6601 /* Release IRQs */ 6661 /* Release IRQs */
6602 bnx2x_free_irq(bp); 6662 bnx2x_free_irq(bp);
6603 6663
6604 if (bp->flags & NO_WOL_FLAG) 6664 if (unload_mode == UNLOAD_NORMAL)
6665 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
6666
6667 else if (bp->flags & NO_WOL_FLAG) {
6605 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP; 6668 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
6669 if (CHIP_IS_E1H(bp))
6670 REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
6606 6671
6607 else if (bp->wol) { 6672 } else if (bp->wol) {
6608 u32 emac_base = BP_PORT(bp) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 6673 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
6609 u8 *mac_addr = bp->dev->dev_addr; 6674 u8 *mac_addr = bp->dev->dev_addr;
6610 u32 val; 6675 u32 val;
6611
6612 /* The mac address is written to entries 1-4 to 6676 /* The mac address is written to entries 1-4 to
6613 preserve entry 0 which is used by the PMF */ 6677 preserve entry 0 which is used by the PMF */
6678 u8 entry = (BP_E1HVN(bp) + 1)*8;
6679
6614 val = (mac_addr[0] << 8) | mac_addr[1]; 6680 val = (mac_addr[0] << 8) | mac_addr[1];
6615 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + (BP_E1HVN(bp) + 1)*8, val); 6681 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry, val);
6616 6682
6617 val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | 6683 val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
6618 (mac_addr[4] << 8) | mac_addr[5]; 6684 (mac_addr[4] << 8) | mac_addr[5];
6619 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + (BP_E1HVN(bp) + 1)*8 + 4, 6685 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val);
6620 val);
6621 6686
6622 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN; 6687 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
6623 6688
6624 } else 6689 } else
6625 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; 6690 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
6626 6691
6692 if (CHIP_IS_E1(bp)) {
6693 struct mac_configuration_cmd *config =
6694 bnx2x_sp(bp, mcast_config);
6695
6696 bnx2x_set_mac_addr_e1(bp, 0);
6697
6698 for (i = 0; i < config->hdr.length_6b; i++)
6699 CAM_INVALIDATE(config->config_table[i]);
6700
6701 config->hdr.length_6b = i;
6702 if (CHIP_REV_IS_SLOW(bp))
6703 config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
6704 else
6705 config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port);
6706 config->hdr.client_id = BP_CL_ID(bp);
6707 config->hdr.reserved1 = 0;
6708
6709 bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
6710 U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
6711 U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);
6712
6713 } else { /* E1H */
6714 bnx2x_set_mac_addr_e1h(bp, 0);
6715
6716 for (i = 0; i < MC_HASH_SIZE; i++)
6717 REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
6718 }
6719
6720 if (CHIP_IS_E1H(bp))
6721 REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
6722
6627 /* Close multi and leading connections 6723 /* Close multi and leading connections
6628 Completions for ramrods are collected in a synchronous way */ 6724 Completions for ramrods are collected in a synchronous way */
6629 for_each_nondefault_queue(bp, i) 6725 for_each_nondefault_queue(bp, i)
6630 if (bnx2x_stop_multi(bp, i)) 6726 if (bnx2x_stop_multi(bp, i))
6631 goto unload_error; 6727 goto unload_error;
6632 6728
6633 if (CHIP_IS_E1H(bp)) 6729 rc = bnx2x_stop_leading(bp);
6634 REG_WR(bp, NIG_REG_LLH0_FUNC_EN + BP_PORT(bp)*8, 0); 6730 if (rc) {
6635
6636 bnx2x_stop_leading(bp);
6637#ifdef BNX2X_STOP_ON_ERROR
6638 /* If ramrod completion timed out - break here! */
6639 if (bp->panic) {
6640 BNX2X_ERR("Stop leading failed!\n"); 6731 BNX2X_ERR("Stop leading failed!\n");
6732#ifdef BNX2X_STOP_ON_ERROR
6641 return -EBUSY; 6733 return -EBUSY;
6642 } 6734#else
6735 goto unload_error;
6643#endif 6736#endif
6644
6645 if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) ||
6646 (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) {
6647 DP(NETIF_MSG_IFDOWN, "failed to close leading properly! "
6648 "state 0x%x fp[0].state 0x%x\n",
6649 bp->state, bp->fp[0].state);
6650 } 6737 }
6651 6738
6652unload_error: 6739unload_error:
@@ -6656,12 +6743,12 @@ unload_error:
6656 DP(NETIF_MSG_IFDOWN, "NO MCP load counts %d, %d, %d\n", 6743 DP(NETIF_MSG_IFDOWN, "NO MCP load counts %d, %d, %d\n",
6657 load_count[0], load_count[1], load_count[2]); 6744 load_count[0], load_count[1], load_count[2]);
6658 load_count[0]--; 6745 load_count[0]--;
6659 load_count[1 + BP_PORT(bp)]--; 6746 load_count[1 + port]--;
6660 DP(NETIF_MSG_IFDOWN, "NO MCP new load counts %d, %d, %d\n", 6747 DP(NETIF_MSG_IFDOWN, "NO MCP new load counts %d, %d, %d\n",
6661 load_count[0], load_count[1], load_count[2]); 6748 load_count[0], load_count[1], load_count[2]);
6662 if (load_count[0] == 0) 6749 if (load_count[0] == 0)
6663 reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; 6750 reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
6664 else if (load_count[1 + BP_PORT(bp)] == 0) 6751 else if (load_count[1 + port] == 0)
6665 reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; 6752 reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT;
6666 else 6753 else
6667 reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; 6754 reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION;
@@ -6681,8 +6768,7 @@ unload_error:
6681 /* Free SKBs, SGEs, TPA pool and driver internals */ 6768 /* Free SKBs, SGEs, TPA pool and driver internals */
6682 bnx2x_free_skbs(bp); 6769 bnx2x_free_skbs(bp);
6683 for_each_queue(bp, i) 6770 for_each_queue(bp, i)
6684 bnx2x_free_rx_sge_range(bp, bp->fp + i, 6771 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
6685 RX_SGE_CNT*NUM_RX_SGE_PAGES);
6686 bnx2x_free_mem(bp); 6772 bnx2x_free_mem(bp);
6687 6773
6688 bp->state = BNX2X_STATE_CLOSED; 6774 bp->state = BNX2X_STATE_CLOSED;
@@ -6733,56 +6819,93 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
6733 /* Check if it is the UNDI driver 6819 /* Check if it is the UNDI driver
6734 * UNDI driver initializes CID offset for normal bell to 0x7 6820 * UNDI driver initializes CID offset for normal bell to 0x7
6735 */ 6821 */
6822 bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
6736 val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); 6823 val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
6737 if (val == 0x7) { 6824 if (val == 0x7) {
6738 u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; 6825 u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
6739 /* save our func and fw_seq */ 6826 /* save our func */
6740 int func = BP_FUNC(bp); 6827 int func = BP_FUNC(bp);
6741 u16 fw_seq = bp->fw_seq; 6828 u32 swap_en;
6829 u32 swap_val;
6742 6830
6743 BNX2X_DEV_INFO("UNDI is active! reset device\n"); 6831 BNX2X_DEV_INFO("UNDI is active! reset device\n");
6744 6832
6745 /* try unload UNDI on port 0 */ 6833 /* try unload UNDI on port 0 */
6746 bp->func = 0; 6834 bp->func = 0;
6747 bp->fw_seq = (SHMEM_RD(bp, 6835 bp->fw_seq =
6748 func_mb[bp->func].drv_mb_header) & 6836 (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
6749 DRV_MSG_SEQ_NUMBER_MASK); 6837 DRV_MSG_SEQ_NUMBER_MASK);
6750
6751 reset_code = bnx2x_fw_command(bp, reset_code); 6838 reset_code = bnx2x_fw_command(bp, reset_code);
6752 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
6753 6839
6754 /* if UNDI is loaded on the other port */ 6840 /* if UNDI is loaded on the other port */
6755 if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { 6841 if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) {
6756 6842
6843 /* send "DONE" for previous unload */
6844 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
6845
6846 /* unload UNDI on port 1 */
6757 bp->func = 1; 6847 bp->func = 1;
6758 bp->fw_seq = (SHMEM_RD(bp, 6848 bp->fw_seq =
6759 func_mb[bp->func].drv_mb_header) & 6849 (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
6760 DRV_MSG_SEQ_NUMBER_MASK); 6850 DRV_MSG_SEQ_NUMBER_MASK);
6761 6851 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
6762 bnx2x_fw_command(bp, 6852
6763 DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS); 6853 bnx2x_fw_command(bp, reset_code);
6764 bnx2x_fw_command(bp,
6765 DRV_MSG_CODE_UNLOAD_DONE);
6766
6767 /* restore our func and fw_seq */
6768 bp->func = func;
6769 bp->fw_seq = fw_seq;
6770 } 6854 }
6771 6855
6856 REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
6857 HC_REG_CONFIG_0), 0x1000);
6858
6859 /* close input traffic and wait for it */
6860 /* Do not rcv packets to BRB */
6861 REG_WR(bp,
6862 (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK :
6863 NIG_REG_LLH0_BRB1_DRV_MASK), 0x0);
6864 /* Do not direct rcv packets that are not for MCP to
6865 * the BRB */
6866 REG_WR(bp,
6867 (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_NOT_MCP :
6868 NIG_REG_LLH0_BRB1_NOT_MCP), 0x0);
6869 /* clear AEU */
6870 REG_WR(bp,
6871 (BP_PORT(bp) ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
6872 MISC_REG_AEU_MASK_ATTN_FUNC_0), 0);
6873 msleep(10);
6874
6875 /* save NIG port swap info */
6876 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
6877 swap_en = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
6772 /* reset device */ 6878 /* reset device */
6773 REG_WR(bp, 6879 REG_WR(bp,
6774 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 6880 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
6775 0xd3ffff7f); 6881 0xd3ffffff);
6776 REG_WR(bp, 6882 REG_WR(bp,
6777 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 6883 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6778 0x1403); 6884 0x1403);
6885 /* take the NIG out of reset and restore swap values */
6886 REG_WR(bp,
6887 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
6888 MISC_REGISTERS_RESET_REG_1_RST_NIG);
6889 REG_WR(bp, NIG_REG_PORT_SWAP, swap_val);
6890 REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en);
6891
6892 /* send unload done to the MCP */
6893 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
6894
6895 /* restore our func and fw_seq */
6896 bp->func = func;
6897 bp->fw_seq =
6898 (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
6899 DRV_MSG_SEQ_NUMBER_MASK);
6779 } 6900 }
6901 bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
6780 } 6902 }
6781} 6903}
6782 6904
6783static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) 6905static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
6784{ 6906{
6785 u32 val, val2, val3, val4, id; 6907 u32 val, val2, val3, val4, id;
6908 u16 pmc;
6786 6909
6787 /* Get the chip revision id and number. */ 6910 /* Get the chip revision id and number. */
6788 /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ 6911 /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
@@ -6840,8 +6963,16 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
6840 BNX2X_ERR("This driver needs bc_ver %X but found %X," 6963 BNX2X_ERR("This driver needs bc_ver %X but found %X,"
6841 " please upgrade BC\n", BNX2X_BC_VER, val); 6964 " please upgrade BC\n", BNX2X_BC_VER, val);
6842 } 6965 }
6843 BNX2X_DEV_INFO("%sWoL Capable\n", 6966
6844 (bp->flags & NO_WOL_FLAG)? "Not " : ""); 6967 if (BP_E1HVN(bp) == 0) {
6968 pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
6969 bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
6970 } else {
6971 /* no WOL capability for E1HVN != 0 */
6972 bp->flags |= NO_WOL_FLAG;
6973 }
6974 BNX2X_DEV_INFO("%sWoL capable\n",
6975 (bp->flags & NO_WOL_FLAG) ? "Not " : "");
6845 6976
6846 val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num); 6977 val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
6847 val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]); 6978 val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
@@ -7202,7 +7333,7 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
7202 bp->link_params.req_flow_ctrl = (bp->port.link_config & 7333 bp->link_params.req_flow_ctrl = (bp->port.link_config &
7203 PORT_FEATURE_FLOW_CONTROL_MASK); 7334 PORT_FEATURE_FLOW_CONTROL_MASK);
7204 if ((bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO) && 7335 if ((bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO) &&
7205 (!bp->port.supported & SUPPORTED_Autoneg)) 7336 !(bp->port.supported & SUPPORTED_Autoneg))
7206 bp->link_params.req_flow_ctrl = FLOW_CTRL_NONE; 7337 bp->link_params.req_flow_ctrl = FLOW_CTRL_NONE;
7207 7338
7208 BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x" 7339 BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x"
@@ -7274,9 +7405,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
7274 bp->mf_config = 7405 bp->mf_config =
7275 SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); 7406 SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
7276 7407
7277 val = 7408 val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func].e1hov_tag) &
7278 (SHMEM_RD(bp, mf_cfg.func_mf_config[func].e1hov_tag) & 7409 FUNC_MF_CFG_E1HOV_TAG_MASK);
7279 FUNC_MF_CFG_E1HOV_TAG_MASK);
7280 if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { 7410 if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
7281 7411
7282 bp->e1hov = val; 7412 bp->e1hov = val;
@@ -7324,7 +7454,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
7324 7454
7325 if (BP_NOMCP(bp)) { 7455 if (BP_NOMCP(bp)) {
7326 /* only supposed to happen on emulation/FPGA */ 7456 /* only supposed to happen on emulation/FPGA */
7327 BNX2X_ERR("warning rendom MAC workaround active\n"); 7457 BNX2X_ERR("warning random MAC workaround active\n");
7328 random_ether_addr(bp->dev->dev_addr); 7458 random_ether_addr(bp->dev->dev_addr);
7329 memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); 7459 memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
7330 } 7460 }
@@ -7337,8 +7467,8 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
7337 int func = BP_FUNC(bp); 7467 int func = BP_FUNC(bp);
7338 int rc; 7468 int rc;
7339 7469
7340 if (nomcp) 7470 /* Disable interrupt handling until HW is initialized */
7341 bp->flags |= NO_MCP_FLAG; 7471 atomic_set(&bp->intr_sem, 1);
7342 7472
7343 mutex_init(&bp->port.phy_mutex); 7473 mutex_init(&bp->port.phy_mutex);
7344 7474
@@ -7377,8 +7507,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
7377 bp->tx_ticks = 50; 7507 bp->tx_ticks = 50;
7378 bp->rx_ticks = 25; 7508 bp->rx_ticks = 25;
7379 7509
7380 bp->stats_ticks = 1000000 & 0xffff00;
7381
7382 bp->timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ); 7510 bp->timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
7383 bp->current_interval = (poll ? poll : bp->timer_interval); 7511 bp->current_interval = (poll ? poll : bp->timer_interval);
7384 7512
@@ -7628,25 +7756,25 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
7628 struct ethtool_drvinfo *info) 7756 struct ethtool_drvinfo *info)
7629{ 7757{
7630 struct bnx2x *bp = netdev_priv(dev); 7758 struct bnx2x *bp = netdev_priv(dev);
7631 char phy_fw_ver[PHY_FW_VER_LEN]; 7759 u8 phy_fw_ver[PHY_FW_VER_LEN];
7632 7760
7633 strcpy(info->driver, DRV_MODULE_NAME); 7761 strcpy(info->driver, DRV_MODULE_NAME);
7634 strcpy(info->version, DRV_MODULE_VERSION); 7762 strcpy(info->version, DRV_MODULE_VERSION);
7635 7763
7636 phy_fw_ver[0] = '\0'; 7764 phy_fw_ver[0] = '\0';
7637 if (bp->port.pmf) { 7765 if (bp->port.pmf) {
7638 bnx2x_phy_hw_lock(bp); 7766 bnx2x_acquire_phy_lock(bp);
7639 bnx2x_get_ext_phy_fw_version(&bp->link_params, 7767 bnx2x_get_ext_phy_fw_version(&bp->link_params,
7640 (bp->state != BNX2X_STATE_CLOSED), 7768 (bp->state != BNX2X_STATE_CLOSED),
7641 phy_fw_ver, PHY_FW_VER_LEN); 7769 phy_fw_ver, PHY_FW_VER_LEN);
7642 bnx2x_phy_hw_unlock(bp); 7770 bnx2x_release_phy_lock(bp);
7643 } 7771 }
7644 7772
7645 snprintf(info->fw_version, 32, "%d.%d.%d:%d BC:%x%s%s", 7773 snprintf(info->fw_version, 32, "BC:%d.%d.%d%s%s",
7646 BCM_5710_FW_MAJOR_VERSION, BCM_5710_FW_MINOR_VERSION, 7774 (bp->common.bc_ver & 0xff0000) >> 16,
7647 BCM_5710_FW_REVISION_VERSION, 7775 (bp->common.bc_ver & 0xff00) >> 8,
7648 BCM_5710_FW_COMPILE_FLAGS, bp->common.bc_ver, 7776 (bp->common.bc_ver & 0xff),
7649 ((phy_fw_ver[0] != '\0')? " PHY:":""), phy_fw_ver); 7777 ((phy_fw_ver[0] != '\0') ? " PHY:" : ""), phy_fw_ver);
7650 strcpy(info->bus_info, pci_name(bp->pdev)); 7778 strcpy(info->bus_info, pci_name(bp->pdev));
7651 info->n_stats = BNX2X_NUM_STATS; 7779 info->n_stats = BNX2X_NUM_STATS;
7652 info->testinfo_len = BNX2X_NUM_TESTS; 7780 info->testinfo_len = BNX2X_NUM_TESTS;
@@ -8097,7 +8225,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
8097 if (eeprom->magic == 0x00504859) 8225 if (eeprom->magic == 0x00504859)
8098 if (bp->port.pmf) { 8226 if (bp->port.pmf) {
8099 8227
8100 bnx2x_phy_hw_lock(bp); 8228 bnx2x_acquire_phy_lock(bp);
8101 rc = bnx2x_flash_download(bp, BP_PORT(bp), 8229 rc = bnx2x_flash_download(bp, BP_PORT(bp),
8102 bp->link_params.ext_phy_config, 8230 bp->link_params.ext_phy_config,
8103 (bp->state != BNX2X_STATE_CLOSED), 8231 (bp->state != BNX2X_STATE_CLOSED),
@@ -8109,7 +8237,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
8109 rc |= bnx2x_phy_init(&bp->link_params, 8237 rc |= bnx2x_phy_init(&bp->link_params,
8110 &bp->link_vars); 8238 &bp->link_vars);
8111 } 8239 }
8112 bnx2x_phy_hw_unlock(bp); 8240 bnx2x_release_phy_lock(bp);
8113 8241
8114 } else /* Only the PMF can access the PHY */ 8242 } else /* Only the PMF can access the PHY */
8115 return -EINVAL; 8243 return -EINVAL;
@@ -8128,7 +8256,6 @@ static int bnx2x_get_coalesce(struct net_device *dev,
8128 8256
8129 coal->rx_coalesce_usecs = bp->rx_ticks; 8257 coal->rx_coalesce_usecs = bp->rx_ticks;
8130 coal->tx_coalesce_usecs = bp->tx_ticks; 8258 coal->tx_coalesce_usecs = bp->tx_ticks;
8131 coal->stats_block_coalesce_usecs = bp->stats_ticks;
8132 8259
8133 return 0; 8260 return 0;
8134} 8261}
@@ -8146,44 +8273,12 @@ static int bnx2x_set_coalesce(struct net_device *dev,
8146 if (bp->tx_ticks > 0x3000) 8273 if (bp->tx_ticks > 0x3000)
8147 bp->tx_ticks = 0x3000; 8274 bp->tx_ticks = 0x3000;
8148 8275
8149 bp->stats_ticks = coal->stats_block_coalesce_usecs;
8150 if (bp->stats_ticks > 0xffff00)
8151 bp->stats_ticks = 0xffff00;
8152 bp->stats_ticks &= 0xffff00;
8153
8154 if (netif_running(dev)) 8276 if (netif_running(dev))
8155 bnx2x_update_coalesce(bp); 8277 bnx2x_update_coalesce(bp);
8156 8278
8157 return 0; 8279 return 0;
8158} 8280}
8159 8281
8160static int bnx2x_set_flags(struct net_device *dev, u32 data)
8161{
8162 struct bnx2x *bp = netdev_priv(dev);
8163 int changed = 0;
8164 int rc = 0;
8165
8166 if (data & ETH_FLAG_LRO) {
8167 if (!(dev->features & NETIF_F_LRO)) {
8168 dev->features |= NETIF_F_LRO;
8169 bp->flags |= TPA_ENABLE_FLAG;
8170 changed = 1;
8171 }
8172
8173 } else if (dev->features & NETIF_F_LRO) {
8174 dev->features &= ~NETIF_F_LRO;
8175 bp->flags &= ~TPA_ENABLE_FLAG;
8176 changed = 1;
8177 }
8178
8179 if (changed && netif_running(dev)) {
8180 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
8181 rc = bnx2x_nic_load(bp, LOAD_NORMAL);
8182 }
8183
8184 return rc;
8185}
8186
8187static void bnx2x_get_ringparam(struct net_device *dev, 8282static void bnx2x_get_ringparam(struct net_device *dev,
8188 struct ethtool_ringparam *ering) 8283 struct ethtool_ringparam *ering)
8189{ 8284{
@@ -8266,7 +8361,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
8266 8361
8267 if (epause->autoneg) { 8362 if (epause->autoneg) {
8268 if (!(bp->port.supported & SUPPORTED_Autoneg)) { 8363 if (!(bp->port.supported & SUPPORTED_Autoneg)) {
8269 DP(NETIF_MSG_LINK, "Autoneg not supported\n"); 8364 DP(NETIF_MSG_LINK, "autoneg not supported\n");
8270 return -EINVAL; 8365 return -EINVAL;
8271 } 8366 }
8272 8367
@@ -8285,6 +8380,34 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
8285 return 0; 8380 return 0;
8286} 8381}
8287 8382
8383static int bnx2x_set_flags(struct net_device *dev, u32 data)
8384{
8385 struct bnx2x *bp = netdev_priv(dev);
8386 int changed = 0;
8387 int rc = 0;
8388
8389 /* TPA requires Rx CSUM offloading */
8390 if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
8391 if (!(dev->features & NETIF_F_LRO)) {
8392 dev->features |= NETIF_F_LRO;
8393 bp->flags |= TPA_ENABLE_FLAG;
8394 changed = 1;
8395 }
8396
8397 } else if (dev->features & NETIF_F_LRO) {
8398 dev->features &= ~NETIF_F_LRO;
8399 bp->flags &= ~TPA_ENABLE_FLAG;
8400 changed = 1;
8401 }
8402
8403 if (changed && netif_running(dev)) {
8404 bnx2x_nic_unload(bp, UNLOAD_NORMAL);
8405 rc = bnx2x_nic_load(bp, LOAD_NORMAL);
8406 }
8407
8408 return rc;
8409}
8410
8288static u32 bnx2x_get_rx_csum(struct net_device *dev) 8411static u32 bnx2x_get_rx_csum(struct net_device *dev)
8289{ 8412{
8290 struct bnx2x *bp = netdev_priv(dev); 8413 struct bnx2x *bp = netdev_priv(dev);
@@ -8295,9 +8418,19 @@ static u32 bnx2x_get_rx_csum(struct net_device *dev)
8295static int bnx2x_set_rx_csum(struct net_device *dev, u32 data) 8418static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
8296{ 8419{
8297 struct bnx2x *bp = netdev_priv(dev); 8420 struct bnx2x *bp = netdev_priv(dev);
8421 int rc = 0;
8298 8422
8299 bp->rx_csum = data; 8423 bp->rx_csum = data;
8300 return 0; 8424
8425 /* Disable TPA, when Rx CSUM is disabled. Otherwise all
8426 TPA'ed packets will be discarded due to wrong TCP CSUM */
8427 if (!data) {
8428 u32 flags = ethtool_op_get_flags(dev);
8429
8430 rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
8431 }
8432
8433 return rc;
8301} 8434}
8302 8435
8303static int bnx2x_set_tso(struct net_device *dev, u32 data) 8436static int bnx2x_set_tso(struct net_device *dev, u32 data)
@@ -8335,6 +8468,7 @@ static int bnx2x_test_registers(struct bnx2x *bp)
8335{ 8468{
8336 int idx, i, rc = -ENODEV; 8469 int idx, i, rc = -ENODEV;
8337 u32 wr_val = 0; 8470 u32 wr_val = 0;
8471 int port = BP_PORT(bp);
8338 static const struct { 8472 static const struct {
8339 u32 offset0; 8473 u32 offset0;
8340 u32 offset1; 8474 u32 offset1;
@@ -8400,7 +8534,6 @@ static int bnx2x_test_registers(struct bnx2x *bp)
8400 8534
8401 for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { 8535 for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
8402 u32 offset, mask, save_val, val; 8536 u32 offset, mask, save_val, val;
8403 int port = BP_PORT(bp);
8404 8537
8405 offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; 8538 offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
8406 mask = reg_tbl[i].mask; 8539 mask = reg_tbl[i].mask;
@@ -8446,16 +8579,17 @@ static int bnx2x_test_memory(struct bnx2x *bp)
8446 static const struct { 8579 static const struct {
8447 char *name; 8580 char *name;
8448 u32 offset; 8581 u32 offset;
8449 u32 mask; 8582 u32 e1_mask;
8583 u32 e1h_mask;
8450 } prty_tbl[] = { 8584 } prty_tbl[] = {
8451 { "CCM_REG_CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0 }, 8585 { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 },
8452 { "CFC_REG_CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0 }, 8586 { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 },
8453 { "DMAE_REG_DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0 }, 8587 { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 },
8454 { "TCM_REG_TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0 }, 8588 { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 },
8455 { "UCM_REG_UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0 }, 8589 { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 },
8456 { "XCM_REG_XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x1 }, 8590 { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 },
8457 8591
8458 { NULL, 0xffffffff, 0 } 8592 { NULL, 0xffffffff, 0, 0 }
8459 }; 8593 };
8460 8594
8461 if (!netif_running(bp->dev)) 8595 if (!netif_running(bp->dev))
@@ -8469,7 +8603,8 @@ static int bnx2x_test_memory(struct bnx2x *bp)
8469 /* Check the parity status */ 8603 /* Check the parity status */
8470 for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { 8604 for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
8471 val = REG_RD(bp, prty_tbl[i].offset); 8605 val = REG_RD(bp, prty_tbl[i].offset);
8472 if (val & ~(prty_tbl[i].mask)) { 8606 if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
8607 (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) {
8473 DP(NETIF_MSG_HW, 8608 DP(NETIF_MSG_HW,
8474 "%s is 0x%x\n", prty_tbl[i].name, val); 8609 "%s is 0x%x\n", prty_tbl[i].name, val);
8475 goto test_mem_exit; 8610 goto test_mem_exit;
@@ -8539,15 +8674,15 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
8539 8674
8540 if (loopback_mode == BNX2X_MAC_LOOPBACK) { 8675 if (loopback_mode == BNX2X_MAC_LOOPBACK) {
8541 bp->link_params.loopback_mode = LOOPBACK_BMAC; 8676 bp->link_params.loopback_mode = LOOPBACK_BMAC;
8542 bnx2x_phy_hw_lock(bp); 8677 bnx2x_acquire_phy_lock(bp);
8543 bnx2x_phy_init(&bp->link_params, &bp->link_vars); 8678 bnx2x_phy_init(&bp->link_params, &bp->link_vars);
8544 bnx2x_phy_hw_unlock(bp); 8679 bnx2x_release_phy_lock(bp);
8545 8680
8546 } else if (loopback_mode == BNX2X_PHY_LOOPBACK) { 8681 } else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
8547 bp->link_params.loopback_mode = LOOPBACK_XGXS_10; 8682 bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
8548 bnx2x_phy_hw_lock(bp); 8683 bnx2x_acquire_phy_lock(bp);
8549 bnx2x_phy_init(&bp->link_params, &bp->link_vars); 8684 bnx2x_phy_init(&bp->link_params, &bp->link_vars);
8550 bnx2x_phy_hw_unlock(bp); 8685 bnx2x_release_phy_lock(bp);
8551 /* wait until link state is restored */ 8686 /* wait until link state is restored */
8552 bnx2x_wait_for_link(bp, link_up); 8687 bnx2x_wait_for_link(bp, link_up);
8553 8688
@@ -8771,7 +8906,7 @@ static void bnx2x_self_test(struct net_device *dev,
8771 if (!netif_running(dev)) 8906 if (!netif_running(dev))
8772 return; 8907 return;
8773 8908
8774 /* offline tests are not suppoerted in MF mode */ 8909 /* offline tests are not supported in MF mode */
8775 if (IS_E1HMF(bp)) 8910 if (IS_E1HMF(bp))
8776 etest->flags &= ~ETH_TEST_FL_OFFLINE; 8911 etest->flags &= ~ETH_TEST_FL_OFFLINE;
8777 8912
@@ -8827,76 +8962,99 @@ static const struct {
8827 long offset; 8962 long offset;
8828 int size; 8963 int size;
8829 u32 flags; 8964 u32 flags;
8830 char string[ETH_GSTRING_LEN]; 8965#define STATS_FLAGS_PORT 1
8966#define STATS_FLAGS_FUNC 2
8967 u8 string[ETH_GSTRING_LEN];
8831} bnx2x_stats_arr[BNX2X_NUM_STATS] = { 8968} bnx2x_stats_arr[BNX2X_NUM_STATS] = {
8832/* 1 */ { STATS_OFFSET32(valid_bytes_received_hi), 8, 1, "rx_bytes" }, 8969/* 1 */ { STATS_OFFSET32(valid_bytes_received_hi),
8833 { STATS_OFFSET32(error_bytes_received_hi), 8, 1, "rx_error_bytes" }, 8970 8, STATS_FLAGS_FUNC, "rx_bytes" },
8834 { STATS_OFFSET32(total_bytes_transmitted_hi), 8, 1, "tx_bytes" }, 8971 { STATS_OFFSET32(error_bytes_received_hi),
8835 { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), 8, 0, "tx_error_bytes" }, 8972 8, STATS_FLAGS_FUNC, "rx_error_bytes" },
8973 { STATS_OFFSET32(total_bytes_transmitted_hi),
8974 8, STATS_FLAGS_FUNC, "tx_bytes" },
8975 { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
8976 8, STATS_FLAGS_PORT, "tx_error_bytes" },
8836 { STATS_OFFSET32(total_unicast_packets_received_hi), 8977 { STATS_OFFSET32(total_unicast_packets_received_hi),
8837 8, 1, "rx_ucast_packets" }, 8978 8, STATS_FLAGS_FUNC, "rx_ucast_packets" },
8838 { STATS_OFFSET32(total_multicast_packets_received_hi), 8979 { STATS_OFFSET32(total_multicast_packets_received_hi),
8839 8, 1, "rx_mcast_packets" }, 8980 8, STATS_FLAGS_FUNC, "rx_mcast_packets" },
8840 { STATS_OFFSET32(total_broadcast_packets_received_hi), 8981 { STATS_OFFSET32(total_broadcast_packets_received_hi),
8841 8, 1, "rx_bcast_packets" }, 8982 8, STATS_FLAGS_FUNC, "rx_bcast_packets" },
8842 { STATS_OFFSET32(total_unicast_packets_transmitted_hi), 8983 { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
8843 8, 1, "tx_packets" }, 8984 8, STATS_FLAGS_FUNC, "tx_packets" },
8844 { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi), 8985 { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
8845 8, 0, "tx_mac_errors" }, 8986 8, STATS_FLAGS_PORT, "tx_mac_errors" },
8846/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi), 8987/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
8847 8, 0, "tx_carrier_errors" }, 8988 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
8848 { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi), 8989 { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
8849 8, 0, "rx_crc_errors" }, 8990 8, STATS_FLAGS_PORT, "rx_crc_errors" },
8850 { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi), 8991 { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
8851 8, 0, "rx_align_errors" }, 8992 8, STATS_FLAGS_PORT, "rx_align_errors" },
8852 { STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi), 8993 { STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
8853 8, 0, "tx_single_collisions" }, 8994 8, STATS_FLAGS_PORT, "tx_single_collisions" },
8854 { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi), 8995 { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
8855 8, 0, "tx_multi_collisions" }, 8996 8, STATS_FLAGS_PORT, "tx_multi_collisions" },
8856 { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi), 8997 { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
8857 8, 0, "tx_deferred" }, 8998 8, STATS_FLAGS_PORT, "tx_deferred" },
8858 { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi), 8999 { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
8859 8, 0, "tx_excess_collisions" }, 9000 8, STATS_FLAGS_PORT, "tx_excess_collisions" },
8860 { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi), 9001 { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
8861 8, 0, "tx_late_collisions" }, 9002 8, STATS_FLAGS_PORT, "tx_late_collisions" },
8862 { STATS_OFFSET32(tx_stat_etherstatscollisions_hi), 9003 { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
8863 8, 0, "tx_total_collisions" }, 9004 8, STATS_FLAGS_PORT, "tx_total_collisions" },
8864 { STATS_OFFSET32(rx_stat_etherstatsfragments_hi), 9005 { STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
8865 8, 0, "rx_fragments" }, 9006 8, STATS_FLAGS_PORT, "rx_fragments" },
8866/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), 8, 0, "rx_jabbers" }, 9007/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
9008 8, STATS_FLAGS_PORT, "rx_jabbers" },
8867 { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi), 9009 { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
8868 8, 0, "rx_undersize_packets" }, 9010 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
8869 { STATS_OFFSET32(jabber_packets_received), 9011 { STATS_OFFSET32(jabber_packets_received),
8870 4, 1, "rx_oversize_packets" }, 9012 4, STATS_FLAGS_FUNC, "rx_oversize_packets" },
8871 { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi), 9013 { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
8872 8, 0, "tx_64_byte_packets" }, 9014 8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
8873 { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi), 9015 { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
8874 8, 0, "tx_65_to_127_byte_packets" }, 9016 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" },
8875 { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi), 9017 { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
8876 8, 0, "tx_128_to_255_byte_packets" }, 9018 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" },
8877 { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi), 9019 { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
8878 8, 0, "tx_256_to_511_byte_packets" }, 9020 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" },
8879 { STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi), 9021 { STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
8880 8, 0, "tx_512_to_1023_byte_packets" }, 9022 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
8881 { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi), 9023 { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
8882 8, 0, "tx_1024_to_1522_byte_packets" }, 9024 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
8883 { STATS_OFFSET32(etherstatspktsover1522octets_hi), 9025 { STATS_OFFSET32(etherstatspktsover1522octets_hi),
8884 8, 0, "tx_1523_to_9022_byte_packets" }, 9026 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
8885/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi), 9027/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
8886 8, 0, "rx_xon_frames" }, 9028 8, STATS_FLAGS_PORT, "rx_xon_frames" },
8887 { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi), 9029 { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
8888 8, 0, "rx_xoff_frames" }, 9030 8, STATS_FLAGS_PORT, "rx_xoff_frames" },
8889 { STATS_OFFSET32(tx_stat_outxonsent_hi), 8, 0, "tx_xon_frames" }, 9031 { STATS_OFFSET32(tx_stat_outxonsent_hi),
8890 { STATS_OFFSET32(tx_stat_outxoffsent_hi), 8, 0, "tx_xoff_frames" }, 9032 8, STATS_FLAGS_PORT, "tx_xon_frames" },
9033 { STATS_OFFSET32(tx_stat_outxoffsent_hi),
9034 8, STATS_FLAGS_PORT, "tx_xoff_frames" },
8891 { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi), 9035 { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
8892 8, 0, "rx_mac_ctrl_frames" }, 9036 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
8893 { STATS_OFFSET32(mac_filter_discard), 4, 1, "rx_filtered_packets" }, 9037 { STATS_OFFSET32(mac_filter_discard),
8894 { STATS_OFFSET32(no_buff_discard), 4, 1, "rx_discards" }, 9038 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
8895 { STATS_OFFSET32(xxoverflow_discard), 4, 1, "rx_fw_discards" }, 9039 { STATS_OFFSET32(no_buff_discard),
8896 { STATS_OFFSET32(brb_drop_hi), 8, 1, "brb_discard" }, 9040 4, STATS_FLAGS_FUNC, "rx_discards" },
8897/* 39 */{ STATS_OFFSET32(brb_truncate_discard), 8, 1, "brb_truncate" } 9041 { STATS_OFFSET32(xxoverflow_discard),
9042 4, STATS_FLAGS_PORT, "rx_fw_discards" },
9043 { STATS_OFFSET32(brb_drop_hi),
9044 8, STATS_FLAGS_PORT, "brb_discard" },
9045 { STATS_OFFSET32(brb_truncate_hi),
9046 8, STATS_FLAGS_PORT, "brb_truncate" },
9047/* 40 */{ STATS_OFFSET32(rx_err_discard_pkt),
9048 4, STATS_FLAGS_FUNC, "rx_phy_ip_err_discards"},
9049 { STATS_OFFSET32(rx_skb_alloc_failed),
9050 4, STATS_FLAGS_FUNC, "rx_skb_alloc_discard" },
9051/* 42 */{ STATS_OFFSET32(hw_csum_err),
9052 4, STATS_FLAGS_FUNC, "rx_csum_offload_errors" }
8898}; 9053};
8899 9054
9055#define IS_NOT_E1HMF_STAT(bp, i) \
9056 (IS_E1HMF(bp) && (bnx2x_stats_arr[i].flags & STATS_FLAGS_PORT))
9057
8900static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) 9058static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
8901{ 9059{
8902 struct bnx2x *bp = netdev_priv(dev); 9060 struct bnx2x *bp = netdev_priv(dev);
@@ -8905,7 +9063,7 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
8905 switch (stringset) { 9063 switch (stringset) {
8906 case ETH_SS_STATS: 9064 case ETH_SS_STATS:
8907 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { 9065 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
8908 if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags)) 9066 if (IS_NOT_E1HMF_STAT(bp, i))
8909 continue; 9067 continue;
8910 strcpy(buf + j*ETH_GSTRING_LEN, 9068 strcpy(buf + j*ETH_GSTRING_LEN,
8911 bnx2x_stats_arr[i].string); 9069 bnx2x_stats_arr[i].string);
@@ -8925,7 +9083,7 @@ static int bnx2x_get_stats_count(struct net_device *dev)
8925 int i, num_stats = 0; 9083 int i, num_stats = 0;
8926 9084
8927 for (i = 0; i < BNX2X_NUM_STATS; i++) { 9085 for (i = 0; i < BNX2X_NUM_STATS; i++) {
8928 if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags)) 9086 if (IS_NOT_E1HMF_STAT(bp, i))
8929 continue; 9087 continue;
8930 num_stats++; 9088 num_stats++;
8931 } 9089 }
@@ -8940,7 +9098,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
8940 int i, j; 9098 int i, j;
8941 9099
8942 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { 9100 for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
8943 if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags)) 9101 if (IS_NOT_E1HMF_STAT(bp, i))
8944 continue; 9102 continue;
8945 9103
8946 if (bnx2x_stats_arr[i].size == 0) { 9104 if (bnx2x_stats_arr[i].size == 0) {
@@ -9057,7 +9215,7 @@ static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
9057 PCI_PM_CTRL_PME_STATUS)); 9215 PCI_PM_CTRL_PME_STATUS));
9058 9216
9059 if (pmcsr & PCI_PM_CTRL_STATE_MASK) 9217 if (pmcsr & PCI_PM_CTRL_STATE_MASK)
9060 /* delay required during transition out of D3hot */ 9218 /* delay required during transition out of D3hot */
9061 msleep(20); 9219 msleep(20);
9062 break; 9220 break;
9063 9221
@@ -9104,17 +9262,16 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
9104 9262
9105 bnx2x_update_fpsb_idx(fp); 9263 bnx2x_update_fpsb_idx(fp);
9106 9264
9107 if ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || 9265 if (BNX2X_HAS_TX_WORK(fp))
9108 (fp->tx_pkt_prod != fp->tx_pkt_cons))
9109 bnx2x_tx_int(fp, budget); 9266 bnx2x_tx_int(fp, budget);
9110 9267
9111 if (le16_to_cpu(*fp->rx_cons_sb) != fp->rx_comp_cons) 9268 if (BNX2X_HAS_RX_WORK(fp))
9112 work_done = bnx2x_rx_int(fp, budget); 9269 work_done = bnx2x_rx_int(fp, budget);
9113 9270
9114 rmb(); /* bnx2x_has_work() reads the status block */ 9271 rmb(); /* BNX2X_HAS_WORK() reads the status block */
9115 9272
9116 /* must not complete if we consumed full budget */ 9273 /* must not complete if we consumed full budget */
9117 if ((work_done < budget) && !bnx2x_has_work(fp)) { 9274 if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
9118 9275
9119#ifdef BNX2X_STOP_ON_ERROR 9276#ifdef BNX2X_STOP_ON_ERROR
9120poll_panic: 9277poll_panic:
@@ -9131,7 +9288,7 @@ poll_panic:
9131 9288
9132 9289
9133/* we split the first BD into headers and data BDs 9290/* we split the first BD into headers and data BDs
9134 * to ease the pain of our fellow micocode engineers 9291 * to ease the pain of our fellow microcode engineers
9135 * we use one mapping for both BDs 9292 * we use one mapping for both BDs
9136 * So far this has only been observed to happen 9293 * So far this has only been observed to happen
9137 * in Other Operating Systems(TM) 9294 * in Other Operating Systems(TM)
@@ -9238,7 +9395,7 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
9238 /* Check if LSO packet needs to be copied: 9395 /* Check if LSO packet needs to be copied:
9239 3 = 1 (for headers BD) + 2 (for PBD and last BD) */ 9396 3 = 1 (for headers BD) + 2 (for PBD and last BD) */
9240 int wnd_size = MAX_FETCH_BD - 3; 9397 int wnd_size = MAX_FETCH_BD - 3;
9241 /* Number of widnows to check */ 9398 /* Number of windows to check */
9242 int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size; 9399 int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
9243 int wnd_idx = 0; 9400 int wnd_idx = 0;
9244 int frag_idx = 0; 9401 int frag_idx = 0;
@@ -9340,7 +9497,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
9340 skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, 9497 skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
9341 ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); 9498 ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
9342 9499
9343 /* First, check if we need to linearaize the skb 9500 /* First, check if we need to linearize the skb
9344 (due to FW restrictions) */ 9501 (due to FW restrictions) */
9345 if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) { 9502 if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
9346 /* Statistics of linearization */ 9503 /* Statistics of linearization */
@@ -9349,7 +9506,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
9349 DP(NETIF_MSG_TX_QUEUED, "SKB linearization failed - " 9506 DP(NETIF_MSG_TX_QUEUED, "SKB linearization failed - "
9350 "silently dropping this SKB\n"); 9507 "silently dropping this SKB\n");
9351 dev_kfree_skb_any(skb); 9508 dev_kfree_skb_any(skb);
9352 return 0; 9509 return NETDEV_TX_OK;
9353 } 9510 }
9354 } 9511 }
9355 9512
@@ -9372,7 +9529,8 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
9372 tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; 9529 tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
9373 tx_bd->general_data = (UNICAST_ADDRESS << 9530 tx_bd->general_data = (UNICAST_ADDRESS <<
9374 ETH_TX_BD_ETH_ADDR_TYPE_SHIFT); 9531 ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
9375 tx_bd->general_data |= 1; /* header nbd */ 9532 /* header nbd */
9533 tx_bd->general_data |= (1 << ETH_TX_BD_HDR_NBDS_SHIFT);
9376 9534
9377 /* remember the first BD of the packet */ 9535 /* remember the first BD of the packet */
9378 tx_buf->first_bd = fp->tx_bd_prod; 9536 tx_buf->first_bd = fp->tx_bd_prod;
@@ -9451,7 +9609,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
9451 9609
9452 tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); 9610 tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
9453 tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); 9611 tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
9454 nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL)? 1 : 2); 9612 nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL) ? 1 : 2);
9455 tx_bd->nbd = cpu_to_le16(nbd); 9613 tx_bd->nbd = cpu_to_le16(nbd);
9456 tx_bd->nbytes = cpu_to_le16(skb_headlen(skb)); 9614 tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
9457 9615
@@ -9721,9 +9879,9 @@ static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
9721 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 9879 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
9722 if (netif_running(dev)) { 9880 if (netif_running(dev)) {
9723 if (CHIP_IS_E1(bp)) 9881 if (CHIP_IS_E1(bp))
9724 bnx2x_set_mac_addr_e1(bp); 9882 bnx2x_set_mac_addr_e1(bp, 1);
9725 else 9883 else
9726 bnx2x_set_mac_addr_e1h(bp); 9884 bnx2x_set_mac_addr_e1h(bp, 1);
9727 } 9885 }
9728 9886
9729 return 0; 9887 return 0;
@@ -9734,6 +9892,7 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
9734{ 9892{
9735 struct mii_ioctl_data *data = if_mii(ifr); 9893 struct mii_ioctl_data *data = if_mii(ifr);
9736 struct bnx2x *bp = netdev_priv(dev); 9894 struct bnx2x *bp = netdev_priv(dev);
9895 int port = BP_PORT(bp);
9737 int err; 9896 int err;
9738 9897
9739 switch (cmd) { 9898 switch (cmd) {
@@ -9749,7 +9908,7 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
9749 return -EAGAIN; 9908 return -EAGAIN;
9750 9909
9751 mutex_lock(&bp->port.phy_mutex); 9910 mutex_lock(&bp->port.phy_mutex);
9752 err = bnx2x_cl45_read(bp, BP_PORT(bp), 0, bp->port.phy_addr, 9911 err = bnx2x_cl45_read(bp, port, 0, bp->port.phy_addr,
9753 DEFAULT_PHY_DEV_ADDR, 9912 DEFAULT_PHY_DEV_ADDR,
9754 (data->reg_num & 0x1f), &mii_regval); 9913 (data->reg_num & 0x1f), &mii_regval);
9755 data->val_out = mii_regval; 9914 data->val_out = mii_regval;
@@ -9765,7 +9924,7 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
9765 return -EAGAIN; 9924 return -EAGAIN;
9766 9925
9767 mutex_lock(&bp->port.phy_mutex); 9926 mutex_lock(&bp->port.phy_mutex);
9768 err = bnx2x_cl45_write(bp, BP_PORT(bp), 0, bp->port.phy_addr, 9927 err = bnx2x_cl45_write(bp, port, 0, bp->port.phy_addr,
9769 DEFAULT_PHY_DEV_ADDR, 9928 DEFAULT_PHY_DEV_ADDR,
9770 (data->reg_num & 0x1f), data->val_in); 9929 (data->reg_num & 0x1f), data->val_in);
9771 mutex_unlock(&bp->port.phy_mutex); 9930 mutex_unlock(&bp->port.phy_mutex);
@@ -10141,7 +10300,7 @@ static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
10141 10300
10142 netif_device_detach(dev); 10301 netif_device_detach(dev);
10143 10302
10144 bnx2x_nic_unload(bp, UNLOAD_NORMAL); 10303 bnx2x_nic_unload(bp, UNLOAD_CLOSE);
10145 10304
10146 bnx2x_set_power_state(bp, pci_choose_state(pdev, state)); 10305 bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
10147 10306
@@ -10174,7 +10333,7 @@ static int bnx2x_resume(struct pci_dev *pdev)
10174 bnx2x_set_power_state(bp, PCI_D0); 10333 bnx2x_set_power_state(bp, PCI_D0);
10175 netif_device_attach(dev); 10334 netif_device_attach(dev);
10176 10335
10177 rc = bnx2x_nic_load(bp, LOAD_NORMAL); 10336 rc = bnx2x_nic_load(bp, LOAD_OPEN);
10178 10337
10179 rtnl_unlock(); 10338 rtnl_unlock();
10180 10339
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index 15c9a9946724..a67b0c358ae4 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -6,7 +6,7 @@
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation. 7 * the Free Software Foundation.
8 * 8 *
9 * The registers description starts with the regsister Access type followed 9 * The registers description starts with the register Access type followed
10 * by size in bits. For example [RW 32]. The access types are: 10 * by size in bits. For example [RW 32]. The access types are:
11 * R - Read only 11 * R - Read only
12 * RC - Clear on read 12 * RC - Clear on read
@@ -49,7 +49,7 @@
49/* [RW 10] Write client 0: Assert pause threshold. */ 49/* [RW 10] Write client 0: Assert pause threshold. */
50#define BRB1_REG_PAUSE_LOW_THRESHOLD_0 0x60068 50#define BRB1_REG_PAUSE_LOW_THRESHOLD_0 0x60068
51#define BRB1_REG_PAUSE_LOW_THRESHOLD_1 0x6006c 51#define BRB1_REG_PAUSE_LOW_THRESHOLD_1 0x6006c
52/* [R 24] The number of full blocks occpied by port. */ 52/* [R 24] The number of full blocks occupied by port. */
53#define BRB1_REG_PORT_NUM_OCC_BLOCKS_0 0x60094 53#define BRB1_REG_PORT_NUM_OCC_BLOCKS_0 0x60094
54/* [RW 1] Reset the design by software. */ 54/* [RW 1] Reset the design by software. */
55#define BRB1_REG_SOFT_RESET 0x600dc 55#define BRB1_REG_SOFT_RESET 0x600dc
@@ -740,6 +740,7 @@
740#define HC_REG_ATTN_MSG1_ADDR_L 0x108020 740#define HC_REG_ATTN_MSG1_ADDR_L 0x108020
741#define HC_REG_ATTN_NUM_P0 0x108038 741#define HC_REG_ATTN_NUM_P0 0x108038
742#define HC_REG_ATTN_NUM_P1 0x10803c 742#define HC_REG_ATTN_NUM_P1 0x10803c
743#define HC_REG_COMMAND_REG 0x108180
743#define HC_REG_CONFIG_0 0x108000 744#define HC_REG_CONFIG_0 0x108000
744#define HC_REG_CONFIG_1 0x108004 745#define HC_REG_CONFIG_1 0x108004
745#define HC_REG_FUNC_NUM_P0 0x1080ac 746#define HC_REG_FUNC_NUM_P0 0x1080ac
@@ -1372,6 +1373,23 @@
1372 be asserted). */ 1373 be asserted). */
1373#define MISC_REG_DRIVER_CONTROL_16 0xa5f0 1374#define MISC_REG_DRIVER_CONTROL_16 0xa5f0
1374#define MISC_REG_DRIVER_CONTROL_16_SIZE 2 1375#define MISC_REG_DRIVER_CONTROL_16_SIZE 2
1376/* [RW 32] The following driver registers(1...16) represent 16 drivers and
1377 32 clients. Each client can be controlled by one driver only. One in each
1378 bit represent that this driver control the appropriate client (Ex: bit 5
1379 is set means this driver control client number 5). addr1 = set; addr0 =
1380 clear; read from both addresses will give the same result = status. write
1381 to address 1 will set a request to control all the clients that their
1382 appropriate bit (in the write command) is set. if the client is free (the
1383 appropriate bit in all the other drivers is clear) one will be written to
1384 that driver register; if the client isn't free the bit will remain zero.
1385 if the appropriate bit is set (the driver request to gain control on a
1386 client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
1387 interrupt will be asserted). write to address 0 will set a request to
1388 free all the clients that their appropriate bit (in the write command) is
1389 set. if the appropriate bit is clear (the driver request to free a client
1390 it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
1391 be asserted). */
1392#define MISC_REG_DRIVER_CONTROL_7 0xa3c8
1375/* [RW 1] e1hmf for WOL. If clr WOL signal o the PXP will be send on bit 0 1393/* [RW 1] e1hmf for WOL. If clr WOL signal o the PXP will be send on bit 0
1376 only. */ 1394 only. */
1377#define MISC_REG_E1HMF_MODE 0xa5f8 1395#define MISC_REG_E1HMF_MODE 0xa5f8
@@ -1394,13 +1412,13 @@
1394#define MISC_REG_GPIO 0xa490 1412#define MISC_REG_GPIO 0xa490
1395/* [R 28] this field hold the last information that caused reserved 1413/* [R 28] this field hold the last information that caused reserved
1396 attention. bits [19:0] - address; [22:20] function; [23] reserved; 1414 attention. bits [19:0] - address; [22:20] function; [23] reserved;
1397 [27:24] the master thatcaused the attention - according to the following 1415 [27:24] the master that caused the attention - according to the following
1398 encodeing:1 = pxp; 2 = mcp; 3 = usdm; 4 = tsdm; 5 = xsdm; 6 = csdm; 7 = 1416 encodeing:1 = pxp; 2 = mcp; 3 = usdm; 4 = tsdm; 5 = xsdm; 6 = csdm; 7 =
1399 dbu; 8 = dmae */ 1417 dbu; 8 = dmae */
1400#define MISC_REG_GRC_RSV_ATTN 0xa3c0 1418#define MISC_REG_GRC_RSV_ATTN 0xa3c0
1401/* [R 28] this field hold the last information that caused timeout 1419/* [R 28] this field hold the last information that caused timeout
1402 attention. bits [19:0] - address; [22:20] function; [23] reserved; 1420 attention. bits [19:0] - address; [22:20] function; [23] reserved;
1403 [27:24] the master thatcaused the attention - according to the following 1421 [27:24] the master that caused the attention - according to the following
1404 encodeing:1 = pxp; 2 = mcp; 3 = usdm; 4 = tsdm; 5 = xsdm; 6 = csdm; 7 = 1422 encodeing:1 = pxp; 2 = mcp; 3 = usdm; 4 = tsdm; 5 = xsdm; 6 = csdm; 7 =
1405 dbu; 8 = dmae */ 1423 dbu; 8 = dmae */
1406#define MISC_REG_GRC_TIMEOUT_ATTN 0xa3c4 1424#define MISC_REG_GRC_TIMEOUT_ATTN 0xa3c4
@@ -1677,6 +1695,7 @@
1677/* [RW 8] init credit counter for port0 in LLH */ 1695/* [RW 8] init credit counter for port0 in LLH */
1678#define NIG_REG_LLH0_XCM_INIT_CREDIT 0x10554 1696#define NIG_REG_LLH0_XCM_INIT_CREDIT 0x10554
1679#define NIG_REG_LLH0_XCM_MASK 0x10130 1697#define NIG_REG_LLH0_XCM_MASK 0x10130
1698#define NIG_REG_LLH1_BRB1_DRV_MASK 0x10248
1680/* [RW 1] send to BRB1 if no match on any of RMP rules. */ 1699/* [RW 1] send to BRB1 if no match on any of RMP rules. */
1681#define NIG_REG_LLH1_BRB1_NOT_MCP 0x102dc 1700#define NIG_REG_LLH1_BRB1_NOT_MCP 0x102dc
1682/* [RW 2] Determine the classification participants. 0: no classification.1: 1701/* [RW 2] Determine the classification participants. 0: no classification.1:
@@ -1727,6 +1746,9 @@
1727/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure 1746/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure
1728 for port0 */ 1747 for port0 */
1729#define NIG_REG_STAT0_BRB_DISCARD 0x105f0 1748#define NIG_REG_STAT0_BRB_DISCARD 0x105f0
1749/* [R 32] Rx statistics : In user packets truncated due to BRB backpressure
1750 for port0 */
1751#define NIG_REG_STAT0_BRB_TRUNCATE 0x105f8
1730/* [WB_R 36] Tx statistics : Number of packets from emac0 or bmac0 that 1752/* [WB_R 36] Tx statistics : Number of packets from emac0 or bmac0 that
1731 between 1024 and 1522 bytes for port0 */ 1753 between 1024 and 1522 bytes for port0 */
1732#define NIG_REG_STAT0_EGRESS_MAC_PKT0 0x10750 1754#define NIG_REG_STAT0_EGRESS_MAC_PKT0 0x10750
@@ -2298,7 +2320,7 @@
2298/* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k; 2320/* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k;
2299 -128k */ 2321 -128k */
2300#define PXP2_REG_RQ_QM_P_SIZE 0x120050 2322#define PXP2_REG_RQ_QM_P_SIZE 0x120050
2301/* [RW 1] 1' indicates that the RBC has finished configurating the PSWRQ */ 2323/* [RW 1] 1' indicates that the RBC has finished configuring the PSWRQ */
2302#define PXP2_REG_RQ_RBC_DONE 0x1201b0 2324#define PXP2_REG_RQ_RBC_DONE 0x1201b0
2303/* [RW 3] Max burst size filed for read requests port 0; 000 - 128B; 2325/* [RW 3] Max burst size filed for read requests port 0; 000 - 128B;
2304 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */ 2326 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */
@@ -2406,7 +2428,7 @@
2406/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the 2428/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
2407 buffer reaches this number has_payload will be asserted */ 2429 buffer reaches this number has_payload will be asserted */
2408#define PXP2_REG_WR_DMAE_MPS 0x1205ec 2430#define PXP2_REG_WR_DMAE_MPS 0x1205ec
2409/* [RW 10] if Number of entries in dmae fifo will be higer than this 2431/* [RW 10] if Number of entries in dmae fifo will be higher than this
2410 threshold then has_payload indication will be asserted; the default value 2432 threshold then has_payload indication will be asserted; the default value
2411 should be equal to &gt; write MBS size! */ 2433 should be equal to &gt; write MBS size! */
2412#define PXP2_REG_WR_DMAE_TH 0x120368 2434#define PXP2_REG_WR_DMAE_TH 0x120368
@@ -2427,7 +2449,7 @@
2427/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the 2449/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
2428 buffer reaches this number has_payload will be asserted */ 2450 buffer reaches this number has_payload will be asserted */
2429#define PXP2_REG_WR_TSDM_MPS 0x1205d4 2451#define PXP2_REG_WR_TSDM_MPS 0x1205d4
2430/* [RW 10] if Number of entries in usdmdp fifo will be higer than this 2452/* [RW 10] if Number of entries in usdmdp fifo will be higher than this
2431 threshold then has_payload indication will be asserted; the default value 2453 threshold then has_payload indication will be asserted; the default value
2432 should be equal to &gt; write MBS size! */ 2454 should be equal to &gt; write MBS size! */
2433#define PXP2_REG_WR_USDMDP_TH 0x120348 2455#define PXP2_REG_WR_USDMDP_TH 0x120348
@@ -3294,12 +3316,12 @@
3294#define XSEM_XSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0 3316#define XSEM_XSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
3295#define CFC_DEBUG1_REG_WRITE_AC (0x1<<4) 3317#define CFC_DEBUG1_REG_WRITE_AC (0x1<<4)
3296#define CFC_DEBUG1_REG_WRITE_AC_SIZE 4 3318#define CFC_DEBUG1_REG_WRITE_AC_SIZE 4
3297/* [R 1] debug only: This bit indicates wheter indicates that external 3319/* [R 1] debug only: This bit indicates whether indicates that external
3298 buffer was wrapped (oldest data was thrown); Relevant only when 3320 buffer was wrapped (oldest data was thrown); Relevant only when
3299 ~dbg_registers_debug_target=2 (PCI) & ~dbg_registers_full_mode=1 (wrap); */ 3321 ~dbg_registers_debug_target=2 (PCI) & ~dbg_registers_full_mode=1 (wrap); */
3300#define DBG_REG_WRAP_ON_EXT_BUFFER 0xc124 3322#define DBG_REG_WRAP_ON_EXT_BUFFER 0xc124
3301#define DBG_REG_WRAP_ON_EXT_BUFFER_SIZE 1 3323#define DBG_REG_WRAP_ON_EXT_BUFFER_SIZE 1
3302/* [R 1] debug only: This bit indicates wheter the internal buffer was 3324/* [R 1] debug only: This bit indicates whether the internal buffer was
3303 wrapped (oldest data was thrown) Relevant only when 3325 wrapped (oldest data was thrown) Relevant only when
3304 ~dbg_registers_debug_target=0 (internal buffer) */ 3326 ~dbg_registers_debug_target=0 (internal buffer) */
3305#define DBG_REG_WRAP_ON_INT_BUFFER 0xc128 3327#define DBG_REG_WRAP_ON_INT_BUFFER 0xc128
@@ -4944,6 +4966,7 @@
4944#define EMAC_RX_MODE_PROMISCUOUS (1L<<8) 4966#define EMAC_RX_MODE_PROMISCUOUS (1L<<8)
4945#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31) 4967#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31)
4946#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3) 4968#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3)
4969#define EMAC_TX_MODE_FLOW_EN (1L<<4)
4947#define MISC_REGISTERS_GPIO_0 0 4970#define MISC_REGISTERS_GPIO_0 0
4948#define MISC_REGISTERS_GPIO_1 1 4971#define MISC_REGISTERS_GPIO_1 1
4949#define MISC_REGISTERS_GPIO_2 2 4972#define MISC_REGISTERS_GPIO_2 2
@@ -4959,6 +4982,7 @@
4959#define MISC_REGISTERS_GPIO_PORT_SHIFT 4 4982#define MISC_REGISTERS_GPIO_PORT_SHIFT 4
4960#define MISC_REGISTERS_GPIO_SET_POS 8 4983#define MISC_REGISTERS_GPIO_SET_POS 8
4961#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 4984#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588
4985#define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7)
4962#define MISC_REGISTERS_RESET_REG_1_SET 0x584 4986#define MISC_REGISTERS_RESET_REG_1_SET 0x584
4963#define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598 4987#define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598
4964#define MISC_REGISTERS_RESET_REG_2_RST_BMAC0 (0x1<<0) 4988#define MISC_REGISTERS_RESET_REG_2_RST_BMAC0 (0x1<<0)
@@ -4993,7 +5017,9 @@
4993#define HW_LOCK_MAX_RESOURCE_VALUE 31 5017#define HW_LOCK_MAX_RESOURCE_VALUE 31
4994#define HW_LOCK_RESOURCE_8072_MDIO 0 5018#define HW_LOCK_RESOURCE_8072_MDIO 0
4995#define HW_LOCK_RESOURCE_GPIO 1 5019#define HW_LOCK_RESOURCE_GPIO 1
5020#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
4996#define HW_LOCK_RESOURCE_SPIO 2 5021#define HW_LOCK_RESOURCE_SPIO 2
5022#define HW_LOCK_RESOURCE_UNDI 5
4997#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) 5023#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18)
4998#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31) 5024#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31)
4999#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9) 5025#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9)
@@ -5144,59 +5170,73 @@
5144#define GRCBASE_MISC_AEU GRCBASE_MISC 5170#define GRCBASE_MISC_AEU GRCBASE_MISC
5145 5171
5146 5172
5147/*the offset of the configuration space in the pci core register*/ 5173/* offset of configuration space in the pci core register */
5148#define PCICFG_OFFSET 0x2000 5174#define PCICFG_OFFSET 0x2000
5149#define PCICFG_VENDOR_ID_OFFSET 0x00 5175#define PCICFG_VENDOR_ID_OFFSET 0x00
5150#define PCICFG_DEVICE_ID_OFFSET 0x02 5176#define PCICFG_DEVICE_ID_OFFSET 0x02
5151#define PCICFG_COMMAND_OFFSET 0x04 5177#define PCICFG_COMMAND_OFFSET 0x04
5178#define PCICFG_COMMAND_IO_SPACE (1<<0)
5179#define PCICFG_COMMAND_MEM_SPACE (1<<1)
5180#define PCICFG_COMMAND_BUS_MASTER (1<<2)
5181#define PCICFG_COMMAND_SPECIAL_CYCLES (1<<3)
5182#define PCICFG_COMMAND_MWI_CYCLES (1<<4)
5183#define PCICFG_COMMAND_VGA_SNOOP (1<<5)
5184#define PCICFG_COMMAND_PERR_ENA (1<<6)
5185#define PCICFG_COMMAND_STEPPING (1<<7)
5186#define PCICFG_COMMAND_SERR_ENA (1<<8)
5187#define PCICFG_COMMAND_FAST_B2B (1<<9)
5188#define PCICFG_COMMAND_INT_DISABLE (1<<10)
5189#define PCICFG_COMMAND_RESERVED (0x1f<<11)
5152#define PCICFG_STATUS_OFFSET 0x06 5190#define PCICFG_STATUS_OFFSET 0x06
5153#define PCICFG_REVESION_ID 0x08 5191#define PCICFG_REVESION_ID 0x08
5154#define PCICFG_CACHE_LINE_SIZE 0x0c 5192#define PCICFG_CACHE_LINE_SIZE 0x0c
5155#define PCICFG_LATENCY_TIMER 0x0d 5193#define PCICFG_LATENCY_TIMER 0x0d
5156#define PCICFG_BAR_1_LOW 0x10 5194#define PCICFG_BAR_1_LOW 0x10
5157#define PCICFG_BAR_1_HIGH 0x14 5195#define PCICFG_BAR_1_HIGH 0x14
5158#define PCICFG_BAR_2_LOW 0x18 5196#define PCICFG_BAR_2_LOW 0x18
5159#define PCICFG_BAR_2_HIGH 0x1c 5197#define PCICFG_BAR_2_HIGH 0x1c
5160#define PCICFG_SUBSYSTEM_VENDOR_ID_OFFSET 0x2c 5198#define PCICFG_SUBSYSTEM_VENDOR_ID_OFFSET 0x2c
5161#define PCICFG_SUBSYSTEM_ID_OFFSET 0x2e 5199#define PCICFG_SUBSYSTEM_ID_OFFSET 0x2e
5162#define PCICFG_INT_LINE 0x3c 5200#define PCICFG_INT_LINE 0x3c
5163#define PCICFG_INT_PIN 0x3d 5201#define PCICFG_INT_PIN 0x3d
5164#define PCICFG_PM_CSR_OFFSET 0x4c 5202#define PCICFG_PM_CAPABILITY 0x48
5165#define PCICFG_GRC_ADDRESS 0x78 5203#define PCICFG_PM_CAPABILITY_VERSION (0x3<<16)
5166#define PCICFG_GRC_DATA 0x80 5204#define PCICFG_PM_CAPABILITY_CLOCK (1<<19)
5205#define PCICFG_PM_CAPABILITY_RESERVED (1<<20)
5206#define PCICFG_PM_CAPABILITY_DSI (1<<21)
5207#define PCICFG_PM_CAPABILITY_AUX_CURRENT (0x7<<22)
5208#define PCICFG_PM_CAPABILITY_D1_SUPPORT (1<<25)
5209#define PCICFG_PM_CAPABILITY_D2_SUPPORT (1<<26)
5210#define PCICFG_PM_CAPABILITY_PME_IN_D0 (1<<27)
5211#define PCICFG_PM_CAPABILITY_PME_IN_D1 (1<<28)
5212#define PCICFG_PM_CAPABILITY_PME_IN_D2 (1<<29)
5213#define PCICFG_PM_CAPABILITY_PME_IN_D3_HOT (1<<30)
5214#define PCICFG_PM_CAPABILITY_PME_IN_D3_COLD (1<<31)
5215#define PCICFG_PM_CSR_OFFSET 0x4c
5216#define PCICFG_PM_CSR_STATE (0x3<<0)
5217#define PCICFG_PM_CSR_PME_ENABLE (1<<8)
5218#define PCICFG_PM_CSR_PME_STATUS (1<<15)
5219#define PCICFG_GRC_ADDRESS 0x78
5220#define PCICFG_GRC_DATA 0x80
5167#define PCICFG_DEVICE_CONTROL 0xb4 5221#define PCICFG_DEVICE_CONTROL 0xb4
5168#define PCICFG_LINK_CONTROL 0xbc 5222#define PCICFG_LINK_CONTROL 0xbc
5169 5223
5170#define PCICFG_COMMAND_IO_SPACE (1<<0)
5171#define PCICFG_COMMAND_MEM_SPACE (1<<1)
5172#define PCICFG_COMMAND_BUS_MASTER (1<<2)
5173#define PCICFG_COMMAND_SPECIAL_CYCLES (1<<3)
5174#define PCICFG_COMMAND_MWI_CYCLES (1<<4)
5175#define PCICFG_COMMAND_VGA_SNOOP (1<<5)
5176#define PCICFG_COMMAND_PERR_ENA (1<<6)
5177#define PCICFG_COMMAND_STEPPING (1<<7)
5178#define PCICFG_COMMAND_SERR_ENA (1<<8)
5179#define PCICFG_COMMAND_FAST_B2B (1<<9)
5180#define PCICFG_COMMAND_INT_DISABLE (1<<10)
5181#define PCICFG_COMMAND_RESERVED (0x1f<<11)
5182
5183#define PCICFG_PM_CSR_STATE (0x3<<0)
5184#define PCICFG_PM_CSR_PME_STATUS (1<<15)
5185 5224
5186#define BAR_USTRORM_INTMEM 0x400000 5225#define BAR_USTRORM_INTMEM 0x400000
5187#define BAR_CSTRORM_INTMEM 0x410000 5226#define BAR_CSTRORM_INTMEM 0x410000
5188#define BAR_XSTRORM_INTMEM 0x420000 5227#define BAR_XSTRORM_INTMEM 0x420000
5189#define BAR_TSTRORM_INTMEM 0x430000 5228#define BAR_TSTRORM_INTMEM 0x430000
5190 5229
5230/* for accessing the IGU in case of status block ACK */
5191#define BAR_IGU_INTMEM 0x440000 5231#define BAR_IGU_INTMEM 0x440000
5192 5232
5193#define BAR_DOORBELL_OFFSET 0x800000 5233#define BAR_DOORBELL_OFFSET 0x800000
5194 5234
5195#define BAR_ME_REGISTER 0x450000 5235#define BAR_ME_REGISTER 0x450000
5196 5236
5197 5237/* config_2 offset */
5198#define GRC_CONFIG_2_SIZE_REG 0x408 /* config_2 offset */ 5238#define GRC_CONFIG_2_SIZE_REG 0x408
5199#define PCI_CONFIG_2_BAR1_SIZE (0xfL<<0) 5239#define PCI_CONFIG_2_BAR1_SIZE (0xfL<<0)
5200#define PCI_CONFIG_2_BAR1_SIZE_DISABLED (0L<<0) 5240#define PCI_CONFIG_2_BAR1_SIZE_DISABLED (0L<<0)
5201#define PCI_CONFIG_2_BAR1_SIZE_64K (1L<<0) 5241#define PCI_CONFIG_2_BAR1_SIZE_64K (1L<<0)
5202#define PCI_CONFIG_2_BAR1_SIZE_128K (2L<<0) 5242#define PCI_CONFIG_2_BAR1_SIZE_128K (2L<<0)
@@ -5213,11 +5253,11 @@
5213#define PCI_CONFIG_2_BAR1_SIZE_256M (13L<<0) 5253#define PCI_CONFIG_2_BAR1_SIZE_256M (13L<<0)
5214#define PCI_CONFIG_2_BAR1_SIZE_512M (14L<<0) 5254#define PCI_CONFIG_2_BAR1_SIZE_512M (14L<<0)
5215#define PCI_CONFIG_2_BAR1_SIZE_1G (15L<<0) 5255#define PCI_CONFIG_2_BAR1_SIZE_1G (15L<<0)
5216#define PCI_CONFIG_2_BAR1_64ENA (1L<<4) 5256#define PCI_CONFIG_2_BAR1_64ENA (1L<<4)
5217#define PCI_CONFIG_2_EXP_ROM_RETRY (1L<<5) 5257#define PCI_CONFIG_2_EXP_ROM_RETRY (1L<<5)
5218#define PCI_CONFIG_2_CFG_CYCLE_RETRY (1L<<6) 5258#define PCI_CONFIG_2_CFG_CYCLE_RETRY (1L<<6)
5219#define PCI_CONFIG_2_FIRST_CFG_DONE (1L<<7) 5259#define PCI_CONFIG_2_FIRST_CFG_DONE (1L<<7)
5220#define PCI_CONFIG_2_EXP_ROM_SIZE (0xffL<<8) 5260#define PCI_CONFIG_2_EXP_ROM_SIZE (0xffL<<8)
5221#define PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED (0L<<8) 5261#define PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED (0L<<8)
5222#define PCI_CONFIG_2_EXP_ROM_SIZE_2K (1L<<8) 5262#define PCI_CONFIG_2_EXP_ROM_SIZE_2K (1L<<8)
5223#define PCI_CONFIG_2_EXP_ROM_SIZE_4K (2L<<8) 5263#define PCI_CONFIG_2_EXP_ROM_SIZE_4K (2L<<8)
@@ -5234,46 +5274,44 @@
5234#define PCI_CONFIG_2_EXP_ROM_SIZE_8M (13L<<8) 5274#define PCI_CONFIG_2_EXP_ROM_SIZE_8M (13L<<8)
5235#define PCI_CONFIG_2_EXP_ROM_SIZE_16M (14L<<8) 5275#define PCI_CONFIG_2_EXP_ROM_SIZE_16M (14L<<8)
5236#define PCI_CONFIG_2_EXP_ROM_SIZE_32M (15L<<8) 5276#define PCI_CONFIG_2_EXP_ROM_SIZE_32M (15L<<8)
5237#define PCI_CONFIG_2_BAR_PREFETCH (1L<<16) 5277#define PCI_CONFIG_2_BAR_PREFETCH (1L<<16)
5238#define PCI_CONFIG_2_RESERVED0 (0x7fffL<<17) 5278#define PCI_CONFIG_2_RESERVED0 (0x7fffL<<17)
5239 5279
5240/* config_3 offset */ 5280/* config_3 offset */
5241#define GRC_CONFIG_3_SIZE_REG (0x40c) 5281#define GRC_CONFIG_3_SIZE_REG 0x40c
5242#define PCI_CONFIG_3_STICKY_BYTE (0xffL<<0) 5282#define PCI_CONFIG_3_STICKY_BYTE (0xffL<<0)
5243#define PCI_CONFIG_3_FORCE_PME (1L<<24) 5283#define PCI_CONFIG_3_FORCE_PME (1L<<24)
5244#define PCI_CONFIG_3_PME_STATUS (1L<<25) 5284#define PCI_CONFIG_3_PME_STATUS (1L<<25)
5245#define PCI_CONFIG_3_PME_ENABLE (1L<<26) 5285#define PCI_CONFIG_3_PME_ENABLE (1L<<26)
5246#define PCI_CONFIG_3_PM_STATE (0x3L<<27) 5286#define PCI_CONFIG_3_PM_STATE (0x3L<<27)
5247#define PCI_CONFIG_3_VAUX_PRESET (1L<<30) 5287#define PCI_CONFIG_3_VAUX_PRESET (1L<<30)
5248#define PCI_CONFIG_3_PCI_POWER (1L<<31) 5288#define PCI_CONFIG_3_PCI_POWER (1L<<31)
5249
5250/* config_2 offset */
5251#define GRC_CONFIG_2_SIZE_REG 0x408
5252 5289
5253#define GRC_BAR2_CONFIG 0x4e0 5290#define GRC_BAR2_CONFIG 0x4e0
5254#define PCI_CONFIG_2_BAR2_SIZE (0xfL<<0) 5291#define PCI_CONFIG_2_BAR2_SIZE (0xfL<<0)
5255#define PCI_CONFIG_2_BAR2_SIZE_DISABLED (0L<<0) 5292#define PCI_CONFIG_2_BAR2_SIZE_DISABLED (0L<<0)
5256#define PCI_CONFIG_2_BAR2_SIZE_64K (1L<<0) 5293#define PCI_CONFIG_2_BAR2_SIZE_64K (1L<<0)
5257#define PCI_CONFIG_2_BAR2_SIZE_128K (2L<<0) 5294#define PCI_CONFIG_2_BAR2_SIZE_128K (2L<<0)
5258#define PCI_CONFIG_2_BAR2_SIZE_256K (3L<<0) 5295#define PCI_CONFIG_2_BAR2_SIZE_256K (3L<<0)
5259#define PCI_CONFIG_2_BAR2_SIZE_512K (4L<<0) 5296#define PCI_CONFIG_2_BAR2_SIZE_512K (4L<<0)
5260#define PCI_CONFIG_2_BAR2_SIZE_1M (5L<<0) 5297#define PCI_CONFIG_2_BAR2_SIZE_1M (5L<<0)
5261#define PCI_CONFIG_2_BAR2_SIZE_2M (6L<<0) 5298#define PCI_CONFIG_2_BAR2_SIZE_2M (6L<<0)
5262#define PCI_CONFIG_2_BAR2_SIZE_4M (7L<<0) 5299#define PCI_CONFIG_2_BAR2_SIZE_4M (7L<<0)
5263#define PCI_CONFIG_2_BAR2_SIZE_8M (8L<<0) 5300#define PCI_CONFIG_2_BAR2_SIZE_8M (8L<<0)
5264#define PCI_CONFIG_2_BAR2_SIZE_16M (9L<<0) 5301#define PCI_CONFIG_2_BAR2_SIZE_16M (9L<<0)
5265#define PCI_CONFIG_2_BAR2_SIZE_32M (10L<<0) 5302#define PCI_CONFIG_2_BAR2_SIZE_32M (10L<<0)
5266#define PCI_CONFIG_2_BAR2_SIZE_64M (11L<<0) 5303#define PCI_CONFIG_2_BAR2_SIZE_64M (11L<<0)
5267#define PCI_CONFIG_2_BAR2_SIZE_128M (12L<<0) 5304#define PCI_CONFIG_2_BAR2_SIZE_128M (12L<<0)
5268#define PCI_CONFIG_2_BAR2_SIZE_256M (13L<<0) 5305#define PCI_CONFIG_2_BAR2_SIZE_256M (13L<<0)
5269#define PCI_CONFIG_2_BAR2_SIZE_512M (14L<<0) 5306#define PCI_CONFIG_2_BAR2_SIZE_512M (14L<<0)
5270#define PCI_CONFIG_2_BAR2_SIZE_1G (15L<<0) 5307#define PCI_CONFIG_2_BAR2_SIZE_1G (15L<<0)
5271#define PCI_CONFIG_2_BAR2_64ENA (1L<<4) 5308#define PCI_CONFIG_2_BAR2_64ENA (1L<<4)
5309
5310#define PCI_PM_DATA_A 0x410
5311#define PCI_PM_DATA_B 0x414
5312#define PCI_ID_VAL1 0x434
5313#define PCI_ID_VAL2 0x438
5272 5314
5273#define PCI_PM_DATA_A (0x410)
5274#define PCI_PM_DATA_B (0x414)
5275#define PCI_ID_VAL1 (0x434)
5276#define PCI_ID_VAL2 (0x438)
5277 5315
5278#define MDIO_REG_BANK_CL73_IEEEB0 0x0 5316#define MDIO_REG_BANK_CL73_IEEEB0 0x0
5279#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL 0x0 5317#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL 0x0
@@ -5522,6 +5560,8 @@ Theotherbitsarereservedandshouldbezero*/
5522#define MDIO_PMA_REG_GEN_CTRL 0xca10 5560#define MDIO_PMA_REG_GEN_CTRL 0xca10
5523#define MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP 0x0188 5561#define MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP 0x0188
5524#define MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET 0x018a 5562#define MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET 0x018a
5563#define MDIO_PMA_REG_M8051_MSGIN_REG 0xca12
5564#define MDIO_PMA_REG_M8051_MSGOUT_REG 0xca13
5525#define MDIO_PMA_REG_ROM_VER1 0xca19 5565#define MDIO_PMA_REG_ROM_VER1 0xca19
5526#define MDIO_PMA_REG_ROM_VER2 0xca1a 5566#define MDIO_PMA_REG_ROM_VER2 0xca1a
5527#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b 5567#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b
@@ -5576,7 +5616,8 @@ Theotherbitsarereservedandshouldbezero*/
5576#define MDIO_AN_REG_LINK_STATUS 0x8304 5616#define MDIO_AN_REG_LINK_STATUS 0x8304
5577#define MDIO_AN_REG_CL37_CL73 0x8370 5617#define MDIO_AN_REG_CL37_CL73 0x8370
5578#define MDIO_AN_REG_CL37_AN 0xffe0 5618#define MDIO_AN_REG_CL37_AN 0xffe0
5579#define MDIO_AN_REG_CL37_FD 0xffe4 5619#define MDIO_AN_REG_CL37_FC_LD 0xffe4
5620#define MDIO_AN_REG_CL37_FC_LP 0xffe5
5580 5621
5581 5622
5582#define IGU_FUNC_BASE 0x0400 5623#define IGU_FUNC_BASE 0x0400
@@ -5600,4 +5641,13 @@ Theotherbitsarereservedandshouldbezero*/
5600#define IGU_INT_NOP 2 5641#define IGU_INT_NOP 2
5601#define IGU_INT_NOP2 3 5642#define IGU_INT_NOP2 3
5602 5643
5644#define COMMAND_REG_INT_ACK 0x0
5645#define COMMAND_REG_PROD_UPD 0x4
5646#define COMMAND_REG_ATTN_BITS_UPD 0x8
5647#define COMMAND_REG_ATTN_BITS_SET 0xc
5648#define COMMAND_REG_ATTN_BITS_CLR 0x10
5649#define COMMAND_REG_COALESCE_NOW 0x14
5650#define COMMAND_REG_SIMD_MASK 0x18
5651#define COMMAND_REG_SIMD_NOMASK 0x1c
5652
5603 5653
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index ebb539e090c3..6106660a4a44 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2107,6 +2107,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
2107 aggregator = __get_first_agg(port); 2107 aggregator = __get_first_agg(port);
2108 ad_agg_selection_logic(aggregator); 2108 ad_agg_selection_logic(aggregator);
2109 } 2109 }
2110 bond_3ad_set_carrier(bond);
2110 } 2111 }
2111 2112
2112 // for each port run the state machines 2113 // for each port run the state machines
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a641eeaa2a2f..c792138511e6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2223,272 +2223,217 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
2223 2223
2224/*-------------------------------- Monitoring -------------------------------*/ 2224/*-------------------------------- Monitoring -------------------------------*/
2225 2225
2226/*
2227 * if !have_locks, return nonzero if a failover is necessary. if
2228 * have_locks, do whatever failover activities are needed.
2229 *
2230 * This is to separate the inspection and failover steps for locking
2231 * purposes; failover requires rtnl, but acquiring it for every
2232 * inspection is undesirable, so a wrapper first does inspection, and
2233 * the acquires the necessary locks and calls again to perform
2234 * failover if needed. Since all locks are dropped, a complete
2235 * restart is needed between calls.
2236 */
2237static int __bond_mii_monitor(struct bonding *bond, int have_locks)
2238{
2239 struct slave *slave, *oldcurrent;
2240 int do_failover = 0;
2241 int i;
2242
2243 if (bond->slave_cnt == 0)
2244 goto out;
2245 2226
2246 /* we will try to read the link status of each of our slaves, and 2227static int bond_miimon_inspect(struct bonding *bond)
2247 * set their IFF_RUNNING flag appropriately. For each slave not 2228{
2248 * supporting MII status, we won't do anything so that a user-space 2229 struct slave *slave;
2249 * program could monitor the link itself if needed. 2230 int i, link_state, commit = 0;
2250 */
2251
2252 read_lock(&bond->curr_slave_lock);
2253 oldcurrent = bond->curr_active_slave;
2254 read_unlock(&bond->curr_slave_lock);
2255 2231
2256 bond_for_each_slave(bond, slave, i) { 2232 bond_for_each_slave(bond, slave, i) {
2257 struct net_device *slave_dev = slave->dev; 2233 slave->new_link = BOND_LINK_NOCHANGE;
2258 int link_state;
2259 u16 old_speed = slave->speed;
2260 u8 old_duplex = slave->duplex;
2261 2234
2262 link_state = bond_check_dev_link(bond, slave_dev, 0); 2235 link_state = bond_check_dev_link(bond, slave->dev, 0);
2263 2236
2264 switch (slave->link) { 2237 switch (slave->link) {
2265 case BOND_LINK_UP: /* the link was up */ 2238 case BOND_LINK_UP:
2266 if (link_state == BMSR_LSTATUS) { 2239 if (link_state)
2267 if (!oldcurrent) { 2240 continue;
2268 if (!have_locks)
2269 return 1;
2270 do_failover = 1;
2271 }
2272 break;
2273 } else { /* link going down */
2274 slave->link = BOND_LINK_FAIL;
2275 slave->delay = bond->params.downdelay;
2276
2277 if (slave->link_failure_count < UINT_MAX) {
2278 slave->link_failure_count++;
2279 }
2280 2241
2281 if (bond->params.downdelay) { 2242 slave->link = BOND_LINK_FAIL;
2282 printk(KERN_INFO DRV_NAME 2243 slave->delay = bond->params.downdelay;
2283 ": %s: link status down for %s " 2244 if (slave->delay) {
2284 "interface %s, disabling it in " 2245 printk(KERN_INFO DRV_NAME
2285 "%d ms.\n", 2246 ": %s: link status down for %s"
2286 bond->dev->name, 2247 "interface %s, disabling it in %d ms.\n",
2287 IS_UP(slave_dev) 2248 bond->dev->name,
2288 ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) 2249 (bond->params.mode ==
2289 ? ((slave == oldcurrent) 2250 BOND_MODE_ACTIVEBACKUP) ?
2290 ? "active " : "backup ") 2251 ((slave->state == BOND_STATE_ACTIVE) ?
2291 : "") 2252 "active " : "backup ") : "",
2292 : "idle ", 2253 slave->dev->name,
2293 slave_dev->name, 2254 bond->params.downdelay * bond->params.miimon);
2294 bond->params.downdelay * bond->params.miimon);
2295 }
2296 } 2255 }
2297 /* no break ! fall through the BOND_LINK_FAIL test to 2256 /*FALLTHRU*/
2298 ensure proper action to be taken 2257 case BOND_LINK_FAIL:
2299 */ 2258 if (link_state) {
2300 case BOND_LINK_FAIL: /* the link has just gone down */ 2259 /*
2301 if (link_state != BMSR_LSTATUS) { 2260 * recovered before downdelay expired
2302 /* link stays down */ 2261 */
2303 if (slave->delay <= 0) { 2262 slave->link = BOND_LINK_UP;
2304 if (!have_locks)
2305 return 1;
2306
2307 /* link down for too long time */
2308 slave->link = BOND_LINK_DOWN;
2309
2310 /* in active/backup mode, we must
2311 * completely disable this interface
2312 */
2313 if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) ||
2314 (bond->params.mode == BOND_MODE_8023AD)) {
2315 bond_set_slave_inactive_flags(slave);
2316 }
2317
2318 printk(KERN_INFO DRV_NAME
2319 ": %s: link status definitely "
2320 "down for interface %s, "
2321 "disabling it\n",
2322 bond->dev->name,
2323 slave_dev->name);
2324
2325 /* notify ad that the link status has changed */
2326 if (bond->params.mode == BOND_MODE_8023AD) {
2327 bond_3ad_handle_link_change(slave, BOND_LINK_DOWN);
2328 }
2329
2330 if ((bond->params.mode == BOND_MODE_TLB) ||
2331 (bond->params.mode == BOND_MODE_ALB)) {
2332 bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN);
2333 }
2334
2335 if (slave == oldcurrent) {
2336 do_failover = 1;
2337 }
2338 } else {
2339 slave->delay--;
2340 }
2341 } else {
2342 /* link up again */
2343 slave->link = BOND_LINK_UP;
2344 slave->jiffies = jiffies; 2263 slave->jiffies = jiffies;
2345 printk(KERN_INFO DRV_NAME 2264 printk(KERN_INFO DRV_NAME
2346 ": %s: link status up again after %d " 2265 ": %s: link status up again after %d "
2347 "ms for interface %s.\n", 2266 "ms for interface %s.\n",
2348 bond->dev->name, 2267 bond->dev->name,
2349 (bond->params.downdelay - slave->delay) * bond->params.miimon, 2268 (bond->params.downdelay - slave->delay) *
2350 slave_dev->name); 2269 bond->params.miimon,
2270 slave->dev->name);
2271 continue;
2351 } 2272 }
2352 break;
2353 case BOND_LINK_DOWN: /* the link was down */
2354 if (link_state != BMSR_LSTATUS) {
2355 /* the link stays down, nothing more to do */
2356 break;
2357 } else { /* link going up */
2358 slave->link = BOND_LINK_BACK;
2359 slave->delay = bond->params.updelay;
2360 2273
2361 if (bond->params.updelay) { 2274 if (slave->delay <= 0) {
2362 /* if updelay == 0, no need to 2275 slave->new_link = BOND_LINK_DOWN;
2363 advertise about a 0 ms delay */ 2276 commit++;
2364 printk(KERN_INFO DRV_NAME 2277 continue;
2365 ": %s: link status up for "
2366 "interface %s, enabling it "
2367 "in %d ms.\n",
2368 bond->dev->name,
2369 slave_dev->name,
2370 bond->params.updelay * bond->params.miimon);
2371 }
2372 } 2278 }
2373 /* no break ! fall through the BOND_LINK_BACK state in
2374 case there's something to do.
2375 */
2376 case BOND_LINK_BACK: /* the link has just come back */
2377 if (link_state != BMSR_LSTATUS) {
2378 /* link down again */
2379 slave->link = BOND_LINK_DOWN;
2380 2279
2280 slave->delay--;
2281 break;
2282
2283 case BOND_LINK_DOWN:
2284 if (!link_state)
2285 continue;
2286
2287 slave->link = BOND_LINK_BACK;
2288 slave->delay = bond->params.updelay;
2289
2290 if (slave->delay) {
2291 printk(KERN_INFO DRV_NAME
2292 ": %s: link status up for "
2293 "interface %s, enabling it in %d ms.\n",
2294 bond->dev->name, slave->dev->name,
2295 bond->params.updelay *
2296 bond->params.miimon);
2297 }
2298 /*FALLTHRU*/
2299 case BOND_LINK_BACK:
2300 if (!link_state) {
2301 slave->link = BOND_LINK_DOWN;
2381 printk(KERN_INFO DRV_NAME 2302 printk(KERN_INFO DRV_NAME
2382 ": %s: link status down again after %d " 2303 ": %s: link status down again after %d "
2383 "ms for interface %s.\n", 2304 "ms for interface %s.\n",
2384 bond->dev->name, 2305 bond->dev->name,
2385 (bond->params.updelay - slave->delay) * bond->params.miimon, 2306 (bond->params.updelay - slave->delay) *
2386 slave_dev->name); 2307 bond->params.miimon,
2387 } else { 2308 slave->dev->name);
2388 /* link stays up */
2389 if (slave->delay == 0) {
2390 if (!have_locks)
2391 return 1;
2392
2393 /* now the link has been up for long time enough */
2394 slave->link = BOND_LINK_UP;
2395 slave->jiffies = jiffies;
2396
2397 if (bond->params.mode == BOND_MODE_8023AD) {
2398 /* prevent it from being the active one */
2399 slave->state = BOND_STATE_BACKUP;
2400 } else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
2401 /* make it immediately active */
2402 slave->state = BOND_STATE_ACTIVE;
2403 } else if (slave != bond->primary_slave) {
2404 /* prevent it from being the active one */
2405 slave->state = BOND_STATE_BACKUP;
2406 }
2407 2309
2408 printk(KERN_INFO DRV_NAME 2310 continue;
2409 ": %s: link status definitely "
2410 "up for interface %s.\n",
2411 bond->dev->name,
2412 slave_dev->name);
2413
2414 /* notify ad that the link status has changed */
2415 if (bond->params.mode == BOND_MODE_8023AD) {
2416 bond_3ad_handle_link_change(slave, BOND_LINK_UP);
2417 }
2418
2419 if ((bond->params.mode == BOND_MODE_TLB) ||
2420 (bond->params.mode == BOND_MODE_ALB)) {
2421 bond_alb_handle_link_change(bond, slave, BOND_LINK_UP);
2422 }
2423
2424 if ((!oldcurrent) ||
2425 (slave == bond->primary_slave)) {
2426 do_failover = 1;
2427 }
2428 } else {
2429 slave->delay--;
2430 }
2431 } 2311 }
2312
2313 if (slave->delay <= 0) {
2314 slave->new_link = BOND_LINK_UP;
2315 commit++;
2316 continue;
2317 }
2318
2319 slave->delay--;
2432 break; 2320 break;
2433 default: 2321 }
2434 /* Should not happen */ 2322 }
2435 printk(KERN_ERR DRV_NAME
2436 ": %s: Error: %s Illegal value (link=%d)\n",
2437 bond->dev->name,
2438 slave->dev->name,
2439 slave->link);
2440 goto out;
2441 } /* end of switch (slave->link) */
2442 2323
2443 bond_update_speed_duplex(slave); 2324 return commit;
2325}
2444 2326
2445 if (bond->params.mode == BOND_MODE_8023AD) { 2327static void bond_miimon_commit(struct bonding *bond)
2446 if (old_speed != slave->speed) { 2328{
2447 bond_3ad_adapter_speed_changed(slave); 2329 struct slave *slave;
2448 } 2330 int i;
2331
2332 bond_for_each_slave(bond, slave, i) {
2333 switch (slave->new_link) {
2334 case BOND_LINK_NOCHANGE:
2335 continue;
2336
2337 case BOND_LINK_UP:
2338 slave->link = BOND_LINK_UP;
2339 slave->jiffies = jiffies;
2449 2340
2450 if (old_duplex != slave->duplex) { 2341 if (bond->params.mode == BOND_MODE_8023AD) {
2451 bond_3ad_adapter_duplex_changed(slave); 2342 /* prevent it from being the active one */
2343 slave->state = BOND_STATE_BACKUP;
2344 } else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
2345 /* make it immediately active */
2346 slave->state = BOND_STATE_ACTIVE;
2347 } else if (slave != bond->primary_slave) {
2348 /* prevent it from being the active one */
2349 slave->state = BOND_STATE_BACKUP;
2452 } 2350 }
2453 }
2454 2351
2455 } /* end of for */ 2352 printk(KERN_INFO DRV_NAME
2353 ": %s: link status definitely "
2354 "up for interface %s.\n",
2355 bond->dev->name, slave->dev->name);
2456 2356
2457 if (do_failover) { 2357 /* notify ad that the link status has changed */
2458 ASSERT_RTNL(); 2358 if (bond->params.mode == BOND_MODE_8023AD)
2359 bond_3ad_handle_link_change(slave, BOND_LINK_UP);
2459 2360
2460 write_lock_bh(&bond->curr_slave_lock); 2361 if ((bond->params.mode == BOND_MODE_TLB) ||
2362 (bond->params.mode == BOND_MODE_ALB))
2363 bond_alb_handle_link_change(bond, slave,
2364 BOND_LINK_UP);
2461 2365
2462 bond_select_active_slave(bond); 2366 if (!bond->curr_active_slave ||
2367 (slave == bond->primary_slave))
2368 goto do_failover;
2463 2369
2464 write_unlock_bh(&bond->curr_slave_lock); 2370 continue;
2465 2371
2466 } else 2372 case BOND_LINK_DOWN:
2467 bond_set_carrier(bond); 2373 slave->link = BOND_LINK_DOWN;
2468 2374
2469out: 2375 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP ||
2470 return 0; 2376 bond->params.mode == BOND_MODE_8023AD)
2377 bond_set_slave_inactive_flags(slave);
2378
2379 printk(KERN_INFO DRV_NAME
2380 ": %s: link status definitely down for "
2381 "interface %s, disabling it\n",
2382 bond->dev->name, slave->dev->name);
2383
2384 if (bond->params.mode == BOND_MODE_8023AD)
2385 bond_3ad_handle_link_change(slave,
2386 BOND_LINK_DOWN);
2387
2388 if (bond->params.mode == BOND_MODE_TLB ||
2389 bond->params.mode == BOND_MODE_ALB)
2390 bond_alb_handle_link_change(bond, slave,
2391 BOND_LINK_DOWN);
2392
2393 if (slave == bond->curr_active_slave)
2394 goto do_failover;
2395
2396 continue;
2397
2398 default:
2399 printk(KERN_ERR DRV_NAME
2400 ": %s: invalid new link %d on slave %s\n",
2401 bond->dev->name, slave->new_link,
2402 slave->dev->name);
2403 slave->new_link = BOND_LINK_NOCHANGE;
2404
2405 continue;
2406 }
2407
2408do_failover:
2409 ASSERT_RTNL();
2410 write_lock_bh(&bond->curr_slave_lock);
2411 bond_select_active_slave(bond);
2412 write_unlock_bh(&bond->curr_slave_lock);
2413 }
2414
2415 bond_set_carrier(bond);
2471} 2416}
2472 2417
2473/* 2418/*
2474 * bond_mii_monitor 2419 * bond_mii_monitor
2475 * 2420 *
2476 * Really a wrapper that splits the mii monitor into two phases: an 2421 * Really a wrapper that splits the mii monitor into two phases: an
2477 * inspection, then (if inspection indicates something needs to be 2422 * inspection, then (if inspection indicates something needs to be done)
2478 * done) an acquisition of appropriate locks followed by another pass 2423 * an acquisition of appropriate locks followed by a commit phase to
2479 * to implement whatever link state changes are indicated. 2424 * implement whatever link state changes are indicated.
2480 */ 2425 */
2481void bond_mii_monitor(struct work_struct *work) 2426void bond_mii_monitor(struct work_struct *work)
2482{ 2427{
2483 struct bonding *bond = container_of(work, struct bonding, 2428 struct bonding *bond = container_of(work, struct bonding,
2484 mii_work.work); 2429 mii_work.work);
2485 unsigned long delay;
2486 2430
2487 read_lock(&bond->lock); 2431 read_lock(&bond->lock);
2488 if (bond->kill_timers) { 2432 if (bond->kill_timers)
2489 read_unlock(&bond->lock); 2433 goto out;
2490 return; 2434
2491 } 2435 if (bond->slave_cnt == 0)
2436 goto re_arm;
2492 2437
2493 if (bond->send_grat_arp) { 2438 if (bond->send_grat_arp) {
2494 read_lock(&bond->curr_slave_lock); 2439 read_lock(&bond->curr_slave_lock);
@@ -2496,19 +2441,24 @@ void bond_mii_monitor(struct work_struct *work)
2496 read_unlock(&bond->curr_slave_lock); 2441 read_unlock(&bond->curr_slave_lock);
2497 } 2442 }
2498 2443
2499 if (__bond_mii_monitor(bond, 0)) { 2444 if (bond_miimon_inspect(bond)) {
2500 read_unlock(&bond->lock); 2445 read_unlock(&bond->lock);
2501 rtnl_lock(); 2446 rtnl_lock();
2502 read_lock(&bond->lock); 2447 read_lock(&bond->lock);
2503 __bond_mii_monitor(bond, 1); 2448
2449 bond_miimon_commit(bond);
2450
2504 read_unlock(&bond->lock); 2451 read_unlock(&bond->lock);
2505 rtnl_unlock(); /* might sleep, hold no other locks */ 2452 rtnl_unlock(); /* might sleep, hold no other locks */
2506 read_lock(&bond->lock); 2453 read_lock(&bond->lock);
2507 } 2454 }
2508 2455
2509 delay = msecs_to_jiffies(bond->params.miimon); 2456re_arm:
2457 if (bond->params.miimon)
2458 queue_delayed_work(bond->wq, &bond->mii_work,
2459 msecs_to_jiffies(bond->params.miimon));
2460out:
2510 read_unlock(&bond->lock); 2461 read_unlock(&bond->lock);
2511 queue_delayed_work(bond->wq, &bond->mii_work, delay);
2512} 2462}
2513 2463
2514static __be32 bond_glean_dev_ip(struct net_device *dev) 2464static __be32 bond_glean_dev_ip(struct net_device *dev)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6caac0ffb2f2..3bdb47382521 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -350,9 +350,6 @@ static ssize_t bonding_store_slaves(struct device *d,
350 if (dev) { 350 if (dev) {
351 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n", 351 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
352 bond->dev->name, dev->name); 352 bond->dev->name, dev->name);
353 if (bond->setup_by_slave)
354 res = bond_release_and_destroy(bond->dev, dev);
355 else
356 res = bond_release(bond->dev, dev); 353 res = bond_release(bond->dev, dev);
357 if (res) { 354 if (res) {
358 ret = res; 355 ret = res;
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index a7800e559090..ec6b0af3d46b 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -26,7 +26,6 @@
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/version.h>
30 29
31#include <linux/netdevice.h> 30#include <linux/netdevice.h>
32#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index fba87abe78ee..ea6144a9565e 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -189,7 +189,7 @@ static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT
189static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; 189static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
190#elif defined(CONFIG_ARCH_PNX010X) 190#elif defined(CONFIG_ARCH_PNX010X)
191#include <asm/irq.h> 191#include <asm/irq.h>
192#include <asm/arch/gpio.h> 192#include <mach/gpio.h>
193#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */ 193#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */
194#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */ 194#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
195static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0}; 195static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
index 3f5190c654cf..d454e143483e 100644
--- a/drivers/net/de620.c
+++ b/drivers/net/de620.c
@@ -488,13 +488,6 @@ static void de620_set_multicast_list(struct net_device *dev)
488{ 488{
489 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 489 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
490 { /* Enable promiscuous mode */ 490 { /* Enable promiscuous mode */
491 /*
492 * We must make the kernel realise we had to move
493 * into promisc mode or we start all out war on
494 * the cable. - AC
495 */
496 dev->flags|=IFF_PROMISC;
497
498 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL); 491 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
499 } 492 }
500 else 493 else
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 0b0f1c407a7e..f42c23f42652 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1374,6 +1374,11 @@ dm9000_probe(struct platform_device *pdev)
1374 for (i = 0; i < 6; i += 2) 1374 for (i = 0; i < 6; i += 2)
1375 dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i); 1375 dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
1376 1376
1377 if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
1378 mac_src = "platform data";
1379 memcpy(ndev->dev_addr, pdata->dev_addr, 6);
1380 }
1381
1377 if (!is_valid_ether_addr(ndev->dev_addr)) { 1382 if (!is_valid_ether_addr(ndev->dev_addr)) {
1378 /* try reading from mac */ 1383 /* try reading from mac */
1379 1384
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index f823b8ba5785..14b0e6cd3b8d 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -389,7 +389,7 @@
389 389
390/* Interrupt Cause Set */ 390/* Interrupt Cause Set */
391#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ 391#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
392#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ 392#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* Rx sequence error */
393#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */ 393#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* Rx desc min. threshold */
394 394
395/* Transmit Descriptor Control */ 395/* Transmit Descriptor Control */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 4a4f62e002b2..ac4e506b4f88 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -41,24 +41,25 @@
41 41
42struct e1000_info; 42struct e1000_info;
43 43
44#define ndev_printk(level, netdev, format, arg...) \ 44#define e_printk(level, adapter, format, arg...) \
45 printk(level "%s: " format, (netdev)->name, ## arg) 45 printk(level "%s: %s: " format, pci_name(adapter->pdev), \
46 adapter->netdev->name, ## arg)
46 47
47#ifdef DEBUG 48#ifdef DEBUG
48#define ndev_dbg(netdev, format, arg...) \ 49#define e_dbg(format, arg...) \
49 ndev_printk(KERN_DEBUG , netdev, format, ## arg) 50 e_printk(KERN_DEBUG , adapter, format, ## arg)
50#else 51#else
51#define ndev_dbg(netdev, format, arg...) do { (void)(netdev); } while (0) 52#define e_dbg(format, arg...) do { (void)(adapter); } while (0)
52#endif 53#endif
53 54
54#define ndev_err(netdev, format, arg...) \ 55#define e_err(format, arg...) \
55 ndev_printk(KERN_ERR , netdev, format, ## arg) 56 e_printk(KERN_ERR, adapter, format, ## arg)
56#define ndev_info(netdev, format, arg...) \ 57#define e_info(format, arg...) \
57 ndev_printk(KERN_INFO , netdev, format, ## arg) 58 e_printk(KERN_INFO, adapter, format, ## arg)
58#define ndev_warn(netdev, format, arg...) \ 59#define e_warn(format, arg...) \
59 ndev_printk(KERN_WARNING , netdev, format, ## arg) 60 e_printk(KERN_WARNING, adapter, format, ## arg)
60#define ndev_notice(netdev, format, arg...) \ 61#define e_notice(format, arg...) \
61 ndev_printk(KERN_NOTICE , netdev, format, ## arg) 62 e_printk(KERN_NOTICE, adapter, format, ## arg)
62 63
63 64
64/* Tx/Rx descriptor defines */ 65/* Tx/Rx descriptor defines */
@@ -283,10 +284,6 @@ struct e1000_adapter {
283 unsigned long led_status; 284 unsigned long led_status;
284 285
285 unsigned int flags; 286 unsigned int flags;
286
287 /* for ioport free */
288 int bars;
289 int need_ioport;
290}; 287};
291 288
292struct e1000_info { 289struct e1000_info {
@@ -329,6 +326,7 @@ struct e1000_info {
329#define FLAG_RX_CSUM_ENABLED (1 << 28) 326#define FLAG_RX_CSUM_ENABLED (1 << 28)
330#define FLAG_TSO_FORCE (1 << 29) 327#define FLAG_TSO_FORCE (1 << 29)
331#define FLAG_RX_RESTART_NOW (1 << 30) 328#define FLAG_RX_RESTART_NOW (1 << 30)
329#define FLAG_MSI_TEST_FAILED (1 << 31)
332 330
333#define E1000_RX_DESC_PS(R, i) \ 331#define E1000_RX_DESC_PS(R, i) \
334 (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) 332 (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 9350564065e7..e21c9e0f3738 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -177,7 +177,7 @@ static u32 e1000_get_link(struct net_device *netdev)
177 u32 status; 177 u32 status;
178 178
179 status = er32(STATUS); 179 status = er32(STATUS);
180 return (status & E1000_STATUS_LU); 180 return (status & E1000_STATUS_LU) ? 1 : 0;
181} 181}
182 182
183static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) 183static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
@@ -189,8 +189,7 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
189 /* Fiber NICs only allow 1000 gbps Full duplex */ 189 /* Fiber NICs only allow 1000 gbps Full duplex */
190 if ((adapter->hw.phy.media_type == e1000_media_type_fiber) && 190 if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
191 spddplx != (SPEED_1000 + DUPLEX_FULL)) { 191 spddplx != (SPEED_1000 + DUPLEX_FULL)) {
192 ndev_err(adapter->netdev, "Unsupported Speed/Duplex " 192 e_err("Unsupported Speed/Duplex configuration\n");
193 "configuration\n");
194 return -EINVAL; 193 return -EINVAL;
195 } 194 }
196 195
@@ -213,8 +212,7 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
213 break; 212 break;
214 case SPEED_1000 + DUPLEX_HALF: /* not supported */ 213 case SPEED_1000 + DUPLEX_HALF: /* not supported */
215 default: 214 default:
216 ndev_err(adapter->netdev, "Unsupported Speed/Duplex " 215 e_err("Unsupported Speed/Duplex configuration\n");
217 "configuration\n");
218 return -EINVAL; 216 return -EINVAL;
219 } 217 }
220 return 0; 218 return 0;
@@ -231,8 +229,8 @@ static int e1000_set_settings(struct net_device *netdev,
231 * cannot be changed 229 * cannot be changed
232 */ 230 */
233 if (e1000_check_reset_block(hw)) { 231 if (e1000_check_reset_block(hw)) {
234 ndev_err(netdev, "Cannot change link " 232 e_err("Cannot change link characteristics when SoL/IDER is "
235 "characteristics when SoL/IDER is active.\n"); 233 "active.\n");
236 return -EINVAL; 234 return -EINVAL;
237 } 235 }
238 236
@@ -380,8 +378,7 @@ static int e1000_set_tso(struct net_device *netdev, u32 data)
380 netdev->features &= ~NETIF_F_TSO6; 378 netdev->features &= ~NETIF_F_TSO6;
381 } 379 }
382 380
383 ndev_info(netdev, "TSO is %s\n", 381 e_info("TSO is %s\n", data ? "Enabled" : "Disabled");
384 data ? "Enabled" : "Disabled");
385 adapter->flags |= FLAG_TSO_FORCE; 382 adapter->flags |= FLAG_TSO_FORCE;
386 return 0; 383 return 0;
387} 384}
@@ -722,10 +719,9 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data,
722 (test[pat] & write)); 719 (test[pat] & write));
723 val = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset); 720 val = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset);
724 if (val != (test[pat] & write & mask)) { 721 if (val != (test[pat] & write & mask)) {
725 ndev_err(adapter->netdev, "pattern test reg %04X " 722 e_err("pattern test reg %04X failed: got 0x%08X "
726 "failed: got 0x%08X expected 0x%08X\n", 723 "expected 0x%08X\n", reg + offset, val,
727 reg + offset, 724 (test[pat] & write & mask));
728 val, (test[pat] & write & mask));
729 *data = reg; 725 *data = reg;
730 return 1; 726 return 1;
731 } 727 }
@@ -740,9 +736,8 @@ static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
740 __ew32(&adapter->hw, reg, write & mask); 736 __ew32(&adapter->hw, reg, write & mask);
741 val = __er32(&adapter->hw, reg); 737 val = __er32(&adapter->hw, reg);
742 if ((write & mask) != (val & mask)) { 738 if ((write & mask) != (val & mask)) {
743 ndev_err(adapter->netdev, "set/check reg %04X test failed: " 739 e_err("set/check reg %04X test failed: got 0x%08X "
744 "got 0x%08X expected 0x%08X\n", reg, (val & mask), 740 "expected 0x%08X\n", reg, (val & mask), (write & mask));
745 (write & mask));
746 *data = reg; 741 *data = reg;
747 return 1; 742 return 1;
748 } 743 }
@@ -766,7 +761,6 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
766{ 761{
767 struct e1000_hw *hw = &adapter->hw; 762 struct e1000_hw *hw = &adapter->hw;
768 struct e1000_mac_info *mac = &adapter->hw.mac; 763 struct e1000_mac_info *mac = &adapter->hw.mac;
769 struct net_device *netdev = adapter->netdev;
770 u32 value; 764 u32 value;
771 u32 before; 765 u32 before;
772 u32 after; 766 u32 after;
@@ -799,8 +793,8 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
799 ew32(STATUS, toggle); 793 ew32(STATUS, toggle);
800 after = er32(STATUS) & toggle; 794 after = er32(STATUS) & toggle;
801 if (value != after) { 795 if (value != after) {
802 ndev_err(netdev, "failed STATUS register test got: " 796 e_err("failed STATUS register test got: 0x%08X expected: "
803 "0x%08X expected: 0x%08X\n", after, value); 797 "0x%08X\n", after, value);
804 *data = 1; 798 *data = 1;
805 return 1; 799 return 1;
806 } 800 }
@@ -903,8 +897,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
903 *data = 1; 897 *data = 1;
904 return -1; 898 return -1;
905 } 899 }
906 ndev_info(netdev, "testing %s interrupt\n", 900 e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared"));
907 (shared_int ? "shared" : "unshared"));
908 901
909 /* Disable all the interrupts */ 902 /* Disable all the interrupts */
910 ew32(IMC, 0xFFFFFFFF); 903 ew32(IMC, 0xFFFFFFFF);
@@ -1526,8 +1519,7 @@ static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
1526 * sessions are active 1519 * sessions are active
1527 */ 1520 */
1528 if (e1000_check_reset_block(&adapter->hw)) { 1521 if (e1000_check_reset_block(&adapter->hw)) {
1529 ndev_err(adapter->netdev, "Cannot do PHY loopback test " 1522 e_err("Cannot do PHY loopback test when SoL/IDER is active.\n");
1530 "when SoL/IDER is active.\n");
1531 *data = 0; 1523 *data = 0;
1532 goto out; 1524 goto out;
1533 } 1525 }
@@ -1612,7 +1604,7 @@ static void e1000_diag_test(struct net_device *netdev,
1612 forced_speed_duplex = adapter->hw.mac.forced_speed_duplex; 1604 forced_speed_duplex = adapter->hw.mac.forced_speed_duplex;
1613 autoneg = adapter->hw.mac.autoneg; 1605 autoneg = adapter->hw.mac.autoneg;
1614 1606
1615 ndev_info(netdev, "offline testing starting\n"); 1607 e_info("offline testing starting\n");
1616 1608
1617 /* 1609 /*
1618 * Link test performed before hardware reset so autoneg doesn't 1610 * Link test performed before hardware reset so autoneg doesn't
@@ -1658,7 +1650,7 @@ static void e1000_diag_test(struct net_device *netdev,
1658 if (if_running) 1650 if (if_running)
1659 dev_open(netdev); 1651 dev_open(netdev);
1660 } else { 1652 } else {
1661 ndev_info(netdev, "online testing starting\n"); 1653 e_info("online testing starting\n");
1662 /* Online tests */ 1654 /* Online tests */
1663 if (e1000_link_test(adapter, &data[4])) 1655 if (e1000_link_test(adapter, &data[4]))
1664 eth_test->flags |= ETH_TEST_FL_FAILED; 1656 eth_test->flags |= ETH_TEST_FL_FAILED;
@@ -1694,8 +1686,8 @@ static void e1000_get_wol(struct net_device *netdev,
1694 wol->supported &= ~WAKE_UCAST; 1686 wol->supported &= ~WAKE_UCAST;
1695 1687
1696 if (adapter->wol & E1000_WUFC_EX) 1688 if (adapter->wol & E1000_WUFC_EX)
1697 ndev_err(netdev, "Interface does not support " 1689 e_err("Interface does not support directed (unicast) "
1698 "directed (unicast) frame wake-up packets\n"); 1690 "frame wake-up packets\n");
1699 } 1691 }
1700 1692
1701 if (adapter->wol & E1000_WUFC_EX) 1693 if (adapter->wol & E1000_WUFC_EX)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index d13677899767..d266510c8a94 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -484,8 +484,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
484 * packet, also make sure the frame isn't just CRC only */ 484 * packet, also make sure the frame isn't just CRC only */
485 if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) { 485 if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) {
486 /* All receives must fit into a single buffer */ 486 /* All receives must fit into a single buffer */
487 ndev_dbg(netdev, "%s: Receive packet consumed " 487 e_dbg("%s: Receive packet consumed multiple buffers\n",
488 "multiple buffers\n", netdev->name); 488 netdev->name);
489 /* recycle */ 489 /* recycle */
490 buffer_info->skb = skb; 490 buffer_info->skb = skb;
491 goto next_desc; 491 goto next_desc;
@@ -510,9 +510,12 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
510 netdev_alloc_skb(netdev, length + NET_IP_ALIGN); 510 netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
511 if (new_skb) { 511 if (new_skb) {
512 skb_reserve(new_skb, NET_IP_ALIGN); 512 skb_reserve(new_skb, NET_IP_ALIGN);
513 memcpy(new_skb->data - NET_IP_ALIGN, 513 skb_copy_to_linear_data_offset(new_skb,
514 skb->data - NET_IP_ALIGN, 514 -NET_IP_ALIGN,
515 length + NET_IP_ALIGN); 515 (skb->data -
516 NET_IP_ALIGN),
517 (length +
518 NET_IP_ALIGN));
516 /* save the skb in buffer_info as good */ 519 /* save the skb in buffer_info as good */
517 buffer_info->skb = skb; 520 buffer_info->skb = skb;
518 skb = new_skb; 521 skb = new_skb;
@@ -576,28 +579,26 @@ static void e1000_print_tx_hang(struct e1000_adapter *adapter)
576 unsigned int i = tx_ring->next_to_clean; 579 unsigned int i = tx_ring->next_to_clean;
577 unsigned int eop = tx_ring->buffer_info[i].next_to_watch; 580 unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
578 struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop); 581 struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
579 struct net_device *netdev = adapter->netdev;
580 582
581 /* detected Tx unit hang */ 583 /* detected Tx unit hang */
582 ndev_err(netdev, 584 e_err("Detected Tx Unit Hang:\n"
583 "Detected Tx Unit Hang:\n" 585 " TDH <%x>\n"
584 " TDH <%x>\n" 586 " TDT <%x>\n"
585 " TDT <%x>\n" 587 " next_to_use <%x>\n"
586 " next_to_use <%x>\n" 588 " next_to_clean <%x>\n"
587 " next_to_clean <%x>\n" 589 "buffer_info[next_to_clean]:\n"
588 "buffer_info[next_to_clean]:\n" 590 " time_stamp <%lx>\n"
589 " time_stamp <%lx>\n" 591 " next_to_watch <%x>\n"
590 " next_to_watch <%x>\n" 592 " jiffies <%lx>\n"
591 " jiffies <%lx>\n" 593 " next_to_watch.status <%x>\n",
592 " next_to_watch.status <%x>\n", 594 readl(adapter->hw.hw_addr + tx_ring->head),
593 readl(adapter->hw.hw_addr + tx_ring->head), 595 readl(adapter->hw.hw_addr + tx_ring->tail),
594 readl(adapter->hw.hw_addr + tx_ring->tail), 596 tx_ring->next_to_use,
595 tx_ring->next_to_use, 597 tx_ring->next_to_clean,
596 tx_ring->next_to_clean, 598 tx_ring->buffer_info[eop].time_stamp,
597 tx_ring->buffer_info[eop].time_stamp, 599 eop,
598 eop, 600 jiffies,
599 jiffies, 601 eop_desc->upper.fields.status);
600 eop_desc->upper.fields.status);
601} 602}
602 603
603/** 604/**
@@ -747,8 +748,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
747 buffer_info->dma = 0; 748 buffer_info->dma = 0;
748 749
749 if (!(staterr & E1000_RXD_STAT_EOP)) { 750 if (!(staterr & E1000_RXD_STAT_EOP)) {
750 ndev_dbg(netdev, "%s: Packet Split buffers didn't pick " 751 e_dbg("%s: Packet Split buffers didn't pick up the "
751 "up the full packet\n", netdev->name); 752 "full packet\n", netdev->name);
752 dev_kfree_skb_irq(skb); 753 dev_kfree_skb_irq(skb);
753 goto next_desc; 754 goto next_desc;
754 } 755 }
@@ -761,8 +762,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
761 length = le16_to_cpu(rx_desc->wb.middle.length0); 762 length = le16_to_cpu(rx_desc->wb.middle.length0);
762 763
763 if (!length) { 764 if (!length) {
764 ndev_dbg(netdev, "%s: Last part of the packet spanning" 765 e_dbg("%s: Last part of the packet spanning multiple "
765 " multiple descriptors\n", netdev->name); 766 "descriptors\n", netdev->name);
766 dev_kfree_skb_irq(skb); 767 dev_kfree_skb_irq(skb);
767 goto next_desc; 768 goto next_desc;
768 } 769 }
@@ -1011,7 +1012,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
1011 1012
1012 /* eth type trans needs skb->data to point to something */ 1013 /* eth type trans needs skb->data to point to something */
1013 if (!pskb_may_pull(skb, ETH_HLEN)) { 1014 if (!pskb_may_pull(skb, ETH_HLEN)) {
1014 ndev_err(netdev, "pskb_may_pull failed.\n"); 1015 e_err("pskb_may_pull failed.\n");
1015 dev_kfree_skb(skb); 1016 dev_kfree_skb(skb);
1016 goto next_desc; 1017 goto next_desc;
1017 } 1018 }
@@ -1235,28 +1236,36 @@ static irqreturn_t e1000_intr(int irq, void *data)
1235 return IRQ_HANDLED; 1236 return IRQ_HANDLED;
1236} 1237}
1237 1238
1239/**
1240 * e1000_request_irq - initialize interrupts
1241 *
1242 * Attempts to configure interrupts using the best available
1243 * capabilities of the hardware and kernel.
1244 **/
1238static int e1000_request_irq(struct e1000_adapter *adapter) 1245static int e1000_request_irq(struct e1000_adapter *adapter)
1239{ 1246{
1240 struct net_device *netdev = adapter->netdev; 1247 struct net_device *netdev = adapter->netdev;
1241 irq_handler_t handler = e1000_intr;
1242 int irq_flags = IRQF_SHARED; 1248 int irq_flags = IRQF_SHARED;
1243 int err; 1249 int err;
1244 1250
1245 if (!pci_enable_msi(adapter->pdev)) { 1251 if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) {
1246 adapter->flags |= FLAG_MSI_ENABLED; 1252 err = pci_enable_msi(adapter->pdev);
1247 handler = e1000_intr_msi; 1253 if (!err) {
1248 irq_flags = 0; 1254 adapter->flags |= FLAG_MSI_ENABLED;
1255 irq_flags = 0;
1256 }
1249 } 1257 }
1250 1258
1251 err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name, 1259 err = request_irq(adapter->pdev->irq,
1252 netdev); 1260 ((adapter->flags & FLAG_MSI_ENABLED) ?
1261 &e1000_intr_msi : &e1000_intr),
1262 irq_flags, netdev->name, netdev);
1253 if (err) { 1263 if (err) {
1254 ndev_err(netdev, 1264 if (adapter->flags & FLAG_MSI_ENABLED) {
1255 "Unable to allocate %s interrupt (return: %d)\n",
1256 adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx",
1257 err);
1258 if (adapter->flags & FLAG_MSI_ENABLED)
1259 pci_disable_msi(adapter->pdev); 1265 pci_disable_msi(adapter->pdev);
1266 adapter->flags &= ~FLAG_MSI_ENABLED;
1267 }
1268 e_err("Unable to allocate interrupt, Error: %d\n", err);
1260 } 1269 }
1261 1270
1262 return err; 1271 return err;
@@ -1395,8 +1404,7 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
1395 return 0; 1404 return 0;
1396err: 1405err:
1397 vfree(tx_ring->buffer_info); 1406 vfree(tx_ring->buffer_info);
1398 ndev_err(adapter->netdev, 1407 e_err("Unable to allocate memory for the transmit descriptor ring\n");
1399 "Unable to allocate memory for the transmit descriptor ring\n");
1400 return err; 1408 return err;
1401} 1409}
1402 1410
@@ -1450,8 +1458,7 @@ err_pages:
1450 } 1458 }
1451err: 1459err:
1452 vfree(rx_ring->buffer_info); 1460 vfree(rx_ring->buffer_info);
1453 ndev_err(adapter->netdev, 1461 e_err("Unable to allocate memory for the transmit descriptor ring\n");
1454 "Unable to allocate memory for the transmit descriptor ring\n");
1455 return err; 1462 return err;
1456} 1463}
1457 1464
@@ -2450,13 +2457,13 @@ void e1000e_reset(struct e1000_adapter *adapter)
2450 * For parts with AMT enabled, let the firmware know 2457 * For parts with AMT enabled, let the firmware know
2451 * that the network interface is in control 2458 * that the network interface is in control
2452 */ 2459 */
2453 if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw)) 2460 if (adapter->flags & FLAG_HAS_AMT)
2454 e1000_get_hw_control(adapter); 2461 e1000_get_hw_control(adapter);
2455 2462
2456 ew32(WUC, 0); 2463 ew32(WUC, 0);
2457 2464
2458 if (mac->ops.init_hw(hw)) 2465 if (mac->ops.init_hw(hw))
2459 ndev_err(adapter->netdev, "Hardware Error\n"); 2466 e_err("Hardware Error\n");
2460 2467
2461 e1000_update_mng_vlan(adapter); 2468 e1000_update_mng_vlan(adapter);
2462 2469
@@ -2591,13 +2598,142 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
2591 return 0; 2598 return 0;
2592 2599
2593err: 2600err:
2594 ndev_err(netdev, "Unable to allocate memory for queues\n"); 2601 e_err("Unable to allocate memory for queues\n");
2595 kfree(adapter->rx_ring); 2602 kfree(adapter->rx_ring);
2596 kfree(adapter->tx_ring); 2603 kfree(adapter->tx_ring);
2597 return -ENOMEM; 2604 return -ENOMEM;
2598} 2605}
2599 2606
2600/** 2607/**
2608 * e1000_intr_msi_test - Interrupt Handler
2609 * @irq: interrupt number
2610 * @data: pointer to a network interface device structure
2611 **/
2612static irqreturn_t e1000_intr_msi_test(int irq, void *data)
2613{
2614 struct net_device *netdev = data;
2615 struct e1000_adapter *adapter = netdev_priv(netdev);
2616 struct e1000_hw *hw = &adapter->hw;
2617 u32 icr = er32(ICR);
2618
2619 e_dbg("%s: icr is %08X\n", netdev->name, icr);
2620 if (icr & E1000_ICR_RXSEQ) {
2621 adapter->flags &= ~FLAG_MSI_TEST_FAILED;
2622 wmb();
2623 }
2624
2625 return IRQ_HANDLED;
2626}
2627
2628/**
2629 * e1000_test_msi_interrupt - Returns 0 for successful test
2630 * @adapter: board private struct
2631 *
2632 * code flow taken from tg3.c
2633 **/
2634static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
2635{
2636 struct net_device *netdev = adapter->netdev;
2637 struct e1000_hw *hw = &adapter->hw;
2638 int err;
2639
2640 /* poll_enable hasn't been called yet, so don't need disable */
2641 /* clear any pending events */
2642 er32(ICR);
2643
2644 /* free the real vector and request a test handler */
2645 e1000_free_irq(adapter);
2646
2647 /* Assume that the test fails, if it succeeds then the test
2648 * MSI irq handler will unset this flag */
2649 adapter->flags |= FLAG_MSI_TEST_FAILED;
2650
2651 err = pci_enable_msi(adapter->pdev);
2652 if (err)
2653 goto msi_test_failed;
2654
2655 err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
2656 netdev->name, netdev);
2657 if (err) {
2658 pci_disable_msi(adapter->pdev);
2659 goto msi_test_failed;
2660 }
2661
2662 wmb();
2663
2664 e1000_irq_enable(adapter);
2665
2666 /* fire an unusual interrupt on the test handler */
2667 ew32(ICS, E1000_ICS_RXSEQ);
2668 e1e_flush();
2669 msleep(50);
2670
2671 e1000_irq_disable(adapter);
2672
2673 rmb();
2674
2675 if (adapter->flags & FLAG_MSI_TEST_FAILED) {
2676 err = -EIO;
2677 e_info("MSI interrupt test failed!\n");
2678 }
2679
2680 free_irq(adapter->pdev->irq, netdev);
2681 pci_disable_msi(adapter->pdev);
2682
2683 if (err == -EIO)
2684 goto msi_test_failed;
2685
2686 /* okay so the test worked, restore settings */
2687 e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
2688msi_test_failed:
2689 /* restore the original vector, even if it failed */
2690 e1000_request_irq(adapter);
2691 return err;
2692}
2693
2694/**
2695 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
2696 * @adapter: board private struct
2697 *
2698 * code flow taken from tg3.c, called with e1000 interrupts disabled.
2699 **/
2700static int e1000_test_msi(struct e1000_adapter *adapter)
2701{
2702 int err;
2703 u16 pci_cmd;
2704
2705 if (!(adapter->flags & FLAG_MSI_ENABLED))
2706 return 0;
2707
2708 /* disable SERR in case the MSI write causes a master abort */
2709 pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
2710 pci_write_config_word(adapter->pdev, PCI_COMMAND,
2711 pci_cmd & ~PCI_COMMAND_SERR);
2712
2713 err = e1000_test_msi_interrupt(adapter);
2714
2715 /* restore previous setting of command word */
2716 pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
2717
2718 /* success ! */
2719 if (!err)
2720 return 0;
2721
2722 /* EIO means MSI test failed */
2723 if (err != -EIO)
2724 return err;
2725
2726 /* back to INTx mode */
2727 e_warn("MSI interrupt test failed, using legacy interrupt.\n");
2728
2729 e1000_free_irq(adapter);
2730
2731 err = e1000_request_irq(adapter);
2732
2733 return err;
2734}
2735
2736/**
2601 * e1000_open - Called when a network interface is made active 2737 * e1000_open - Called when a network interface is made active
2602 * @netdev: network interface device structure 2738 * @netdev: network interface device structure
2603 * 2739 *
@@ -2640,8 +2776,7 @@ static int e1000_open(struct net_device *netdev)
2640 * If AMT is enabled, let the firmware know that the network 2776 * If AMT is enabled, let the firmware know that the network
2641 * interface is now open 2777 * interface is now open
2642 */ 2778 */
2643 if ((adapter->flags & FLAG_HAS_AMT) && 2779 if (adapter->flags & FLAG_HAS_AMT)
2644 e1000e_check_mng_mode(&adapter->hw))
2645 e1000_get_hw_control(adapter); 2780 e1000_get_hw_control(adapter);
2646 2781
2647 /* 2782 /*
@@ -2656,6 +2791,19 @@ static int e1000_open(struct net_device *netdev)
2656 if (err) 2791 if (err)
2657 goto err_req_irq; 2792 goto err_req_irq;
2658 2793
2794 /*
2795 * Work around PCIe errata with MSI interrupts causing some chipsets to
2796 * ignore e1000e MSI messages, which means we need to test our MSI
2797 * interrupt now
2798 */
2799 {
2800 err = e1000_test_msi(adapter);
2801 if (err) {
2802 e_err("Interrupt allocation failed\n");
2803 goto err_req_irq;
2804 }
2805 }
2806
2659 /* From here on the code is the same as e1000e_up() */ 2807 /* From here on the code is the same as e1000e_up() */
2660 clear_bit(__E1000_DOWN, &adapter->state); 2808 clear_bit(__E1000_DOWN, &adapter->state);
2661 2809
@@ -2719,8 +2867,7 @@ static int e1000_close(struct net_device *netdev)
2719 * If AMT is enabled, let the firmware know that the network 2867 * If AMT is enabled, let the firmware know that the network
2720 * interface is now closed 2868 * interface is now closed
2721 */ 2869 */
2722 if ((adapter->flags & FLAG_HAS_AMT) && 2870 if (adapter->flags & FLAG_HAS_AMT)
2723 e1000e_check_mng_mode(&adapter->hw))
2724 e1000_release_hw_control(adapter); 2871 e1000_release_hw_control(adapter);
2725 2872
2726 return 0; 2873 return 0;
@@ -2917,8 +3064,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
2917 ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000); 3064 ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
2918 ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus); 3065 ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
2919 if (ret_val) 3066 if (ret_val)
2920 ndev_warn(adapter->netdev, 3067 e_warn("Error reading PHY register\n");
2921 "Error reading PHY register\n");
2922 } else { 3068 } else {
2923 /* 3069 /*
2924 * Do not read PHY registers if link is not up 3070 * Do not read PHY registers if link is not up
@@ -2943,18 +3089,16 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
2943static void e1000_print_link_info(struct e1000_adapter *adapter) 3089static void e1000_print_link_info(struct e1000_adapter *adapter)
2944{ 3090{
2945 struct e1000_hw *hw = &adapter->hw; 3091 struct e1000_hw *hw = &adapter->hw;
2946 struct net_device *netdev = adapter->netdev;
2947 u32 ctrl = er32(CTRL); 3092 u32 ctrl = er32(CTRL);
2948 3093
2949 ndev_info(netdev, 3094 e_info("Link is Up %d Mbps %s, Flow Control: %s\n",
2950 "Link is Up %d Mbps %s, Flow Control: %s\n", 3095 adapter->link_speed,
2951 adapter->link_speed, 3096 (adapter->link_duplex == FULL_DUPLEX) ?
2952 (adapter->link_duplex == FULL_DUPLEX) ? 3097 "Full Duplex" : "Half Duplex",
2953 "Full Duplex" : "Half Duplex", 3098 ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
2954 ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? 3099 "RX/TX" :
2955 "RX/TX" : 3100 ((ctrl & E1000_CTRL_RFCE) ? "RX" :
2956 ((ctrl & E1000_CTRL_RFCE) ? "RX" : 3101 ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
2957 ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
2958} 3102}
2959 3103
2960static bool e1000_has_link(struct e1000_adapter *adapter) 3104static bool e1000_has_link(struct e1000_adapter *adapter)
@@ -2994,8 +3138,7 @@ static bool e1000_has_link(struct e1000_adapter *adapter)
2994 if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) && 3138 if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
2995 (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) { 3139 (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
2996 /* See e1000_kmrn_lock_loss_workaround_ich8lan() */ 3140 /* See e1000_kmrn_lock_loss_workaround_ich8lan() */
2997 ndev_info(adapter->netdev, 3141 e_info("Gigabit has been disabled, downgrading speed\n");
2998 "Gigabit has been disabled, downgrading speed\n");
2999 } 3142 }
3000 3143
3001 return link_active; 3144 return link_active;
@@ -3067,7 +3210,7 @@ static void e1000_watchdog_task(struct work_struct *work)
3067 case SPEED_10: 3210 case SPEED_10:
3068 txb2b = 0; 3211 txb2b = 0;
3069 netdev->tx_queue_len = 10; 3212 netdev->tx_queue_len = 10;
3070 adapter->tx_timeout_factor = 14; 3213 adapter->tx_timeout_factor = 16;
3071 break; 3214 break;
3072 case SPEED_100: 3215 case SPEED_100:
3073 txb2b = 0; 3216 txb2b = 0;
@@ -3096,8 +3239,7 @@ static void e1000_watchdog_task(struct work_struct *work)
3096 switch (adapter->link_speed) { 3239 switch (adapter->link_speed) {
3097 case SPEED_10: 3240 case SPEED_10:
3098 case SPEED_100: 3241 case SPEED_100:
3099 ndev_info(netdev, 3242 e_info("10/100 speed: disabling TSO\n");
3100 "10/100 speed: disabling TSO\n");
3101 netdev->features &= ~NETIF_F_TSO; 3243 netdev->features &= ~NETIF_F_TSO;
3102 netdev->features &= ~NETIF_F_TSO6; 3244 netdev->features &= ~NETIF_F_TSO6;
3103 break; 3245 break;
@@ -3130,7 +3272,7 @@ static void e1000_watchdog_task(struct work_struct *work)
3130 if (netif_carrier_ok(netdev)) { 3272 if (netif_carrier_ok(netdev)) {
3131 adapter->link_speed = 0; 3273 adapter->link_speed = 0;
3132 adapter->link_duplex = 0; 3274 adapter->link_duplex = 0;
3133 ndev_info(netdev, "Link is Down\n"); 3275 e_info("Link is Down\n");
3134 netif_carrier_off(netdev); 3276 netif_carrier_off(netdev);
3135 netif_tx_stop_all_queues(netdev); 3277 netif_tx_stop_all_queues(netdev);
3136 if (!test_bit(__E1000_DOWN, &adapter->state)) 3278 if (!test_bit(__E1000_DOWN, &adapter->state))
@@ -3604,8 +3746,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
3604 3746
3605 pull_size = min((unsigned int)4, skb->data_len); 3747 pull_size = min((unsigned int)4, skb->data_len);
3606 if (!__pskb_pull_tail(skb, pull_size)) { 3748 if (!__pskb_pull_tail(skb, pull_size)) {
3607 ndev_err(netdev, 3749 e_err("__pskb_pull_tail failed.\n");
3608 "__pskb_pull_tail failed.\n");
3609 dev_kfree_skb_any(skb); 3750 dev_kfree_skb_any(skb);
3610 return NETDEV_TX_OK; 3751 return NETDEV_TX_OK;
3611 } 3752 }
@@ -3735,27 +3876,27 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
3735 struct e1000_adapter *adapter = netdev_priv(netdev); 3876 struct e1000_adapter *adapter = netdev_priv(netdev);
3736 int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; 3877 int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
3737 3878
3738 if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || 3879 if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
3739 (max_frame > MAX_JUMBO_FRAME_SIZE)) { 3880 (max_frame > MAX_JUMBO_FRAME_SIZE)) {
3740 ndev_err(netdev, "Invalid MTU setting\n"); 3881 e_err("Invalid MTU setting\n");
3741 return -EINVAL; 3882 return -EINVAL;
3742 } 3883 }
3743 3884
3744 /* Jumbo frame size limits */ 3885 /* Jumbo frame size limits */
3745 if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { 3886 if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
3746 if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { 3887 if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
3747 ndev_err(netdev, "Jumbo Frames not supported.\n"); 3888 e_err("Jumbo Frames not supported.\n");
3748 return -EINVAL; 3889 return -EINVAL;
3749 } 3890 }
3750 if (adapter->hw.phy.type == e1000_phy_ife) { 3891 if (adapter->hw.phy.type == e1000_phy_ife) {
3751 ndev_err(netdev, "Jumbo Frames not supported.\n"); 3892 e_err("Jumbo Frames not supported.\n");
3752 return -EINVAL; 3893 return -EINVAL;
3753 } 3894 }
3754 } 3895 }
3755 3896
3756#define MAX_STD_JUMBO_FRAME_SIZE 9234 3897#define MAX_STD_JUMBO_FRAME_SIZE 9234
3757 if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { 3898 if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
3758 ndev_err(netdev, "MTU > 9216 not supported.\n"); 3899 e_err("MTU > 9216 not supported.\n");
3759 return -EINVAL; 3900 return -EINVAL;
3760 } 3901 }
3761 3902
@@ -3792,8 +3933,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
3792 adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN 3933 adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
3793 + ETH_FCS_LEN; 3934 + ETH_FCS_LEN;
3794 3935
3795 ndev_info(netdev, "changing MTU from %d to %d\n", 3936 e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
3796 netdev->mtu, new_mtu);
3797 netdev->mtu = new_mtu; 3937 netdev->mtu = new_mtu;
3798 3938
3799 if (netif_running(netdev)) 3939 if (netif_running(netdev))
@@ -4006,10 +4146,7 @@ static int e1000_resume(struct pci_dev *pdev)
4006 pci_restore_state(pdev); 4146 pci_restore_state(pdev);
4007 e1000e_disable_l1aspm(pdev); 4147 e1000e_disable_l1aspm(pdev);
4008 4148
4009 if (adapter->need_ioport) 4149 err = pci_enable_device_mem(pdev);
4010 err = pci_enable_device(pdev);
4011 else
4012 err = pci_enable_device_mem(pdev);
4013 if (err) { 4150 if (err) {
4014 dev_err(&pdev->dev, 4151 dev_err(&pdev->dev,
4015 "Cannot enable PCI device from suspend\n"); 4152 "Cannot enable PCI device from suspend\n");
@@ -4043,7 +4180,7 @@ static int e1000_resume(struct pci_dev *pdev)
4043 * is up. For all other cases, let the f/w know that the h/w is now 4180 * is up. For all other cases, let the f/w know that the h/w is now
4044 * under the control of the driver. 4181 * under the control of the driver.
4045 */ 4182 */
4046 if (!(adapter->flags & FLAG_HAS_AMT) || !e1000e_check_mng_mode(&adapter->hw)) 4183 if (!(adapter->flags & FLAG_HAS_AMT))
4047 e1000_get_hw_control(adapter); 4184 e1000_get_hw_control(adapter);
4048 4185
4049 return 0; 4186 return 0;
@@ -4111,10 +4248,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
4111 int err; 4248 int err;
4112 4249
4113 e1000e_disable_l1aspm(pdev); 4250 e1000e_disable_l1aspm(pdev);
4114 if (adapter->need_ioport) 4251 err = pci_enable_device_mem(pdev);
4115 err = pci_enable_device(pdev);
4116 else
4117 err = pci_enable_device_mem(pdev);
4118 if (err) { 4252 if (err) {
4119 dev_err(&pdev->dev, 4253 dev_err(&pdev->dev,
4120 "Cannot re-enable PCI device after reset.\n"); 4254 "Cannot re-enable PCI device after reset.\n");
@@ -4162,8 +4296,7 @@ static void e1000_io_resume(struct pci_dev *pdev)
4162 * is up. For all other cases, let the f/w know that the h/w is now 4296 * is up. For all other cases, let the f/w know that the h/w is now
4163 * under the control of the driver. 4297 * under the control of the driver.
4164 */ 4298 */
4165 if (!(adapter->flags & FLAG_HAS_AMT) || 4299 if (!(adapter->flags & FLAG_HAS_AMT))
4166 !e1000e_check_mng_mode(&adapter->hw))
4167 e1000_get_hw_control(adapter); 4300 e1000_get_hw_control(adapter);
4168 4301
4169} 4302}
@@ -4175,36 +4308,40 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
4175 u32 pba_num; 4308 u32 pba_num;
4176 4309
4177 /* print bus type/speed/width info */ 4310 /* print bus type/speed/width info */
4178 ndev_info(netdev, "(PCI Express:2.5GB/s:%s) " 4311 e_info("(PCI Express:2.5GB/s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
4179 "%02x:%02x:%02x:%02x:%02x:%02x\n", 4312 /* bus width */
4180 /* bus width */ 4313 ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
4181 ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : 4314 "Width x1"),
4182 "Width x1"), 4315 /* MAC address */
4183 /* MAC address */ 4316 netdev->dev_addr[0], netdev->dev_addr[1],
4184 netdev->dev_addr[0], netdev->dev_addr[1], 4317 netdev->dev_addr[2], netdev->dev_addr[3],
4185 netdev->dev_addr[2], netdev->dev_addr[3], 4318 netdev->dev_addr[4], netdev->dev_addr[5]);
4186 netdev->dev_addr[4], netdev->dev_addr[5]); 4319 e_info("Intel(R) PRO/%s Network Connection\n",
4187 ndev_info(netdev, "Intel(R) PRO/%s Network Connection\n", 4320 (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
4188 (hw->phy.type == e1000_phy_ife)
4189 ? "10/100" : "1000");
4190 e1000e_read_pba_num(hw, &pba_num); 4321 e1000e_read_pba_num(hw, &pba_num);
4191 ndev_info(netdev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n", 4322 e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
4192 hw->mac.type, hw->phy.type, 4323 hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));
4193 (pba_num >> 8), (pba_num & 0xff));
4194} 4324}
4195 4325
4196/** 4326static void e1000_eeprom_checks(struct e1000_adapter *adapter)
4197 * e1000e_is_need_ioport - determine if an adapter needs ioport resources or not
4198 * @pdev: PCI device information struct
4199 *
4200 * Returns true if an adapters needs ioport resources
4201 **/
4202static int e1000e_is_need_ioport(struct pci_dev *pdev)
4203{ 4327{
4204 switch (pdev->device) { 4328 struct e1000_hw *hw = &adapter->hw;
4205 /* Currently there are no adapters that need ioport resources */ 4329 int ret_val;
4206 default: 4330 u16 buf = 0;
4207 return false; 4331
4332 if (hw->mac.type != e1000_82573)
4333 return;
4334
4335 ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
4336 if (!(le16_to_cpu(buf) & (1 << 0))) {
4337 /* Deep Smart Power Down (DSPD) */
4338 e_warn("Warning: detected DSPD enabled in EEPROM\n");
4339 }
4340
4341 ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
4342 if (le16_to_cpu(buf) & (3 << 2)) {
4343 /* ASPM enable */
4344 e_warn("Warning: detected ASPM enabled in EEPROM\n");
4208 } 4345 }
4209} 4346}
4210 4347
@@ -4233,19 +4370,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4233 int i, err, pci_using_dac; 4370 int i, err, pci_using_dac;
4234 u16 eeprom_data = 0; 4371 u16 eeprom_data = 0;
4235 u16 eeprom_apme_mask = E1000_EEPROM_APME; 4372 u16 eeprom_apme_mask = E1000_EEPROM_APME;
4236 int bars, need_ioport;
4237 4373
4238 e1000e_disable_l1aspm(pdev); 4374 e1000e_disable_l1aspm(pdev);
4239 4375
4240 /* do not allocate ioport bars when not needed */ 4376 err = pci_enable_device_mem(pdev);
4241 need_ioport = e1000e_is_need_ioport(pdev);
4242 if (need_ioport) {
4243 bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
4244 err = pci_enable_device(pdev);
4245 } else {
4246 bars = pci_select_bars(pdev, IORESOURCE_MEM);
4247 err = pci_enable_device_mem(pdev);
4248 }
4249 if (err) 4377 if (err)
4250 return err; 4378 return err;
4251 4379
@@ -4268,7 +4396,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4268 } 4396 }
4269 } 4397 }
4270 4398
4271 err = pci_request_selected_regions(pdev, bars, e1000e_driver_name); 4399 err = pci_request_selected_regions(pdev,
4400 pci_select_bars(pdev, IORESOURCE_MEM),
4401 e1000e_driver_name);
4272 if (err) 4402 if (err)
4273 goto err_pci_reg; 4403 goto err_pci_reg;
4274 4404
@@ -4293,8 +4423,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4293 adapter->hw.adapter = adapter; 4423 adapter->hw.adapter = adapter;
4294 adapter->hw.mac.type = ei->mac; 4424 adapter->hw.mac.type = ei->mac;
4295 adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; 4425 adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
4296 adapter->bars = bars;
4297 adapter->need_ioport = need_ioport;
4298 4426
4299 mmio_start = pci_resource_start(pdev, 0); 4427 mmio_start = pci_resource_start(pdev, 0);
4300 mmio_len = pci_resource_len(pdev, 0); 4428 mmio_len = pci_resource_len(pdev, 0);
@@ -4366,8 +4494,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4366 } 4494 }
4367 4495
4368 if (e1000_check_reset_block(&adapter->hw)) 4496 if (e1000_check_reset_block(&adapter->hw))
4369 ndev_info(netdev, 4497 e_info("PHY reset is blocked due to SOL/IDER session.\n");
4370 "PHY reset is blocked due to SOL/IDER session.\n");
4371 4498
4372 netdev->features = NETIF_F_SG | 4499 netdev->features = NETIF_F_SG |
4373 NETIF_F_HW_CSUM | 4500 NETIF_F_HW_CSUM |
@@ -4411,25 +4538,26 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4411 if (e1000_validate_nvm_checksum(&adapter->hw) >= 0) 4538 if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
4412 break; 4539 break;
4413 if (i == 2) { 4540 if (i == 2) {
4414 ndev_err(netdev, "The NVM Checksum Is Not Valid\n"); 4541 e_err("The NVM Checksum Is Not Valid\n");
4415 err = -EIO; 4542 err = -EIO;
4416 goto err_eeprom; 4543 goto err_eeprom;
4417 } 4544 }
4418 } 4545 }
4419 4546
4547 e1000_eeprom_checks(adapter);
4548
4420 /* copy the MAC address out of the NVM */ 4549 /* copy the MAC address out of the NVM */
4421 if (e1000e_read_mac_addr(&adapter->hw)) 4550 if (e1000e_read_mac_addr(&adapter->hw))
4422 ndev_err(netdev, "NVM Read Error while reading MAC address\n"); 4551 e_err("NVM Read Error while reading MAC address\n");
4423 4552
4424 memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); 4553 memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
4425 memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); 4554 memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
4426 4555
4427 if (!is_valid_ether_addr(netdev->perm_addr)) { 4556 if (!is_valid_ether_addr(netdev->perm_addr)) {
4428 ndev_err(netdev, "Invalid MAC Address: " 4557 e_err("Invalid MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
4429 "%02x:%02x:%02x:%02x:%02x:%02x\n", 4558 netdev->perm_addr[0], netdev->perm_addr[1],
4430 netdev->perm_addr[0], netdev->perm_addr[1], 4559 netdev->perm_addr[2], netdev->perm_addr[3],
4431 netdev->perm_addr[2], netdev->perm_addr[3], 4560 netdev->perm_addr[4], netdev->perm_addr[5]);
4432 netdev->perm_addr[4], netdev->perm_addr[5]);
4433 err = -EIO; 4561 err = -EIO;
4434 goto err_eeprom; 4562 goto err_eeprom;
4435 } 4563 }
@@ -4499,8 +4627,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4499 * is up. For all other cases, let the f/w know that the h/w is now 4627 * is up. For all other cases, let the f/w know that the h/w is now
4500 * under the control of the driver. 4628 * under the control of the driver.
4501 */ 4629 */
4502 if (!(adapter->flags & FLAG_HAS_AMT) || 4630 if (!(adapter->flags & FLAG_HAS_AMT))
4503 !e1000e_check_mng_mode(&adapter->hw))
4504 e1000_get_hw_control(adapter); 4631 e1000_get_hw_control(adapter);
4505 4632
4506 /* tell the stack to leave us alone until e1000_open() is called */ 4633 /* tell the stack to leave us alone until e1000_open() is called */
@@ -4517,24 +4644,25 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4517 return 0; 4644 return 0;
4518 4645
4519err_register: 4646err_register:
4520err_hw_init: 4647 if (!(adapter->flags & FLAG_HAS_AMT))
4521 e1000_release_hw_control(adapter); 4648 e1000_release_hw_control(adapter);
4522err_eeprom: 4649err_eeprom:
4523 if (!e1000_check_reset_block(&adapter->hw)) 4650 if (!e1000_check_reset_block(&adapter->hw))
4524 e1000_phy_hw_reset(&adapter->hw); 4651 e1000_phy_hw_reset(&adapter->hw);
4652err_hw_init:
4525 4653
4526 if (adapter->hw.flash_address)
4527 iounmap(adapter->hw.flash_address);
4528
4529err_flashmap:
4530 kfree(adapter->tx_ring); 4654 kfree(adapter->tx_ring);
4531 kfree(adapter->rx_ring); 4655 kfree(adapter->rx_ring);
4532err_sw_init: 4656err_sw_init:
4657 if (adapter->hw.flash_address)
4658 iounmap(adapter->hw.flash_address);
4659err_flashmap:
4533 iounmap(adapter->hw.hw_addr); 4660 iounmap(adapter->hw.hw_addr);
4534err_ioremap: 4661err_ioremap:
4535 free_netdev(netdev); 4662 free_netdev(netdev);
4536err_alloc_etherdev: 4663err_alloc_etherdev:
4537 pci_release_selected_regions(pdev, bars); 4664 pci_release_selected_regions(pdev,
4665 pci_select_bars(pdev, IORESOURCE_MEM));
4538err_pci_reg: 4666err_pci_reg:
4539err_dma: 4667err_dma:
4540 pci_disable_device(pdev); 4668 pci_disable_device(pdev);
@@ -4582,7 +4710,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
4582 iounmap(adapter->hw.hw_addr); 4710 iounmap(adapter->hw.hw_addr);
4583 if (adapter->hw.flash_address) 4711 if (adapter->hw.flash_address)
4584 iounmap(adapter->hw.flash_address); 4712 iounmap(adapter->hw.flash_address);
4585 pci_release_selected_regions(pdev, adapter->bars); 4713 pci_release_selected_regions(pdev,
4714 pci_select_bars(pdev, IORESOURCE_MEM));
4586 4715
4587 free_netdev(netdev); 4716 free_netdev(netdev);
4588 4717
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index a66b92efcf80..ed912e023a72 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -27,6 +27,7 @@
27*******************************************************************************/ 27*******************************************************************************/
28 28
29#include <linux/netdevice.h> 29#include <linux/netdevice.h>
30#include <linux/pci.h>
30 31
31#include "e1000.h" 32#include "e1000.h"
32 33
@@ -162,17 +163,16 @@ static int __devinit e1000_validate_option(unsigned int *value,
162 case enable_option: 163 case enable_option:
163 switch (*value) { 164 switch (*value) {
164 case OPTION_ENABLED: 165 case OPTION_ENABLED:
165 ndev_info(adapter->netdev, "%s Enabled\n", opt->name); 166 e_info("%s Enabled\n", opt->name);
166 return 0; 167 return 0;
167 case OPTION_DISABLED: 168 case OPTION_DISABLED:
168 ndev_info(adapter->netdev, "%s Disabled\n", opt->name); 169 e_info("%s Disabled\n", opt->name);
169 return 0; 170 return 0;
170 } 171 }
171 break; 172 break;
172 case range_option: 173 case range_option:
173 if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { 174 if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
174 ndev_info(adapter->netdev, 175 e_info("%s set to %i\n", opt->name, *value);
175 "%s set to %i\n", opt->name, *value);
176 return 0; 176 return 0;
177 } 177 }
178 break; 178 break;
@@ -184,8 +184,7 @@ static int __devinit e1000_validate_option(unsigned int *value,
184 ent = &opt->arg.l.p[i]; 184 ent = &opt->arg.l.p[i];
185 if (*value == ent->i) { 185 if (*value == ent->i) {
186 if (ent->str[0] != '\0') 186 if (ent->str[0] != '\0')
187 ndev_info(adapter->netdev, "%s\n", 187 e_info("%s\n", ent->str);
188 ent->str);
189 return 0; 188 return 0;
190 } 189 }
191 } 190 }
@@ -195,8 +194,8 @@ static int __devinit e1000_validate_option(unsigned int *value,
195 BUG(); 194 BUG();
196 } 195 }
197 196
198 ndev_info(adapter->netdev, "Invalid %s value specified (%i) %s\n", 197 e_info("Invalid %s value specified (%i) %s\n", opt->name, *value,
199 opt->name, *value, opt->err); 198 opt->err);
200 *value = opt->def; 199 *value = opt->def;
201 return -1; 200 return -1;
202} 201}
@@ -213,13 +212,11 @@ static int __devinit e1000_validate_option(unsigned int *value,
213void __devinit e1000e_check_options(struct e1000_adapter *adapter) 212void __devinit e1000e_check_options(struct e1000_adapter *adapter)
214{ 213{
215 struct e1000_hw *hw = &adapter->hw; 214 struct e1000_hw *hw = &adapter->hw;
216 struct net_device *netdev = adapter->netdev;
217 int bd = adapter->bd_number; 215 int bd = adapter->bd_number;
218 216
219 if (bd >= E1000_MAX_NIC) { 217 if (bd >= E1000_MAX_NIC) {
220 ndev_notice(netdev, 218 e_notice("Warning: no configuration for board #%i\n", bd);
221 "Warning: no configuration for board #%i\n", bd); 219 e_notice("Using defaults for all values\n");
222 ndev_notice(netdev, "Using defaults for all values\n");
223 } 220 }
224 221
225 { /* Transmit Interrupt Delay */ 222 { /* Transmit Interrupt Delay */
@@ -313,32 +310,41 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
313 adapter->itr = InterruptThrottleRate[bd]; 310 adapter->itr = InterruptThrottleRate[bd];
314 switch (adapter->itr) { 311 switch (adapter->itr) {
315 case 0: 312 case 0:
316 ndev_info(netdev, "%s turned off\n", 313 e_info("%s turned off\n", opt.name);
317 opt.name);
318 break; 314 break;
319 case 1: 315 case 1:
320 ndev_info(netdev, 316 e_info("%s set to dynamic mode\n", opt.name);
321 "%s set to dynamic mode\n",
322 opt.name);
323 adapter->itr_setting = adapter->itr; 317 adapter->itr_setting = adapter->itr;
324 adapter->itr = 20000; 318 adapter->itr = 20000;
325 break; 319 break;
326 case 3: 320 case 3:
327 ndev_info(netdev, 321 e_info("%s set to dynamic conservative mode\n",
328 "%s set to dynamic conservative mode\n",
329 opt.name); 322 opt.name);
330 adapter->itr_setting = adapter->itr; 323 adapter->itr_setting = adapter->itr;
331 adapter->itr = 20000; 324 adapter->itr = 20000;
332 break; 325 break;
333 default: 326 default:
334 e1000_validate_option(&adapter->itr, &opt,
335 adapter);
336 /* 327 /*
337 * save the setting, because the dynamic bits 328 * Save the setting, because the dynamic bits
338 * change itr. clear the lower two bits 329 * change itr.
339 * because they are used as control
340 */ 330 */
341 adapter->itr_setting = adapter->itr & ~3; 331 if (e1000_validate_option(&adapter->itr, &opt,
332 adapter) &&
333 (adapter->itr == 3)) {
334 /*
335 * In case of invalid user value,
336 * default to conservative mode.
337 */
338 adapter->itr_setting = adapter->itr;
339 adapter->itr = 20000;
340 } else {
341 /*
342 * Clear the lower two bits because
343 * they are used as control.
344 */
345 adapter->itr_setting =
346 adapter->itr & ~3;
347 }
342 break; 348 break;
343 } 349 }
344 } else { 350 } else {
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 56f50491a453..1f11350e16cf 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1283,14 +1283,6 @@ set_multicast_list(struct net_device *dev)
1283 1283
1284 if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63) 1284 if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
1285 { 1285 {
1286 /*
1287 * We must make the kernel realise we had to move
1288 * into promisc mode or we start all out war on
1289 * the cable. If it was a promisc request the
1290 * flag is already set. If not we assert it.
1291 */
1292 dev->flags|=IFF_PROMISC;
1293
1294 eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */ 1286 eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
1295 mode = inb(ioaddr + REG2); 1287 mode = inb(ioaddr + REG2);
1296 outb(mode | PRMSC_Mode, ioaddr + REG2); 1288 outb(mode | PRMSC_Mode, ioaddr + REG2);
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index e3dd8b136908..bee8b3fbc565 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -1356,7 +1356,6 @@ static void eth16i_multicast(struct net_device *dev)
1356 1356
1357 if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 1357 if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
1358 { 1358 {
1359 dev->flags|=IFF_PROMISC; /* Must do this */
1360 outb(3, ioaddr + RECEIVE_MODE_REG); 1359 outb(3, ioaddr + RECEIVE_MODE_REG);
1361 } else { 1360 } else {
1362 outb(2, ioaddr + RECEIVE_MODE_REG); 1361 outb(2, ioaddr + RECEIVE_MODE_REG);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 01b38b092c76..053971e5fc94 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -77,26 +77,27 @@
77 * Hardware access: 77 * Hardware access:
78 */ 78 */
79 79
80#define DEV_NEED_TIMERIRQ 0x00001 /* set the timer irq flag in the irq mask */ 80#define DEV_NEED_TIMERIRQ 0x000001 /* set the timer irq flag in the irq mask */
81#define DEV_NEED_LINKTIMER 0x00002 /* poll link settings. Relies on the timer irq */ 81#define DEV_NEED_LINKTIMER 0x000002 /* poll link settings. Relies on the timer irq */
82#define DEV_HAS_LARGEDESC 0x00004 /* device supports jumbo frames and needs packet format 2 */ 82#define DEV_HAS_LARGEDESC 0x000004 /* device supports jumbo frames and needs packet format 2 */
83#define DEV_HAS_HIGH_DMA 0x00008 /* device supports 64bit dma */ 83#define DEV_HAS_HIGH_DMA 0x000008 /* device supports 64bit dma */
84#define DEV_HAS_CHECKSUM 0x00010 /* device supports tx and rx checksum offloads */ 84#define DEV_HAS_CHECKSUM 0x000010 /* device supports tx and rx checksum offloads */
85#define DEV_HAS_VLAN 0x00020 /* device supports vlan tagging and striping */ 85#define DEV_HAS_VLAN 0x000020 /* device supports vlan tagging and striping */
86#define DEV_HAS_MSI 0x00040 /* device supports MSI */ 86#define DEV_HAS_MSI 0x000040 /* device supports MSI */
87#define DEV_HAS_MSI_X 0x00080 /* device supports MSI-X */ 87#define DEV_HAS_MSI_X 0x000080 /* device supports MSI-X */
88#define DEV_HAS_POWER_CNTRL 0x00100 /* device supports power savings */ 88#define DEV_HAS_POWER_CNTRL 0x000100 /* device supports power savings */
89#define DEV_HAS_STATISTICS_V1 0x00200 /* device supports hw statistics version 1 */ 89#define DEV_HAS_STATISTICS_V1 0x000200 /* device supports hw statistics version 1 */
90#define DEV_HAS_STATISTICS_V2 0x00400 /* device supports hw statistics version 2 */ 90#define DEV_HAS_STATISTICS_V2 0x000400 /* device supports hw statistics version 2 */
91#define DEV_HAS_TEST_EXTENDED 0x00800 /* device supports extended diagnostic test */ 91#define DEV_HAS_STATISTICS_V3 0x000800 /* device supports hw statistics version 3 */
92#define DEV_HAS_MGMT_UNIT 0x01000 /* device supports management unit */ 92#define DEV_HAS_TEST_EXTENDED 0x001000 /* device supports extended diagnostic test */
93#define DEV_HAS_CORRECT_MACADDR 0x02000 /* device supports correct mac address order */ 93#define DEV_HAS_MGMT_UNIT 0x002000 /* device supports management unit */
94#define DEV_HAS_COLLISION_FIX 0x04000 /* device supports tx collision fix */ 94#define DEV_HAS_CORRECT_MACADDR 0x004000 /* device supports correct mac address order */
95#define DEV_HAS_PAUSEFRAME_TX_V1 0x08000 /* device supports tx pause frames version 1 */ 95#define DEV_HAS_COLLISION_FIX 0x008000 /* device supports tx collision fix */
96#define DEV_HAS_PAUSEFRAME_TX_V2 0x10000 /* device supports tx pause frames version 2 */ 96#define DEV_HAS_PAUSEFRAME_TX_V1 0x010000 /* device supports tx pause frames version 1 */
97#define DEV_HAS_PAUSEFRAME_TX_V3 0x20000 /* device supports tx pause frames version 3 */ 97#define DEV_HAS_PAUSEFRAME_TX_V2 0x020000 /* device supports tx pause frames version 2 */
98#define DEV_NEED_TX_LIMIT 0x40000 /* device needs to limit tx */ 98#define DEV_HAS_PAUSEFRAME_TX_V3 0x040000 /* device supports tx pause frames version 3 */
99#define DEV_HAS_GEAR_MODE 0x80000 /* device supports gear mode */ 99#define DEV_NEED_TX_LIMIT 0x080000 /* device needs to limit tx */
100#define DEV_HAS_GEAR_MODE 0x100000 /* device supports gear mode */
100 101
101enum { 102enum {
102 NvRegIrqStatus = 0x000, 103 NvRegIrqStatus = 0x000,
@@ -248,6 +249,8 @@ enum {
248#define NVREG_TX_PAUSEFRAME_ENABLE_V1 0x01800010 249#define NVREG_TX_PAUSEFRAME_ENABLE_V1 0x01800010
249#define NVREG_TX_PAUSEFRAME_ENABLE_V2 0x056003f0 250#define NVREG_TX_PAUSEFRAME_ENABLE_V2 0x056003f0
250#define NVREG_TX_PAUSEFRAME_ENABLE_V3 0x09f00880 251#define NVREG_TX_PAUSEFRAME_ENABLE_V3 0x09f00880
252 NvRegTxPauseFrameLimit = 0x174,
253#define NVREG_TX_PAUSEFRAMELIMIT_ENABLE 0x00010000
251 NvRegMIIStatus = 0x180, 254 NvRegMIIStatus = 0x180,
252#define NVREG_MIISTAT_ERROR 0x0001 255#define NVREG_MIISTAT_ERROR 0x0001
253#define NVREG_MIISTAT_LINKCHANGE 0x0008 256#define NVREG_MIISTAT_LINKCHANGE 0x0008
@@ -270,6 +273,9 @@ enum {
270#define NVREG_MIICTL_WRITE 0x00400 273#define NVREG_MIICTL_WRITE 0x00400
271#define NVREG_MIICTL_ADDRSHIFT 5 274#define NVREG_MIICTL_ADDRSHIFT 5
272 NvRegMIIData = 0x194, 275 NvRegMIIData = 0x194,
276 NvRegTxUnicast = 0x1a0,
277 NvRegTxMulticast = 0x1a4,
278 NvRegTxBroadcast = 0x1a8,
273 NvRegWakeUpFlags = 0x200, 279 NvRegWakeUpFlags = 0x200,
274#define NVREG_WAKEUPFLAGS_VAL 0x7770 280#define NVREG_WAKEUPFLAGS_VAL 0x7770
275#define NVREG_WAKEUPFLAGS_BUSYSHIFT 24 281#define NVREG_WAKEUPFLAGS_BUSYSHIFT 24
@@ -402,6 +408,7 @@ union ring_type {
402#define NV_RX_FRAMINGERR (1<<29) 408#define NV_RX_FRAMINGERR (1<<29)
403#define NV_RX_ERROR (1<<30) 409#define NV_RX_ERROR (1<<30)
404#define NV_RX_AVAIL (1<<31) 410#define NV_RX_AVAIL (1<<31)
411#define NV_RX_ERROR_MASK (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4|NV_RX_CRCERR|NV_RX_OVERFLOW|NV_RX_FRAMINGERR)
405 412
406#define NV_RX2_CHECKSUMMASK (0x1C000000) 413#define NV_RX2_CHECKSUMMASK (0x1C000000)
407#define NV_RX2_CHECKSUM_IP (0x10000000) 414#define NV_RX2_CHECKSUM_IP (0x10000000)
@@ -419,6 +426,7 @@ union ring_type {
419/* error and avail are the same for both */ 426/* error and avail are the same for both */
420#define NV_RX2_ERROR (1<<30) 427#define NV_RX2_ERROR (1<<30)
421#define NV_RX2_AVAIL (1<<31) 428#define NV_RX2_AVAIL (1<<31)
429#define NV_RX2_ERROR_MASK (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4|NV_RX2_CRCERR|NV_RX2_OVERFLOW|NV_RX2_FRAMINGERR)
422 430
423#define NV_RX3_VLAN_TAG_PRESENT (1<<16) 431#define NV_RX3_VLAN_TAG_PRESENT (1<<16)
424#define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) 432#define NV_RX3_VLAN_TAG_MASK (0x0000FFFF)
@@ -616,7 +624,12 @@ static const struct nv_ethtool_str nv_estats_str[] = {
616 { "rx_bytes" }, 624 { "rx_bytes" },
617 { "tx_pause" }, 625 { "tx_pause" },
618 { "rx_pause" }, 626 { "rx_pause" },
619 { "rx_drop_frame" } 627 { "rx_drop_frame" },
628
629 /* version 3 stats */
630 { "tx_unicast" },
631 { "tx_multicast" },
632 { "tx_broadcast" }
620}; 633};
621 634
622struct nv_ethtool_stats { 635struct nv_ethtool_stats {
@@ -652,9 +665,15 @@ struct nv_ethtool_stats {
652 u64 tx_pause; 665 u64 tx_pause;
653 u64 rx_pause; 666 u64 rx_pause;
654 u64 rx_drop_frame; 667 u64 rx_drop_frame;
668
669 /* version 3 stats */
670 u64 tx_unicast;
671 u64 tx_multicast;
672 u64 tx_broadcast;
655}; 673};
656 674
657#define NV_DEV_STATISTICS_V2_COUNT (sizeof(struct nv_ethtool_stats)/sizeof(u64)) 675#define NV_DEV_STATISTICS_V3_COUNT (sizeof(struct nv_ethtool_stats)/sizeof(u64))
676#define NV_DEV_STATISTICS_V2_COUNT (NV_DEV_STATISTICS_V3_COUNT - 3)
658#define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6) 677#define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6)
659 678
660/* diagnostics */ 679/* diagnostics */
@@ -1628,6 +1647,12 @@ static void nv_get_hw_stats(struct net_device *dev)
1628 np->estats.rx_pause += readl(base + NvRegRxPause); 1647 np->estats.rx_pause += readl(base + NvRegRxPause);
1629 np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame); 1648 np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame);
1630 } 1649 }
1650
1651 if (np->driver_data & DEV_HAS_STATISTICS_V3) {
1652 np->estats.tx_unicast += readl(base + NvRegTxUnicast);
1653 np->estats.tx_multicast += readl(base + NvRegTxMulticast);
1654 np->estats.tx_broadcast += readl(base + NvRegTxBroadcast);
1655 }
1631} 1656}
1632 1657
1633/* 1658/*
@@ -1641,7 +1666,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
1641 struct fe_priv *np = netdev_priv(dev); 1666 struct fe_priv *np = netdev_priv(dev);
1642 1667
1643 /* If the nic supports hw counters then retrieve latest values */ 1668 /* If the nic supports hw counters then retrieve latest values */
1644 if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) { 1669 if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {
1645 nv_get_hw_stats(dev); 1670 nv_get_hw_stats(dev);
1646 1671
1647 /* copy to net_device stats */ 1672 /* copy to net_device stats */
@@ -2632,7 +2657,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
2632 if (likely(flags & NV_RX_DESCRIPTORVALID)) { 2657 if (likely(flags & NV_RX_DESCRIPTORVALID)) {
2633 len = flags & LEN_MASK_V1; 2658 len = flags & LEN_MASK_V1;
2634 if (unlikely(flags & NV_RX_ERROR)) { 2659 if (unlikely(flags & NV_RX_ERROR)) {
2635 if (flags & NV_RX_ERROR4) { 2660 if ((flags & NV_RX_ERROR_MASK) == NV_RX_ERROR4) {
2636 len = nv_getlen(dev, skb->data, len); 2661 len = nv_getlen(dev, skb->data, len);
2637 if (len < 0) { 2662 if (len < 0) {
2638 dev->stats.rx_errors++; 2663 dev->stats.rx_errors++;
@@ -2641,7 +2666,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
2641 } 2666 }
2642 } 2667 }
2643 /* framing errors are soft errors */ 2668 /* framing errors are soft errors */
2644 else if (flags & NV_RX_FRAMINGERR) { 2669 else if ((flags & NV_RX_ERROR_MASK) == NV_RX_FRAMINGERR) {
2645 if (flags & NV_RX_SUBSTRACT1) { 2670 if (flags & NV_RX_SUBSTRACT1) {
2646 len--; 2671 len--;
2647 } 2672 }
@@ -2667,7 +2692,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
2667 if (likely(flags & NV_RX2_DESCRIPTORVALID)) { 2692 if (likely(flags & NV_RX2_DESCRIPTORVALID)) {
2668 len = flags & LEN_MASK_V2; 2693 len = flags & LEN_MASK_V2;
2669 if (unlikely(flags & NV_RX2_ERROR)) { 2694 if (unlikely(flags & NV_RX2_ERROR)) {
2670 if (flags & NV_RX2_ERROR4) { 2695 if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_ERROR4) {
2671 len = nv_getlen(dev, skb->data, len); 2696 len = nv_getlen(dev, skb->data, len);
2672 if (len < 0) { 2697 if (len < 0) {
2673 dev->stats.rx_errors++; 2698 dev->stats.rx_errors++;
@@ -2676,7 +2701,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
2676 } 2701 }
2677 } 2702 }
2678 /* framing errors are soft errors */ 2703 /* framing errors are soft errors */
2679 else if (flags & NV_RX2_FRAMINGERR) { 2704 else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) {
2680 if (flags & NV_RX2_SUBSTRACT1) { 2705 if (flags & NV_RX2_SUBSTRACT1) {
2681 len--; 2706 len--;
2682 } 2707 }
@@ -2766,7 +2791,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
2766 if (likely(flags & NV_RX2_DESCRIPTORVALID)) { 2791 if (likely(flags & NV_RX2_DESCRIPTORVALID)) {
2767 len = flags & LEN_MASK_V2; 2792 len = flags & LEN_MASK_V2;
2768 if (unlikely(flags & NV_RX2_ERROR)) { 2793 if (unlikely(flags & NV_RX2_ERROR)) {
2769 if (flags & NV_RX2_ERROR4) { 2794 if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_ERROR4) {
2770 len = nv_getlen(dev, skb->data, len); 2795 len = nv_getlen(dev, skb->data, len);
2771 if (len < 0) { 2796 if (len < 0) {
2772 dev_kfree_skb(skb); 2797 dev_kfree_skb(skb);
@@ -2774,7 +2799,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
2774 } 2799 }
2775 } 2800 }
2776 /* framing errors are soft errors */ 2801 /* framing errors are soft errors */
2777 else if (flags & NV_RX2_FRAMINGERR) { 2802 else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) {
2778 if (flags & NV_RX2_SUBSTRACT1) { 2803 if (flags & NV_RX2_SUBSTRACT1) {
2779 len--; 2804 len--;
2780 } 2805 }
@@ -3053,8 +3078,11 @@ static void nv_update_pause(struct net_device *dev, u32 pause_flags)
3053 u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1; 3078 u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1;
3054 if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) 3079 if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2)
3055 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2; 3080 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2;
3056 if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3) 3081 if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3) {
3057 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3; 3082 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3;
3083 /* limit the number of tx pause frames to a default of 8 */
3084 writel(readl(base + NvRegTxPauseFrameLimit)|NVREG_TX_PAUSEFRAMELIMIT_ENABLE, base + NvRegTxPauseFrameLimit);
3085 }
3058 writel(pause_enable, base + NvRegTxPauseFrame); 3086 writel(pause_enable, base + NvRegTxPauseFrame);
3059 writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1); 3087 writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1);
3060 np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE; 3088 np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
@@ -4740,6 +4768,8 @@ static int nv_get_sset_count(struct net_device *dev, int sset)
4740 return NV_DEV_STATISTICS_V1_COUNT; 4768 return NV_DEV_STATISTICS_V1_COUNT;
4741 else if (np->driver_data & DEV_HAS_STATISTICS_V2) 4769 else if (np->driver_data & DEV_HAS_STATISTICS_V2)
4742 return NV_DEV_STATISTICS_V2_COUNT; 4770 return NV_DEV_STATISTICS_V2_COUNT;
4771 else if (np->driver_data & DEV_HAS_STATISTICS_V3)
4772 return NV_DEV_STATISTICS_V3_COUNT;
4743 else 4773 else
4744 return 0; 4774 return 0;
4745 default: 4775 default:
@@ -5324,7 +5354,7 @@ static int nv_open(struct net_device *dev)
5324 mod_timer(&np->oom_kick, jiffies + OOM_REFILL); 5354 mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
5325 5355
5326 /* start statistics timer */ 5356 /* start statistics timer */
5327 if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) 5357 if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3))
5328 mod_timer(&np->stats_poll, 5358 mod_timer(&np->stats_poll,
5329 round_jiffies(jiffies + STATS_INTERVAL)); 5359 round_jiffies(jiffies + STATS_INTERVAL));
5330 5360
@@ -5428,7 +5458,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
5428 if (err < 0) 5458 if (err < 0)
5429 goto out_disable; 5459 goto out_disable;
5430 5460
5431 if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V2)) 5461 if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3))
5432 np->register_size = NV_PCI_REGSZ_VER3; 5462 np->register_size = NV_PCI_REGSZ_VER3;
5433 else if (id->driver_data & DEV_HAS_STATISTICS_V1) 5463 else if (id->driver_data & DEV_HAS_STATISTICS_V1)
5434 np->register_size = NV_PCI_REGSZ_VER2; 5464 np->register_size = NV_PCI_REGSZ_VER2;
@@ -6083,35 +6113,35 @@ static struct pci_device_id pci_tbl[] = {
6083 }, 6113 },
6084 { /* MCP77 Ethernet Controller */ 6114 { /* MCP77 Ethernet Controller */
6085 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32), 6115 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
6086 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6116 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6087 }, 6117 },
6088 { /* MCP77 Ethernet Controller */ 6118 { /* MCP77 Ethernet Controller */
6089 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33), 6119 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
6090 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6120 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6091 }, 6121 },
6092 { /* MCP77 Ethernet Controller */ 6122 { /* MCP77 Ethernet Controller */
6093 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34), 6123 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
6094 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6124 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6095 }, 6125 },
6096 { /* MCP77 Ethernet Controller */ 6126 { /* MCP77 Ethernet Controller */
6097 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35), 6127 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
6098 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6128 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6099 }, 6129 },
6100 { /* MCP79 Ethernet Controller */ 6130 { /* MCP79 Ethernet Controller */
6101 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36), 6131 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
6102 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6132 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6103 }, 6133 },
6104 { /* MCP79 Ethernet Controller */ 6134 { /* MCP79 Ethernet Controller */
6105 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37), 6135 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
6106 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6136 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6107 }, 6137 },
6108 { /* MCP79 Ethernet Controller */ 6138 { /* MCP79 Ethernet Controller */
6109 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38), 6139 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
6110 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6140 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6111 }, 6141 },
6112 { /* MCP79 Ethernet Controller */ 6142 { /* MCP79 Ethernet Controller */
6113 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39), 6143 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
6114 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, 6144 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
6115 }, 6145 },
6116 {0,}, 6146 {0,},
6117}; 6147};
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 0a97fc2d97ec..1c7ef812a8e3 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -126,7 +126,7 @@ out:
126#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB) 126#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
127#define FCC_RX_EVENT (FCC_ENET_RXF) 127#define FCC_RX_EVENT (FCC_ENET_RXF)
128#define FCC_TX_EVENT (FCC_ENET_TXB) 128#define FCC_TX_EVENT (FCC_ENET_TXB)
129#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE | FCC_ENET_BSY) 129#define FCC_ERR_EVENT_MSK (FCC_ENET_TXE)
130 130
131static int setup_data(struct net_device *dev) 131static int setup_data(struct net_device *dev)
132{ 132{
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b8394cf134e8..999d69168277 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -134,9 +134,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
134static void gfar_vlan_rx_register(struct net_device *netdev, 134static void gfar_vlan_rx_register(struct net_device *netdev,
135 struct vlan_group *grp); 135 struct vlan_group *grp);
136void gfar_halt(struct net_device *dev); 136void gfar_halt(struct net_device *dev);
137#ifdef CONFIG_PM
138static void gfar_halt_nodisable(struct net_device *dev); 137static void gfar_halt_nodisable(struct net_device *dev);
139#endif
140void gfar_start(struct net_device *dev); 138void gfar_start(struct net_device *dev);
141static void gfar_clear_exact_match(struct net_device *dev); 139static void gfar_clear_exact_match(struct net_device *dev);
142static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); 140static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
@@ -414,9 +412,7 @@ static int gfar_suspend(struct platform_device *pdev, pm_message_t state)
414 spin_unlock(&priv->rxlock); 412 spin_unlock(&priv->rxlock);
415 spin_unlock_irqrestore(&priv->txlock, flags); 413 spin_unlock_irqrestore(&priv->txlock, flags);
416 414
417#ifdef CONFIG_GFAR_NAPI
418 napi_disable(&priv->napi); 415 napi_disable(&priv->napi);
419#endif
420 416
421 if (magic_packet) { 417 if (magic_packet) {
422 /* Enable interrupt on Magic Packet */ 418 /* Enable interrupt on Magic Packet */
@@ -469,9 +465,7 @@ static int gfar_resume(struct platform_device *pdev)
469 465
470 netif_device_attach(dev); 466 netif_device_attach(dev);
471 467
472#ifdef CONFIG_GFAR_NAPI
473 napi_enable(&priv->napi); 468 napi_enable(&priv->napi);
474#endif
475 469
476 return 0; 470 return 0;
477} 471}
@@ -635,7 +629,6 @@ static void init_registers(struct net_device *dev)
635} 629}
636 630
637 631
638#ifdef CONFIG_PM
639/* Halt the receive and transmit queues */ 632/* Halt the receive and transmit queues */
640static void gfar_halt_nodisable(struct net_device *dev) 633static void gfar_halt_nodisable(struct net_device *dev)
641{ 634{
@@ -661,7 +654,6 @@ static void gfar_halt_nodisable(struct net_device *dev)
661 cpu_relax(); 654 cpu_relax();
662 } 655 }
663} 656}
664#endif
665 657
666/* Halt the receive and transmit queues */ 658/* Halt the receive and transmit queues */
667void gfar_halt(struct net_device *dev) 659void gfar_halt(struct net_device *dev)
@@ -670,6 +662,8 @@ void gfar_halt(struct net_device *dev)
670 struct gfar __iomem *regs = priv->regs; 662 struct gfar __iomem *regs = priv->regs;
671 u32 tempval; 663 u32 tempval;
672 664
665 gfar_halt_nodisable(dev);
666
673 /* Disable Rx and Tx */ 667 /* Disable Rx and Tx */
674 tempval = gfar_read(&regs->maccfg1); 668 tempval = gfar_read(&regs->maccfg1);
675 tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); 669 tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 5116f68e01b9..782c20170082 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -33,7 +33,6 @@
33 33
34#include <asm/uaccess.h> 34#include <asm/uaccess.h>
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/version.h>
37 36
38#include "gianfar.h" 37#include "gianfar.h"
39 38
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 3249df5e0f17..b8e25c4624d2 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -548,7 +548,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
548 } 548 }
549 549
550 printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name, 550 printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
551 (ax->tty->ops->chars_in_buffer(ax->tty) || ax->xleft) ? 551 (tty_chars_in_buffer(ax->tty) || ax->xleft) ?
552 "bad line quality" : "driver error"); 552 "bad line quality" : "driver error");
553 553
554 ax->xleft = 0; 554 ax->xleft = 0;
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index e098f234770f..bb823acc7443 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -850,7 +850,7 @@ void igb_update_mc_addr_list_82575(struct e1000_hw *hw,
850 for (; mc_addr_count > 0; mc_addr_count--) { 850 for (; mc_addr_count > 0; mc_addr_count--) {
851 hash_value = igb_hash_mc_addr(hw, mc_addr_list); 851 hash_value = igb_hash_mc_addr(hw, mc_addr_list);
852 hw_dbg("Hash value = 0x%03X\n", hash_value); 852 hw_dbg("Hash value = 0x%03X\n", hash_value);
853 hw->mac.ops.mta_set(hw, hash_value); 853 igb_mta_set(hw, hash_value);
854 mc_addr_list += ETH_ALEN; 854 mc_addr_list += ETH_ALEN;
855 } 855 }
856} 856}
@@ -1136,6 +1136,12 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
1136 E1000_PCS_LCTL_FORCE_LINK; /* Force Link */ 1136 E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
1137 hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg); 1137 hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
1138 } 1138 }
1139
1140 if (hw->mac.type == e1000_82576) {
1141 reg |= E1000_PCS_LCTL_FORCE_FCTRL;
1142 igb_force_mac_fc(hw);
1143 }
1144
1139 wr32(E1000_PCS_LCTL, reg); 1145 wr32(E1000_PCS_LCTL, reg);
1140 1146
1141 return 0; 1147 return 0;
@@ -1232,70 +1238,6 @@ out:
1232} 1238}
1233 1239
1234/** 1240/**
1235 * igb_translate_register_82576 - Translate the proper register offset
1236 * @reg: e1000 register to be read
1237 *
1238 * Registers in 82576 are located in different offsets than other adapters
1239 * even though they function in the same manner. This function takes in
1240 * the name of the register to read and returns the correct offset for
1241 * 82576 silicon.
1242 **/
1243u32 igb_translate_register_82576(u32 reg)
1244{
1245 /*
1246 * Some of the Kawela registers are located at different
1247 * offsets than they are in older adapters.
1248 * Despite the difference in location, the registers
1249 * function in the same manner.
1250 */
1251 switch (reg) {
1252 case E1000_TDBAL(0):
1253 reg = 0x0E000;
1254 break;
1255 case E1000_TDBAH(0):
1256 reg = 0x0E004;
1257 break;
1258 case E1000_TDLEN(0):
1259 reg = 0x0E008;
1260 break;
1261 case E1000_TDH(0):
1262 reg = 0x0E010;
1263 break;
1264 case E1000_TDT(0):
1265 reg = 0x0E018;
1266 break;
1267 case E1000_TXDCTL(0):
1268 reg = 0x0E028;
1269 break;
1270 case E1000_RDBAL(0):
1271 reg = 0x0C000;
1272 break;
1273 case E1000_RDBAH(0):
1274 reg = 0x0C004;
1275 break;
1276 case E1000_RDLEN(0):
1277 reg = 0x0C008;
1278 break;
1279 case E1000_RDH(0):
1280 reg = 0x0C010;
1281 break;
1282 case E1000_RDT(0):
1283 reg = 0x0C018;
1284 break;
1285 case E1000_RXDCTL(0):
1286 reg = 0x0C028;
1287 break;
1288 case E1000_SRRCTL(0):
1289 reg = 0x0C00C;
1290 break;
1291 default:
1292 break;
1293 }
1294
1295 return reg;
1296}
1297
1298/**
1299 * igb_reset_init_script_82575 - Inits HW defaults after reset 1241 * igb_reset_init_script_82575 - Inits HW defaults after reset
1300 * @hw: pointer to the HW structure 1242 * @hw: pointer to the HW structure
1301 * 1243 *
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index 2f848e578a24..c1928b5efe1f 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -28,7 +28,6 @@
28#ifndef _E1000_82575_H_ 28#ifndef _E1000_82575_H_
29#define _E1000_82575_H_ 29#define _E1000_82575_H_
30 30
31u32 igb_translate_register_82576(u32 reg);
32void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32); 31void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32);
33extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw); 32extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
34extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); 33extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index afdba3c9073c..ce700689fb57 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -257,6 +257,7 @@
257#define E1000_PCS_LCTL_FDV_FULL 8 257#define E1000_PCS_LCTL_FDV_FULL 8
258#define E1000_PCS_LCTL_FSD 0x10 258#define E1000_PCS_LCTL_FSD 0x10
259#define E1000_PCS_LCTL_FORCE_LINK 0x20 259#define E1000_PCS_LCTL_FORCE_LINK 0x20
260#define E1000_PCS_LCTL_FORCE_FCTRL 0x80
260#define E1000_PCS_LCTL_AN_ENABLE 0x10000 261#define E1000_PCS_LCTL_AN_ENABLE 0x10000
261#define E1000_PCS_LCTL_AN_RESTART 0x20000 262#define E1000_PCS_LCTL_AN_RESTART 0x20000
262#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000 263#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 19fa4ee96f2e..a65ccc3095c3 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -420,7 +420,6 @@ struct e1000_mac_operations {
420 void (*rar_set)(struct e1000_hw *, u8 *, u32); 420 void (*rar_set)(struct e1000_hw *, u8 *, u32);
421 s32 (*read_mac_addr)(struct e1000_hw *); 421 s32 (*read_mac_addr)(struct e1000_hw *);
422 s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *); 422 s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
423 void (*mta_set)(struct e1000_hw *, u32);
424}; 423};
425 424
426struct e1000_phy_operations { 425struct e1000_phy_operations {
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 20408aa1f916..e18747c70bec 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -144,34 +144,6 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
144} 144}
145 145
146/** 146/**
147 * igb_init_rx_addrs - Initialize receive address's
148 * @hw: pointer to the HW structure
149 * @rar_count: receive address registers
150 *
151 * Setups the receive address registers by setting the base receive address
152 * register to the devices MAC address and clearing all the other receive
153 * address registers to 0.
154 **/
155void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
156{
157 u32 i;
158
159 /* Setup the receive address */
160 hw_dbg("Programming MAC Address into RAR[0]\n");
161
162 hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
163
164 /* Zero out the other (rar_entry_count - 1) receive addresses */
165 hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
166 for (i = 1; i < rar_count; i++) {
167 array_wr32(E1000_RA, (i << 1), 0);
168 wrfl();
169 array_wr32(E1000_RA, ((i << 1) + 1), 0);
170 wrfl();
171 }
172}
173
174/**
175 * igb_check_alt_mac_addr - Check for alternate MAC addr 147 * igb_check_alt_mac_addr - Check for alternate MAC addr
176 * @hw: pointer to the HW structure 148 * @hw: pointer to the HW structure
177 * 149 *
@@ -271,7 +243,7 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
271 * current value is read, the new bit is OR'd in and the new value is 243 * current value is read, the new bit is OR'd in and the new value is
272 * written back into the register. 244 * written back into the register.
273 **/ 245 **/
274static void igb_mta_set(struct e1000_hw *hw, u32 hash_value) 246void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
275{ 247{
276 u32 hash_bit, hash_reg, mta; 248 u32 hash_bit, hash_reg, mta;
277 249
@@ -297,60 +269,6 @@ static void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
297} 269}
298 270
299/** 271/**
300 * igb_update_mc_addr_list - Update Multicast addresses
301 * @hw: pointer to the HW structure
302 * @mc_addr_list: array of multicast addresses to program
303 * @mc_addr_count: number of multicast addresses to program
304 * @rar_used_count: the first RAR register free to program
305 * @rar_count: total number of supported Receive Address Registers
306 *
307 * Updates the Receive Address Registers and Multicast Table Array.
308 * The caller must have a packed mc_addr_list of multicast addresses.
309 * The parameter rar_count will usually be hw->mac.rar_entry_count
310 * unless there are workarounds that change this.
311 **/
312void igb_update_mc_addr_list(struct e1000_hw *hw,
313 u8 *mc_addr_list, u32 mc_addr_count,
314 u32 rar_used_count, u32 rar_count)
315{
316 u32 hash_value;
317 u32 i;
318
319 /*
320 * Load the first set of multicast addresses into the exact
321 * filters (RAR). If there are not enough to fill the RAR
322 * array, clear the filters.
323 */
324 for (i = rar_used_count; i < rar_count; i++) {
325 if (mc_addr_count) {
326 hw->mac.ops.rar_set(hw, mc_addr_list, i);
327 mc_addr_count--;
328 mc_addr_list += ETH_ALEN;
329 } else {
330 array_wr32(E1000_RA, i << 1, 0);
331 wrfl();
332 array_wr32(E1000_RA, (i << 1) + 1, 0);
333 wrfl();
334 }
335 }
336
337 /* Clear the old settings from the MTA */
338 hw_dbg("Clearing MTA\n");
339 for (i = 0; i < hw->mac.mta_reg_count; i++) {
340 array_wr32(E1000_MTA, i, 0);
341 wrfl();
342 }
343
344 /* Load any remaining multicast addresses into the hash table. */
345 for (; mc_addr_count > 0; mc_addr_count--) {
346 hash_value = igb_hash_mc_addr(hw, mc_addr_list);
347 hw_dbg("Hash value = 0x%03X\n", hash_value);
348 igb_mta_set(hw, hash_value);
349 mc_addr_list += ETH_ALEN;
350 }
351}
352
353/**
354 * igb_hash_mc_addr - Generate a multicast hash value 272 * igb_hash_mc_addr - Generate a multicast hash value
355 * @hw: pointer to the HW structure 273 * @hw: pointer to the HW structure
356 * @mc_addr: pointer to a multicast address 274 * @mc_addr: pointer to a multicast address
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index dc2f8cce15e7..cbee6af7d912 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -51,9 +51,6 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
51 u16 *duplex); 51 u16 *duplex);
52s32 igb_id_led_init(struct e1000_hw *hw); 52s32 igb_id_led_init(struct e1000_hw *hw);
53s32 igb_led_off(struct e1000_hw *hw); 53s32 igb_led_off(struct e1000_hw *hw);
54void igb_update_mc_addr_list(struct e1000_hw *hw,
55 u8 *mc_addr_list, u32 mc_addr_count,
56 u32 rar_used_count, u32 rar_count);
57s32 igb_setup_link(struct e1000_hw *hw); 54s32 igb_setup_link(struct e1000_hw *hw);
58s32 igb_validate_mdi_setting(struct e1000_hw *hw); 55s32 igb_validate_mdi_setting(struct e1000_hw *hw);
59s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, 56s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
@@ -62,7 +59,7 @@ s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
62void igb_clear_hw_cntrs_base(struct e1000_hw *hw); 59void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
63void igb_clear_vfta(struct e1000_hw *hw); 60void igb_clear_vfta(struct e1000_hw *hw);
64void igb_config_collision_dist(struct e1000_hw *hw); 61void igb_config_collision_dist(struct e1000_hw *hw);
65void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count); 62void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
66void igb_put_hw_semaphore(struct e1000_hw *hw); 63void igb_put_hw_semaphore(struct e1000_hw *hw);
67void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); 64void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
68s32 igb_check_alt_mac_addr(struct e1000_hw *hw); 65s32 igb_check_alt_mac_addr(struct e1000_hw *hw);
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index b95093d24c09..95523af26056 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -262,9 +262,6 @@
262#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) 262#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
263#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */ 263#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
264 264
265#define E1000_REGISTER(a, reg) (((a)->mac.type < e1000_82576) \
266 ? reg : e1000_translate_register_82576(reg))
267
268#define wr32(reg, value) (writel(value, hw->hw_addr + reg)) 265#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
269#define rd32(reg) (readl(hw->hw_addr + reg)) 266#define rd32(reg) (readl(hw->hw_addr + reg))
270#define wrfl() ((void)rd32(E1000_STATUS)) 267#define wrfl() ((void)rd32(E1000_STATUS))
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index b602c4dd0d14..8f66e15ec8d6 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -311,7 +311,7 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
311 array_wr32(E1000_MSIXBM(0), msix_vector, msixbm); 311 array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
312 break; 312 break;
313 case e1000_82576: 313 case e1000_82576:
314 /* Kawela uses a table-based method for assigning vectors. 314 /* The 82576 uses a table-based method for assigning vectors.
315 Each queue has a single entry in the table to which we write 315 Each queue has a single entry in the table to which we write
316 a vector number along with a "valid" bit. Sadly, the layout 316 a vector number along with a "valid" bit. Sadly, the layout
317 of the table is somewhat counterintuitive. */ 317 of the table is somewhat counterintuitive. */
@@ -720,28 +720,6 @@ static void igb_get_hw_control(struct igb_adapter *adapter)
720 ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); 720 ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
721} 721}
722 722
723static void igb_init_manageability(struct igb_adapter *adapter)
724{
725 struct e1000_hw *hw = &adapter->hw;
726
727 if (adapter->en_mng_pt) {
728 u32 manc2h = rd32(E1000_MANC2H);
729 u32 manc = rd32(E1000_MANC);
730
731 /* enable receiving management packets to the host */
732 /* this will probably generate destination unreachable messages
733 * from the host OS, but the packets will be handled on SMBUS */
734 manc |= E1000_MANC_EN_MNG2HOST;
735#define E1000_MNG2HOST_PORT_623 (1 << 5)
736#define E1000_MNG2HOST_PORT_664 (1 << 6)
737 manc2h |= E1000_MNG2HOST_PORT_623;
738 manc2h |= E1000_MNG2HOST_PORT_664;
739 wr32(E1000_MANC2H, manc2h);
740
741 wr32(E1000_MANC, manc);
742 }
743}
744
745/** 723/**
746 * igb_configure - configure the hardware for RX and TX 724 * igb_configure - configure the hardware for RX and TX
747 * @adapter: private board structure 725 * @adapter: private board structure
@@ -755,7 +733,6 @@ static void igb_configure(struct igb_adapter *adapter)
755 igb_set_multi(netdev); 733 igb_set_multi(netdev);
756 734
757 igb_restore_vlan(adapter); 735 igb_restore_vlan(adapter);
758 igb_init_manageability(adapter);
759 736
760 igb_configure_tx(adapter); 737 igb_configure_tx(adapter);
761 igb_setup_rctl(adapter); 738 igb_setup_rctl(adapter);
@@ -1372,7 +1349,8 @@ static void __devexit igb_remove(struct pci_dev *pdev)
1372 1349
1373 unregister_netdev(netdev); 1350 unregister_netdev(netdev);
1374 1351
1375 if (!igb_check_reset_block(&adapter->hw)) 1352 if (adapter->hw.phy.ops.reset_phy &&
1353 !igb_check_reset_block(&adapter->hw))
1376 adapter->hw.phy.ops.reset_phy(&adapter->hw); 1354 adapter->hw.phy.ops.reset_phy(&adapter->hw);
1377 1355
1378 igb_remove_device(&adapter->hw); 1356 igb_remove_device(&adapter->hw);
@@ -4523,8 +4501,6 @@ static void igb_io_resume(struct pci_dev *pdev)
4523 struct net_device *netdev = pci_get_drvdata(pdev); 4501 struct net_device *netdev = pci_get_drvdata(pdev);
4524 struct igb_adapter *adapter = netdev_priv(netdev); 4502 struct igb_adapter *adapter = netdev_priv(netdev);
4525 4503
4526 igb_init_manageability(adapter);
4527
4528 if (netif_running(netdev)) { 4504 if (netif_running(netdev)) {
4529 if (igb_up(adapter)) { 4505 if (igb_up(adapter)) {
4530 dev_err(&pdev->dev, "igb_up failed after reset\n"); 4506 dev_err(&pdev->dev, "igb_up failed after reset\n");
diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h
index e0e718ab4c2e..dd9318f19497 100644
--- a/drivers/net/ipg.h
+++ b/drivers/net/ipg.h
@@ -7,7 +7,6 @@
7#ifndef __LINUX_IPG_H 7#ifndef __LINUX_IPG_H
8#define __LINUX_IPG_H 8#define __LINUX_IPG_H
9 9
10#include <linux/version.h>
11#include <linux/module.h> 10#include <linux/module.h>
12 11
13#include <linux/kernel.h> 12#include <linux/kernel.h>
@@ -21,7 +20,6 @@
21#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
22#include <linux/init.h> 21#include <linux/init.h>
23#include <linux/skbuff.h> 22#include <linux/skbuff.h>
24#include <linux/version.h>
25#include <asm/bitops.h> 23#include <asm/bitops.h>
26 24
27/* 25/*
diff --git a/drivers/net/irda/ep7211-sir.c b/drivers/net/irda/ep7211-sir.c
index 831572429bb9..f83c5b881d2d 100644
--- a/drivers/net/irda/ep7211-sir.c
+++ b/drivers/net/irda/ep7211-sir.c
@@ -14,7 +14,7 @@
14#include <net/irda/irda_device.h> 14#include <net/irda/irda_device.h>
15 15
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/hardware.h> 17#include <mach/hardware.h>
18 18
19#include "sir-dev.h" 19#include "sir-dev.h"
20 20
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index f76b0b6c277d..4aa61a1a3d55 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -23,8 +23,8 @@
23#include <net/irda/irda_device.h> 23#include <net/irda/irda_device.h>
24 24
25#include <asm/dma.h> 25#include <asm/dma.h>
26#include <asm/arch/irda.h> 26#include <mach/irda.h>
27#include <asm/arch/pxa-regs.h> 27#include <mach/pxa-regs.h>
28 28
29#define IrSR_RXPL_NEG_IS_ZERO (1<<4) 29#define IrSR_RXPL_NEG_IS_ZERO (1<<4)
30#define IrSR_RXPL_POS_IS_ZERO 0x0 30#define IrSR_RXPL_POS_IS_ZERO 0x0
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 1bc8518f9197..a95188948de7 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -37,7 +37,7 @@
37 37
38#include <asm/irq.h> 38#include <asm/irq.h>
39#include <asm/dma.h> 39#include <asm/dma.h>
40#include <asm/hardware.h> 40#include <mach/hardware.h>
41#include <asm/mach/irda.h> 41#include <asm/mach/irda.h>
42 42
43static int power_level = 3; 43static int power_level = 3;
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 2f38e847e2cd..f96358b641af 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -190,6 +190,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
190 case IXGBE_DEV_ID_82598AF_DUAL_PORT: 190 case IXGBE_DEV_ID_82598AF_DUAL_PORT:
191 case IXGBE_DEV_ID_82598AF_SINGLE_PORT: 191 case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
192 case IXGBE_DEV_ID_82598EB_CX4: 192 case IXGBE_DEV_ID_82598EB_CX4:
193 case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
193 media_type = ixgbe_media_type_fiber; 194 media_type = ixgbe_media_type_fiber;
194 break; 195 break;
195 case IXGBE_DEV_ID_82598AT_DUAL_PORT: 196 case IXGBE_DEV_ID_82598AT_DUAL_PORT:
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index e5f3da8468cc..34bca16d48a6 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
48static const char ixgbe_driver_string[] = 48static const char ixgbe_driver_string[] =
49 "Intel(R) 10 Gigabit PCI Express Network Driver"; 49 "Intel(R) 10 Gigabit PCI Express Network Driver";
50 50
51#define DRV_VERSION "1.3.18-k2" 51#define DRV_VERSION "1.3.18-k4"
52const char ixgbe_driver_version[] = DRV_VERSION; 52const char ixgbe_driver_version[] = DRV_VERSION;
53static const char ixgbe_copyright[] = 53static const char ixgbe_copyright[] =
54 "Copyright (c) 1999-2007 Intel Corporation."; 54 "Copyright (c) 1999-2007 Intel Corporation.";
@@ -72,6 +72,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
72 board_82598 }, 72 board_82598 },
73 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), 73 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
74 board_82598 }, 74 board_82598 },
75 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
76 board_82598 },
75 77
76 /* required last entry */ 78 /* required last entry */
77 {0, } 79 {0, }
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 1ad7cb9c25a8..c0282a223df3 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -39,6 +39,7 @@
39#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 39#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
40#define IXGBE_DEV_ID_82598AT_DUAL_PORT 0x10C8 40#define IXGBE_DEV_ID_82598AT_DUAL_PORT 0x10C8
41#define IXGBE_DEV_ID_82598EB_CX4 0x10DD 41#define IXGBE_DEV_ID_82598EB_CX4 0x10DD
42#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
42 43
43/* General Registers */ 44/* General Registers */
44#define IXGBE_CTRL 0x00000 45#define IXGBE_CTRL 0x00000
diff --git a/drivers/net/ixp2000/ixp2400-msf.c b/drivers/net/ixp2000/ixp2400-msf.c
index 9ec38eebfb56..f5ffd7e05d26 100644
--- a/drivers/net/ixp2000/ixp2400-msf.c
+++ b/drivers/net/ixp2000/ixp2400-msf.c
@@ -13,8 +13,8 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <asm/hardware.h> 16#include <mach/hardware.h>
17#include <asm/arch/ixp2000-regs.h> 17#include <mach/ixp2000-regs.h>
18#include <asm/delay.h> 18#include <asm/delay.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include "ixp2400-msf.h" 20#include "ixp2400-msf.h"
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 7111c65f0b30..7b70c66504a0 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -16,7 +16,6 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <asm/hardware/uengine.h> 18#include <asm/hardware/uengine.h>
19#include <asm/mach-types.h>
20#include <asm/io.h> 19#include <asm/io.h>
21#include "ixp2400_rx.ucode" 20#include "ixp2400_rx.ucode"
22#include "ixp2400_tx.ucode" 21#include "ixp2400_tx.ucode"
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 49f6bc036a92..3b43bfd85a0f 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -64,68 +64,6 @@ struct pcpu_lstats {
64 unsigned long bytes; 64 unsigned long bytes;
65}; 65};
66 66
67/* KISS: just allocate small chunks and copy bits.
68 *
69 * So, in fact, this is documentation, explaining what we expect
70 * of largesending device modulo TCP checksum, which is ignored for loopback.
71 */
72
73#ifdef LOOPBACK_TSO
74static void emulate_large_send_offload(struct sk_buff *skb)
75{
76 struct iphdr *iph = ip_hdr(skb);
77 struct tcphdr *th = (struct tcphdr *)(skb_network_header(skb) +
78 (iph->ihl * 4));
79 unsigned int doffset = (iph->ihl + th->doff) * 4;
80 unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
81 unsigned int offset = 0;
82 u32 seq = ntohl(th->seq);
83 u16 id = ntohs(iph->id);
84
85 while (offset + doffset < skb->len) {
86 unsigned int frag_size = min(mtu, skb->len - offset) - doffset;
87 struct sk_buff *nskb = alloc_skb(mtu + 32, GFP_ATOMIC);
88
89 if (!nskb)
90 break;
91 skb_reserve(nskb, 32);
92 skb_set_mac_header(nskb, -ETH_HLEN);
93 skb_reset_network_header(nskb);
94 iph = ip_hdr(nskb);
95 skb_copy_to_linear_data(nskb, skb_network_header(skb),
96 doffset);
97 if (skb_copy_bits(skb,
98 doffset + offset,
99 nskb->data + doffset,
100 frag_size))
101 BUG();
102 skb_put(nskb, doffset + frag_size);
103 nskb->ip_summed = CHECKSUM_UNNECESSARY;
104 nskb->dev = skb->dev;
105 nskb->priority = skb->priority;
106 nskb->protocol = skb->protocol;
107 nskb->dst = dst_clone(skb->dst);
108 memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
109 nskb->pkt_type = skb->pkt_type;
110
111 th = (struct tcphdr *)(skb_network_header(nskb) + iph->ihl * 4);
112 iph->tot_len = htons(frag_size + doffset);
113 iph->id = htons(id);
114 iph->check = 0;
115 iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl);
116 th->seq = htonl(seq);
117 if (offset + doffset + frag_size < skb->len)
118 th->fin = th->psh = 0;
119 netif_rx(nskb);
120 offset += frag_size;
121 seq += frag_size;
122 id++;
123 }
124
125 dev_kfree_skb(skb);
126}
127#endif /* LOOPBACK_TSO */
128
129/* 67/*
130 * The higher levels take care of making this non-reentrant (it's 68 * The higher levels take care of making this non-reentrant (it's
131 * called with bh's disabled). 69 * called with bh's disabled).
@@ -137,9 +75,6 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
137 skb_orphan(skb); 75 skb_orphan(skb);
138 76
139 skb->protocol = eth_type_trans(skb,dev); 77 skb->protocol = eth_type_trans(skb,dev);
140#ifndef LOOPBACK_MUST_CHECKSUM
141 skb->ip_summed = CHECKSUM_UNNECESSARY;
142#endif
143 78
144#ifdef LOOPBACK_TSO 79#ifdef LOOPBACK_TSO
145 if (skb_is_gso(skb)) { 80 if (skb_is_gso(skb)) {
@@ -234,9 +169,7 @@ static void loopback_setup(struct net_device *dev)
234 dev->type = ARPHRD_LOOPBACK; /* 0x0001*/ 169 dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
235 dev->flags = IFF_LOOPBACK; 170 dev->flags = IFF_LOOPBACK;
236 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST 171 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
237#ifdef LOOPBACK_TSO
238 | NETIF_F_TSO 172 | NETIF_F_TSO
239#endif
240 | NETIF_F_NO_CSUM 173 | NETIF_F_NO_CSUM
241 | NETIF_F_HIGHDMA 174 | NETIF_F_HIGHDMA
242 | NETIF_F_LLTX 175 | NETIF_F_LLTX
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index 591a7e4220c7..83fa9d82a004 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -1272,8 +1272,6 @@ static void set_multicast_list(struct net_device *dev) {
1272 return; 1272 return;
1273 } 1273 }
1274 if (dev->mc_count == 0 && !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { 1274 if (dev->mc_count == 0 && !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
1275 if (dev->flags & IFF_ALLMULTI)
1276 dev->flags |= IFF_PROMISC;
1277 lp->i596_config[8] &= ~0x01; 1275 lp->i596_config[8] &= ~0x01;
1278 } else { 1276 } else {
1279 lp->i596_config[8] |= 0x01; 1277 lp->i596_config[8] |= 0x01;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index daba82bbcb56..84c77f1f9a5c 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -21,8 +21,8 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/phy.h> 22#include <linux/phy.h>
23 23
24#include <asm/arch/board.h> 24#include <mach/board.h>
25#include <asm/arch/cpu.h> 25#include <mach/cpu.h>
26 26
27#include "macb.h" 27#include "macb.h"
28 28
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 4cb364e67dc6..0a97c26df6ab 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -100,7 +100,7 @@ static inline void load_eaddr(struct net_device *dev)
100 DPRINTK("Loading MAC Address: %s\n", print_mac(mac, dev->dev_addr)); 100 DPRINTK("Loading MAC Address: %s\n", print_mac(mac, dev->dev_addr));
101 macaddr = 0; 101 macaddr = 0;
102 for (i = 0; i < 6; i++) 102 for (i = 0; i < 6; i++)
103 macaddr |= dev->dev_addr[i] << ((5 - i) * 8); 103 macaddr |= (u64)dev->dev_addr[i] << ((5 - i) * 8);
104 104
105 mace->eth.mac_addr = macaddr; 105 mace->eth.mac_addr = macaddr;
106} 106}
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 3ab0e5289f7a..5d76cd09e246 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -3548,7 +3548,11 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
3548 3548
3549 /* try to load the slice aware rss firmware */ 3549 /* try to load the slice aware rss firmware */
3550 old_fw = mgp->fw_name; 3550 old_fw = mgp->fw_name;
3551 if (old_fw == myri10ge_fw_aligned) 3551 if (myri10ge_fw_name != NULL) {
3552 dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n",
3553 myri10ge_fw_name);
3554 mgp->fw_name = myri10ge_fw_name;
3555 } else if (old_fw == myri10ge_fw_aligned)
3552 mgp->fw_name = myri10ge_fw_rss_aligned; 3556 mgp->fw_name = myri10ge_fw_rss_aligned;
3553 else 3557 else
3554 mgp->fw_name = myri10ge_fw_rss_unaligned; 3558 mgp->fw_name = myri10ge_fw_rss_unaligned;
@@ -3699,6 +3703,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3699 dev_err(&pdev->dev, "Error %d setting DMA mask\n", status); 3703 dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
3700 goto abort_with_netdev; 3704 goto abort_with_netdev;
3701 } 3705 }
3706 (void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
3702 mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd), 3707 mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
3703 &mgp->cmd_bus, GFP_KERNEL); 3708 &mgp->cmd_bus, GFP_KERNEL);
3704 if (mgp->cmd == NULL) 3709 if (mgp->cmd == NULL)
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index fdbeeee07372..993721090777 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -101,6 +101,8 @@ struct mcp_kreq_ether_recv {
101#define MXGEFW_ETH_SEND_3 0x2c0000 101#define MXGEFW_ETH_SEND_3 0x2c0000
102#define MXGEFW_ETH_RECV_SMALL 0x300000 102#define MXGEFW_ETH_RECV_SMALL 0x300000
103#define MXGEFW_ETH_RECV_BIG 0x340000 103#define MXGEFW_ETH_RECV_BIG 0x340000
104#define MXGEFW_ETH_SEND_GO 0x380000
105#define MXGEFW_ETH_SEND_STOP 0x3C0000
104 106
105#define MXGEFW_ETH_SEND(n) (0x200000 + (((n) & 0x03) * 0x40000)) 107#define MXGEFW_ETH_SEND(n) (0x200000 + (((n) & 0x03) * 0x40000))
106#define MXGEFW_ETH_SEND_OFFSET(n) (MXGEFW_ETH_SEND(n) - MXGEFW_ETH_SEND_4) 108#define MXGEFW_ETH_SEND_OFFSET(n) (MXGEFW_ETH_SEND(n) - MXGEFW_ETH_SEND_4)
@@ -120,6 +122,11 @@ enum myri10ge_mcp_cmd_type {
120 * MXGEFW_CMD_RESET is issued */ 122 * MXGEFW_CMD_RESET is issued */
121 123
122 MXGEFW_CMD_SET_INTRQ_DMA, 124 MXGEFW_CMD_SET_INTRQ_DMA,
125 /* data0 = LSW of the host address
126 * data1 = MSW of the host address
127 * data2 = slice number if multiple slices are used
128 */
129
123 MXGEFW_CMD_SET_BIG_BUFFER_SIZE, /* in bytes, power of 2 */ 130 MXGEFW_CMD_SET_BIG_BUFFER_SIZE, /* in bytes, power of 2 */
124 MXGEFW_CMD_SET_SMALL_BUFFER_SIZE, /* in bytes */ 131 MXGEFW_CMD_SET_SMALL_BUFFER_SIZE, /* in bytes */
125 132
@@ -129,6 +136,8 @@ enum myri10ge_mcp_cmd_type {
129 MXGEFW_CMD_GET_SEND_OFFSET, 136 MXGEFW_CMD_GET_SEND_OFFSET,
130 MXGEFW_CMD_GET_SMALL_RX_OFFSET, 137 MXGEFW_CMD_GET_SMALL_RX_OFFSET,
131 MXGEFW_CMD_GET_BIG_RX_OFFSET, 138 MXGEFW_CMD_GET_BIG_RX_OFFSET,
139 /* data0 = slice number if multiple slices are used */
140
132 MXGEFW_CMD_GET_IRQ_ACK_OFFSET, 141 MXGEFW_CMD_GET_IRQ_ACK_OFFSET,
133 MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, 142 MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
134 143
@@ -200,7 +209,12 @@ enum myri10ge_mcp_cmd_type {
200 MXGEFW_CMD_SET_STATS_DMA_V2, 209 MXGEFW_CMD_SET_STATS_DMA_V2,
201 /* data0, data1 = bus addr, 210 /* data0, data1 = bus addr,
202 * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows 211 * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows
203 * adding new stuff to mcp_irq_data without changing the ABI */ 212 * adding new stuff to mcp_irq_data without changing the ABI
213 *
214 * If multiple slices are used, data2 contains both the size of the
215 * structure (in the lower 16 bits) and the slice number
216 * (in the upper 16 bits).
217 */
204 218
205 MXGEFW_CMD_UNALIGNED_TEST, 219 MXGEFW_CMD_UNALIGNED_TEST,
206 /* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned 220 /* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
@@ -222,13 +236,18 @@ enum myri10ge_mcp_cmd_type {
222 MXGEFW_CMD_GET_MAX_RSS_QUEUES, 236 MXGEFW_CMD_GET_MAX_RSS_QUEUES,
223 MXGEFW_CMD_ENABLE_RSS_QUEUES, 237 MXGEFW_CMD_ENABLE_RSS_QUEUES,
224 /* data0 = number of slices n (0, 1, ..., n-1) to enable 238 /* data0 = number of slices n (0, 1, ..., n-1) to enable
225 * data1 = interrupt mode. 239 * data1 = interrupt mode | use of multiple transmit queues.
226 * 0=share one INTx/MSI, 1=use one MSI-X per queue. 240 * 0=share one INTx/MSI.
241 * 1=use one MSI-X per queue.
227 * If all queues share one interrupt, the driver must have set 242 * If all queues share one interrupt, the driver must have set
228 * RSS_SHARED_INTERRUPT_DMA before enabling queues. 243 * RSS_SHARED_INTERRUPT_DMA before enabling queues.
244 * 2=enable both receive and send queues.
245 * Without this bit set, only one send queue (slice 0's send queue)
246 * is enabled. The receive queues are always enabled.
229 */ 247 */
230#define MXGEFW_SLICE_INTR_MODE_SHARED 0 248#define MXGEFW_SLICE_INTR_MODE_SHARED 0x0
231#define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE 1 249#define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE 0x1
250#define MXGEFW_SLICE_ENABLE_MULTIPLE_TX_QUEUES 0x2
232 251
233 MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET, 252 MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
234 MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA, 253 MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
@@ -250,10 +269,13 @@ enum myri10ge_mcp_cmd_type {
250 * 2: TCP_IPV4 (required by RSS) 269 * 2: TCP_IPV4 (required by RSS)
251 * 3: IPV4 | TCP_IPV4 (required by RSS) 270 * 3: IPV4 | TCP_IPV4 (required by RSS)
252 * 4: source port 271 * 4: source port
272 * 5: source port + destination port
253 */ 273 */
254#define MXGEFW_RSS_HASH_TYPE_IPV4 0x1 274#define MXGEFW_RSS_HASH_TYPE_IPV4 0x1
255#define MXGEFW_RSS_HASH_TYPE_TCP_IPV4 0x2 275#define MXGEFW_RSS_HASH_TYPE_TCP_IPV4 0x2
256#define MXGEFW_RSS_HASH_TYPE_SRC_PORT 0x4 276#define MXGEFW_RSS_HASH_TYPE_SRC_PORT 0x4
277#define MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT 0x5
278#define MXGEFW_RSS_HASH_TYPE_MAX 0x5
257 279
258 MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, 280 MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
259 /* Return data = the max. size of the entire headers of a IPv6 TSO packet. 281 /* Return data = the max. size of the entire headers of a IPv6 TSO packet.
@@ -329,6 +351,20 @@ enum myri10ge_mcp_cmd_type {
329 351
330 MXGEFW_CMD_GET_DCA_OFFSET, 352 MXGEFW_CMD_GET_DCA_OFFSET,
331 /* offset of dca control for WDMAs */ 353 /* offset of dca control for WDMAs */
354
355 /* VMWare NetQueue commands */
356 MXGEFW_CMD_NETQ_GET_FILTERS_PER_QUEUE,
357 MXGEFW_CMD_NETQ_ADD_FILTER,
358 /* data0 = filter_id << 16 | queue << 8 | type */
359 /* data1 = MS4 of MAC Addr */
360 /* data2 = LS2_MAC << 16 | VLAN_tag */
361 MXGEFW_CMD_NETQ_DEL_FILTER,
362 /* data0 = filter_id */
363 MXGEFW_CMD_NETQ_QUERY1,
364 MXGEFW_CMD_NETQ_QUERY2,
365 MXGEFW_CMD_NETQ_QUERY3,
366 MXGEFW_CMD_NETQ_QUERY4,
367
332}; 368};
333 369
334enum myri10ge_mcp_cmd_status { 370enum myri10ge_mcp_cmd_status {
@@ -381,4 +417,10 @@ struct mcp_irq_data {
381 u8 valid; 417 u8 valid;
382}; 418};
383 419
420/* definitions for NETQ filter type */
421#define MXGEFW_NETQ_FILTERTYPE_NONE 0
422#define MXGEFW_NETQ_FILTERTYPE_MACADDR 1
423#define MXGEFW_NETQ_FILTERTYPE_VLAN 2
424#define MXGEFW_NETQ_FILTERTYPE_VLANMACADDR 3
425
384#endif /* __MYRI10GE_MCP_H__ */ 426#endif /* __MYRI10GE_MCP_H__ */
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
index 07d65c2cbb24..a8662ea8079a 100644
--- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
@@ -35,7 +35,7 @@ struct mcp_gen_header {
35 unsigned char mcp_index; 35 unsigned char mcp_index;
36 unsigned char disable_rabbit; 36 unsigned char disable_rabbit;
37 unsigned char unaligned_tlp; 37 unsigned char unaligned_tlp;
38 unsigned char pad1; 38 unsigned char pcie_link_algo;
39 unsigned counters_addr; 39 unsigned counters_addr;
40 unsigned copy_block_info; /* for small mcps loaded with "lload -d" */ 40 unsigned copy_block_info; /* for small mcps loaded with "lload -d" */
41 unsigned short handoff_id_major; /* must be equal */ 41 unsigned short handoff_id_major; /* must be equal */
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 42443d697423..fa3ceca4e15c 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -118,7 +118,7 @@ bad_clone_list[] __initdata = {
118 {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ 118 {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
119 {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ 119 {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
120 {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ 120 {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
121#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) 121#ifdef CONFIG_MACH_TX49XX
122 {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ 122 {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
123#endif 123#endif
124 {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ 124 {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
142#if defined(CONFIG_PLAT_MAPPI) 142#if defined(CONFIG_PLAT_MAPPI)
143# define DCR_VAL 0x4b 143# define DCR_VAL 0x4b
144#elif defined(CONFIG_PLAT_OAKS32R) || \ 144#elif defined(CONFIG_PLAT_OAKS32R) || \
145 defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) 145 defined(CONFIG_MACH_TX49XX)
146# define DCR_VAL 0x48 /* 8-bit mode */ 146# define DCR_VAL 0x48 /* 8-bit mode */
147#else 147#else
148# define DCR_VAL 0x49 148# define DCR_VAL 0x49
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index dc442e370850..3f9af759cb90 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -29,12 +29,11 @@
29#include <linux/mii.h> 29#include <linux/mii.h>
30 30
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/hardware.h> 32#include <mach/hardware.h>
33#include <asm/arch/hardware.h> 33#include <mach/netx-regs.h>
34#include <asm/arch/netx-regs.h> 34#include <mach/pfifo.h>
35#include <asm/arch/pfifo.h> 35#include <mach/xc.h>
36#include <asm/arch/xc.h> 36#include <mach/eth.h>
37#include <asm/arch/eth.h>
38 37
39/* XC Fifo Offsets */ 38/* XC Fifo Offsets */
40#define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */ 39#define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 8e736614407d..ab871df6b1db 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -66,8 +66,8 @@
66 66
67#define _NETXEN_NIC_LINUX_MAJOR 4 67#define _NETXEN_NIC_LINUX_MAJOR 4
68#define _NETXEN_NIC_LINUX_MINOR 0 68#define _NETXEN_NIC_LINUX_MINOR 0
69#define _NETXEN_NIC_LINUX_SUBVERSION 0 69#define _NETXEN_NIC_LINUX_SUBVERSION 11
70#define NETXEN_NIC_LINUX_VERSIONID "4.0.0" 70#define NETXEN_NIC_LINUX_VERSIONID "4.0.11"
71 71
72#define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c)) 72#define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c))
73 73
@@ -508,6 +508,8 @@ typedef enum {
508 NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027, 508 NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027,
509 NETXEN_BRDTYPE_P3_XG_LOM = 0x0028, 509 NETXEN_BRDTYPE_P3_XG_LOM = 0x0028,
510 NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029, 510 NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029,
511 NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a,
512 NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b,
511 NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031, 513 NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
512 NETXEN_BRDTYPE_P3_10G_XFP = 0x0032 514 NETXEN_BRDTYPE_P3_10G_XFP = 0x0032
513 515
@@ -1170,6 +1172,36 @@ typedef struct {
1170 nx_nic_intr_coalesce_data_t irq; 1172 nx_nic_intr_coalesce_data_t irq;
1171} nx_nic_intr_coalesce_t; 1173} nx_nic_intr_coalesce_t;
1172 1174
1175#define NX_HOST_REQUEST 0x13
1176#define NX_NIC_REQUEST 0x14
1177
1178#define NX_MAC_EVENT 0x1
1179
1180enum {
1181 NX_NIC_H2C_OPCODE_START = 0,
1182 NX_NIC_H2C_OPCODE_CONFIG_RSS,
1183 NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL,
1184 NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE,
1185 NX_NIC_H2C_OPCODE_CONFIG_LED,
1186 NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS,
1187 NX_NIC_H2C_OPCODE_CONFIG_L2_MAC,
1188 NX_NIC_H2C_OPCODE_LRO_REQUEST,
1189 NX_NIC_H2C_OPCODE_GET_SNMP_STATS,
1190 NX_NIC_H2C_OPCODE_PROXY_START_REQUEST,
1191 NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST,
1192 NX_NIC_H2C_OPCODE_PROXY_SET_MTU,
1193 NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE,
1194 NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST,
1195 NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST,
1196 NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST,
1197 NX_NIC_H2C_OPCODE_GET_NET_STATS,
1198 NX_NIC_H2C_OPCODE_LAST
1199};
1200
1201#define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */
1202#define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */
1203#define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */
1204
1173typedef struct { 1205typedef struct {
1174 u64 qhdr; 1206 u64 qhdr;
1175 u64 req_hdr; 1207 u64 req_hdr;
@@ -1288,7 +1320,7 @@ struct netxen_adapter {
1288 int (*disable_phy_interrupts) (struct netxen_adapter *); 1320 int (*disable_phy_interrupts) (struct netxen_adapter *);
1289 int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t); 1321 int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
1290 int (*set_mtu) (struct netxen_adapter *, int); 1322 int (*set_mtu) (struct netxen_adapter *, int);
1291 int (*set_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t); 1323 int (*set_promisc) (struct netxen_adapter *, u32);
1292 int (*phy_read) (struct netxen_adapter *, long reg, u32 *); 1324 int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
1293 int (*phy_write) (struct netxen_adapter *, long reg, u32 val); 1325 int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
1294 int (*init_port) (struct netxen_adapter *, int); 1326 int (*init_port) (struct netxen_adapter *, int);
@@ -1465,9 +1497,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter);
1465u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); 1497u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
1466void netxen_p2_nic_set_multi(struct net_device *netdev); 1498void netxen_p2_nic_set_multi(struct net_device *netdev);
1467void netxen_p3_nic_set_multi(struct net_device *netdev); 1499void netxen_p3_nic_set_multi(struct net_device *netdev);
1500int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
1468int netxen_config_intr_coalesce(struct netxen_adapter *adapter); 1501int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
1469 1502
1470u32 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu); 1503int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
1471int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); 1504int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
1472 1505
1473int netxen_nic_set_mac(struct net_device *netdev, void *p); 1506int netxen_nic_set_mac(struct net_device *netdev, void *p);
@@ -1502,7 +1535,9 @@ static const struct netxen_brdinfo netxen_boards[] = {
1502 {NETXEN_BRDTYPE_P3_10G_SFP_PLUS, 2, "Dual XGb SFP+ LP"}, 1535 {NETXEN_BRDTYPE_P3_10G_SFP_PLUS, 2, "Dual XGb SFP+ LP"},
1503 {NETXEN_BRDTYPE_P3_10000_BASE_T, 1, "XGB 10G BaseT LP"}, 1536 {NETXEN_BRDTYPE_P3_10000_BASE_T, 1, "XGB 10G BaseT LP"},
1504 {NETXEN_BRDTYPE_P3_XG_LOM, 2, "Dual XGb LOM"}, 1537 {NETXEN_BRDTYPE_P3_XG_LOM, 2, "Dual XGb LOM"},
1505 {NETXEN_BRDTYPE_P3_4_GB_MM, 4, "Quad GB - March Madness"}, 1538 {NETXEN_BRDTYPE_P3_4_GB_MM, 4, "NX3031 Gigabit Ethernet"},
1539 {NETXEN_BRDTYPE_P3_10G_SFP_CT, 2, "NX3031 10 Gigabit Ethernet"},
1540 {NETXEN_BRDTYPE_P3_10G_SFP_QT, 2, "Quanta Dual XGb SFP+"},
1506 {NETXEN_BRDTYPE_P3_10G_CX4, 2, "Reference Dual CX4 Option"}, 1541 {NETXEN_BRDTYPE_P3_10G_CX4, 2, "Reference Dual CX4 Option"},
1507 {NETXEN_BRDTYPE_P3_10G_XFP, 1, "Reference Single XFP Option"} 1542 {NETXEN_BRDTYPE_P3_10G_XFP, 1, "Reference Single XFP Option"}
1508}; 1543};
@@ -1580,7 +1615,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
1580 1615
1581 1616
1582int netxen_is_flash_supported(struct netxen_adapter *adapter); 1617int netxen_is_flash_supported(struct netxen_adapter *adapter);
1583int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]); 1618int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
1619int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
1584extern void netxen_change_ringparam(struct netxen_adapter *adapter); 1620extern void netxen_change_ringparam(struct netxen_adapter *adapter);
1585extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, 1621extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
1586 int *valp); 1622 int *valp);
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 64babc59e699..64b51643c626 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -145,8 +145,8 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
145 return rcode; 145 return rcode;
146} 146}
147 147
148u32 148int
149nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu) 149nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
150{ 150{
151 u32 rcode = NX_RCODE_SUCCESS; 151 u32 rcode = NX_RCODE_SUCCESS;
152 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0]; 152 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
@@ -160,7 +160,10 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu)
160 0, 160 0,
161 NX_CDRP_CMD_SET_MTU); 161 NX_CDRP_CMD_SET_MTU);
162 162
163 return rcode; 163 if (rcode != NX_RCODE_SUCCESS)
164 return -EIO;
165
166 return 0;
164} 167}
165 168
166static int 169static int
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 48ee06b6f4e9..4ad3e0844b99 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -140,18 +140,33 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
140 if (netif_running(dev)) { 140 if (netif_running(dev)) {
141 ecmd->speed = adapter->link_speed; 141 ecmd->speed = adapter->link_speed;
142 ecmd->duplex = adapter->link_duplex; 142 ecmd->duplex = adapter->link_duplex;
143 } else 143 ecmd->autoneg = adapter->link_autoneg;
144 return -EIO; /* link absent */ 144 }
145
145 } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { 146 } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
146 ecmd->supported = (SUPPORTED_TP | 147 u32 val;
147 SUPPORTED_1000baseT_Full | 148
148 SUPPORTED_10000baseT_Full); 149 adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
149 ecmd->advertising = (ADVERTISED_TP | 150 if (val == NETXEN_PORT_MODE_802_3_AP) {
150 ADVERTISED_1000baseT_Full | 151 ecmd->supported = SUPPORTED_1000baseT_Full;
151 ADVERTISED_10000baseT_Full); 152 ecmd->advertising = ADVERTISED_1000baseT_Full;
153 } else {
154 ecmd->supported = SUPPORTED_10000baseT_Full;
155 ecmd->advertising = ADVERTISED_10000baseT_Full;
156 }
157
152 ecmd->port = PORT_TP; 158 ecmd->port = PORT_TP;
153 159
154 ecmd->speed = SPEED_10000; 160 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
161 u16 pcifn = adapter->ahw.pci_func;
162
163 adapter->hw_read_wx(adapter,
164 P3_LINK_SPEED_REG(pcifn), &val, 4);
165 ecmd->speed = P3_LINK_SPEED_MHZ *
166 P3_LINK_SPEED_VAL(pcifn, val);
167 } else
168 ecmd->speed = SPEED_10000;
169
155 ecmd->duplex = DUPLEX_FULL; 170 ecmd->duplex = DUPLEX_FULL;
156 ecmd->autoneg = AUTONEG_DISABLE; 171 ecmd->autoneg = AUTONEG_DISABLE;
157 } else 172 } else
@@ -192,6 +207,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
192 break; 207 break;
193 case NETXEN_BRDTYPE_P2_SB31_10G: 208 case NETXEN_BRDTYPE_P2_SB31_10G:
194 case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: 209 case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
210 case NETXEN_BRDTYPE_P3_10G_SFP_CT:
211 case NETXEN_BRDTYPE_P3_10G_SFP_QT:
195 case NETXEN_BRDTYPE_P3_10G_XFP: 212 case NETXEN_BRDTYPE_P3_10G_XFP:
196 ecmd->supported |= SUPPORTED_FIBRE; 213 ecmd->supported |= SUPPORTED_FIBRE;
197 ecmd->advertising |= ADVERTISED_FIBRE; 214 ecmd->advertising |= ADVERTISED_FIBRE;
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 3ce13e451aac..e8e8d73f6ed7 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -724,6 +724,13 @@ enum {
724#define XG_LINK_STATE_P3(pcifn,val) \ 724#define XG_LINK_STATE_P3(pcifn,val) \
725 (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK) 725 (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK)
726 726
727#define P3_LINK_SPEED_MHZ 100
728#define P3_LINK_SPEED_MASK 0xff
729#define P3_LINK_SPEED_REG(pcifn) \
730 (CRB_PF_LINK_SPEED_1 + (((pcifn) / 4) * 4))
731#define P3_LINK_SPEED_VAL(pcifn, reg) \
732 (((reg) >> (8 * ((pcifn) & 0x3))) & P3_LINK_SPEED_MASK)
733
727#define NETXEN_CAM_RAM_BASE (NETXEN_CRB_CAM + 0x02000) 734#define NETXEN_CAM_RAM_BASE (NETXEN_CRB_CAM + 0x02000)
728#define NETXEN_CAM_RAM(reg) (NETXEN_CAM_RAM_BASE + (reg)) 735#define NETXEN_CAM_RAM(reg) (NETXEN_CAM_RAM_BASE + (reg))
729#define NETXEN_FW_VERSION_MAJOR (NETXEN_CAM_RAM(0x150)) 736#define NETXEN_FW_VERSION_MAJOR (NETXEN_CAM_RAM(0x150))
@@ -836,9 +843,11 @@ enum {
836 843
837#define PCIE_SETUP_FUNCTION (0x12040) 844#define PCIE_SETUP_FUNCTION (0x12040)
838#define PCIE_SETUP_FUNCTION2 (0x12048) 845#define PCIE_SETUP_FUNCTION2 (0x12048)
846#define PCIE_MISCCFG_RC (0x1206c)
839#define PCIE_TGT_SPLIT_CHICKEN (0x12080) 847#define PCIE_TGT_SPLIT_CHICKEN (0x12080)
840#define PCIE_CHICKEN3 (0x120c8) 848#define PCIE_CHICKEN3 (0x120c8)
841 849
850#define ISR_INT_STATE_REG (NETXEN_PCIX_PS_REG(PCIE_MISCCFG_RC))
842#define PCIE_MAX_MASTER_SPLIT (0x14048) 851#define PCIE_MAX_MASTER_SPLIT (0x14048)
843 852
844#define NETXEN_PORT_MODE_NONE 0 853#define NETXEN_PORT_MODE_NONE 0
@@ -854,6 +863,7 @@ enum {
854#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) 863#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14)
855 864
856#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC))) 865#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
866#define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200)
857 867
858/* 868/*
859 * PCI Interrupt Vector Values. 869 * PCI Interrupt Vector Values.
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 96a3bc6426e2..84978f80f396 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -285,14 +285,7 @@ static unsigned crb_hub_agt[64] =
285#define ADDR_IN_RANGE(addr, low, high) \ 285#define ADDR_IN_RANGE(addr, low, high) \
286 (((addr) <= (high)) && ((addr) >= (low))) 286 (((addr) <= (high)) && ((addr) >= (low)))
287 287
288#define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
289#define NETXEN_MIN_MTU 64
290#define NETXEN_ETH_FCS_SIZE 4
291#define NETXEN_ENET_HEADER_SIZE 14
292#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ 288#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */
293#define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4)
294#define NETXEN_NIU_HDRSIZE (0x1 << 6)
295#define NETXEN_NIU_TLRSIZE (0x1 << 5)
296 289
297#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL 290#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL
298#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL 291#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL
@@ -541,9 +534,6 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
541 return 0; 534 return 0;
542} 535}
543 536
544#define NIC_REQUEST 0x14
545#define NETXEN_MAC_EVENT 0x1
546
547static int nx_p3_sre_macaddr_change(struct net_device *dev, 537static int nx_p3_sre_macaddr_change(struct net_device *dev,
548 u8 *addr, unsigned op) 538 u8 *addr, unsigned op)
549{ 539{
@@ -553,8 +543,8 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
553 int rv; 543 int rv;
554 544
555 memset(&req, 0, sizeof(nx_nic_req_t)); 545 memset(&req, 0, sizeof(nx_nic_req_t));
556 req.qhdr |= (NIC_REQUEST << 23); 546 req.qhdr |= (NX_NIC_REQUEST << 23);
557 req.req_hdr |= NETXEN_MAC_EVENT; 547 req.req_hdr |= NX_MAC_EVENT;
558 req.req_hdr |= ((u64)adapter->portnum << 16); 548 req.req_hdr |= ((u64)adapter->portnum << 16);
559 mac_req.op = op; 549 mac_req.op = op;
560 memcpy(&mac_req.mac_addr, addr, 6); 550 memcpy(&mac_req.mac_addr, addr, 6);
@@ -575,31 +565,35 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
575 nx_mac_list_t *cur, *next, *del_list, *add_list = NULL; 565 nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
576 struct dev_mc_list *mc_ptr; 566 struct dev_mc_list *mc_ptr;
577 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 567 u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
578 568 u32 mode = VPORT_MISS_MODE_DROP;
579 adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE);
580
581 /*
582 * Programming mac addresses will automaticly enabling L2 filtering.
583 * HW will replace timestamp with L2 conid when L2 filtering is
584 * enabled. This causes problem for LSA. Do not enabling L2 filtering
585 * until that problem is fixed.
586 */
587 if ((netdev->flags & IFF_PROMISC) ||
588 (netdev->mc_count > adapter->max_mc_count))
589 return;
590 569
591 del_list = adapter->mac_list; 570 del_list = adapter->mac_list;
592 adapter->mac_list = NULL; 571 adapter->mac_list = NULL;
593 572
594 nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list); 573 nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
574 nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
575
576 if (netdev->flags & IFF_PROMISC) {
577 mode = VPORT_MISS_MODE_ACCEPT_ALL;
578 goto send_fw_cmd;
579 }
580
581 if ((netdev->flags & IFF_ALLMULTI) ||
582 (netdev->mc_count > adapter->max_mc_count)) {
583 mode = VPORT_MISS_MODE_ACCEPT_MULTI;
584 goto send_fw_cmd;
585 }
586
595 if (netdev->mc_count > 0) { 587 if (netdev->mc_count > 0) {
596 nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
597 for (mc_ptr = netdev->mc_list; mc_ptr; 588 for (mc_ptr = netdev->mc_list; mc_ptr;
598 mc_ptr = mc_ptr->next) { 589 mc_ptr = mc_ptr->next) {
599 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, 590 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
600 &add_list, &del_list); 591 &add_list, &del_list);
601 } 592 }
602 } 593 }
594
595send_fw_cmd:
596 adapter->set_promisc(adapter, mode);
603 for (cur = del_list; cur;) { 597 for (cur = del_list; cur;) {
604 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL); 598 nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
605 next = cur->next; 599 next = cur->next;
@@ -615,6 +609,21 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
615 } 609 }
616} 610}
617 611
612int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
613{
614 nx_nic_req_t req;
615
616 memset(&req, 0, sizeof(nx_nic_req_t));
617
618 req.qhdr |= (NX_HOST_REQUEST << 23);
619 req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
620 req.req_hdr |= ((u64)adapter->portnum << 16);
621 req.words[0] = cpu_to_le64(mode);
622
623 return netxen_send_cmd_descs(adapter,
624 (struct cmd_desc_type0 *)&req, 1);
625}
626
618#define NETXEN_CONFIG_INTR_COALESCE 3 627#define NETXEN_CONFIG_INTR_COALESCE 3
619 628
620/* 629/*
@@ -627,7 +636,7 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
627 636
628 memset(&req, 0, sizeof(nx_nic_req_t)); 637 memset(&req, 0, sizeof(nx_nic_req_t));
629 638
630 req.qhdr |= (NIC_REQUEST << 23); 639 req.qhdr |= (NX_NIC_REQUEST << 23);
631 req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE; 640 req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE;
632 req.req_hdr |= ((u64)adapter->portnum << 16); 641 req.req_hdr |= ((u64)adapter->portnum << 16);
633 642
@@ -653,6 +662,7 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
653{ 662{
654 struct netxen_adapter *adapter = netdev_priv(netdev); 663 struct netxen_adapter *adapter = netdev_priv(netdev);
655 int max_mtu; 664 int max_mtu;
665 int rc = 0;
656 666
657 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 667 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
658 max_mtu = P3_MAX_MTU; 668 max_mtu = P3_MAX_MTU;
@@ -666,16 +676,12 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
666 } 676 }
667 677
668 if (adapter->set_mtu) 678 if (adapter->set_mtu)
669 adapter->set_mtu(adapter, mtu); 679 rc = adapter->set_mtu(adapter, mtu);
670 netdev->mtu = mtu;
671 680
672 mtu += MTU_FUDGE_FACTOR; 681 if (!rc)
673 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 682 netdev->mtu = mtu;
674 nx_fw_cmd_set_mtu(adapter, mtu);
675 else if (adapter->set_mtu)
676 adapter->set_mtu(adapter, mtu);
677 683
678 return 0; 684 return rc;
679} 685}
680 686
681int netxen_is_flash_supported(struct netxen_adapter *adapter) 687int netxen_is_flash_supported(struct netxen_adapter *adapter)
@@ -727,31 +733,56 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
727 return 0; 733 return 0;
728} 734}
729 735
730int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]) 736int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
731{ 737{
732 __le32 *pmac = (__le32 *) & mac[0]; 738 __le32 *pmac = (__le32 *) mac;
739 u32 offset;
740
741 offset = NETXEN_USER_START +
742 offsetof(struct netxen_new_user_info, mac_addr) +
743 adapter->portnum * sizeof(u64);
733 744
734 if (netxen_get_flash_block(adapter, 745 if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
735 NETXEN_USER_START +
736 offsetof(struct netxen_new_user_info,
737 mac_addr),
738 FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
739 return -1; 746 return -1;
740 } 747
741 if (*mac == cpu_to_le64(~0ULL)) { 748 if (*mac == cpu_to_le64(~0ULL)) {
749
750 offset = NETXEN_USER_START_OLD +
751 offsetof(struct netxen_user_old_info, mac_addr) +
752 adapter->portnum * sizeof(u64);
753
742 if (netxen_get_flash_block(adapter, 754 if (netxen_get_flash_block(adapter,
743 NETXEN_USER_START_OLD + 755 offset, sizeof(u64), pmac) == -1)
744 offsetof(struct netxen_user_old_info,
745 mac_addr),
746 FLASH_NUM_PORTS * sizeof(u64),
747 pmac) == -1)
748 return -1; 756 return -1;
757
749 if (*mac == cpu_to_le64(~0ULL)) 758 if (*mac == cpu_to_le64(~0ULL))
750 return -1; 759 return -1;
751 } 760 }
752 return 0; 761 return 0;
753} 762}
754 763
764int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
765{
766 uint32_t crbaddr, mac_hi, mac_lo;
767 int pci_func = adapter->ahw.pci_func;
768
769 crbaddr = CRB_MAC_BLOCK_START +
770 (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
771
772 adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
773 adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
774
775 mac_hi = cpu_to_le32(mac_hi);
776 mac_lo = cpu_to_le32(mac_lo);
777
778 if (pci_func & 1)
779 *mac = ((mac_lo >> 16) | ((u64)mac_hi << 16));
780 else
781 *mac = ((mac_lo) | ((u64)mac_hi << 32));
782
783 return 0;
784}
785
755#define CRB_WIN_LOCK_TIMEOUT 100000000 786#define CRB_WIN_LOCK_TIMEOUT 100000000
756 787
757static int crb_win_lock(struct netxen_adapter *adapter) 788static int crb_win_lock(struct netxen_adapter *adapter)
@@ -1411,7 +1442,8 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
1411 (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { 1442 (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
1412 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1443 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1413 printk(KERN_ERR "%s out of bound pci memory access. " 1444 printk(KERN_ERR "%s out of bound pci memory access. "
1414 "offset is 0x%llx\n", netxen_nic_driver_name, off); 1445 "offset is 0x%llx\n", netxen_nic_driver_name,
1446 (unsigned long long)off);
1415 return -1; 1447 return -1;
1416 } 1448 }
1417 1449
@@ -1484,7 +1516,8 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
1484 (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) { 1516 (netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
1485 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1517 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1486 printk(KERN_ERR "%s out of bound pci memory access. " 1518 printk(KERN_ERR "%s out of bound pci memory access. "
1487 "offset is 0x%llx\n", netxen_nic_driver_name, off); 1519 "offset is 0x%llx\n", netxen_nic_driver_name,
1520 (unsigned long long)off);
1488 return -1; 1521 return -1;
1489 } 1522 }
1490 1523
@@ -2016,6 +2049,8 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
2016 case NETXEN_BRDTYPE_P3_10G_CX4_LP: 2049 case NETXEN_BRDTYPE_P3_10G_CX4_LP:
2017 case NETXEN_BRDTYPE_P3_IMEZ: 2050 case NETXEN_BRDTYPE_P3_IMEZ:
2018 case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: 2051 case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
2052 case NETXEN_BRDTYPE_P3_10G_SFP_CT:
2053 case NETXEN_BRDTYPE_P3_10G_SFP_QT:
2019 case NETXEN_BRDTYPE_P3_10G_XFP: 2054 case NETXEN_BRDTYPE_P3_10G_XFP:
2020 case NETXEN_BRDTYPE_P3_10000_BASE_T: 2055 case NETXEN_BRDTYPE_P3_10000_BASE_T:
2021 2056
@@ -2034,6 +2069,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
2034 default: 2069 default:
2035 printk("%s: Unknown(%x)\n", netxen_nic_driver_name, 2070 printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
2036 boardinfo->board_type); 2071 boardinfo->board_type);
2072 rv = -ENODEV;
2037 break; 2073 break;
2038 } 2074 }
2039 2075
@@ -2044,6 +2080,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
2044 2080
2045int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) 2081int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
2046{ 2082{
2083 new_mtu += MTU_FUDGE_FACTOR;
2047 netxen_nic_write_w0(adapter, 2084 netxen_nic_write_w0(adapter,
2048 NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), 2085 NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
2049 new_mtu); 2086 new_mtu);
@@ -2052,7 +2089,7 @@ int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
2052 2089
2053int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) 2090int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
2054{ 2091{
2055 new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; 2092 new_mtu += MTU_FUDGE_FACTOR;
2056 if (adapter->physical_port == 0) 2093 if (adapter->physical_port == 0)
2057 netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, 2094 netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
2058 new_mtu); 2095 new_mtu);
@@ -2074,12 +2111,22 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
2074 __u32 status; 2111 __u32 status;
2075 __u32 autoneg; 2112 __u32 autoneg;
2076 __u32 mode; 2113 __u32 mode;
2114 __u32 port_mode;
2077 2115
2078 netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); 2116 netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
2079 if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ 2117 if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */
2118
2119 adapter->hw_read_wx(adapter,
2120 NETXEN_PORT_MODE_ADDR, &port_mode, 4);
2121 if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
2122 adapter->link_speed = SPEED_1000;
2123 adapter->link_duplex = DUPLEX_FULL;
2124 adapter->link_autoneg = AUTONEG_DISABLE;
2125 return;
2126 }
2127
2080 if (adapter->phy_read 2128 if (adapter->phy_read
2081 && adapter-> 2129 && adapter->phy_read(adapter,
2082 phy_read(adapter,
2083 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 2130 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
2084 &status) == 0) { 2131 &status) == 0) {
2085 if (netxen_get_phy_link(status)) { 2132 if (netxen_get_phy_link(status)) {
@@ -2109,8 +2156,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
2109 break; 2156 break;
2110 } 2157 }
2111 if (adapter->phy_read 2158 if (adapter->phy_read
2112 && adapter-> 2159 && adapter->phy_read(adapter,
2113 phy_read(adapter,
2114 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, 2160 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
2115 &autoneg) != 0) 2161 &autoneg) != 0)
2116 adapter->link_autoneg = autoneg; 2162 adapter->link_autoneg = autoneg;
@@ -2162,10 +2208,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
2162 if (adapter->portnum == 0) { 2208 if (adapter->portnum == 0) {
2163 get_brd_name_by_type(board_info->board_type, brd_name); 2209 get_brd_name_by_type(board_info->board_type, brd_name);
2164 2210
2165 printk("NetXen %s Board S/N %s Chip id 0x%x\n", 2211 printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n",
2166 brd_name, serial_num, board_info->chip_id); 2212 brd_name, serial_num, adapter->ahw.revision_id);
2167 printk("NetXen Firmware version %d.%d.%d\n", fw_major, 2213 printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
2168 fw_minor, fw_build); 2214 fw_major, fw_minor, fw_build);
2169 } 2215 }
2170 2216
2171 if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) < 2217 if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index b8e0030f03d7..aae737dc77a8 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -419,12 +419,9 @@ typedef enum {
419#define netxen_get_niu_enable_ge(config_word) \ 419#define netxen_get_niu_enable_ge(config_word) \
420 _netxen_crb_get_bit(config_word, 1) 420 _netxen_crb_get_bit(config_word, 1)
421 421
422/* Promiscous mode options (GbE mode only) */ 422#define NETXEN_NIU_NON_PROMISC_MODE 0
423typedef enum { 423#define NETXEN_NIU_PROMISC_MODE 1
424 NETXEN_NIU_PROMISC_MODE = 0, 424#define NETXEN_NIU_ALLMULTI_MODE 2
425 NETXEN_NIU_NON_PROMISC_MODE,
426 NETXEN_NIU_ALLMULTI_MODE
427} netxen_niu_prom_mode_t;
428 425
429/* 426/*
430 * NIU GB Drop CRC Register 427 * NIU GB Drop CRC Register
@@ -471,9 +468,9 @@ typedef enum {
471 468
472/* Set promiscuous mode for a GbE interface */ 469/* Set promiscuous mode for a GbE interface */
473int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, 470int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
474 netxen_niu_prom_mode_t mode); 471 u32 mode);
475int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 472int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
476 netxen_niu_prom_mode_t mode); 473 u32 mode);
477 474
478/* set the MAC address for a given MAC */ 475/* set the MAC address for a given MAC */
479int netxen_niu_macaddr_set(struct netxen_adapter *adapter, 476int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 01ab31b34a85..5bba675d0504 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -364,6 +364,11 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
364 default: 364 default:
365 break; 365 break;
366 } 366 }
367
368 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
369 adapter->set_mtu = nx_fw_cmd_set_mtu;
370 adapter->set_promisc = netxen_p3_nic_set_promisc;
371 }
367} 372}
368 373
369/* 374/*
@@ -1074,10 +1079,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
1074 1079
1075void netxen_free_adapter_offload(struct netxen_adapter *adapter) 1080void netxen_free_adapter_offload(struct netxen_adapter *adapter)
1076{ 1081{
1077 int i; 1082 int i = 100;
1083
1084 if (!adapter->dummy_dma.addr)
1085 return;
1078 1086
1079 if (adapter->dummy_dma.addr) { 1087 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1080 i = 100;
1081 do { 1088 do {
1082 if (dma_watchdog_shutdown_request(adapter) == 1) 1089 if (dma_watchdog_shutdown_request(adapter) == 1)
1083 break; 1090 break;
@@ -1085,17 +1092,17 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
1085 if (dma_watchdog_shutdown_poll_result(adapter) == 1) 1092 if (dma_watchdog_shutdown_poll_result(adapter) == 1)
1086 break; 1093 break;
1087 } while (--i); 1094 } while (--i);
1095 }
1088 1096
1089 if (i) { 1097 if (i) {
1090 pci_free_consistent(adapter->pdev, 1098 pci_free_consistent(adapter->pdev,
1091 NETXEN_HOST_DUMMY_DMA_SIZE, 1099 NETXEN_HOST_DUMMY_DMA_SIZE,
1092 adapter->dummy_dma.addr, 1100 adapter->dummy_dma.addr,
1093 adapter->dummy_dma.phys_addr); 1101 adapter->dummy_dma.phys_addr);
1094 adapter->dummy_dma.addr = NULL; 1102 adapter->dummy_dma.addr = NULL;
1095 } else { 1103 } else {
1096 printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n", 1104 printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
1097 adapter->netdev->name); 1105 adapter->netdev->name);
1098 }
1099 } 1106 }
1100} 1107}
1101 1108
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 91d209a8f6cb..32bb47adbe39 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -149,80 +149,18 @@ static uint32_t msi_tgt_status[8] = {
149 149
150static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; 150static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
151 151
152static void netxen_nic_disable_int(struct netxen_adapter *adapter) 152static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
153{ 153{
154 u32 mask = 0x7ff; 154 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
155 int retries = 32;
156 int pci_fn = adapter->ahw.pci_func;
157
158 if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
159 adapter->pci_write_normalize(adapter,
160 adapter->crb_intr_mask, 0);
161
162 if (adapter->intr_scheme != -1 &&
163 adapter->intr_scheme != INTR_SCHEME_PERPORT)
164 adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
165
166 if (!NETXEN_IS_MSI_FAMILY(adapter)) {
167 do {
168 adapter->pci_write_immediate(adapter,
169 ISR_INT_TARGET_STATUS, 0xffffffff);
170 mask = adapter->pci_read_immediate(adapter,
171 ISR_INT_VECTOR);
172 if (!(mask & 0x80))
173 break;
174 udelay(10);
175 } while (--retries);
176
177 if (!retries) {
178 printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
179 netxen_nic_driver_name);
180 }
181 } else {
182 if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
183 adapter->pci_write_immediate(adapter,
184 msi_tgt_status[pci_fn], 0xffffffff);
185 }
186 }
187} 155}
188 156
189static void netxen_nic_enable_int(struct netxen_adapter *adapter) 157static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
190{ 158{
191 u32 mask;
192
193 DPRINTK(1, INFO, "Entered ISR Enable \n");
194
195 if (adapter->intr_scheme != -1 &&
196 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
197 switch (adapter->ahw.board_type) {
198 case NETXEN_NIC_GBE:
199 mask = 0x77b;
200 break;
201 case NETXEN_NIC_XGBE:
202 mask = 0x77f;
203 break;
204 default:
205 mask = 0x7ff;
206 break;
207 }
208
209 adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
210 }
211
212 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1); 159 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
213 160
214 if (!NETXEN_IS_MSI_FAMILY(adapter)) { 161 if (!NETXEN_IS_MSI_FAMILY(adapter))
215 mask = 0xbff;
216 if (adapter->intr_scheme != -1 &&
217 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
218 adapter->pci_write_normalize(adapter,
219 CRB_INT_VECTOR, 0);
220 }
221 adapter->pci_write_immediate(adapter, 162 adapter->pci_write_immediate(adapter,
222 ISR_INT_TARGET_MASK, mask); 163 adapter->legacy_intr.tgt_mask_reg, 0xfbff);
223 }
224
225 DPRINTK(1, INFO, "Done with enable Int\n");
226} 164}
227 165
228static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) 166static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@@ -284,6 +222,8 @@ static void netxen_check_options(struct netxen_adapter *adapter)
284 case NETXEN_BRDTYPE_P3_10G_CX4_LP: 222 case NETXEN_BRDTYPE_P3_10G_CX4_LP:
285 case NETXEN_BRDTYPE_P3_IMEZ: 223 case NETXEN_BRDTYPE_P3_IMEZ:
286 case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: 224 case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
225 case NETXEN_BRDTYPE_P3_10G_SFP_QT:
226 case NETXEN_BRDTYPE_P3_10G_SFP_CT:
287 case NETXEN_BRDTYPE_P3_10G_XFP: 227 case NETXEN_BRDTYPE_P3_10G_XFP:
288 case NETXEN_BRDTYPE_P3_10000_BASE_T: 228 case NETXEN_BRDTYPE_P3_10000_BASE_T:
289 adapter->msix_supported = !!use_msi_x; 229 adapter->msix_supported = !!use_msi_x;
@@ -301,6 +241,10 @@ static void netxen_check_options(struct netxen_adapter *adapter)
301 case NETXEN_BRDTYPE_P3_REF_QG: 241 case NETXEN_BRDTYPE_P3_REF_QG:
302 case NETXEN_BRDTYPE_P3_4_GB: 242 case NETXEN_BRDTYPE_P3_4_GB:
303 case NETXEN_BRDTYPE_P3_4_GB_MM: 243 case NETXEN_BRDTYPE_P3_4_GB_MM:
244 adapter->msix_supported = 0;
245 adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
246 break;
247
304 case NETXEN_BRDTYPE_P2_SB35_4G: 248 case NETXEN_BRDTYPE_P2_SB35_4G:
305 case NETXEN_BRDTYPE_P2_SB31_2G: 249 case NETXEN_BRDTYPE_P2_SB31_2G:
306 adapter->msix_supported = 0; 250 adapter->msix_supported = 0;
@@ -499,6 +443,44 @@ static void netxen_init_msix_entries(struct netxen_adapter *adapter)
499 adapter->msix_entries[i].entry = i; 443 adapter->msix_entries[i].entry = i;
500} 444}
501 445
446static int
447netxen_read_mac_addr(struct netxen_adapter *adapter)
448{
449 int i;
450 unsigned char *p;
451 __le64 mac_addr;
452 DECLARE_MAC_BUF(mac);
453 struct net_device *netdev = adapter->netdev;
454 struct pci_dev *pdev = adapter->pdev;
455
456 if (netxen_is_flash_supported(adapter) != 0)
457 return -EIO;
458
459 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
460 if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
461 return -EIO;
462 } else {
463 if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0)
464 return -EIO;
465 }
466
467 p = (unsigned char *)&mac_addr;
468 for (i = 0; i < 6; i++)
469 netdev->dev_addr[i] = *(p + 5 - i);
470
471 memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
472
473 /* set station address */
474
475 if (!is_valid_ether_addr(netdev->perm_addr)) {
476 dev_warn(&pdev->dev, "Bad MAC address %s.\n",
477 print_mac(mac, netdev->dev_addr));
478 } else
479 adapter->macaddr_set(adapter, netdev->dev_addr);
480
481 return 0;
482}
483
502/* 484/*
503 * netxen_nic_probe() 485 * netxen_nic_probe()
504 * 486 *
@@ -527,10 +509,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
527 unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0; 509 unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
528 int i = 0, err; 510 int i = 0, err;
529 int first_driver, first_boot; 511 int first_driver, first_boot;
530 __le64 mac_addr[FLASH_NUM_PORTS + 1];
531 u32 val; 512 u32 val;
532 int pci_func_id = PCI_FUNC(pdev->devfn); 513 int pci_func_id = PCI_FUNC(pdev->devfn);
533 DECLARE_MAC_BUF(mac);
534 struct netxen_legacy_intr_set *legacy_intrp; 514 struct netxen_legacy_intr_set *legacy_intrp;
535 uint8_t revision_id; 515 uint8_t revision_id;
536 516
@@ -543,6 +523,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
543 return -ENODEV; 523 return -ENODEV;
544 } 524 }
545 525
526 if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
527 printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
528 "will not be enabled.\n",
529 NX_P3_A0, NX_P3_B1);
530 return -ENODEV;
531 }
532
546 if ((err = pci_enable_device(pdev))) 533 if ((err = pci_enable_device(pdev)))
547 return err; 534 return err;
548 535
@@ -700,13 +687,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
700 adapter->status &= ~NETXEN_NETDEV_STATUS; 687 adapter->status &= ~NETXEN_NETDEV_STATUS;
701 adapter->rx_csum = 1; 688 adapter->rx_csum = 1;
702 adapter->mc_enabled = 0; 689 adapter->mc_enabled = 0;
703 if (NX_IS_REVISION_P3(revision_id)) { 690 if (NX_IS_REVISION_P3(revision_id))
704 adapter->max_mc_count = 38; 691 adapter->max_mc_count = 38;
705 adapter->max_rds_rings = 2; 692 else
706 } else {
707 adapter->max_mc_count = 16; 693 adapter->max_mc_count = 16;
708 adapter->max_rds_rings = 3;
709 }
710 694
711 netdev->open = netxen_nic_open; 695 netdev->open = netxen_nic_open;
712 netdev->stop = netxen_nic_close; 696 netdev->stop = netxen_nic_close;
@@ -779,10 +763,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
779 if (adapter->portnum == 0) 763 if (adapter->portnum == 0)
780 first_driver = 1; 764 first_driver = 1;
781 } 765 }
782 adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum];
783 adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum];
784 netxen_nic_update_cmd_producer(adapter, 0);
785 netxen_nic_update_cmd_consumer(adapter, 0);
786 766
787 if (first_driver) { 767 if (first_driver) {
788 first_boot = adapter->pci_read_normalize(adapter, 768 first_boot = adapter->pci_read_normalize(adapter,
@@ -903,34 +883,14 @@ request_msi:
903 goto err_out_disable_msi; 883 goto err_out_disable_msi;
904 884
905 init_timer(&adapter->watchdog_timer); 885 init_timer(&adapter->watchdog_timer);
906 adapter->ahw.linkup = 0;
907 adapter->watchdog_timer.function = &netxen_watchdog; 886 adapter->watchdog_timer.function = &netxen_watchdog;
908 adapter->watchdog_timer.data = (unsigned long)adapter; 887 adapter->watchdog_timer.data = (unsigned long)adapter;
909 INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); 888 INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
910 INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); 889 INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
911 890
912 if (netxen_is_flash_supported(adapter) == 0 && 891 err = netxen_read_mac_addr(adapter);
913 netxen_get_flash_mac_addr(adapter, mac_addr) == 0) { 892 if (err)
914 unsigned char *p; 893 dev_warn(&pdev->dev, "failed to read mac addr\n");
915
916 p = (unsigned char *)&mac_addr[adapter->portnum];
917 netdev->dev_addr[0] = *(p + 5);
918 netdev->dev_addr[1] = *(p + 4);
919 netdev->dev_addr[2] = *(p + 3);
920 netdev->dev_addr[3] = *(p + 2);
921 netdev->dev_addr[4] = *(p + 1);
922 netdev->dev_addr[5] = *(p + 0);
923
924 memcpy(netdev->perm_addr, netdev->dev_addr,
925 netdev->addr_len);
926 if (!is_valid_ether_addr(netdev->perm_addr)) {
927 printk(KERN_ERR "%s: Bad MAC address %s.\n",
928 netxen_nic_driver_name,
929 print_mac(mac, netdev->dev_addr));
930 } else {
931 adapter->macaddr_set(adapter, netdev->dev_addr);
932 }
933 }
934 894
935 netif_carrier_off(netdev); 895 netif_carrier_off(netdev);
936 netif_stop_queue(netdev); 896 netif_stop_queue(netdev);
@@ -1005,6 +965,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
1005 965
1006 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { 966 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
1007 netxen_free_hw_resources(adapter); 967 netxen_free_hw_resources(adapter);
968 netxen_release_rx_buffers(adapter);
1008 netxen_free_sw_resources(adapter); 969 netxen_free_sw_resources(adapter);
1009 } 970 }
1010 971
@@ -1053,6 +1014,11 @@ static int netxen_nic_open(struct net_device *netdev)
1053 return -EIO; 1014 return -EIO;
1054 } 1015 }
1055 1016
1017 if (adapter->fw_major < 4)
1018 adapter->max_rds_rings = 3;
1019 else
1020 adapter->max_rds_rings = 2;
1021
1056 err = netxen_alloc_sw_resources(adapter); 1022 err = netxen_alloc_sw_resources(adapter);
1057 if (err) { 1023 if (err) {
1058 printk(KERN_ERR "%s: Error in setting sw resources\n", 1024 printk(KERN_ERR "%s: Error in setting sw resources\n",
@@ -1069,15 +1035,24 @@ static int netxen_nic_open(struct net_device *netdev)
1069 goto err_out_free_sw; 1035 goto err_out_free_sw;
1070 } 1036 }
1071 1037
1038 if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
1039 (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
1040 printk(KERN_ERR "%s: Firmware interrupt scheme is "
1041 "incompatible with driver\n",
1042 netdev->name);
1043 adapter->driver_mismatch = 1;
1044 goto err_out_free_hw;
1045 }
1046
1072 if (adapter->fw_major < 4) { 1047 if (adapter->fw_major < 4) {
1073 adapter->crb_addr_cmd_producer = 1048 adapter->crb_addr_cmd_producer =
1074 crb_cmd_producer[adapter->portnum]; 1049 crb_cmd_producer[adapter->portnum];
1075 adapter->crb_addr_cmd_consumer = 1050 adapter->crb_addr_cmd_consumer =
1076 crb_cmd_consumer[adapter->portnum]; 1051 crb_cmd_consumer[adapter->portnum];
1077 }
1078 1052
1079 netxen_nic_update_cmd_producer(adapter, 0); 1053 netxen_nic_update_cmd_producer(adapter, 0);
1080 netxen_nic_update_cmd_consumer(adapter, 0); 1054 netxen_nic_update_cmd_consumer(adapter, 0);
1055 }
1081 1056
1082 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { 1057 for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
1083 for (ring = 0; ring < adapter->max_rds_rings; ring++) 1058 for (ring = 0; ring < adapter->max_rds_rings; ring++)
@@ -1094,7 +1069,7 @@ static int netxen_nic_open(struct net_device *netdev)
1094 flags, netdev->name, adapter); 1069 flags, netdev->name, adapter);
1095 if (err) { 1070 if (err) {
1096 printk(KERN_ERR "request_irq failed with: %d\n", err); 1071 printk(KERN_ERR "request_irq failed with: %d\n", err);
1097 goto err_out_free_hw; 1072 goto err_out_free_rxbuf;
1098 } 1073 }
1099 1074
1100 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; 1075 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
@@ -1113,11 +1088,10 @@ static int netxen_nic_open(struct net_device *netdev)
1113 netxen_nic_set_link_parameters(adapter); 1088 netxen_nic_set_link_parameters(adapter);
1114 1089
1115 netdev->set_multicast_list(netdev); 1090 netdev->set_multicast_list(netdev);
1116 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 1091 if (adapter->set_mtu)
1117 nx_fw_cmd_set_mtu(adapter, netdev->mtu);
1118 else
1119 adapter->set_mtu(adapter, netdev->mtu); 1092 adapter->set_mtu(adapter, netdev->mtu);
1120 1093
1094 adapter->ahw.linkup = 0;
1121 mod_timer(&adapter->watchdog_timer, jiffies); 1095 mod_timer(&adapter->watchdog_timer, jiffies);
1122 1096
1123 napi_enable(&adapter->napi); 1097 napi_enable(&adapter->napi);
@@ -1129,6 +1103,8 @@ static int netxen_nic_open(struct net_device *netdev)
1129 1103
1130err_out_free_irq: 1104err_out_free_irq:
1131 free_irq(adapter->irq, adapter); 1105 free_irq(adapter->irq, adapter);
1106err_out_free_rxbuf:
1107 netxen_release_rx_buffers(adapter);
1132err_out_free_hw: 1108err_out_free_hw:
1133 netxen_free_hw_resources(adapter); 1109 netxen_free_hw_resources(adapter);
1134err_out_free_sw: 1110err_out_free_sw:
@@ -1154,10 +1130,8 @@ static int netxen_nic_close(struct net_device *netdev)
1154 1130
1155 netxen_release_tx_buffers(adapter); 1131 netxen_release_tx_buffers(adapter);
1156 1132
1157 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { 1133 FLUSH_SCHEDULED_WORK();
1158 FLUSH_SCHEDULED_WORK(); 1134 del_timer_sync(&adapter->watchdog_timer);
1159 del_timer_sync(&adapter->watchdog_timer);
1160 }
1161 1135
1162 return 0; 1136 return 0;
1163} 1137}
@@ -1410,20 +1384,17 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
1410 1384
1411 port = adapter->physical_port; 1385 port = adapter->physical_port;
1412 1386
1413 if (adapter->ahw.board_type == NETXEN_NIC_GBE) { 1387 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
1414 val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); 1388 val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3);
1415 linkup = (val >> port) & 1; 1389 val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
1390 linkup = (val == XG_LINK_UP_P3);
1416 } else { 1391 } else {
1417 if (adapter->fw_major < 4) { 1392 val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
1418 val = adapter->pci_read_normalize(adapter, 1393 if (adapter->ahw.board_type == NETXEN_NIC_GBE)
1419 CRB_XG_STATE); 1394 linkup = (val >> port) & 1;
1395 else {
1420 val = (val >> port*8) & 0xff; 1396 val = (val >> port*8) & 0xff;
1421 linkup = (val == XG_LINK_UP); 1397 linkup = (val == XG_LINK_UP);
1422 } else {
1423 val = adapter->pci_read_normalize(adapter,
1424 CRB_XG_STATE_P3);
1425 val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
1426 linkup = (val == XG_LINK_UP_P3);
1427 } 1398 }
1428 } 1399 }
1429 1400
@@ -1463,7 +1434,8 @@ void netxen_watchdog_task(struct work_struct *work)
1463 1434
1464 netxen_nic_handle_phy_intr(adapter); 1435 netxen_nic_handle_phy_intr(adapter);
1465 1436
1466 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); 1437 if (netif_running(adapter->netdev))
1438 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
1467} 1439}
1468 1440
1469static void netxen_tx_timeout(struct net_device *netdev) 1441static void netxen_tx_timeout(struct net_device *netdev)
@@ -1523,30 +1495,49 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
1523 return stats; 1495 return stats;
1524} 1496}
1525 1497
1526static inline void
1527netxen_handle_int(struct netxen_adapter *adapter)
1528{
1529 netxen_nic_disable_int(adapter);
1530 napi_schedule(&adapter->napi);
1531}
1532
1533static irqreturn_t netxen_intr(int irq, void *data) 1498static irqreturn_t netxen_intr(int irq, void *data)
1534{ 1499{
1535 struct netxen_adapter *adapter = data; 1500 struct netxen_adapter *adapter = data;
1536 u32 our_int = 0; 1501 u32 status = 0;
1502
1503 status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1537 1504
1538 our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR); 1505 if (!(status & adapter->legacy_intr.int_vec_bit))
1539 /* not our interrupt */
1540 if ((our_int & (0x80 << adapter->portnum)) == 0)
1541 return IRQ_NONE; 1506 return IRQ_NONE;
1542 1507
1543 if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { 1508 if (adapter->ahw.revision_id >= NX_P3_B1) {
1509 /* check interrupt state machine, to be sure */
1510 status = adapter->pci_read_immediate(adapter,
1511 ISR_INT_STATE_REG);
1512 if (!ISR_LEGACY_INT_TRIGGERED(status))
1513 return IRQ_NONE;
1514
1515 } else {
1516 unsigned long our_int = 0;
1517
1518 our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
1519
1520 /* not our interrupt */
1521 if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
1522 return IRQ_NONE;
1523
1544 /* claim interrupt */ 1524 /* claim interrupt */
1545 adapter->pci_write_normalize(adapter, CRB_INT_VECTOR, 1525 adapter->pci_write_normalize(adapter,
1546 our_int & ~((u32)(0x80 << adapter->portnum))); 1526 CRB_INT_VECTOR, (our_int & 0xffffffff));
1547 } 1527 }
1548 1528
1549 netxen_handle_int(adapter); 1529 /* clear interrupt */
1530 if (adapter->fw_major < 4)
1531 netxen_nic_disable_int(adapter);
1532
1533 adapter->pci_write_immediate(adapter,
1534 adapter->legacy_intr.tgt_status_reg,
1535 0xffffffff);
1536 /* read twice to ensure write is flushed */
1537 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1538 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1539
1540 napi_schedule(&adapter->napi);
1550 1541
1551 return IRQ_HANDLED; 1542 return IRQ_HANDLED;
1552} 1543}
@@ -1555,7 +1546,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
1555{ 1546{
1556 struct netxen_adapter *adapter = data; 1547 struct netxen_adapter *adapter = data;
1557 1548
1558 netxen_handle_int(adapter); 1549 /* clear interrupt */
1550 adapter->pci_write_immediate(adapter,
1551 msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
1552
1553 napi_schedule(&adapter->napi);
1559 return IRQ_HANDLED; 1554 return IRQ_HANDLED;
1560} 1555}
1561 1556
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index 4cb8f4a1cf4b..27f07f6a45b1 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -610,6 +610,9 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
610 int i; 610 int i;
611 DECLARE_MAC_BUF(mac); 611 DECLARE_MAC_BUF(mac);
612 612
613 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
614 return 0;
615
613 for (i = 0; i < 10; i++) { 616 for (i = 0; i < 10; i++) {
614 temp[0] = temp[1] = 0; 617 temp[0] = temp[1] = 0;
615 memcpy(temp + 2, addr, 2); 618 memcpy(temp + 2, addr, 2);
@@ -727,6 +730,9 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
727 __u32 mac_cfg0; 730 __u32 mac_cfg0;
728 u32 port = adapter->physical_port; 731 u32 port = adapter->physical_port;
729 732
733 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
734 return 0;
735
730 if (port > NETXEN_NIU_MAX_GBE_PORTS) 736 if (port > NETXEN_NIU_MAX_GBE_PORTS)
731 return -EINVAL; 737 return -EINVAL;
732 mac_cfg0 = 0; 738 mac_cfg0 = 0;
@@ -743,6 +749,9 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
743 __u32 mac_cfg; 749 __u32 mac_cfg;
744 u32 port = adapter->physical_port; 750 u32 port = adapter->physical_port;
745 751
752 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
753 return 0;
754
746 if (port > NETXEN_NIU_MAX_XG_PORTS) 755 if (port > NETXEN_NIU_MAX_XG_PORTS)
747 return -EINVAL; 756 return -EINVAL;
748 757
@@ -755,7 +764,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
755 764
756/* Set promiscuous mode for a GbE interface */ 765/* Set promiscuous mode for a GbE interface */
757int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, 766int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
758 netxen_niu_prom_mode_t mode) 767 u32 mode)
759{ 768{
760 __u32 reg; 769 __u32 reg;
761 u32 port = adapter->physical_port; 770 u32 port = adapter->physical_port;
@@ -819,6 +828,9 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
819 u8 temp[4]; 828 u8 temp[4];
820 u32 val; 829 u32 val;
821 830
831 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
832 return 0;
833
822 if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS)) 834 if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
823 return -EIO; 835 return -EIO;
824 836
@@ -894,7 +906,7 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
894#endif /* 0 */ 906#endif /* 0 */
895 907
896int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, 908int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
897 netxen_niu_prom_mode_t mode) 909 u32 mode)
898{ 910{
899 __u32 reg; 911 __u32 reg;
900 u32 port = adapter->physical_port; 912 u32 port = adapter->physical_port;
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index 3bfa51b62a4f..b293adcc95ab 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -95,8 +95,8 @@
95#define CRB_HOST_STS_PROD NETXEN_NIC_REG(0xdc) 95#define CRB_HOST_STS_PROD NETXEN_NIC_REG(0xdc)
96#define CRB_HOST_STS_CONS NETXEN_NIC_REG(0xe0) 96#define CRB_HOST_STS_CONS NETXEN_NIC_REG(0xe0)
97#define CRB_PEG_CMD_PROD NETXEN_NIC_REG(0xe4) 97#define CRB_PEG_CMD_PROD NETXEN_NIC_REG(0xe4)
98#define CRB_PEG_CMD_CONS NETXEN_NIC_REG(0xe8) 98#define CRB_PF_LINK_SPEED_1 NETXEN_NIC_REG(0xe8)
99#define CRB_HOST_BUFFER_PROD NETXEN_NIC_REG(0xec) 99#define CRB_PF_LINK_SPEED_2 NETXEN_NIC_REG(0xec)
100#define CRB_HOST_BUFFER_CONS NETXEN_NIC_REG(0xf0) 100#define CRB_HOST_BUFFER_CONS NETXEN_NIC_REG(0xf0)
101#define CRB_JUMBO_BUFFER_PROD NETXEN_NIC_REG(0xf4) 101#define CRB_JUMBO_BUFFER_PROD NETXEN_NIC_REG(0xf4)
102#define CRB_JUMBO_BUFFER_CONS NETXEN_NIC_REG(0xf8) 102#define CRB_JUMBO_BUFFER_CONS NETXEN_NIC_REG(0xf8)
@@ -125,6 +125,8 @@
125#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4) 125#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4)
126#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8) 126#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8)
127 127
128#define CRB_MAC_BLOCK_START NETXEN_CAM_RAM(0x1c0)
129
128/* 130/*
129 * capabilities register, can be used to selectively enable/disable features 131 * capabilities register, can be used to selectively enable/disable features
130 * for backward compability 132 * for backward compability
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index a20005c09e07..8e0ca9f4e404 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -648,7 +648,6 @@ static void ni5010_set_multicast_list(struct net_device *dev)
648 PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name)); 648 PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
649 649
650 if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) { 650 if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) {
651 dev->flags |= IFF_PROMISC;
652 outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */ 651 outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
653 PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name)); 652 PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
654 } else { 653 } else {
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index a316dcc8a06d..b9a882d362da 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -621,7 +621,7 @@ static int init586(struct net_device *dev)
621 if (num_addrs > len) { 621 if (num_addrs > len) {
622 printk(KERN_ERR "%s: switching to promisc. mode\n", 622 printk(KERN_ERR "%s: switching to promisc. mode\n",
623 dev->name); 623 dev->name);
624 dev->flags |= IFF_PROMISC; 624 writeb(0x01, &cfg_cmd->promisc);
625 } 625 }
626 } 626 }
627 if (dev->flags & IFF_PROMISC) 627 if (dev->flags & IFF_PROMISC)
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index b35d79449500..88f03c9e9403 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -46,7 +46,6 @@
46#include <linux/err.h> 46#include <linux/err.h>
47#include <linux/module.h> 47#include <linux/module.h>
48#include <linux/kernel.h> 48#include <linux/kernel.h>
49#include <linux/version.h>
50#include <linux/init.h> 49#include <linux/init.h>
51#include <linux/types.h> 50#include <linux/types.h>
52#include <linux/slab.h> 51#include <linux/slab.h>
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f9298827a76c..ff175e8f36b2 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -61,7 +61,6 @@
61 */ 61 */
62 62
63#include <linux/module.h> 63#include <linux/module.h>
64#include <linux/version.h>
65#include <linux/string.h> 64#include <linux/string.h>
66#include <linux/list.h> 65#include <linux/list.h>
67#include <asm/uaccess.h> 66#include <asm/uaccess.h>
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index e82b37bbd6c3..3cdd07c45b6d 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -38,7 +38,7 @@
38 38
39#define DRV_NAME "qla3xxx" 39#define DRV_NAME "qla3xxx"
40#define DRV_STRING "QLogic ISP3XXX Network Driver" 40#define DRV_STRING "QLogic ISP3XXX Network Driver"
41#define DRV_VERSION "v2.03.00-k4" 41#define DRV_VERSION "v2.03.00-k5"
42#define PFX DRV_NAME " " 42#define PFX DRV_NAME " "
43 43
44static const char ql3xxx_driver_name[] = DRV_NAME; 44static const char ql3xxx_driver_name[] = DRV_NAME;
@@ -3495,8 +3495,6 @@ static void ql_set_mac_info(struct ql3_adapter *qdev)
3495 case ISP_CONTROL_FN0_NET: 3495 case ISP_CONTROL_FN0_NET:
3496 qdev->mac_index = 0; 3496 qdev->mac_index = 0;
3497 qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number; 3497 qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number;
3498 qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number;
3499 qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number;
3500 qdev->mb_bit_mask = FN0_MA_BITS_MASK; 3498 qdev->mb_bit_mask = FN0_MA_BITS_MASK;
3501 qdev->PHYAddr = PORT0_PHY_ADDRESS; 3499 qdev->PHYAddr = PORT0_PHY_ADDRESS;
3502 if (port_status & PORT_STATUS_SM0) 3500 if (port_status & PORT_STATUS_SM0)
@@ -3508,8 +3506,6 @@ static void ql_set_mac_info(struct ql3_adapter *qdev)
3508 case ISP_CONTROL_FN1_NET: 3506 case ISP_CONTROL_FN1_NET:
3509 qdev->mac_index = 1; 3507 qdev->mac_index = 1;
3510 qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number; 3508 qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number;
3511 qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number;
3512 qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number;
3513 qdev->mb_bit_mask = FN1_MA_BITS_MASK; 3509 qdev->mb_bit_mask = FN1_MA_BITS_MASK;
3514 qdev->PHYAddr = PORT1_PHY_ADDRESS; 3510 qdev->PHYAddr = PORT1_PHY_ADDRESS;
3515 if (port_status & PORT_STATUS_SM1) 3511 if (port_status & PORT_STATUS_SM1)
@@ -3730,14 +3726,6 @@ static int ql3xxx_open(struct net_device *ndev)
3730 return (ql_adapter_up(qdev)); 3726 return (ql_adapter_up(qdev));
3731} 3727}
3732 3728
3733static void ql3xxx_set_multicast_list(struct net_device *ndev)
3734{
3735 /*
3736 * We are manually parsing the list in the net_device structure.
3737 */
3738 return;
3739}
3740
3741static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) 3729static int ql3xxx_set_mac_address(struct net_device *ndev, void *p)
3742{ 3730{
3743 struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); 3731 struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
@@ -4007,7 +3995,11 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
4007 ndev->open = ql3xxx_open; 3995 ndev->open = ql3xxx_open;
4008 ndev->hard_start_xmit = ql3xxx_send; 3996 ndev->hard_start_xmit = ql3xxx_send;
4009 ndev->stop = ql3xxx_close; 3997 ndev->stop = ql3xxx_close;
4010 ndev->set_multicast_list = ql3xxx_set_multicast_list; 3998 /* ndev->set_multicast_list
3999 * This device is one side of a two-function adapter
4000 * (NIC and iSCSI). Promiscuous mode setting/clearing is
4001 * not allowed from the NIC side.
4002 */
4011 SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops); 4003 SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops);
4012 ndev->set_mac_address = ql3xxx_set_mac_address; 4004 ndev->set_mac_address = ql3xxx_set_mac_address;
4013 ndev->tx_timeout = ql3xxx_tx_timeout; 4005 ndev->tx_timeout = ql3xxx_tx_timeout;
@@ -4040,9 +4032,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
4040 4032
4041 ndev->tx_queue_len = NUM_REQ_Q_ENTRIES; 4033 ndev->tx_queue_len = NUM_REQ_Q_ENTRIES;
4042 4034
4043 /* Turn off support for multicasting */
4044 ndev->flags &= ~IFF_MULTICAST;
4045
4046 /* Record PCI bus information. */ 4035 /* Record PCI bus information. */
4047 ql_get_board_info(qdev); 4036 ql_get_board_info(qdev);
4048 4037
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 58a086fddec6..7113e71b15a1 100644
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -14,24 +14,14 @@
14 14
15#define OPCODE_OB_MAC_IOCB_FN0 0x01 15#define OPCODE_OB_MAC_IOCB_FN0 0x01
16#define OPCODE_OB_MAC_IOCB_FN2 0x21 16#define OPCODE_OB_MAC_IOCB_FN2 0x21
17#define OPCODE_OB_TCP_IOCB_FN0 0x03
18#define OPCODE_OB_TCP_IOCB_FN2 0x23
19#define OPCODE_UPDATE_NCB_IOCB_FN0 0x00
20#define OPCODE_UPDATE_NCB_IOCB_FN2 0x20
21 17
22#define OPCODE_UPDATE_NCB_IOCB 0xF0
23#define OPCODE_IB_MAC_IOCB 0xF9 18#define OPCODE_IB_MAC_IOCB 0xF9
24#define OPCODE_IB_3032_MAC_IOCB 0x09 19#define OPCODE_IB_3032_MAC_IOCB 0x09
25#define OPCODE_IB_IP_IOCB 0xFA 20#define OPCODE_IB_IP_IOCB 0xFA
26#define OPCODE_IB_3032_IP_IOCB 0x0A 21#define OPCODE_IB_3032_IP_IOCB 0x0A
27#define OPCODE_IB_TCP_IOCB 0xFB
28#define OPCODE_DUMP_PROTO_IOCB 0xFE
29#define OPCODE_BUFFER_ALERT_IOCB 0xFB
30 22
31#define OPCODE_FUNC_ID_MASK 0x30 23#define OPCODE_FUNC_ID_MASK 0x30
32#define OUTBOUND_MAC_IOCB 0x01 /* plus function bits */ 24#define OUTBOUND_MAC_IOCB 0x01 /* plus function bits */
33#define OUTBOUND_TCP_IOCB 0x03 /* plus function bits */
34#define UPDATE_NCB_IOCB 0x00 /* plus function bits */
35 25
36#define FN0_MA_BITS_MASK 0x00 26#define FN0_MA_BITS_MASK 0x00
37#define FN1_MA_BITS_MASK 0x80 27#define FN1_MA_BITS_MASK 0x80
@@ -159,75 +149,6 @@ struct ob_ip_iocb_rsp {
159 __le32 reserved2; 149 __le32 reserved2;
160}; 150};
161 151
162struct ob_tcp_iocb_req {
163 u8 opcode;
164
165 u8 flags0;
166#define OB_TCP_IOCB_REQ_P 0x80
167#define OB_TCP_IOCB_REQ_CI 0x20
168#define OB_TCP_IOCB_REQ_H 0x10
169#define OB_TCP_IOCB_REQ_LN 0x08
170#define OB_TCP_IOCB_REQ_K 0x04
171#define OB_TCP_IOCB_REQ_D 0x02
172#define OB_TCP_IOCB_REQ_I 0x01
173
174 u8 flags1;
175#define OB_TCP_IOCB_REQ_OSM 0x40
176#define OB_TCP_IOCB_REQ_URG 0x20
177#define OB_TCP_IOCB_REQ_ACK 0x10
178#define OB_TCP_IOCB_REQ_PSH 0x08
179#define OB_TCP_IOCB_REQ_RST 0x04
180#define OB_TCP_IOCB_REQ_SYN 0x02
181#define OB_TCP_IOCB_REQ_FIN 0x01
182
183 u8 options_len;
184#define OB_TCP_IOCB_REQ_OMASK 0xF0
185#define OB_TCP_IOCB_REQ_SHIFT 4
186
187 __le32 transaction_id;
188 __le32 data_len;
189 __le32 hncb_ptr_low;
190 __le32 hncb_ptr_high;
191 __le32 buf_addr0_low;
192 __le32 buf_addr0_high;
193 __le32 buf_0_len;
194 __le32 buf_addr1_low;
195 __le32 buf_addr1_high;
196 __le32 buf_1_len;
197 __le32 buf_addr2_low;
198 __le32 buf_addr2_high;
199 __le32 buf_2_len;
200 __le32 time_stamp;
201 __le32 reserved1;
202};
203
204struct ob_tcp_iocb_rsp {
205 u8 opcode;
206
207 u8 flags0;
208#define OB_TCP_IOCB_RSP_C 0x20
209#define OB_TCP_IOCB_RSP_H 0x10
210#define OB_TCP_IOCB_RSP_LN 0x08
211#define OB_TCP_IOCB_RSP_K 0x04
212#define OB_TCP_IOCB_RSP_D 0x02
213#define OB_TCP_IOCB_RSP_I 0x01
214
215 u8 flags1;
216#define OB_TCP_IOCB_RSP_E 0x10
217#define OB_TCP_IOCB_RSP_W 0x08
218#define OB_TCP_IOCB_RSP_P 0x04
219#define OB_TCP_IOCB_RSP_T 0x02
220#define OB_TCP_IOCB_RSP_F 0x01
221
222 u8 state;
223#define OB_TCP_IOCB_RSP_SMASK 0xF0
224#define OB_TCP_IOCB_RSP_SHIFT 4
225
226 __le32 transaction_id;
227 __le32 local_ncb_ptr;
228 __le32 reserved0;
229};
230
231struct ib_ip_iocb_rsp { 152struct ib_ip_iocb_rsp {
232 u8 opcode; 153 u8 opcode;
233#define IB_IP_IOCB_RSP_3032_V 0x80 154#define IB_IP_IOCB_RSP_3032_V 0x80
@@ -256,25 +177,6 @@ struct ib_ip_iocb_rsp {
256 __le32 ial_high; 177 __le32 ial_high;
257}; 178};
258 179
259struct ib_tcp_iocb_rsp {
260 u8 opcode;
261 u8 flags;
262#define IB_TCP_IOCB_RSP_P 0x80
263#define IB_TCP_IOCB_RSP_T 0x40
264#define IB_TCP_IOCB_RSP_D 0x20
265#define IB_TCP_IOCB_RSP_N 0x10
266#define IB_TCP_IOCB_RSP_IP 0x03
267#define IB_TCP_FLAG_MASK 0xf0
268#define IB_TCP_FLAG_IOCB_SYN 0x00
269
270#define TCP_IB_RSP_FLAGS(x) (x->flags & ~IB_TCP_FLAG_MASK)
271
272 __le16 length;
273 __le32 hncb_ref_num;
274 __le32 ial_low;
275 __le32 ial_high;
276};
277
278struct net_rsp_iocb { 180struct net_rsp_iocb {
279 u8 opcode; 181 u8 opcode;
280 u8 flags; 182 u8 flags;
@@ -1266,20 +1168,13 @@ struct ql3_adapter {
1266 u32 small_buf_release_cnt; 1168 u32 small_buf_release_cnt;
1267 u32 small_buf_total_size; 1169 u32 small_buf_total_size;
1268 1170
1269 /* ISR related, saves status for DPC. */
1270 u32 control_status;
1271
1272 struct eeprom_data nvram_data; 1171 struct eeprom_data nvram_data;
1273 struct timer_list ioctl_timer;
1274 u32 port_link_state; 1172 u32 port_link_state;
1275 u32 last_rsp_offset;
1276 1173
1277 /* 4022 specific */ 1174 /* 4022 specific */
1278 u32 mac_index; /* Driver's MAC number can be 0 or 1 for first and second networking functions respectively */ 1175 u32 mac_index; /* Driver's MAC number can be 0 or 1 for first and second networking functions respectively */
1279 u32 PHYAddr; /* Address of PHY 0x1e00 Port 0 and 0x1f00 Port 1 */ 1176 u32 PHYAddr; /* Address of PHY 0x1e00 Port 0 and 0x1f00 Port 1 */
1280 u32 mac_ob_opcode; /* Opcode to use on mac transmission */ 1177 u32 mac_ob_opcode; /* Opcode to use on mac transmission */
1281 u32 tcp_ob_opcode; /* Opcode to use on tcp transmission */
1282 u32 update_ob_opcode; /* Opcode to use for updating NCB */
1283 u32 mb_bit_mask; /* MA Bits mask to use on transmission */ 1178 u32 mb_bit_mask; /* MA Bits mask to use on transmission */
1284 u32 numPorts; 1179 u32 numPorts;
1285 struct workqueue_struct *workqueue; 1180 struct workqueue_struct *workqueue;
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 6531ff565c54..5d86281d9363 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -24,7 +24,6 @@
24 24
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/version.h>
28#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
29#include <linux/string.h> 28#include <linux/string.h>
30#include <linux/timer.h> 29#include <linux/timer.h>
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 6a06b9503e4f..1c370e6aa641 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -20,7 +20,6 @@
20 * the file called "COPYING". 20 * the file called "COPYING".
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/init.h> 23#include <linux/init.h>
25#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
26#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
@@ -34,6 +33,29 @@
34 33
35#include "sh_eth.h" 34#include "sh_eth.h"
36 35
36/* CPU <-> EDMAC endian convert */
37static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
38{
39 switch (mdp->edmac_endian) {
40 case EDMAC_LITTLE_ENDIAN:
41 return cpu_to_le32(x);
42 case EDMAC_BIG_ENDIAN:
43 return cpu_to_be32(x);
44 }
45 return x;
46}
47
48static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
49{
50 switch (mdp->edmac_endian) {
51 case EDMAC_LITTLE_ENDIAN:
52 return le32_to_cpu(x);
53 case EDMAC_BIG_ENDIAN:
54 return be32_to_cpu(x);
55 }
56 return x;
57}
58
37/* 59/*
38 * Program the hardware MAC address from dev->dev_addr. 60 * Program the hardware MAC address from dev->dev_addr.
39 */ 61 */
@@ -240,7 +262,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
240 /* RX descriptor */ 262 /* RX descriptor */
241 rxdesc = &mdp->rx_ring[i]; 263 rxdesc = &mdp->rx_ring[i];
242 rxdesc->addr = (u32)skb->data & ~0x3UL; 264 rxdesc->addr = (u32)skb->data & ~0x3UL;
243 rxdesc->status = cpu_to_le32(RD_RACT | RD_RFP); 265 rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
244 266
245 /* The size of the buffer is 16 byte boundary. */ 267 /* The size of the buffer is 16 byte boundary. */
246 rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F; 268 rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
@@ -262,7 +284,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
262 mdp->dirty_rx = (u32) (i - RX_RING_SIZE); 284 mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
263 285
264 /* Mark the last entry as wrapping the ring. */ 286 /* Mark the last entry as wrapping the ring. */
265 rxdesc->status |= cpu_to_le32(RD_RDEL); 287 rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
266 288
267 memset(mdp->tx_ring, 0, tx_ringsize); 289 memset(mdp->tx_ring, 0, tx_ringsize);
268 290
@@ -270,10 +292,10 @@ static void sh_eth_ring_format(struct net_device *ndev)
270 for (i = 0; i < TX_RING_SIZE; i++) { 292 for (i = 0; i < TX_RING_SIZE; i++) {
271 mdp->tx_skbuff[i] = NULL; 293 mdp->tx_skbuff[i] = NULL;
272 txdesc = &mdp->tx_ring[i]; 294 txdesc = &mdp->tx_ring[i];
273 txdesc->status = cpu_to_le32(TD_TFP); 295 txdesc->status = cpu_to_edmac(mdp, TD_TFP);
274 txdesc->buffer_length = 0; 296 txdesc->buffer_length = 0;
275 if (i == 0) { 297 if (i == 0) {
276 /* Rx descriptor address set */ 298 /* Tx descriptor address set */
277 ctrl_outl((u32)txdesc, ioaddr + TDLAR); 299 ctrl_outl((u32)txdesc, ioaddr + TDLAR);
278#if defined(CONFIG_CPU_SUBTYPE_SH7763) 300#if defined(CONFIG_CPU_SUBTYPE_SH7763)
279 ctrl_outl((u32)txdesc, ioaddr + TDFAR); 301 ctrl_outl((u32)txdesc, ioaddr + TDFAR);
@@ -281,13 +303,13 @@ static void sh_eth_ring_format(struct net_device *ndev)
281 } 303 }
282 } 304 }
283 305
284 /* Rx descriptor address set */ 306 /* Tx descriptor address set */
285#if defined(CONFIG_CPU_SUBTYPE_SH7763) 307#if defined(CONFIG_CPU_SUBTYPE_SH7763)
286 ctrl_outl((u32)txdesc, ioaddr + TDFXR); 308 ctrl_outl((u32)txdesc, ioaddr + TDFXR);
287 ctrl_outl(0x1, ioaddr + TDFFR); 309 ctrl_outl(0x1, ioaddr + TDFFR);
288#endif 310#endif
289 311
290 txdesc->status |= cpu_to_le32(TD_TDLE); 312 txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
291} 313}
292 314
293/* Get skb and descriptor buffer */ 315/* Get skb and descriptor buffer */
@@ -455,7 +477,7 @@ static int sh_eth_txfree(struct net_device *ndev)
455 for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) { 477 for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
456 entry = mdp->dirty_tx % TX_RING_SIZE; 478 entry = mdp->dirty_tx % TX_RING_SIZE;
457 txdesc = &mdp->tx_ring[entry]; 479 txdesc = &mdp->tx_ring[entry];
458 if (txdesc->status & cpu_to_le32(TD_TACT)) 480 if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
459 break; 481 break;
460 /* Free the original skb. */ 482 /* Free the original skb. */
461 if (mdp->tx_skbuff[entry]) { 483 if (mdp->tx_skbuff[entry]) {
@@ -463,9 +485,9 @@ static int sh_eth_txfree(struct net_device *ndev)
463 mdp->tx_skbuff[entry] = NULL; 485 mdp->tx_skbuff[entry] = NULL;
464 freeNum++; 486 freeNum++;
465 } 487 }
466 txdesc->status = cpu_to_le32(TD_TFP); 488 txdesc->status = cpu_to_edmac(mdp, TD_TFP);
467 if (entry >= TX_RING_SIZE - 1) 489 if (entry >= TX_RING_SIZE - 1)
468 txdesc->status |= cpu_to_le32(TD_TDLE); 490 txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
469 491
470 mdp->stats.tx_packets++; 492 mdp->stats.tx_packets++;
471 mdp->stats.tx_bytes += txdesc->buffer_length; 493 mdp->stats.tx_bytes += txdesc->buffer_length;
@@ -486,8 +508,8 @@ static int sh_eth_rx(struct net_device *ndev)
486 u32 desc_status, reserve = 0; 508 u32 desc_status, reserve = 0;
487 509
488 rxdesc = &mdp->rx_ring[entry]; 510 rxdesc = &mdp->rx_ring[entry];
489 while (!(rxdesc->status & cpu_to_le32(RD_RACT))) { 511 while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
490 desc_status = le32_to_cpu(rxdesc->status); 512 desc_status = edmac_to_cpu(mdp, rxdesc->status);
491 pkt_len = rxdesc->frame_length; 513 pkt_len = rxdesc->frame_length;
492 514
493 if (--boguscnt < 0) 515 if (--boguscnt < 0)
@@ -522,7 +544,7 @@ static int sh_eth_rx(struct net_device *ndev)
522 mdp->stats.rx_packets++; 544 mdp->stats.rx_packets++;
523 mdp->stats.rx_bytes += pkt_len; 545 mdp->stats.rx_bytes += pkt_len;
524 } 546 }
525 rxdesc->status |= cpu_to_le32(RD_RACT); 547 rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
526 entry = (++mdp->cur_rx) % RX_RING_SIZE; 548 entry = (++mdp->cur_rx) % RX_RING_SIZE;
527 } 549 }
528 550
@@ -552,10 +574,10 @@ static int sh_eth_rx(struct net_device *ndev)
552 } 574 }
553 if (entry >= RX_RING_SIZE - 1) 575 if (entry >= RX_RING_SIZE - 1)
554 rxdesc->status |= 576 rxdesc->status |=
555 cpu_to_le32(RD_RACT | RD_RFP | RD_RDEL); 577 cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
556 else 578 else
557 rxdesc->status |= 579 rxdesc->status |=
558 cpu_to_le32(RD_RACT | RD_RFP); 580 cpu_to_edmac(mdp, RD_RACT | RD_RFP);
559 } 581 }
560 582
561 /* Restart Rx engine if stopped. */ 583 /* Restart Rx engine if stopped. */
@@ -931,9 +953,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
931 txdesc->buffer_length = skb->len; 953 txdesc->buffer_length = skb->len;
932 954
933 if (entry >= TX_RING_SIZE - 1) 955 if (entry >= TX_RING_SIZE - 1)
934 txdesc->status |= cpu_to_le32(TD_TACT | TD_TDLE); 956 txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
935 else 957 else
936 txdesc->status |= cpu_to_le32(TD_TACT); 958 txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
937 959
938 mdp->cur_tx++; 960 mdp->cur_tx++;
939 961
@@ -1159,6 +1181,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1159 struct resource *res; 1181 struct resource *res;
1160 struct net_device *ndev = NULL; 1182 struct net_device *ndev = NULL;
1161 struct sh_eth_private *mdp; 1183 struct sh_eth_private *mdp;
1184 struct sh_eth_plat_data *pd;
1162 1185
1163 /* get base addr */ 1186 /* get base addr */
1164 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1187 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1196,8 +1219,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1196 mdp = netdev_priv(ndev); 1219 mdp = netdev_priv(ndev);
1197 spin_lock_init(&mdp->lock); 1220 spin_lock_init(&mdp->lock);
1198 1221
1222 pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
1199 /* get PHY ID */ 1223 /* get PHY ID */
1200 mdp->phy_id = (int)pdev->dev.platform_data; 1224 mdp->phy_id = pd->phy;
1225 /* EDMAC endian */
1226 mdp->edmac_endian = pd->edmac_endian;
1201 1227
1202 /* set function */ 1228 /* set function */
1203 ndev->open = sh_eth_open; 1229 ndev->open = sh_eth_open;
@@ -1217,12 +1243,16 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1217 1243
1218 /* First device only init */ 1244 /* First device only init */
1219 if (!devno) { 1245 if (!devno) {
1246#if defined(ARSTR)
1220 /* reset device */ 1247 /* reset device */
1221 ctrl_outl(ARSTR_ARSTR, ARSTR); 1248 ctrl_outl(ARSTR_ARSTR, ARSTR);
1222 mdelay(1); 1249 mdelay(1);
1250#endif
1223 1251
1252#if defined(SH_TSU_ADDR)
1224 /* TSU init (Init only)*/ 1253 /* TSU init (Init only)*/
1225 sh_eth_tsu_init(SH_TSU_ADDR); 1254 sh_eth_tsu_init(SH_TSU_ADDR);
1255#endif
1226 } 1256 }
1227 1257
1228 /* network device register */ 1258 /* network device register */
@@ -1240,8 +1270,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1240 ndev->name, CARDNAME, (u32) ndev->base_addr); 1270 ndev->name, CARDNAME, (u32) ndev->base_addr);
1241 1271
1242 for (i = 0; i < 5; i++) 1272 for (i = 0; i < 5; i++)
1243 printk(KERN_INFO "%02X:", ndev->dev_addr[i]); 1273 printk("%02X:", ndev->dev_addr[i]);
1244 printk(KERN_INFO "%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq); 1274 printk("%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
1245 1275
1246 platform_set_drvdata(pdev, ndev); 1276 platform_set_drvdata(pdev, ndev);
1247 1277
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 45ad1b09ca5a..73bc7181cc18 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -30,6 +30,8 @@
30#include <linux/netdevice.h> 30#include <linux/netdevice.h>
31#include <linux/phy.h> 31#include <linux/phy.h>
32 32
33#include <asm/sh_eth.h>
34
33#define CARDNAME "sh-eth" 35#define CARDNAME "sh-eth"
34#define TX_TIMEOUT (5*HZ) 36#define TX_TIMEOUT (5*HZ)
35#define TX_RING_SIZE 64 /* Tx ring size */ 37#define TX_RING_SIZE 64 /* Tx ring size */
@@ -143,10 +145,11 @@
143 145
144#else /* CONFIG_CPU_SUBTYPE_SH7763 */ 146#else /* CONFIG_CPU_SUBTYPE_SH7763 */
145# define RX_OFFSET 2 /* skb offset */ 147# define RX_OFFSET 2 /* skb offset */
148#ifndef CONFIG_CPU_SUBTYPE_SH7619
146/* Chip base address */ 149/* Chip base address */
147# define SH_TSU_ADDR 0xA7000804 150# define SH_TSU_ADDR 0xA7000804
148# define ARSTR 0xA7000800 151# define ARSTR 0xA7000800
149 152#endif
150/* Chip Registers */ 153/* Chip Registers */
151/* E-DMAC */ 154/* E-DMAC */
152# define EDMR 0x0000 155# define EDMR 0x0000
@@ -384,7 +387,11 @@ enum FCFTR_BIT {
384 FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001, 387 FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
385}; 388};
386#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0) 389#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0)
390#ifndef CONFIG_CPU_SUBTYPE_SH7619
387#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0) 391#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0)
392#else
393#define FIFO_F_D_RFD (FCFTR_RFD0)
394#endif
388 395
389/* Transfer descriptor bit */ 396/* Transfer descriptor bit */
390enum TD_STS_BIT { 397enum TD_STS_BIT {
@@ -414,8 +421,10 @@ enum FELIC_MODE_BIT {
414#ifdef CONFIG_CPU_SUBTYPE_SH7763 421#ifdef CONFIG_CPU_SUBTYPE_SH7763
415#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\ 422#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\
416 ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT) 423 ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
424#elif CONFIG_CPU_SUBTYPE_SH7619
425#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
417#else 426#else
418#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR ECMR_RXF | ECMR_TXF | ECMR_MCT) 427#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
419#endif 428#endif
420 429
421/* ECSR */ 430/* ECSR */
@@ -485,7 +494,11 @@ enum RPADIR_BIT {
485 494
486/* FDR */ 495/* FDR */
487enum FIFO_SIZE_BIT { 496enum FIFO_SIZE_BIT {
497#ifndef CONFIG_CPU_SUBTYPE_SH7619
488 FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007, 498 FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
499#else
500 FIFO_SIZE_T = 0x00000100, FIFO_SIZE_R = 0x00000001,
501#endif
489}; 502};
490enum phy_offsets { 503enum phy_offsets {
491 PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3, 504 PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
@@ -601,7 +614,7 @@ struct sh_eth_txdesc {
601#endif 614#endif
602 u32 addr; /* TD2 */ 615 u32 addr; /* TD2 */
603 u32 pad1; /* padding data */ 616 u32 pad1; /* padding data */
604}; 617} __attribute__((aligned(2), packed));
605 618
606/* 619/*
607 * The sh ether Rx buffer descriptors. 620 * The sh ether Rx buffer descriptors.
@@ -618,7 +631,7 @@ struct sh_eth_rxdesc {
618#endif 631#endif
619 u32 addr; /* RD2 */ 632 u32 addr; /* RD2 */
620 u32 pad0; /* padding data */ 633 u32 pad0; /* padding data */
621}; 634} __attribute__((aligned(2), packed));
622 635
623struct sh_eth_private { 636struct sh_eth_private {
624 dma_addr_t rx_desc_dma; 637 dma_addr_t rx_desc_dma;
@@ -633,6 +646,7 @@ struct sh_eth_private {
633 u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */ 646 u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */
634 u32 cur_tx, dirty_tx; 647 u32 cur_tx, dirty_tx;
635 u32 rx_buf_sz; /* Based on MTU+slack. */ 648 u32 rx_buf_sz; /* Based on MTU+slack. */
649 int edmac_endian;
636 /* MII transceiver section. */ 650 /* MII transceiver section. */
637 u32 phy_id; /* PHY ID */ 651 u32 phy_id; /* PHY ID */
638 struct mii_bus *mii_bus; /* MDIO bus control */ 652 struct mii_bus *mii_bus; /* MDIO bus control */
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 5257cf464f1a..e24b25ca1c69 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -24,7 +24,6 @@
24 24
25#include <linux/crc32.h> 25#include <linux/crc32.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/version.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/netdevice.h> 28#include <linux/netdevice.h>
30#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
@@ -275,86 +274,6 @@ static void sky2_power_aux(struct sky2_hw *hw)
275 PC_VAUX_ON | PC_VCC_OFF)); 274 PC_VAUX_ON | PC_VCC_OFF));
276} 275}
277 276
278static void sky2_power_state(struct sky2_hw *hw, pci_power_t state)
279{
280 u16 power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL);
281 int pex = pci_find_capability(hw->pdev, PCI_CAP_ID_EXP);
282 u32 reg;
283
284 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
285
286 switch (state) {
287 case PCI_D0:
288 break;
289
290 case PCI_D1:
291 power_control |= 1;
292 break;
293
294 case PCI_D2:
295 power_control |= 2;
296 break;
297
298 case PCI_D3hot:
299 case PCI_D3cold:
300 power_control |= 3;
301 if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
302 /* additional power saving measurements */
303 reg = sky2_pci_read32(hw, PCI_DEV_REG4);
304
305 /* set gating core clock for LTSSM in L1 state */
306 reg |= P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) |
307 /* auto clock gated scheme controlled by CLKREQ */
308 P_ASPM_A1_MODE_SELECT |
309 /* enable Gate Root Core Clock */
310 P_CLK_GATE_ROOT_COR_ENA;
311
312 if (pex && (hw->flags & SKY2_HW_CLK_POWER)) {
313 /* enable Clock Power Management (CLKREQ) */
314 u16 ctrl = sky2_pci_read16(hw, pex + PCI_EXP_DEVCTL);
315
316 ctrl |= PCI_EXP_DEVCTL_AUX_PME;
317 sky2_pci_write16(hw, pex + PCI_EXP_DEVCTL, ctrl);
318 } else
319 /* force CLKREQ Enable in Our4 (A1b only) */
320 reg |= P_ASPM_FORCE_CLKREQ_ENA;
321
322 /* set Mask Register for Release/Gate Clock */
323 sky2_pci_write32(hw, PCI_DEV_REG5,
324 P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST |
325 P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE |
326 P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN);
327 } else
328 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_CLK_HALT);
329
330 /* put CPU into reset state */
331 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_RESET);
332 if (hw->chip_id == CHIP_ID_YUKON_SUPR && hw->chip_rev == CHIP_REV_YU_SU_A0)
333 /* put CPU into halt state */
334 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_HALTED);
335
336 if (pex && !(hw->flags & SKY2_HW_RAM_BUFFER)) {
337 reg = sky2_pci_read32(hw, PCI_DEV_REG1);
338 /* force to PCIe L1 */
339 reg |= PCI_FORCE_PEX_L1;
340 sky2_pci_write32(hw, PCI_DEV_REG1, reg);
341 }
342 break;
343
344 default:
345 dev_warn(&hw->pdev->dev, PFX "Invalid power state (%d) ",
346 state);
347 return;
348 }
349
350 power_control |= PCI_PM_CTRL_PME_ENABLE;
351 /* Finally, set the new power state. */
352 sky2_pci_write32(hw, hw->pm_cap + PCI_PM_CTRL, power_control);
353
354 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
355 sky2_pci_read32(hw, B0_CTST);
356}
357
358static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) 277static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
359{ 278{
360 u16 reg; 279 u16 reg;
@@ -709,6 +628,11 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
709 sky2_pci_write32(hw, PCI_DEV_REG1, reg1); 628 sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
710 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); 629 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
711 sky2_pci_read32(hw, PCI_DEV_REG1); 630 sky2_pci_read32(hw, PCI_DEV_REG1);
631
632 if (hw->chip_id == CHIP_ID_YUKON_FE)
633 gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_ANE);
634 else if (hw->flags & SKY2_HW_ADV_POWER_CTL)
635 sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
712} 636}
713 637
714static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) 638static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
@@ -741,11 +665,16 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
741 665
742 if (hw->chip_id != CHIP_ID_YUKON_EC) { 666 if (hw->chip_id != CHIP_ID_YUKON_EC) {
743 if (hw->chip_id == CHIP_ID_YUKON_EC_U) { 667 if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
744 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); 668 /* select page 2 to access MAC control register */
669 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
745 670
671 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
746 /* enable Power Down */ 672 /* enable Power Down */
747 ctrl |= PHY_M_PC_POW_D_ENA; 673 ctrl |= PHY_M_PC_POW_D_ENA;
748 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); 674 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
675
676 /* set page register back to 0 */
677 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
749 } 678 }
750 679
751 /* set IEEE compatible Power Down Mode (dev. #4.99) */ 680 /* set IEEE compatible Power Down Mode (dev. #4.99) */
@@ -2855,10 +2784,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2855 hw->flags = SKY2_HW_GIGABIT 2784 hw->flags = SKY2_HW_GIGABIT
2856 | SKY2_HW_NEWER_PHY 2785 | SKY2_HW_NEWER_PHY
2857 | SKY2_HW_ADV_POWER_CTL; 2786 | SKY2_HW_ADV_POWER_CTL;
2858
2859 /* check for Rev. A1 dev 4200 */
2860 if (sky2_read16(hw, Q_ADDR(Q_XA1, Q_WM)) == 0)
2861 hw->flags |= SKY2_HW_CLK_POWER;
2862 break; 2787 break;
2863 2788
2864 case CHIP_ID_YUKON_EX: 2789 case CHIP_ID_YUKON_EX:
@@ -2914,12 +2839,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2914 if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P') 2839 if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
2915 hw->flags |= SKY2_HW_FIBRE_PHY; 2840 hw->flags |= SKY2_HW_FIBRE_PHY;
2916 2841
2917 hw->pm_cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PM);
2918 if (hw->pm_cap == 0) {
2919 dev_err(&hw->pdev->dev, "cannot find PowerManagement capability\n");
2920 return -EIO;
2921 }
2922
2923 hw->ports = 1; 2842 hw->ports = 1;
2924 t8 = sky2_read8(hw, B2_Y2_HW_RES); 2843 t8 = sky2_read8(hw, B2_Y2_HW_RES);
2925 if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { 2844 if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
@@ -4512,7 +4431,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
4512 4431
4513 pci_save_state(pdev); 4432 pci_save_state(pdev);
4514 pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); 4433 pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
4515 sky2_power_state(hw, pci_choose_state(pdev, state)); 4434 pci_set_power_state(pdev, pci_choose_state(pdev, state));
4516 4435
4517 return 0; 4436 return 0;
4518} 4437}
@@ -4525,7 +4444,9 @@ static int sky2_resume(struct pci_dev *pdev)
4525 if (!hw) 4444 if (!hw)
4526 return 0; 4445 return 0;
4527 4446
4528 sky2_power_state(hw, PCI_D0); 4447 err = pci_set_power_state(pdev, PCI_D0);
4448 if (err)
4449 goto out;
4529 4450
4530 err = pci_restore_state(pdev); 4451 err = pci_restore_state(pdev);
4531 if (err) 4452 if (err)
@@ -4595,7 +4516,7 @@ static void sky2_shutdown(struct pci_dev *pdev)
4595 pci_enable_wake(pdev, PCI_D3cold, wol); 4516 pci_enable_wake(pdev, PCI_D3cold, wol);
4596 4517
4597 pci_disable_device(pdev); 4518 pci_disable_device(pdev);
4598 sky2_power_state(hw, PCI_D3hot); 4519 pci_set_power_state(pdev, PCI_D3hot);
4599} 4520}
4600 4521
4601static struct pci_driver sky2_driver = { 4522static struct pci_driver sky2_driver = {
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 4d9c4a19bb85..92fb24b27d45 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2072,9 +2072,7 @@ struct sky2_hw {
2072#define SKY2_HW_NEW_LE 0x00000020 /* new LSOv2 format */ 2072#define SKY2_HW_NEW_LE 0x00000020 /* new LSOv2 format */
2073#define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */ 2073#define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */
2074#define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */ 2074#define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */
2075#define SKY2_HW_CLK_POWER 0x00000100 /* clock power management */
2076 2075
2077 int pm_cap;
2078 u8 chip_id; 2076 u8 chip_id;
2079 u8 chip_rev; 2077 u8 chip_rev;
2080 u8 pmd_type; 2078 u8 pmd_type;
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 76c17c28fab4..2abfc2845198 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -222,7 +222,7 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
222 */ 222 */
223#include <linux/dma-mapping.h> 223#include <linux/dma-mapping.h>
224#include <asm/dma.h> 224#include <asm/dma.h>
225#include <asm/arch/pxa-regs.h> 225#include <mach/pxa-regs.h>
226 226
227static dma_addr_t rx_dmabuf, tx_dmabuf; 227static dma_addr_t rx_dmabuf, tx_dmabuf;
228static int rx_dmalen, tx_dmalen; 228static int rx_dmalen, tx_dmalen;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 22209b6f1405..997e7f1d5c6e 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -187,7 +187,7 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
187 187
188#elif defined(CONFIG_SA1100_ASSABET) 188#elif defined(CONFIG_SA1100_ASSABET)
189 189
190#include <asm/arch/neponset.h> 190#include <mach/neponset.h>
191 191
192/* We can only do 8-bit reads and writes in the static memory space. */ 192/* We can only do 8-bit reads and writes in the static memory space. */
193#define SMC_CAN_USE_8BIT 1 193#define SMC_CAN_USE_8BIT 1
@@ -339,7 +339,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
339 * IOBARRIER on entry to their ISR. 339 * IOBARRIER on entry to their ISR.
340 */ 340 */
341 341
342#include <asm/arch/constants.h> /* IOBARRIER_VIRT */ 342#include <mach/constants.h> /* IOBARRIER_VIRT */
343 343
344#define SMC_CAN_USE_8BIT 0 344#define SMC_CAN_USE_8BIT 0
345#define SMC_CAN_USE_16BIT 1 345#define SMC_CAN_USE_16BIT 1
@@ -525,7 +525,7 @@ struct smc_local {
525 */ 525 */
526#include <linux/dma-mapping.h> 526#include <linux/dma-mapping.h>
527#include <asm/dma.h> 527#include <asm/dma.h>
528#include <asm/arch/pxa-regs.h> 528#include <mach/pxa-regs.h>
529 529
530#ifdef SMC_insl 530#ifdef SMC_insl
531#undef SMC_insl 531#undef SMC_insl
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index 9b2a7f7bb258..e531302d95f5 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -425,14 +425,11 @@ static int init586(struct net_device *dev)
425 int len = ((char *) p->iscp - (char *) ptr - 8) / 6; 425 int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
426 if(num_addrs > len) { 426 if(num_addrs > len) {
427 printk("%s: switching to promisc. mode\n",dev->name); 427 printk("%s: switching to promisc. mode\n",dev->name);
428 dev->flags|=IFF_PROMISC; 428 cfg_cmd->promisc = 1;
429 } 429 }
430 } 430 }
431 if(dev->flags&IFF_PROMISC) 431 if(dev->flags&IFF_PROMISC)
432 { 432 cfg_cmd->promisc = 1;
433 cfg_cmd->promisc=1;
434 dev->flags|=IFF_PROMISC;
435 }
436 cfg_cmd->carr_coll = 0x00; 433 cfg_cmd->carr_coll = 0x00;
437 434
438 p->scb->cbl_offset = make16(cfg_cmd); 435 p->scb->cbl_offset = make16(cfg_cmd);
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index c66dfc9ec1ec..7db48f1cd949 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -27,7 +27,6 @@
27#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/tty.h> 28#include <linux/tty.h>
29#include <linux/if_vlan.h> 29#include <linux/if_vlan.h>
30#include <linux/version.h>
31#include <linux/interrupt.h> 30#include <linux/interrupt.h>
32#include <linux/vmalloc.h> 31#include <linux/vmalloc.h>
33#include <asm/byteorder.h> 32#include <asm/byteorder.h>
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index d2439b85a790..71d2c5cfdad9 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -66,8 +66,8 @@
66 66
67#define DRV_MODULE_NAME "tg3" 67#define DRV_MODULE_NAME "tg3"
68#define PFX DRV_MODULE_NAME ": " 68#define PFX DRV_MODULE_NAME ": "
69#define DRV_MODULE_VERSION "3.93" 69#define DRV_MODULE_VERSION "3.94"
70#define DRV_MODULE_RELDATE "May 22, 2008" 70#define DRV_MODULE_RELDATE "August 14, 2008"
71 71
72#define TG3_DEF_MAC_MODE 0 72#define TG3_DEF_MAC_MODE 0
73#define TG3_DEF_RX_MODE 0 73#define TG3_DEF_RX_MODE 0
@@ -536,6 +536,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
536 return 0; 536 return 0;
537 537
538 switch (locknum) { 538 switch (locknum) {
539 case TG3_APE_LOCK_GRC:
539 case TG3_APE_LOCK_MEM: 540 case TG3_APE_LOCK_MEM:
540 break; 541 break;
541 default: 542 default:
@@ -573,6 +574,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
573 return; 574 return;
574 575
575 switch (locknum) { 576 switch (locknum) {
577 case TG3_APE_LOCK_GRC:
576 case TG3_APE_LOCK_MEM: 578 case TG3_APE_LOCK_MEM:
577 break; 579 break;
578 default: 580 default:
@@ -1018,15 +1020,43 @@ static void tg3_mdio_fini(struct tg3 *tp)
1018} 1020}
1019 1021
1020/* tp->lock is held. */ 1022/* tp->lock is held. */
1023static inline void tg3_generate_fw_event(struct tg3 *tp)
1024{
1025 u32 val;
1026
1027 val = tr32(GRC_RX_CPU_EVENT);
1028 val |= GRC_RX_CPU_DRIVER_EVENT;
1029 tw32_f(GRC_RX_CPU_EVENT, val);
1030
1031 tp->last_event_jiffies = jiffies;
1032}
1033
1034#define TG3_FW_EVENT_TIMEOUT_USEC 2500
1035
1036/* tp->lock is held. */
1021static void tg3_wait_for_event_ack(struct tg3 *tp) 1037static void tg3_wait_for_event_ack(struct tg3 *tp)
1022{ 1038{
1023 int i; 1039 int i;
1040 unsigned int delay_cnt;
1041 long time_remain;
1042
1043 /* If enough time has passed, no wait is necessary. */
1044 time_remain = (long)(tp->last_event_jiffies + 1 +
1045 usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) -
1046 (long)jiffies;
1047 if (time_remain < 0)
1048 return;
1024 1049
1025 /* Wait for up to 2.5 milliseconds */ 1050 /* Check if we can shorten the wait time. */
1026 for (i = 0; i < 250000; i++) { 1051 delay_cnt = jiffies_to_usecs(time_remain);
1052 if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC)
1053 delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC;
1054 delay_cnt = (delay_cnt >> 3) + 1;
1055
1056 for (i = 0; i < delay_cnt; i++) {
1027 if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) 1057 if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
1028 break; 1058 break;
1029 udelay(10); 1059 udelay(8);
1030 } 1060 }
1031} 1061}
1032 1062
@@ -1075,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
1075 val = 0; 1105 val = 0;
1076 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val); 1106 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
1077 1107
1078 val = tr32(GRC_RX_CPU_EVENT); 1108 tg3_generate_fw_event(tp);
1079 val |= GRC_RX_CPU_DRIVER_EVENT;
1080 tw32_f(GRC_RX_CPU_EVENT, val);
1081} 1109}
1082 1110
1083static void tg3_link_report(struct tg3 *tp) 1111static void tg3_link_report(struct tg3 *tp)
@@ -2124,6 +2152,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
2124 (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) 2152 (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
2125 mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE; 2153 mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
2126 2154
2155 if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
2156 mac_mode |= tp->mac_mode &
2157 (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
2158 if (mac_mode & MAC_MODE_APE_TX_EN)
2159 mac_mode |= MAC_MODE_TDE_ENABLE;
2160 }
2161
2127 tw32_f(MAC_MODE, mac_mode); 2162 tw32_f(MAC_MODE, mac_mode);
2128 udelay(100); 2163 udelay(100);
2129 2164
@@ -5493,7 +5528,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
5493 return; 5528 return;
5494 5529
5495 apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); 5530 apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
5496 if (apedata != APE_FW_STATUS_READY) 5531 if (!(apedata & APE_FW_STATUS_READY))
5497 return; 5532 return;
5498 5533
5499 /* Wait for up to 1 millisecond for APE to service previous event. */ 5534 /* Wait for up to 1 millisecond for APE to service previous event. */
@@ -5760,6 +5795,8 @@ static int tg3_chip_reset(struct tg3 *tp)
5760 5795
5761 tg3_mdio_stop(tp); 5796 tg3_mdio_stop(tp);
5762 5797
5798 tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
5799
5763 /* No matching tg3_nvram_unlock() after this because 5800 /* No matching tg3_nvram_unlock() after this because
5764 * chip reset below will undo the nvram lock. 5801 * chip reset below will undo the nvram lock.
5765 */ 5802 */
@@ -5908,12 +5945,19 @@ static int tg3_chip_reset(struct tg3 *tp)
5908 } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { 5945 } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
5909 tp->mac_mode = MAC_MODE_PORT_MODE_GMII; 5946 tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
5910 tw32_f(MAC_MODE, tp->mac_mode); 5947 tw32_f(MAC_MODE, tp->mac_mode);
5948 } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
5949 tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
5950 if (tp->mac_mode & MAC_MODE_APE_TX_EN)
5951 tp->mac_mode |= MAC_MODE_TDE_ENABLE;
5952 tw32_f(MAC_MODE, tp->mac_mode);
5911 } else 5953 } else
5912 tw32_f(MAC_MODE, 0); 5954 tw32_f(MAC_MODE, 0);
5913 udelay(40); 5955 udelay(40);
5914 5956
5915 tg3_mdio_start(tp); 5957 tg3_mdio_start(tp);
5916 5958
5959 tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
5960
5917 err = tg3_poll_fw(tp); 5961 err = tg3_poll_fw(tp);
5918 if (err) 5962 if (err)
5919 return err; 5963 return err;
@@ -5935,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp)
5935 tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); 5979 tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
5936 if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { 5980 if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
5937 tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; 5981 tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
5982 tp->last_event_jiffies = jiffies;
5938 if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) 5983 if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
5939 tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; 5984 tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
5940 } 5985 }
@@ -5948,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp)
5948{ 5993{
5949 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && 5994 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
5950 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { 5995 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
5951 u32 val;
5952
5953 /* Wait for RX cpu to ACK the previous event. */ 5996 /* Wait for RX cpu to ACK the previous event. */
5954 tg3_wait_for_event_ack(tp); 5997 tg3_wait_for_event_ack(tp);
5955 5998
5956 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW); 5999 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
5957 val = tr32(GRC_RX_CPU_EVENT); 6000
5958 val |= GRC_RX_CPU_DRIVER_EVENT; 6001 tg3_generate_fw_event(tp);
5959 tw32(GRC_RX_CPU_EVENT, val);
5960 6002
5961 /* Wait for RX cpu to ACK this event. */ 6003 /* Wait for RX cpu to ACK this event. */
5962 tg3_wait_for_event_ack(tp); 6004 tg3_wait_for_event_ack(tp);
@@ -7406,7 +7448,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
7406 udelay(10); 7448 udelay(10);
7407 } 7449 }
7408 7450
7409 tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | 7451 if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
7452 tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
7453 else
7454 tp->mac_mode = 0;
7455 tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
7410 MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; 7456 MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
7411 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && 7457 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
7412 !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && 7458 !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
@@ -7840,9 +7886,8 @@ static void tg3_timer(unsigned long __opaque)
7840 * resets. 7886 * resets.
7841 */ 7887 */
7842 if (!--tp->asf_counter) { 7888 if (!--tp->asf_counter) {
7843 if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { 7889 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
7844 u32 val; 7890 !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
7845
7846 tg3_wait_for_event_ack(tp); 7891 tg3_wait_for_event_ack(tp);
7847 7892
7848 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, 7893 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
@@ -7850,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque)
7850 tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); 7895 tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
7851 /* 5 seconds timeout */ 7896 /* 5 seconds timeout */
7852 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); 7897 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
7853 val = tr32(GRC_RX_CPU_EVENT); 7898
7854 val |= GRC_RX_CPU_DRIVER_EVENT; 7899 tg3_generate_fw_event(tp);
7855 tw32_f(GRC_RX_CPU_EVENT, val);
7856 } 7900 }
7857 tp->asf_counter = tp->asf_multiplier; 7901 tp->asf_counter = tp->asf_multiplier;
7858 } 7902 }
@@ -8422,6 +8466,11 @@ static inline unsigned long get_stat64(tg3_stat64_t *val)
8422 return ret; 8466 return ret;
8423} 8467}
8424 8468
8469static inline u64 get_estat64(tg3_stat64_t *val)
8470{
8471 return ((u64)val->high << 32) | ((u64)val->low);
8472}
8473
8425static unsigned long calc_crc_errors(struct tg3 *tp) 8474static unsigned long calc_crc_errors(struct tg3 *tp)
8426{ 8475{
8427 struct tg3_hw_stats *hw_stats = tp->hw_stats; 8476 struct tg3_hw_stats *hw_stats = tp->hw_stats;
@@ -8450,7 +8499,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
8450 8499
8451#define ESTAT_ADD(member) \ 8500#define ESTAT_ADD(member) \
8452 estats->member = old_estats->member + \ 8501 estats->member = old_estats->member + \
8453 get_stat64(&hw_stats->member) 8502 get_estat64(&hw_stats->member)
8454 8503
8455static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp) 8504static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
8456{ 8505{
@@ -12416,6 +12465,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
12416 tp->misc_host_ctrl); 12465 tp->misc_host_ctrl);
12417 } 12466 }
12418 12467
12468 /* Preserve the APE MAC_MODE bits */
12469 if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
12470 tp->mac_mode = tr32(MAC_MODE) |
12471 MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
12472 else
12473 tp->mac_mode = TG3_DEF_MAC_MODE;
12474
12419 /* these are limited to 10/100 only */ 12475 /* these are limited to 10/100 only */
12420 if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && 12476 if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
12421 (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || 12477 (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
@@ -13275,7 +13331,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
13275 tp->pdev = pdev; 13331 tp->pdev = pdev;
13276 tp->dev = dev; 13332 tp->dev = dev;
13277 tp->pm_cap = pm_cap; 13333 tp->pm_cap = pm_cap;
13278 tp->mac_mode = TG3_DEF_MAC_MODE;
13279 tp->rx_mode = TG3_DEF_RX_MODE; 13334 tp->rx_mode = TG3_DEF_RX_MODE;
13280 tp->tx_mode = TG3_DEF_TX_MODE; 13335 tp->tx_mode = TG3_DEF_TX_MODE;
13281 13336
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index df07842172b7..f5b8cab8d4b5 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -325,6 +325,8 @@
325#define MAC_MODE_TDE_ENABLE 0x00200000 325#define MAC_MODE_TDE_ENABLE 0x00200000
326#define MAC_MODE_RDE_ENABLE 0x00400000 326#define MAC_MODE_RDE_ENABLE 0x00400000
327#define MAC_MODE_FHDE_ENABLE 0x00800000 327#define MAC_MODE_FHDE_ENABLE 0x00800000
328#define MAC_MODE_APE_RX_EN 0x08000000
329#define MAC_MODE_APE_TX_EN 0x10000000
328#define MAC_STATUS 0x00000404 330#define MAC_STATUS 0x00000404
329#define MAC_STATUS_PCS_SYNCED 0x00000001 331#define MAC_STATUS_PCS_SYNCED 0x00000001
330#define MAC_STATUS_SIGNAL_DET 0x00000002 332#define MAC_STATUS_SIGNAL_DET 0x00000002
@@ -1889,6 +1891,7 @@
1889#define APE_EVENT_STATUS_EVENT_PENDING 0x80000000 1891#define APE_EVENT_STATUS_EVENT_PENDING 0x80000000
1890 1892
1891/* APE convenience enumerations. */ 1893/* APE convenience enumerations. */
1894#define TG3_APE_LOCK_GRC 1
1892#define TG3_APE_LOCK_MEM 4 1895#define TG3_APE_LOCK_MEM 4
1893 1896
1894#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 1897#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10
@@ -2429,7 +2432,10 @@ struct tg3 {
2429 struct tg3_ethtool_stats estats; 2432 struct tg3_ethtool_stats estats;
2430 struct tg3_ethtool_stats estats_prev; 2433 struct tg3_ethtool_stats estats_prev;
2431 2434
2435 union {
2432 unsigned long phy_crc_errors; 2436 unsigned long phy_crc_errors;
2437 unsigned long last_event_jiffies;
2438 };
2433 2439
2434 u32 rx_offset; 2440 u32 rx_offset;
2435 u32 tg3_flags; 2441 u32 tg3_flags;
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 85246ed7cb9c..ec871f646766 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -360,8 +360,8 @@ TLan_GetSKB( const struct tlan_list_tag *tag)
360{ 360{
361 unsigned long addr; 361 unsigned long addr;
362 362
363 addr = tag->buffer[8].address; 363 addr = tag->buffer[9].address;
364 addr |= (tag->buffer[9].address << 16) << 16; 364 addr |= (tag->buffer[8].address << 16) << 16;
365 return (struct sk_buff *) addr; 365 return (struct sk_buff *) addr;
366} 366}
367 367
@@ -1984,7 +1984,6 @@ static void TLan_ResetLists( struct net_device *dev )
1984 TLanList *list; 1984 TLanList *list;
1985 dma_addr_t list_phys; 1985 dma_addr_t list_phys;
1986 struct sk_buff *skb; 1986 struct sk_buff *skb;
1987 void *t = NULL;
1988 1987
1989 priv->txHead = 0; 1988 priv->txHead = 0;
1990 priv->txTail = 0; 1989 priv->txTail = 0;
@@ -2022,7 +2021,8 @@ static void TLan_ResetLists( struct net_device *dev )
2022 } 2021 }
2023 2022
2024 skb_reserve( skb, NET_IP_ALIGN ); 2023 skb_reserve( skb, NET_IP_ALIGN );
2025 list->buffer[0].address = pci_map_single(priv->pciDev, t, 2024 list->buffer[0].address = pci_map_single(priv->pciDev,
2025 skb->data,
2026 TLAN_MAX_FRAME_SIZE, 2026 TLAN_MAX_FRAME_SIZE,
2027 PCI_DMA_FROMDEVICE); 2027 PCI_DMA_FROMDEVICE);
2028 TLan_StoreSKB(list, skb); 2028 TLan_StoreSKB(list, skb);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index e6bbc639c2d0..6daea0c91862 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -358,6 +358,66 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
358 return mask; 358 return mask;
359} 359}
360 360
361/* prepad is the amount to reserve at front. len is length after that.
362 * linear is a hint as to how much to copy (usually headers). */
363static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear,
364 gfp_t gfp)
365{
366 struct sk_buff *skb;
367 unsigned int i;
368
369 skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN);
370 if (skb) {
371 skb_reserve(skb, prepad);
372 skb_put(skb, len);
373 return skb;
374 }
375
376 /* Under a page? Don't bother with paged skb. */
377 if (prepad + len < PAGE_SIZE)
378 return NULL;
379
380 /* Start with a normal skb, and add pages. */
381 skb = alloc_skb(prepad + linear, gfp);
382 if (!skb)
383 return NULL;
384
385 skb_reserve(skb, prepad);
386 skb_put(skb, linear);
387
388 len -= linear;
389
390 for (i = 0; i < MAX_SKB_FRAGS; i++) {
391 skb_frag_t *f = &skb_shinfo(skb)->frags[i];
392
393 f->page = alloc_page(gfp|__GFP_ZERO);
394 if (!f->page)
395 break;
396
397 f->page_offset = 0;
398 f->size = PAGE_SIZE;
399
400 skb->data_len += PAGE_SIZE;
401 skb->len += PAGE_SIZE;
402 skb->truesize += PAGE_SIZE;
403 skb_shinfo(skb)->nr_frags++;
404
405 if (len < PAGE_SIZE) {
406 len = 0;
407 break;
408 }
409 len -= PAGE_SIZE;
410 }
411
412 /* Too large, or alloc fail? */
413 if (unlikely(len)) {
414 kfree_skb(skb);
415 skb = NULL;
416 }
417
418 return skb;
419}
420
361/* Get packet from user space buffer */ 421/* Get packet from user space buffer */
362static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count) 422static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
363{ 423{
@@ -391,14 +451,12 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
391 return -EINVAL; 451 return -EINVAL;
392 } 452 }
393 453
394 if (!(skb = alloc_skb(len + align, GFP_KERNEL))) { 454 if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
395 tun->dev->stats.rx_dropped++; 455 tun->dev->stats.rx_dropped++;
396 return -ENOMEM; 456 return -ENOMEM;
397 } 457 }
398 458
399 if (align) 459 if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
400 skb_reserve(skb, align);
401 if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
402 tun->dev->stats.rx_dropped++; 460 tun->dev->stats.rx_dropped++;
403 kfree_skb(skb); 461 kfree_skb(skb);
404 return -EFAULT; 462 return -EFAULT;
@@ -748,6 +806,36 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
748 return err; 806 return err;
749} 807}
750 808
809static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
810{
811 struct tun_struct *tun = file->private_data;
812
813 if (!tun)
814 return -EBADFD;
815
816 DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name);
817
818 strcpy(ifr->ifr_name, tun->dev->name);
819
820 ifr->ifr_flags = 0;
821
822 if (ifr->ifr_flags & TUN_TUN_DEV)
823 ifr->ifr_flags |= IFF_TUN;
824 else
825 ifr->ifr_flags |= IFF_TAP;
826
827 if (tun->flags & TUN_NO_PI)
828 ifr->ifr_flags |= IFF_NO_PI;
829
830 if (tun->flags & TUN_ONE_QUEUE)
831 ifr->ifr_flags |= IFF_ONE_QUEUE;
832
833 if (tun->flags & TUN_VNET_HDR)
834 ifr->ifr_flags |= IFF_VNET_HDR;
835
836 return 0;
837}
838
751/* This is like a cut-down ethtool ops, except done via tun fd so no 839/* This is like a cut-down ethtool ops, except done via tun fd so no
752 * privs required. */ 840 * privs required. */
753static int set_offload(struct net_device *dev, unsigned long arg) 841static int set_offload(struct net_device *dev, unsigned long arg)
@@ -833,6 +921,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
833 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd); 921 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
834 922
835 switch (cmd) { 923 switch (cmd) {
924 case TUNGETIFF:
925 ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
926 if (ret)
927 return ret;
928
929 if (copy_to_user(argp, &ifr, sizeof(ifr)))
930 return -EFAULT;
931 break;
932
836 case TUNSETNOCSUM: 933 case TUNSETNOCSUM:
837 /* Disable/Enable checksum */ 934 /* Disable/Enable checksum */
838 if (arg) 935 if (arg)
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 8549f1159a30..734ce0977f02 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -128,7 +128,6 @@ static const int multicast_filter_limit = 32;
128#include <asm/io.h> 128#include <asm/io.h>
129#include <asm/uaccess.h> 129#include <asm/uaccess.h>
130#include <linux/in6.h> 130#include <linux/in6.h>
131#include <linux/version.h>
132#include <linux/dma-mapping.h> 131#include <linux/dma-mapping.h>
133 132
134#include "typhoon.h" 133#include "typhoon.h"
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 68e198bd538b..0973b6e37024 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -154,17 +154,6 @@ config USB_NET_AX8817X
154 This driver creates an interface named "ethX", where X depends on 154 This driver creates an interface named "ethX", where X depends on
155 what other networking devices you have in use. 155 what other networking devices you have in use.
156 156
157config USB_HSO
158 tristate "Option USB High Speed Mobile Devices"
159 depends on USB && RFKILL
160 default n
161 help
162 Choose this option if you have an Option HSDPA/HSUPA card.
163 These cards support downlink speeds of 7.2Mbps or greater.
164
165 To compile this driver as a module, choose M here: the
166 module will be called hso.
167
168config USB_NET_CDCETHER 157config USB_NET_CDCETHER
169 tristate "CDC Ethernet support (smart devices such as cable modems)" 158 tristate "CDC Ethernet support (smart devices such as cable modems)"
170 depends on USB_USBNET 159 depends on USB_USBNET
@@ -337,5 +326,15 @@ config USB_NET_ZAURUS
337 really need this non-conformant variant of CDC Ethernet (or in 326 really need this non-conformant variant of CDC Ethernet (or in
338 some cases CDC MDLM) protocol, not "g_ether". 327 some cases CDC MDLM) protocol, not "g_ether".
339 328
329config USB_HSO
330 tristate "Option USB High Speed Mobile Devices"
331 depends on USB && RFKILL
332 default n
333 help
334 Choose this option if you have an Option HSDPA/HSUPA card.
335 These cards support downlink speeds of 7.2Mbps or greater.
336
337 To compile this driver as a module, choose M here: the
338 module will be called hso.
340 339
341endmenu 340endmenu
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 031d07b105af..1b7cac77159e 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -102,8 +102,12 @@
102 102
103#define MAX_RX_URBS 2 103#define MAX_RX_URBS 2
104 104
105#define get_serial_by_tty(x) \ 105static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty)
106 (x ? (struct hso_serial *)x->driver_data : NULL) 106{
107 if (tty)
108 return tty->driver_data;
109 return NULL;
110}
107 111
108/*****************************************************************************/ 112/*****************************************************************************/
109/* Debugging functions */ 113/* Debugging functions */
@@ -294,24 +298,25 @@ static int hso_get_activity(struct hso_device *hso_dev);
294 298
295/* #define DEBUG */ 299/* #define DEBUG */
296 300
297#define dev2net(x) (x->port_data.dev_net) 301static inline struct hso_net *dev2net(struct hso_device *hso_dev)
298#define dev2ser(x) (x->port_data.dev_serial) 302{
303 return hso_dev->port_data.dev_net;
304}
305
306static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
307{
308 return hso_dev->port_data.dev_serial;
309}
299 310
300/* Debugging functions */ 311/* Debugging functions */
301#ifdef DEBUG 312#ifdef DEBUG
302static void dbg_dump(int line_count, const char *func_name, unsigned char *buf, 313static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
303 unsigned int len) 314 unsigned int len)
304{ 315{
305 u8 i = 0; 316 static char name[255];
306 317
307 printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len); 318 sprintf(name, "hso[%d:%s]", line_count, func_name);
308 319 print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
309 for (i = 0; i < len; i++) {
310 if (!(i % 16))
311 printk("\n 0x%03x: ", i);
312 printk("%02x ", (unsigned char)buf[i]);
313 }
314 printk("\n");
315} 320}
316 321
317#define DUMP(buf_, len_) \ 322#define DUMP(buf_, len_) \
@@ -528,13 +533,12 @@ static struct hso_serial *get_serial_by_shared_int_and_type(
528 533
529static struct hso_serial *get_serial_by_index(unsigned index) 534static struct hso_serial *get_serial_by_index(unsigned index)
530{ 535{
531 struct hso_serial *serial; 536 struct hso_serial *serial = NULL;
532 unsigned long flags; 537 unsigned long flags;
533 538
534 if (!serial_table[index])
535 return NULL;
536 spin_lock_irqsave(&serial_table_lock, flags); 539 spin_lock_irqsave(&serial_table_lock, flags);
537 serial = dev2ser(serial_table[index]); 540 if (serial_table[index])
541 serial = dev2ser(serial_table[index]);
538 spin_unlock_irqrestore(&serial_table_lock, flags); 542 spin_unlock_irqrestore(&serial_table_lock, flags);
539 543
540 return serial; 544 return serial;
@@ -561,6 +565,7 @@ static int get_free_serial_index(void)
561static void set_serial_by_index(unsigned index, struct hso_serial *serial) 565static void set_serial_by_index(unsigned index, struct hso_serial *serial)
562{ 566{
563 unsigned long flags; 567 unsigned long flags;
568
564 spin_lock_irqsave(&serial_table_lock, flags); 569 spin_lock_irqsave(&serial_table_lock, flags);
565 if (serial) 570 if (serial)
566 serial_table[index] = serial->parent; 571 serial_table[index] = serial->parent;
@@ -569,7 +574,7 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial)
569 spin_unlock_irqrestore(&serial_table_lock, flags); 574 spin_unlock_irqrestore(&serial_table_lock, flags);
570} 575}
571 576
572/* log a meaningfull explanation of an USB status */ 577/* log a meaningful explanation of an USB status */
573static void log_usb_status(int status, const char *function) 578static void log_usb_status(int status, const char *function)
574{ 579{
575 char *explanation; 580 char *explanation;
@@ -1103,8 +1108,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
1103 /* reset the rts and dtr */ 1108 /* reset the rts and dtr */
1104 /* do the actual close */ 1109 /* do the actual close */
1105 serial->open_count--; 1110 serial->open_count--;
1111 kref_put(&serial->parent->ref, hso_serial_ref_free);
1106 if (serial->open_count <= 0) { 1112 if (serial->open_count <= 0) {
1107 kref_put(&serial->parent->ref, hso_serial_ref_free);
1108 serial->open_count = 0; 1113 serial->open_count = 0;
1109 if (serial->tty) { 1114 if (serial->tty) {
1110 serial->tty->driver_data = NULL; 1115 serial->tty->driver_data = NULL;
@@ -1467,7 +1472,8 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
1467 return; 1472 return;
1468 } 1473 }
1469 hso_put_activity(serial->parent); 1474 hso_put_activity(serial->parent);
1470 tty_wakeup(serial->tty); 1475 if (serial->tty)
1476 tty_wakeup(serial->tty);
1471 hso_kick_transmit(serial); 1477 hso_kick_transmit(serial);
1472 1478
1473 D1(" "); 1479 D1(" ");
@@ -1538,7 +1544,8 @@ static void ctrl_callback(struct urb *urb)
1538 clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags); 1544 clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
1539 } else { 1545 } else {
1540 hso_put_activity(serial->parent); 1546 hso_put_activity(serial->parent);
1541 tty_wakeup(serial->tty); 1547 if (serial->tty)
1548 tty_wakeup(serial->tty);
1542 /* response to a write command */ 1549 /* response to a write command */
1543 hso_kick_transmit(serial); 1550 hso_kick_transmit(serial);
1544 } 1551 }
@@ -2652,7 +2659,7 @@ static void hso_free_interface(struct usb_interface *interface)
2652 hso_stop_net_device(network_table[i]); 2659 hso_stop_net_device(network_table[i]);
2653 cancel_work_sync(&network_table[i]->async_put_intf); 2660 cancel_work_sync(&network_table[i]->async_put_intf);
2654 cancel_work_sync(&network_table[i]->async_get_intf); 2661 cancel_work_sync(&network_table[i]->async_get_intf);
2655 if(rfk) 2662 if (rfk)
2656 rfkill_unregister(rfk); 2663 rfkill_unregister(rfk);
2657 hso_free_net_device(network_table[i]); 2664 hso_free_net_device(network_table[i]);
2658 } 2665 }
@@ -2723,7 +2730,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
2723} 2730}
2724 2731
2725/* operations setup of the serial interface */ 2732/* operations setup of the serial interface */
2726static struct tty_operations hso_serial_ops = { 2733static const struct tty_operations hso_serial_ops = {
2727 .open = hso_serial_open, 2734 .open = hso_serial_open,
2728 .close = hso_serial_close, 2735 .close = hso_serial_close,
2729 .write = hso_serial_write, 2736 .write = hso_serial_write,
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index b588c890ea70..a84ba487c713 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -1285,6 +1285,21 @@ static void check_carrier(struct work_struct *work)
1285 } 1285 }
1286} 1286}
1287 1287
1288static int pegasus_blacklisted(struct usb_device *udev)
1289{
1290 struct usb_device_descriptor *udd = &udev->descriptor;
1291
1292 /* Special quirk to keep the driver from handling the Belkin Bluetooth
1293 * dongle which happens to have the same ID.
1294 */
1295 if ((udd->idVendor == VENDOR_BELKIN && udd->idProduct == 0x0121) &&
1296 (udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) &&
1297 (udd->bDeviceProtocol == 1))
1298 return 1;
1299
1300 return 0;
1301}
1302
1288static int pegasus_probe(struct usb_interface *intf, 1303static int pegasus_probe(struct usb_interface *intf,
1289 const struct usb_device_id *id) 1304 const struct usb_device_id *id)
1290{ 1305{
@@ -1296,6 +1311,12 @@ static int pegasus_probe(struct usb_interface *intf,
1296 DECLARE_MAC_BUF(mac); 1311 DECLARE_MAC_BUF(mac);
1297 1312
1298 usb_get_dev(dev); 1313 usb_get_dev(dev);
1314
1315 if (pegasus_blacklisted(dev)) {
1316 res = -ENODEV;
1317 goto out;
1318 }
1319
1299 net = alloc_etherdev(sizeof(struct pegasus)); 1320 net = alloc_etherdev(sizeof(struct pegasus));
1300 if (!net) { 1321 if (!net) {
1301 dev_err(&intf->dev, "can't allocate %s\n", "device"); 1322 dev_err(&intf->dev, "can't allocate %s\n", "device");
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 370ce30f2f45..007c12970065 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -662,6 +662,10 @@ static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid
662 spin_unlock_irq(&vptr->lock); 662 spin_unlock_irq(&vptr->lock);
663} 663}
664 664
665static void velocity_init_rx_ring_indexes(struct velocity_info *vptr)
666{
667 vptr->rx.dirty = vptr->rx.filled = vptr->rx.curr = 0;
668}
665 669
666/** 670/**
667 * velocity_rx_reset - handle a receive reset 671 * velocity_rx_reset - handle a receive reset
@@ -677,16 +681,16 @@ static void velocity_rx_reset(struct velocity_info *vptr)
677 struct mac_regs __iomem * regs = vptr->mac_regs; 681 struct mac_regs __iomem * regs = vptr->mac_regs;
678 int i; 682 int i;
679 683
680 vptr->rd_dirty = vptr->rd_filled = vptr->rd_curr = 0; 684 velocity_init_rx_ring_indexes(vptr);
681 685
682 /* 686 /*
683 * Init state, all RD entries belong to the NIC 687 * Init state, all RD entries belong to the NIC
684 */ 688 */
685 for (i = 0; i < vptr->options.numrx; ++i) 689 for (i = 0; i < vptr->options.numrx; ++i)
686 vptr->rd_ring[i].rdesc0.len |= OWNED_BY_NIC; 690 vptr->rx.ring[i].rdesc0.len |= OWNED_BY_NIC;
687 691
688 writew(vptr->options.numrx, &regs->RBRDU); 692 writew(vptr->options.numrx, &regs->RBRDU);
689 writel(vptr->rd_pool_dma, &regs->RDBaseLo); 693 writel(vptr->rx.pool_dma, &regs->RDBaseLo);
690 writew(0, &regs->RDIdx); 694 writew(0, &regs->RDIdx);
691 writew(vptr->options.numrx - 1, &regs->RDCSize); 695 writew(vptr->options.numrx - 1, &regs->RDCSize);
692} 696}
@@ -779,15 +783,15 @@ static void velocity_init_registers(struct velocity_info *vptr,
779 783
780 vptr->int_mask = INT_MASK_DEF; 784 vptr->int_mask = INT_MASK_DEF;
781 785
782 writel(vptr->rd_pool_dma, &regs->RDBaseLo); 786 writel(vptr->rx.pool_dma, &regs->RDBaseLo);
783 writew(vptr->options.numrx - 1, &regs->RDCSize); 787 writew(vptr->options.numrx - 1, &regs->RDCSize);
784 mac_rx_queue_run(regs); 788 mac_rx_queue_run(regs);
785 mac_rx_queue_wake(regs); 789 mac_rx_queue_wake(regs);
786 790
787 writew(vptr->options.numtx - 1, &regs->TDCSize); 791 writew(vptr->options.numtx - 1, &regs->TDCSize);
788 792
789 for (i = 0; i < vptr->num_txq; i++) { 793 for (i = 0; i < vptr->tx.numq; i++) {
790 writel(vptr->td_pool_dma[i], &regs->TDBaseLo[i]); 794 writel(vptr->tx.pool_dma[i], &regs->TDBaseLo[i]);
791 mac_tx_queue_run(regs, i); 795 mac_tx_queue_run(regs, i);
792 } 796 }
793 797
@@ -1047,7 +1051,7 @@ static void __devinit velocity_init_info(struct pci_dev *pdev,
1047 1051
1048 vptr->pdev = pdev; 1052 vptr->pdev = pdev;
1049 vptr->chip_id = info->chip_id; 1053 vptr->chip_id = info->chip_id;
1050 vptr->num_txq = info->txqueue; 1054 vptr->tx.numq = info->txqueue;
1051 vptr->multicast_limit = MCAM_SIZE; 1055 vptr->multicast_limit = MCAM_SIZE;
1052 spin_lock_init(&vptr->lock); 1056 spin_lock_init(&vptr->lock);
1053 INIT_LIST_HEAD(&vptr->list); 1057 INIT_LIST_HEAD(&vptr->list);
@@ -1093,14 +1097,14 @@ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pc
1093} 1097}
1094 1098
1095/** 1099/**
1096 * velocity_init_rings - set up DMA rings 1100 * velocity_init_dma_rings - set up DMA rings
1097 * @vptr: Velocity to set up 1101 * @vptr: Velocity to set up
1098 * 1102 *
1099 * Allocate PCI mapped DMA rings for the receive and transmit layer 1103 * Allocate PCI mapped DMA rings for the receive and transmit layer
1100 * to use. 1104 * to use.
1101 */ 1105 */
1102 1106
1103static int velocity_init_rings(struct velocity_info *vptr) 1107static int velocity_init_dma_rings(struct velocity_info *vptr)
1104{ 1108{
1105 struct velocity_opt *opt = &vptr->options; 1109 struct velocity_opt *opt = &vptr->options;
1106 const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc); 1110 const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc);
@@ -1116,7 +1120,7 @@ static int velocity_init_rings(struct velocity_info *vptr)
1116 * pci_alloc_consistent() fulfills the requirement for 64 bytes 1120 * pci_alloc_consistent() fulfills the requirement for 64 bytes
1117 * alignment 1121 * alignment
1118 */ 1122 */
1119 pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->num_txq + 1123 pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->tx.numq +
1120 rx_ring_size, &pool_dma); 1124 rx_ring_size, &pool_dma);
1121 if (!pool) { 1125 if (!pool) {
1122 dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n", 1126 dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
@@ -1124,15 +1128,15 @@ static int velocity_init_rings(struct velocity_info *vptr)
1124 return -ENOMEM; 1128 return -ENOMEM;
1125 } 1129 }
1126 1130
1127 vptr->rd_ring = pool; 1131 vptr->rx.ring = pool;
1128 vptr->rd_pool_dma = pool_dma; 1132 vptr->rx.pool_dma = pool_dma;
1129 1133
1130 pool += rx_ring_size; 1134 pool += rx_ring_size;
1131 pool_dma += rx_ring_size; 1135 pool_dma += rx_ring_size;
1132 1136
1133 for (i = 0; i < vptr->num_txq; i++) { 1137 for (i = 0; i < vptr->tx.numq; i++) {
1134 vptr->td_rings[i] = pool; 1138 vptr->tx.rings[i] = pool;
1135 vptr->td_pool_dma[i] = pool_dma; 1139 vptr->tx.pool_dma[i] = pool_dma;
1136 pool += tx_ring_size; 1140 pool += tx_ring_size;
1137 pool_dma += tx_ring_size; 1141 pool_dma += tx_ring_size;
1138 } 1142 }
@@ -1141,18 +1145,18 @@ static int velocity_init_rings(struct velocity_info *vptr)
1141} 1145}
1142 1146
1143/** 1147/**
1144 * velocity_free_rings - free PCI ring pointers 1148 * velocity_free_dma_rings - free PCI ring pointers
1145 * @vptr: Velocity to free from 1149 * @vptr: Velocity to free from
1146 * 1150 *
1147 * Clean up the PCI ring buffers allocated to this velocity. 1151 * Clean up the PCI ring buffers allocated to this velocity.
1148 */ 1152 */
1149 1153
1150static void velocity_free_rings(struct velocity_info *vptr) 1154static void velocity_free_dma_rings(struct velocity_info *vptr)
1151{ 1155{
1152 const int size = vptr->options.numrx * sizeof(struct rx_desc) + 1156 const int size = vptr->options.numrx * sizeof(struct rx_desc) +
1153 vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq; 1157 vptr->options.numtx * sizeof(struct tx_desc) * vptr->tx.numq;
1154 1158
1155 pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma); 1159 pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
1156} 1160}
1157 1161
1158static void velocity_give_many_rx_descs(struct velocity_info *vptr) 1162static void velocity_give_many_rx_descs(struct velocity_info *vptr)
@@ -1164,44 +1168,44 @@ static void velocity_give_many_rx_descs(struct velocity_info *vptr)
1164 * RD number must be equal to 4X per hardware spec 1168 * RD number must be equal to 4X per hardware spec
1165 * (programming guide rev 1.20, p.13) 1169 * (programming guide rev 1.20, p.13)
1166 */ 1170 */
1167 if (vptr->rd_filled < 4) 1171 if (vptr->rx.filled < 4)
1168 return; 1172 return;
1169 1173
1170 wmb(); 1174 wmb();
1171 1175
1172 unusable = vptr->rd_filled & 0x0003; 1176 unusable = vptr->rx.filled & 0x0003;
1173 dirty = vptr->rd_dirty - unusable; 1177 dirty = vptr->rx.dirty - unusable;
1174 for (avail = vptr->rd_filled & 0xfffc; avail; avail--) { 1178 for (avail = vptr->rx.filled & 0xfffc; avail; avail--) {
1175 dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1; 1179 dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
1176 vptr->rd_ring[dirty].rdesc0.len |= OWNED_BY_NIC; 1180 vptr->rx.ring[dirty].rdesc0.len |= OWNED_BY_NIC;
1177 } 1181 }
1178 1182
1179 writew(vptr->rd_filled & 0xfffc, &regs->RBRDU); 1183 writew(vptr->rx.filled & 0xfffc, &regs->RBRDU);
1180 vptr->rd_filled = unusable; 1184 vptr->rx.filled = unusable;
1181} 1185}
1182 1186
1183static int velocity_rx_refill(struct velocity_info *vptr) 1187static int velocity_rx_refill(struct velocity_info *vptr)
1184{ 1188{
1185 int dirty = vptr->rd_dirty, done = 0; 1189 int dirty = vptr->rx.dirty, done = 0;
1186 1190
1187 do { 1191 do {
1188 struct rx_desc *rd = vptr->rd_ring + dirty; 1192 struct rx_desc *rd = vptr->rx.ring + dirty;
1189 1193
1190 /* Fine for an all zero Rx desc at init time as well */ 1194 /* Fine for an all zero Rx desc at init time as well */
1191 if (rd->rdesc0.len & OWNED_BY_NIC) 1195 if (rd->rdesc0.len & OWNED_BY_NIC)
1192 break; 1196 break;
1193 1197
1194 if (!vptr->rd_info[dirty].skb) { 1198 if (!vptr->rx.info[dirty].skb) {
1195 if (velocity_alloc_rx_buf(vptr, dirty) < 0) 1199 if (velocity_alloc_rx_buf(vptr, dirty) < 0)
1196 break; 1200 break;
1197 } 1201 }
1198 done++; 1202 done++;
1199 dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0; 1203 dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
1200 } while (dirty != vptr->rd_curr); 1204 } while (dirty != vptr->rx.curr);
1201 1205
1202 if (done) { 1206 if (done) {
1203 vptr->rd_dirty = dirty; 1207 vptr->rx.dirty = dirty;
1204 vptr->rd_filled += done; 1208 vptr->rx.filled += done;
1205 } 1209 }
1206 1210
1207 return done; 1211 return done;
@@ -1209,7 +1213,7 @@ static int velocity_rx_refill(struct velocity_info *vptr)
1209 1213
1210static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu) 1214static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu)
1211{ 1215{
1212 vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32; 1216 vptr->rx.buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
1213} 1217}
1214 1218
1215/** 1219/**
@@ -1224,12 +1228,12 @@ static int velocity_init_rd_ring(struct velocity_info *vptr)
1224{ 1228{
1225 int ret = -ENOMEM; 1229 int ret = -ENOMEM;
1226 1230
1227 vptr->rd_info = kcalloc(vptr->options.numrx, 1231 vptr->rx.info = kcalloc(vptr->options.numrx,
1228 sizeof(struct velocity_rd_info), GFP_KERNEL); 1232 sizeof(struct velocity_rd_info), GFP_KERNEL);
1229 if (!vptr->rd_info) 1233 if (!vptr->rx.info)
1230 goto out; 1234 goto out;
1231 1235
1232 vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0; 1236 velocity_init_rx_ring_indexes(vptr);
1233 1237
1234 if (velocity_rx_refill(vptr) != vptr->options.numrx) { 1238 if (velocity_rx_refill(vptr) != vptr->options.numrx) {
1235 VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR 1239 VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
@@ -1255,18 +1259,18 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
1255{ 1259{
1256 int i; 1260 int i;
1257 1261
1258 if (vptr->rd_info == NULL) 1262 if (vptr->rx.info == NULL)
1259 return; 1263 return;
1260 1264
1261 for (i = 0; i < vptr->options.numrx; i++) { 1265 for (i = 0; i < vptr->options.numrx; i++) {
1262 struct velocity_rd_info *rd_info = &(vptr->rd_info[i]); 1266 struct velocity_rd_info *rd_info = &(vptr->rx.info[i]);
1263 struct rx_desc *rd = vptr->rd_ring + i; 1267 struct rx_desc *rd = vptr->rx.ring + i;
1264 1268
1265 memset(rd, 0, sizeof(*rd)); 1269 memset(rd, 0, sizeof(*rd));
1266 1270
1267 if (!rd_info->skb) 1271 if (!rd_info->skb)
1268 continue; 1272 continue;
1269 pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz, 1273 pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
1270 PCI_DMA_FROMDEVICE); 1274 PCI_DMA_FROMDEVICE);
1271 rd_info->skb_dma = (dma_addr_t) NULL; 1275 rd_info->skb_dma = (dma_addr_t) NULL;
1272 1276
@@ -1274,8 +1278,8 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
1274 rd_info->skb = NULL; 1278 rd_info->skb = NULL;
1275 } 1279 }
1276 1280
1277 kfree(vptr->rd_info); 1281 kfree(vptr->rx.info);
1278 vptr->rd_info = NULL; 1282 vptr->rx.info = NULL;
1279} 1283}
1280 1284
1281/** 1285/**
@@ -1293,19 +1297,19 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
1293 unsigned int j; 1297 unsigned int j;
1294 1298
1295 /* Init the TD ring entries */ 1299 /* Init the TD ring entries */
1296 for (j = 0; j < vptr->num_txq; j++) { 1300 for (j = 0; j < vptr->tx.numq; j++) {
1297 curr = vptr->td_pool_dma[j]; 1301 curr = vptr->tx.pool_dma[j];
1298 1302
1299 vptr->td_infos[j] = kcalloc(vptr->options.numtx, 1303 vptr->tx.infos[j] = kcalloc(vptr->options.numtx,
1300 sizeof(struct velocity_td_info), 1304 sizeof(struct velocity_td_info),
1301 GFP_KERNEL); 1305 GFP_KERNEL);
1302 if (!vptr->td_infos[j]) { 1306 if (!vptr->tx.infos[j]) {
1303 while(--j >= 0) 1307 while(--j >= 0)
1304 kfree(vptr->td_infos[j]); 1308 kfree(vptr->tx.infos[j]);
1305 return -ENOMEM; 1309 return -ENOMEM;
1306 } 1310 }
1307 1311
1308 vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0; 1312 vptr->tx.tail[j] = vptr->tx.curr[j] = vptr->tx.used[j] = 0;
1309 } 1313 }
1310 return 0; 1314 return 0;
1311} 1315}
@@ -1317,7 +1321,7 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
1317static void velocity_free_td_ring_entry(struct velocity_info *vptr, 1321static void velocity_free_td_ring_entry(struct velocity_info *vptr,
1318 int q, int n) 1322 int q, int n)
1319{ 1323{
1320 struct velocity_td_info * td_info = &(vptr->td_infos[q][n]); 1324 struct velocity_td_info * td_info = &(vptr->tx.infos[q][n]);
1321 int i; 1325 int i;
1322 1326
1323 if (td_info == NULL) 1327 if (td_info == NULL)
@@ -1349,15 +1353,15 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
1349{ 1353{
1350 int i, j; 1354 int i, j;
1351 1355
1352 for (j = 0; j < vptr->num_txq; j++) { 1356 for (j = 0; j < vptr->tx.numq; j++) {
1353 if (vptr->td_infos[j] == NULL) 1357 if (vptr->tx.infos[j] == NULL)
1354 continue; 1358 continue;
1355 for (i = 0; i < vptr->options.numtx; i++) { 1359 for (i = 0; i < vptr->options.numtx; i++) {
1356 velocity_free_td_ring_entry(vptr, j, i); 1360 velocity_free_td_ring_entry(vptr, j, i);
1357 1361
1358 } 1362 }
1359 kfree(vptr->td_infos[j]); 1363 kfree(vptr->tx.infos[j]);
1360 vptr->td_infos[j] = NULL; 1364 vptr->tx.infos[j] = NULL;
1361 } 1365 }
1362} 1366}
1363 1367
@@ -1374,13 +1378,13 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
1374static int velocity_rx_srv(struct velocity_info *vptr, int status) 1378static int velocity_rx_srv(struct velocity_info *vptr, int status)
1375{ 1379{
1376 struct net_device_stats *stats = &vptr->stats; 1380 struct net_device_stats *stats = &vptr->stats;
1377 int rd_curr = vptr->rd_curr; 1381 int rd_curr = vptr->rx.curr;
1378 int works = 0; 1382 int works = 0;
1379 1383
1380 do { 1384 do {
1381 struct rx_desc *rd = vptr->rd_ring + rd_curr; 1385 struct rx_desc *rd = vptr->rx.ring + rd_curr;
1382 1386
1383 if (!vptr->rd_info[rd_curr].skb) 1387 if (!vptr->rx.info[rd_curr].skb)
1384 break; 1388 break;
1385 1389
1386 if (rd->rdesc0.len & OWNED_BY_NIC) 1390 if (rd->rdesc0.len & OWNED_BY_NIC)
@@ -1412,7 +1416,7 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
1412 rd_curr = 0; 1416 rd_curr = 0;
1413 } while (++works <= 15); 1417 } while (++works <= 15);
1414 1418
1415 vptr->rd_curr = rd_curr; 1419 vptr->rx.curr = rd_curr;
1416 1420
1417 if ((works > 0) && (velocity_rx_refill(vptr) > 0)) 1421 if ((works > 0) && (velocity_rx_refill(vptr) > 0))
1418 velocity_give_many_rx_descs(vptr); 1422 velocity_give_many_rx_descs(vptr);
@@ -1510,8 +1514,8 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
1510{ 1514{
1511 void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int); 1515 void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
1512 struct net_device_stats *stats = &vptr->stats; 1516 struct net_device_stats *stats = &vptr->stats;
1513 struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]); 1517 struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
1514 struct rx_desc *rd = &(vptr->rd_ring[idx]); 1518 struct rx_desc *rd = &(vptr->rx.ring[idx]);
1515 int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff; 1519 int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
1516 struct sk_buff *skb; 1520 struct sk_buff *skb;
1517 1521
@@ -1527,7 +1531,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
1527 skb = rd_info->skb; 1531 skb = rd_info->skb;
1528 1532
1529 pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma, 1533 pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
1530 vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); 1534 vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
1531 1535
1532 /* 1536 /*
1533 * Drop frame not meeting IEEE 802.3 1537 * Drop frame not meeting IEEE 802.3
@@ -1550,7 +1554,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
1550 rd_info->skb = NULL; 1554 rd_info->skb = NULL;
1551 } 1555 }
1552 1556
1553 pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz, 1557 pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
1554 PCI_DMA_FROMDEVICE); 1558 PCI_DMA_FROMDEVICE);
1555 1559
1556 skb_put(skb, pkt_len - 4); 1560 skb_put(skb, pkt_len - 4);
@@ -1580,10 +1584,10 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
1580 1584
1581static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx) 1585static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
1582{ 1586{
1583 struct rx_desc *rd = &(vptr->rd_ring[idx]); 1587 struct rx_desc *rd = &(vptr->rx.ring[idx]);
1584 struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]); 1588 struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
1585 1589
1586 rd_info->skb = netdev_alloc_skb(vptr->dev, vptr->rx_buf_sz + 64); 1590 rd_info->skb = dev_alloc_skb(vptr->rx.buf_sz + 64);
1587 if (rd_info->skb == NULL) 1591 if (rd_info->skb == NULL)
1588 return -ENOMEM; 1592 return -ENOMEM;
1589 1593
@@ -1592,14 +1596,15 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
1592 * 64byte alignment. 1596 * 64byte alignment.
1593 */ 1597 */
1594 skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63); 1598 skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
1595 rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); 1599 rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data,
1600 vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
1596 1601
1597 /* 1602 /*
1598 * Fill in the descriptor to match 1603 * Fill in the descriptor to match
1599 */ 1604 */
1600 1605
1601 *((u32 *) & (rd->rdesc0)) = 0; 1606 *((u32 *) & (rd->rdesc0)) = 0;
1602 rd->size = cpu_to_le16(vptr->rx_buf_sz) | RX_INTEN; 1607 rd->size = cpu_to_le16(vptr->rx.buf_sz) | RX_INTEN;
1603 rd->pa_low = cpu_to_le32(rd_info->skb_dma); 1608 rd->pa_low = cpu_to_le32(rd_info->skb_dma);
1604 rd->pa_high = 0; 1609 rd->pa_high = 0;
1605 return 0; 1610 return 0;
@@ -1625,15 +1630,15 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
1625 struct velocity_td_info *tdinfo; 1630 struct velocity_td_info *tdinfo;
1626 struct net_device_stats *stats = &vptr->stats; 1631 struct net_device_stats *stats = &vptr->stats;
1627 1632
1628 for (qnum = 0; qnum < vptr->num_txq; qnum++) { 1633 for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
1629 for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0; 1634 for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
1630 idx = (idx + 1) % vptr->options.numtx) { 1635 idx = (idx + 1) % vptr->options.numtx) {
1631 1636
1632 /* 1637 /*
1633 * Get Tx Descriptor 1638 * Get Tx Descriptor
1634 */ 1639 */
1635 td = &(vptr->td_rings[qnum][idx]); 1640 td = &(vptr->tx.rings[qnum][idx]);
1636 tdinfo = &(vptr->td_infos[qnum][idx]); 1641 tdinfo = &(vptr->tx.infos[qnum][idx]);
1637 1642
1638 if (td->tdesc0.len & OWNED_BY_NIC) 1643 if (td->tdesc0.len & OWNED_BY_NIC)
1639 break; 1644 break;
@@ -1657,9 +1662,9 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
1657 stats->tx_bytes += tdinfo->skb->len; 1662 stats->tx_bytes += tdinfo->skb->len;
1658 } 1663 }
1659 velocity_free_tx_buf(vptr, tdinfo); 1664 velocity_free_tx_buf(vptr, tdinfo);
1660 vptr->td_used[qnum]--; 1665 vptr->tx.used[qnum]--;
1661 } 1666 }
1662 vptr->td_tail[qnum] = idx; 1667 vptr->tx.tail[qnum] = idx;
1663 1668
1664 if (AVAIL_TD(vptr, qnum) < 1) { 1669 if (AVAIL_TD(vptr, qnum) < 1) {
1665 full = 1; 1670 full = 1;
@@ -1846,6 +1851,40 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_
1846 tdinfo->skb = NULL; 1851 tdinfo->skb = NULL;
1847} 1852}
1848 1853
1854static int velocity_init_rings(struct velocity_info *vptr, int mtu)
1855{
1856 int ret;
1857
1858 velocity_set_rxbufsize(vptr, mtu);
1859
1860 ret = velocity_init_dma_rings(vptr);
1861 if (ret < 0)
1862 goto out;
1863
1864 ret = velocity_init_rd_ring(vptr);
1865 if (ret < 0)
1866 goto err_free_dma_rings_0;
1867
1868 ret = velocity_init_td_ring(vptr);
1869 if (ret < 0)
1870 goto err_free_rd_ring_1;
1871out:
1872 return ret;
1873
1874err_free_rd_ring_1:
1875 velocity_free_rd_ring(vptr);
1876err_free_dma_rings_0:
1877 velocity_free_dma_rings(vptr);
1878 goto out;
1879}
1880
1881static void velocity_free_rings(struct velocity_info *vptr)
1882{
1883 velocity_free_td_ring(vptr);
1884 velocity_free_rd_ring(vptr);
1885 velocity_free_dma_rings(vptr);
1886}
1887
1849/** 1888/**
1850 * velocity_open - interface activation callback 1889 * velocity_open - interface activation callback
1851 * @dev: network layer device to open 1890 * @dev: network layer device to open
@@ -1862,20 +1901,10 @@ static int velocity_open(struct net_device *dev)
1862 struct velocity_info *vptr = netdev_priv(dev); 1901 struct velocity_info *vptr = netdev_priv(dev);
1863 int ret; 1902 int ret;
1864 1903
1865 velocity_set_rxbufsize(vptr, dev->mtu); 1904 ret = velocity_init_rings(vptr, dev->mtu);
1866
1867 ret = velocity_init_rings(vptr);
1868 if (ret < 0) 1905 if (ret < 0)
1869 goto out; 1906 goto out;
1870 1907
1871 ret = velocity_init_rd_ring(vptr);
1872 if (ret < 0)
1873 goto err_free_desc_rings;
1874
1875 ret = velocity_init_td_ring(vptr);
1876 if (ret < 0)
1877 goto err_free_rd_ring;
1878
1879 /* Ensure chip is running */ 1908 /* Ensure chip is running */
1880 pci_set_power_state(vptr->pdev, PCI_D0); 1909 pci_set_power_state(vptr->pdev, PCI_D0);
1881 1910
@@ -1888,7 +1917,8 @@ static int velocity_open(struct net_device *dev)
1888 if (ret < 0) { 1917 if (ret < 0) {
1889 /* Power down the chip */ 1918 /* Power down the chip */
1890 pci_set_power_state(vptr->pdev, PCI_D3hot); 1919 pci_set_power_state(vptr->pdev, PCI_D3hot);
1891 goto err_free_td_ring; 1920 velocity_free_rings(vptr);
1921 goto out;
1892 } 1922 }
1893 1923
1894 mac_enable_int(vptr->mac_regs); 1924 mac_enable_int(vptr->mac_regs);
@@ -1896,14 +1926,6 @@ static int velocity_open(struct net_device *dev)
1896 vptr->flags |= VELOCITY_FLAGS_OPENED; 1926 vptr->flags |= VELOCITY_FLAGS_OPENED;
1897out: 1927out:
1898 return ret; 1928 return ret;
1899
1900err_free_td_ring:
1901 velocity_free_td_ring(vptr);
1902err_free_rd_ring:
1903 velocity_free_rd_ring(vptr);
1904err_free_desc_rings:
1905 velocity_free_rings(vptr);
1906 goto out;
1907} 1929}
1908 1930
1909/** 1931/**
@@ -1919,50 +1941,72 @@ err_free_desc_rings:
1919static int velocity_change_mtu(struct net_device *dev, int new_mtu) 1941static int velocity_change_mtu(struct net_device *dev, int new_mtu)
1920{ 1942{
1921 struct velocity_info *vptr = netdev_priv(dev); 1943 struct velocity_info *vptr = netdev_priv(dev);
1922 unsigned long flags;
1923 int oldmtu = dev->mtu;
1924 int ret = 0; 1944 int ret = 0;
1925 1945
1926 if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) { 1946 if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
1927 VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n", 1947 VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
1928 vptr->dev->name); 1948 vptr->dev->name);
1929 return -EINVAL; 1949 ret = -EINVAL;
1950 goto out_0;
1930 } 1951 }
1931 1952
1932 if (!netif_running(dev)) { 1953 if (!netif_running(dev)) {
1933 dev->mtu = new_mtu; 1954 dev->mtu = new_mtu;
1934 return 0; 1955 goto out_0;
1935 } 1956 }
1936 1957
1937 if (new_mtu != oldmtu) { 1958 if (dev->mtu != new_mtu) {
1959 struct velocity_info *tmp_vptr;
1960 unsigned long flags;
1961 struct rx_info rx;
1962 struct tx_info tx;
1963
1964 tmp_vptr = kzalloc(sizeof(*tmp_vptr), GFP_KERNEL);
1965 if (!tmp_vptr) {
1966 ret = -ENOMEM;
1967 goto out_0;
1968 }
1969
1970 tmp_vptr->dev = dev;
1971 tmp_vptr->pdev = vptr->pdev;
1972 tmp_vptr->options = vptr->options;
1973 tmp_vptr->tx.numq = vptr->tx.numq;
1974
1975 ret = velocity_init_rings(tmp_vptr, new_mtu);
1976 if (ret < 0)
1977 goto out_free_tmp_vptr_1;
1978
1938 spin_lock_irqsave(&vptr->lock, flags); 1979 spin_lock_irqsave(&vptr->lock, flags);
1939 1980
1940 netif_stop_queue(dev); 1981 netif_stop_queue(dev);
1941 velocity_shutdown(vptr); 1982 velocity_shutdown(vptr);
1942 1983
1943 velocity_free_td_ring(vptr); 1984 rx = vptr->rx;
1944 velocity_free_rd_ring(vptr); 1985 tx = vptr->tx;
1945 1986
1946 dev->mtu = new_mtu; 1987 vptr->rx = tmp_vptr->rx;
1988 vptr->tx = tmp_vptr->tx;
1947 1989
1948 velocity_set_rxbufsize(vptr, new_mtu); 1990 tmp_vptr->rx = rx;
1991 tmp_vptr->tx = tx;
1949 1992
1950 ret = velocity_init_rd_ring(vptr); 1993 dev->mtu = new_mtu;
1951 if (ret < 0)
1952 goto out_unlock;
1953 1994
1954 ret = velocity_init_td_ring(vptr); 1995 velocity_give_many_rx_descs(vptr);
1955 if (ret < 0)
1956 goto out_unlock;
1957 1996
1958 velocity_init_registers(vptr, VELOCITY_INIT_COLD); 1997 velocity_init_registers(vptr, VELOCITY_INIT_COLD);
1959 1998
1960 mac_enable_int(vptr->mac_regs); 1999 mac_enable_int(vptr->mac_regs);
1961 netif_start_queue(dev); 2000 netif_start_queue(dev);
1962out_unlock: 2001
1963 spin_unlock_irqrestore(&vptr->lock, flags); 2002 spin_unlock_irqrestore(&vptr->lock, flags);
1964 }
1965 2003
2004 velocity_free_rings(tmp_vptr);
2005
2006out_free_tmp_vptr_1:
2007 kfree(tmp_vptr);
2008 }
2009out_0:
1966 return ret; 2010 return ret;
1967} 2011}
1968 2012
@@ -2008,9 +2052,6 @@ static int velocity_close(struct net_device *dev)
2008 /* Power down the chip */ 2052 /* Power down the chip */
2009 pci_set_power_state(vptr->pdev, PCI_D3hot); 2053 pci_set_power_state(vptr->pdev, PCI_D3hot);
2010 2054
2011 /* Free the resources */
2012 velocity_free_td_ring(vptr);
2013 velocity_free_rd_ring(vptr);
2014 velocity_free_rings(vptr); 2055 velocity_free_rings(vptr);
2015 2056
2016 vptr->flags &= (~VELOCITY_FLAGS_OPENED); 2057 vptr->flags &= (~VELOCITY_FLAGS_OPENED);
@@ -2056,9 +2097,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
2056 2097
2057 spin_lock_irqsave(&vptr->lock, flags); 2098 spin_lock_irqsave(&vptr->lock, flags);
2058 2099
2059 index = vptr->td_curr[qnum]; 2100 index = vptr->tx.curr[qnum];
2060 td_ptr = &(vptr->td_rings[qnum][index]); 2101 td_ptr = &(vptr->tx.rings[qnum][index]);
2061 tdinfo = &(vptr->td_infos[qnum][index]); 2102 tdinfo = &(vptr->tx.infos[qnum][index]);
2062 2103
2063 td_ptr->tdesc1.TCR = TCR0_TIC; 2104 td_ptr->tdesc1.TCR = TCR0_TIC;
2064 td_ptr->td_buf[0].size &= ~TD_QUEUE; 2105 td_ptr->td_buf[0].size &= ~TD_QUEUE;
@@ -2071,9 +2112,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
2071 skb_copy_from_linear_data(skb, tdinfo->buf, skb->len); 2112 skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
2072 tdinfo->skb_dma[0] = tdinfo->buf_dma; 2113 tdinfo->skb_dma[0] = tdinfo->buf_dma;
2073 td_ptr->tdesc0.len = len; 2114 td_ptr->tdesc0.len = len;
2074 td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); 2115 td_ptr->tx.buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
2075 td_ptr->td_buf[0].pa_high = 0; 2116 td_ptr->tx.buf[0].pa_high = 0;
2076 td_ptr->td_buf[0].size = len; /* queue is 0 anyway */ 2117 td_ptr->tx.buf[0].size = len; /* queue is 0 anyway */
2077 tdinfo->nskb_dma = 1; 2118 tdinfo->nskb_dma = 1;
2078 } else { 2119 } else {
2079 int i = 0; 2120 int i = 0;
@@ -2084,9 +2125,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
2084 td_ptr->tdesc0.len = len; 2125 td_ptr->tdesc0.len = len;
2085 2126
2086 /* FIXME: support 48bit DMA later */ 2127 /* FIXME: support 48bit DMA later */
2087 td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma); 2128 td_ptr->tx.buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
2088 td_ptr->td_buf[i].pa_high = 0; 2129 td_ptr->tx.buf[i].pa_high = 0;
2089 td_ptr->td_buf[i].size = cpu_to_le16(skb_headlen(skb)); 2130 td_ptr->tx.buf[i].size = cpu_to_le16(skb_headlen(skb));
2090 2131
2091 for (i = 0; i < nfrags; i++) { 2132 for (i = 0; i < nfrags; i++) {
2092 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 2133 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2094,9 +2135,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
2094 2135
2095 tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE); 2136 tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE);
2096 2137
2097 td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]); 2138 td_ptr->tx.buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
2098 td_ptr->td_buf[i + 1].pa_high = 0; 2139 td_ptr->tx.buf[i + 1].pa_high = 0;
2099 td_ptr->td_buf[i + 1].size = cpu_to_le16(frag->size); 2140 td_ptr->tx.buf[i + 1].size = cpu_to_le16(frag->size);
2100 } 2141 }
2101 tdinfo->nskb_dma = i - 1; 2142 tdinfo->nskb_dma = i - 1;
2102 } 2143 }
@@ -2142,13 +2183,13 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
2142 if (prev < 0) 2183 if (prev < 0)
2143 prev = vptr->options.numtx - 1; 2184 prev = vptr->options.numtx - 1;
2144 td_ptr->tdesc0.len |= OWNED_BY_NIC; 2185 td_ptr->tdesc0.len |= OWNED_BY_NIC;
2145 vptr->td_used[qnum]++; 2186 vptr->tx.used[qnum]++;
2146 vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx; 2187 vptr->tx.curr[qnum] = (index + 1) % vptr->options.numtx;
2147 2188
2148 if (AVAIL_TD(vptr, qnum) < 1) 2189 if (AVAIL_TD(vptr, qnum) < 1)
2149 netif_stop_queue(dev); 2190 netif_stop_queue(dev);
2150 2191
2151 td_ptr = &(vptr->td_rings[qnum][prev]); 2192 td_ptr = &(vptr->tx.rings[qnum][prev]);
2152 td_ptr->td_buf[0].size |= TD_QUEUE; 2193 td_ptr->td_buf[0].size |= TD_QUEUE;
2153 mac_tx_queue_wake(vptr->mac_regs, qnum); 2194 mac_tx_queue_wake(vptr->mac_regs, qnum);
2154 } 2195 }
@@ -3405,8 +3446,8 @@ static int velocity_resume(struct pci_dev *pdev)
3405 3446
3406 velocity_tx_srv(vptr, 0); 3447 velocity_tx_srv(vptr, 0);
3407 3448
3408 for (i = 0; i < vptr->num_txq; i++) { 3449 for (i = 0; i < vptr->tx.numq; i++) {
3409 if (vptr->td_used[i]) { 3450 if (vptr->tx.used[i]) {
3410 mac_tx_queue_wake(vptr->mac_regs, i); 3451 mac_tx_queue_wake(vptr->mac_regs, i);
3411 } 3452 }
3412 } 3453 }
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 86446147284c..1b95b04c9257 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1494,6 +1494,10 @@ struct velocity_opt {
1494 u32 flags; 1494 u32 flags;
1495}; 1495};
1496 1496
1497#define AVAIL_TD(p,q) ((p)->options.numtx-((p)->tx.used[(q)]))
1498
1499#define GET_RD_BY_IDX(vptr, idx) (vptr->rd_ring[idx])
1500
1497struct velocity_info { 1501struct velocity_info {
1498 struct list_head list; 1502 struct list_head list;
1499 1503
@@ -1501,9 +1505,6 @@ struct velocity_info {
1501 struct net_device *dev; 1505 struct net_device *dev;
1502 struct net_device_stats stats; 1506 struct net_device_stats stats;
1503 1507
1504 dma_addr_t rd_pool_dma;
1505 dma_addr_t td_pool_dma[TX_QUEUE_NO];
1506
1507 struct vlan_group *vlgrp; 1508 struct vlan_group *vlgrp;
1508 u8 ip_addr[4]; 1509 u8 ip_addr[4];
1509 enum chip_type chip_id; 1510 enum chip_type chip_id;
@@ -1512,25 +1513,29 @@ struct velocity_info {
1512 unsigned long memaddr; 1513 unsigned long memaddr;
1513 unsigned long ioaddr; 1514 unsigned long ioaddr;
1514 1515
1515 u8 rev_id; 1516 struct tx_info {
1516 1517 int numq;
1517#define AVAIL_TD(p,q) ((p)->options.numtx-((p)->td_used[(q)])) 1518
1519 /* FIXME: the locality of the data seems rather poor. */
1520 int used[TX_QUEUE_NO];
1521 int curr[TX_QUEUE_NO];
1522 int tail[TX_QUEUE_NO];
1523 struct tx_desc *rings[TX_QUEUE_NO];
1524 struct velocity_td_info *infos[TX_QUEUE_NO];
1525 dma_addr_t pool_dma[TX_QUEUE_NO];
1526 } tx;
1527
1528 struct rx_info {
1529 int buf_sz;
1530
1531 int dirty;
1532 int curr;
1533 u32 filled;
1534 struct rx_desc *ring;
1535 struct velocity_rd_info *info; /* It's an array */
1536 dma_addr_t pool_dma;
1537 } rx;
1518 1538
1519 int num_txq;
1520
1521 volatile int td_used[TX_QUEUE_NO];
1522 int td_curr[TX_QUEUE_NO];
1523 int td_tail[TX_QUEUE_NO];
1524 struct tx_desc *td_rings[TX_QUEUE_NO];
1525 struct velocity_td_info *td_infos[TX_QUEUE_NO];
1526
1527 int rd_curr;
1528 int rd_dirty;
1529 u32 rd_filled;
1530 struct rx_desc *rd_ring;
1531 struct velocity_rd_info *rd_info; /* It's an array */
1532
1533#define GET_RD_BY_IDX(vptr, idx) (vptr->rd_ring[idx])
1534 u32 mib_counter[MAX_HW_MIB_COUNTER]; 1539 u32 mib_counter[MAX_HW_MIB_COUNTER];
1535 struct velocity_opt options; 1540 struct velocity_opt options;
1536 1541
@@ -1538,7 +1543,6 @@ struct velocity_info {
1538 1543
1539 u32 flags; 1544 u32 flags;
1540 1545
1541 int rx_buf_sz;
1542 u32 mii_status; 1546 u32 mii_status;
1543 u32 phy_id; 1547 u32 phy_id;
1544 int multicast_limit; 1548 int multicast_limit;
@@ -1554,8 +1558,8 @@ struct velocity_info {
1554 struct velocity_context context; 1558 struct velocity_context context;
1555 1559
1556 u32 ticks; 1560 u32 ticks;
1557 u32 rx_bytes;
1558 1561
1562 u8 rev_id;
1559}; 1563};
1560 1564
1561/** 1565/**
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 846be60e7821..2ae2ec40015d 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -25,7 +25,7 @@ if WAN
25# There is no way to detect a comtrol sv11 - force it modular for now. 25# There is no way to detect a comtrol sv11 - force it modular for now.
26config HOSTESS_SV11 26config HOSTESS_SV11
27 tristate "Comtrol Hostess SV-11 support" 27 tristate "Comtrol Hostess SV-11 support"
28 depends on ISA && m && ISA_DMA_API && INET 28 depends on ISA && m && ISA_DMA_API && INET && HDLC
29 help 29 help
30 Driver for Comtrol Hostess SV-11 network card which 30 Driver for Comtrol Hostess SV-11 network card which
31 operates on low speed synchronous serial links at up to 31 operates on low speed synchronous serial links at up to
@@ -37,7 +37,7 @@ config HOSTESS_SV11
37# The COSA/SRP driver has not been tested as non-modular yet. 37# The COSA/SRP driver has not been tested as non-modular yet.
38config COSA 38config COSA
39 tristate "COSA/SRP sync serial boards support" 39 tristate "COSA/SRP sync serial boards support"
40 depends on ISA && m && ISA_DMA_API 40 depends on ISA && m && ISA_DMA_API && HDLC
41 ---help--- 41 ---help---
42 Driver for COSA and SRP synchronous serial boards. 42 Driver for COSA and SRP synchronous serial boards.
43 43
@@ -61,7 +61,7 @@ config COSA
61# 61#
62config LANMEDIA 62config LANMEDIA
63 tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards" 63 tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
64 depends on PCI && VIRT_TO_BUS 64 depends on PCI && VIRT_TO_BUS && HDLC
65 ---help--- 65 ---help---
66 Driver for the following Lan Media family of serial boards: 66 Driver for the following Lan Media family of serial boards:
67 67
@@ -78,9 +78,8 @@ config LANMEDIA
78 - LMC 5245 board connects directly to a T3 circuit saving the 78 - LMC 5245 board connects directly to a T3 circuit saving the
79 additional external hardware. 79 additional external hardware.
80 80
81 To change setting such as syncPPP vs Cisco HDLC or clock source you 81 To change setting such as clock source you will need lmcctl.
82 will need lmcctl. It is available at <ftp://ftp.lanmedia.com/> 82 It is available at <ftp://ftp.lanmedia.com/> (broken link).
83 (broken link).
84 83
85 To compile this driver as a module, choose M here: the 84 To compile this driver as a module, choose M here: the
86 module will be called lmc. 85 module will be called lmc.
@@ -88,7 +87,7 @@ config LANMEDIA
88# There is no way to detect a Sealevel board. Force it modular 87# There is no way to detect a Sealevel board. Force it modular
89config SEALEVEL_4021 88config SEALEVEL_4021
90 tristate "Sealevel Systems 4021 support" 89 tristate "Sealevel Systems 4021 support"
91 depends on ISA && m && ISA_DMA_API && INET 90 depends on ISA && m && ISA_DMA_API && INET && HDLC
92 help 91 help
93 This is a driver for the Sealevel Systems ACB 56 serial I/O adapter. 92 This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
94 93
@@ -154,8 +153,6 @@ config HDLC_PPP
154 help 153 help
155 Generic HDLC driver supporting PPP over WAN connections. 154 Generic HDLC driver supporting PPP over WAN connections.
156 155
157 It will be replaced by new PPP implementation in Linux 2.6.26.
158
159 If unsure, say N. 156 If unsure, say N.
160 157
161config HDLC_X25 158config HDLC_X25
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index d61fef36afc9..102549605d09 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -21,12 +21,11 @@ pc300-y := pc300_drv.o
21pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o 21pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o
22pc300-objs := $(pc300-y) 22pc300-objs := $(pc300-y)
23 23
24obj-$(CONFIG_HOSTESS_SV11) += z85230.o syncppp.o hostess_sv11.o 24obj-$(CONFIG_HOSTESS_SV11) += z85230.o hostess_sv11.o
25obj-$(CONFIG_SEALEVEL_4021) += z85230.o syncppp.o sealevel.o 25obj-$(CONFIG_SEALEVEL_4021) += z85230.o sealevel.o
26obj-$(CONFIG_COSA) += syncppp.o cosa.o 26obj-$(CONFIG_COSA) += cosa.o
27obj-$(CONFIG_FARSYNC) += syncppp.o farsync.o 27obj-$(CONFIG_FARSYNC) += farsync.o
28obj-$(CONFIG_DSCC4) += dscc4.o 28obj-$(CONFIG_DSCC4) += dscc4.o
29obj-$(CONFIG_LANMEDIA) += syncppp.o
30obj-$(CONFIG_X25_ASY) += x25_asy.o 29obj-$(CONFIG_X25_ASY) += x25_asy.o
31 30
32obj-$(CONFIG_LANMEDIA) += lmc/ 31obj-$(CONFIG_LANMEDIA) += lmc/
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index f7d3349dc3ec..f14051556c87 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -2,6 +2,7 @@
2 2
3/* 3/*
4 * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak <kas@fi.muni.cz> 4 * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak <kas@fi.muni.cz>
5 * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -54,7 +55,7 @@
54 * 55 *
55 * The Linux driver (unlike the present *BSD drivers :-) can work even 56 * The Linux driver (unlike the present *BSD drivers :-) can work even
56 * for the COSA and SRP in one computer and allows each channel to work 57 * for the COSA and SRP in one computer and allows each channel to work
57 * in one of the three modes (character device, Cisco HDLC, Sync PPP). 58 * in one of the two modes (character or network device).
58 * 59 *
59 * AUTHOR 60 * AUTHOR
60 * 61 *
@@ -72,12 +73,6 @@
72 * The Comtrol Hostess SV11 driver by Alan Cox 73 * The Comtrol Hostess SV11 driver by Alan Cox
73 * The Sync PPP/Cisco HDLC layer (syncppp.c) ported to Linux by Alan Cox 74 * The Sync PPP/Cisco HDLC layer (syncppp.c) ported to Linux by Alan Cox
74 */ 75 */
75/*
76 * 5/25/1999 : Marcelo Tosatti <marcelo@conectiva.com.br>
77 * fixed a deadlock in cosa_sppp_open
78 */
79
80/* ---------- Headers, macros, data structures ---------- */
81 76
82#include <linux/module.h> 77#include <linux/module.h>
83#include <linux/kernel.h> 78#include <linux/kernel.h>
@@ -86,6 +81,7 @@
86#include <linux/fs.h> 81#include <linux/fs.h>
87#include <linux/interrupt.h> 82#include <linux/interrupt.h>
88#include <linux/delay.h> 83#include <linux/delay.h>
84#include <linux/hdlc.h>
89#include <linux/errno.h> 85#include <linux/errno.h>
90#include <linux/ioport.h> 86#include <linux/ioport.h>
91#include <linux/netdevice.h> 87#include <linux/netdevice.h>
@@ -93,14 +89,12 @@
93#include <linux/mutex.h> 89#include <linux/mutex.h>
94#include <linux/device.h> 90#include <linux/device.h>
95#include <linux/smp_lock.h> 91#include <linux/smp_lock.h>
96
97#undef COSA_SLOW_IO /* for testing purposes only */
98
99#include <asm/io.h> 92#include <asm/io.h>
100#include <asm/dma.h> 93#include <asm/dma.h>
101#include <asm/byteorder.h> 94#include <asm/byteorder.h>
102 95
103#include <net/syncppp.h> 96#undef COSA_SLOW_IO /* for testing purposes only */
97
104#include "cosa.h" 98#include "cosa.h"
105 99
106/* Maximum length of the identification string. */ 100/* Maximum length of the identification string. */
@@ -112,7 +106,6 @@
112/* Per-channel data structure */ 106/* Per-channel data structure */
113 107
114struct channel_data { 108struct channel_data {
115 void *if_ptr; /* General purpose pointer (used by SPPP) */
116 int usage; /* Usage count; >0 for chrdev, -1 for netdev */ 109 int usage; /* Usage count; >0 for chrdev, -1 for netdev */
117 int num; /* Number of the channel */ 110 int num; /* Number of the channel */
118 struct cosa_data *cosa; /* Pointer to the per-card structure */ 111 struct cosa_data *cosa; /* Pointer to the per-card structure */
@@ -136,10 +129,9 @@ struct channel_data {
136 wait_queue_head_t txwaitq, rxwaitq; 129 wait_queue_head_t txwaitq, rxwaitq;
137 int tx_status, rx_status; 130 int tx_status, rx_status;
138 131
139 /* SPPP/HDLC device parts */ 132 /* generic HDLC device parts */
140 struct ppp_device pppdev; 133 struct net_device *netdev;
141 struct sk_buff *rx_skb, *tx_skb; 134 struct sk_buff *rx_skb, *tx_skb;
142 struct net_device_stats stats;
143}; 135};
144 136
145/* cosa->firmware_status bits */ 137/* cosa->firmware_status bits */
@@ -281,21 +273,19 @@ static int cosa_start_tx(struct channel_data *channel, char *buf, int size);
281static void cosa_kick(struct cosa_data *cosa); 273static void cosa_kick(struct cosa_data *cosa);
282static int cosa_dma_able(struct channel_data *chan, char *buf, int data); 274static int cosa_dma_able(struct channel_data *chan, char *buf, int data);
283 275
284/* SPPP/HDLC stuff */ 276/* Network device stuff */
285static void sppp_channel_init(struct channel_data *chan); 277static int cosa_net_attach(struct net_device *dev, unsigned short encoding,
286static void sppp_channel_delete(struct channel_data *chan); 278 unsigned short parity);
287static int cosa_sppp_open(struct net_device *d); 279static int cosa_net_open(struct net_device *d);
288static int cosa_sppp_close(struct net_device *d); 280static int cosa_net_close(struct net_device *d);
289static void cosa_sppp_timeout(struct net_device *d); 281static void cosa_net_timeout(struct net_device *d);
290static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *d); 282static int cosa_net_tx(struct sk_buff *skb, struct net_device *d);
291static char *sppp_setup_rx(struct channel_data *channel, int size); 283static char *cosa_net_setup_rx(struct channel_data *channel, int size);
292static int sppp_rx_done(struct channel_data *channel); 284static int cosa_net_rx_done(struct channel_data *channel);
293static int sppp_tx_done(struct channel_data *channel, int size); 285static int cosa_net_tx_done(struct channel_data *channel, int size);
294static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 286static int cosa_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
295static struct net_device_stats *cosa_net_stats(struct net_device *dev);
296 287
297/* Character device */ 288/* Character device */
298static void chardev_channel_init(struct channel_data *chan);
299static char *chrdev_setup_rx(struct channel_data *channel, int size); 289static char *chrdev_setup_rx(struct channel_data *channel, int size);
300static int chrdev_rx_done(struct channel_data *channel); 290static int chrdev_rx_done(struct channel_data *channel);
301static int chrdev_tx_done(struct channel_data *channel, int size); 291static int chrdev_tx_done(struct channel_data *channel, int size);
@@ -357,17 +347,17 @@ static void debug_status_in(struct cosa_data *cosa, int status);
357static void debug_status_out(struct cosa_data *cosa, int status); 347static void debug_status_out(struct cosa_data *cosa, int status);
358#endif 348#endif
359 349
360 350static inline struct channel_data* dev_to_chan(struct net_device *dev)
351{
352 return (struct channel_data *)dev_to_hdlc(dev)->priv;
353}
354
361/* ---------- Initialization stuff ---------- */ 355/* ---------- Initialization stuff ---------- */
362 356
363static int __init cosa_init(void) 357static int __init cosa_init(void)
364{ 358{
365 int i, err = 0; 359 int i, err = 0;
366 360
367 printk(KERN_INFO "cosa v1.08 (c) 1997-2000 Jan Kasprzak <kas@fi.muni.cz>\n");
368#ifdef CONFIG_SMP
369 printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n");
370#endif
371 if (cosa_major > 0) { 361 if (cosa_major > 0) {
372 if (register_chrdev(cosa_major, "cosa", &cosa_fops)) { 362 if (register_chrdev(cosa_major, "cosa", &cosa_fops)) {
373 printk(KERN_WARNING "cosa: unable to get major %d\n", 363 printk(KERN_WARNING "cosa: unable to get major %d\n",
@@ -402,7 +392,7 @@ static int __init cosa_init(void)
402 NULL, "cosa%d", i); 392 NULL, "cosa%d", i);
403 err = 0; 393 err = 0;
404 goto out; 394 goto out;
405 395
406out_chrdev: 396out_chrdev:
407 unregister_chrdev(cosa_major, "cosa"); 397 unregister_chrdev(cosa_major, "cosa");
408out: 398out:
@@ -414,43 +404,29 @@ static void __exit cosa_exit(void)
414{ 404{
415 struct cosa_data *cosa; 405 struct cosa_data *cosa;
416 int i; 406 int i;
417 printk(KERN_INFO "Unloading the cosa module\n");
418 407
419 for (i=0; i<nr_cards; i++) 408 for (i = 0; i < nr_cards; i++)
420 device_destroy(cosa_class, MKDEV(cosa_major, i)); 409 device_destroy(cosa_class, MKDEV(cosa_major, i));
421 class_destroy(cosa_class); 410 class_destroy(cosa_class);
422 for (cosa=cosa_cards; nr_cards--; cosa++) { 411
412 for (cosa = cosa_cards; nr_cards--; cosa++) {
423 /* Clean up the per-channel data */ 413 /* Clean up the per-channel data */
424 for (i=0; i<cosa->nchannels; i++) { 414 for (i = 0; i < cosa->nchannels; i++) {
425 /* Chardev driver has no alloc'd per-channel data */ 415 /* Chardev driver has no alloc'd per-channel data */
426 sppp_channel_delete(cosa->chan+i); 416 unregister_hdlc_device(cosa->chan[i].netdev);
417 free_netdev(cosa->chan[i].netdev);
427 } 418 }
428 /* Clean up the per-card data */ 419 /* Clean up the per-card data */
429 kfree(cosa->chan); 420 kfree(cosa->chan);
430 kfree(cosa->bouncebuf); 421 kfree(cosa->bouncebuf);
431 free_irq(cosa->irq, cosa); 422 free_irq(cosa->irq, cosa);
432 free_dma(cosa->dma); 423 free_dma(cosa->dma);
433 release_region(cosa->datareg,is_8bit(cosa)?2:4); 424 release_region(cosa->datareg, is_8bit(cosa) ? 2 : 4);
434 } 425 }
435 unregister_chrdev(cosa_major, "cosa"); 426 unregister_chrdev(cosa_major, "cosa");
436} 427}
437module_exit(cosa_exit); 428module_exit(cosa_exit);
438 429
439/*
440 * This function should register all the net devices needed for the
441 * single channel.
442 */
443static __inline__ void channel_init(struct channel_data *chan)
444{
445 sprintf(chan->name, "cosa%dc%d", chan->cosa->num, chan->num);
446
447 /* Initialize the chardev data structures */
448 chardev_channel_init(chan);
449
450 /* Register the sppp interface */
451 sppp_channel_init(chan);
452}
453
454static int cosa_probe(int base, int irq, int dma) 430static int cosa_probe(int base, int irq, int dma)
455{ 431{
456 struct cosa_data *cosa = cosa_cards+nr_cards; 432 struct cosa_data *cosa = cosa_cards+nr_cards;
@@ -576,13 +552,43 @@ static int cosa_probe(int base, int irq, int dma)
576 /* Initialize the per-channel data */ 552 /* Initialize the per-channel data */
577 cosa->chan = kcalloc(cosa->nchannels, sizeof(struct channel_data), GFP_KERNEL); 553 cosa->chan = kcalloc(cosa->nchannels, sizeof(struct channel_data), GFP_KERNEL);
578 if (!cosa->chan) { 554 if (!cosa->chan) {
579 err = -ENOMEM; 555 err = -ENOMEM;
580 goto err_out3; 556 goto err_out3;
581 } 557 }
582 for (i=0; i<cosa->nchannels; i++) { 558
583 cosa->chan[i].cosa = cosa; 559 for (i = 0; i < cosa->nchannels; i++) {
584 cosa->chan[i].num = i; 560 struct channel_data *chan = &cosa->chan[i];
585 channel_init(cosa->chan+i); 561
562 chan->cosa = cosa;
563 chan->num = i;
564 sprintf(chan->name, "cosa%dc%d", chan->cosa->num, i);
565
566 /* Initialize the chardev data structures */
567 mutex_init(&chan->rlock);
568 init_MUTEX(&chan->wsem);
569
570 /* Register the network interface */
571 if (!(chan->netdev = alloc_hdlcdev(chan))) {
572 printk(KERN_WARNING "%s: alloc_hdlcdev failed.\n",
573 chan->name);
574 goto err_hdlcdev;
575 }
576 dev_to_hdlc(chan->netdev)->attach = cosa_net_attach;
577 dev_to_hdlc(chan->netdev)->xmit = cosa_net_tx;
578 chan->netdev->open = cosa_net_open;
579 chan->netdev->stop = cosa_net_close;
580 chan->netdev->do_ioctl = cosa_net_ioctl;
581 chan->netdev->tx_timeout = cosa_net_timeout;
582 chan->netdev->watchdog_timeo = TX_TIMEOUT;
583 chan->netdev->base_addr = chan->cosa->datareg;
584 chan->netdev->irq = chan->cosa->irq;
585 chan->netdev->dma = chan->cosa->dma;
586 if (register_hdlc_device(chan->netdev)) {
587 printk(KERN_WARNING "%s: register_hdlc_device()"
588 " failed.\n", chan->netdev->name);
589 free_netdev(chan->netdev);
590 goto err_hdlcdev;
591 }
586 } 592 }
587 593
588 printk (KERN_INFO "cosa%d: %s (%s at 0x%x irq %d dma %d), %d channels\n", 594 printk (KERN_INFO "cosa%d: %s (%s at 0x%x irq %d dma %d), %d channels\n",
@@ -590,13 +596,20 @@ static int cosa_probe(int base, int irq, int dma)
590 cosa->datareg, cosa->irq, cosa->dma, cosa->nchannels); 596 cosa->datareg, cosa->irq, cosa->dma, cosa->nchannels);
591 597
592 return nr_cards++; 598 return nr_cards++;
599
600err_hdlcdev:
601 while (i-- > 0) {
602 unregister_hdlc_device(cosa->chan[i].netdev);
603 free_netdev(cosa->chan[i].netdev);
604 }
605 kfree(cosa->chan);
593err_out3: 606err_out3:
594 kfree(cosa->bouncebuf); 607 kfree(cosa->bouncebuf);
595err_out2: 608err_out2:
596 free_dma(cosa->dma); 609 free_dma(cosa->dma);
597err_out1: 610err_out1:
598 free_irq(cosa->irq, cosa); 611 free_irq(cosa->irq, cosa);
599err_out: 612err_out:
600 release_region(cosa->datareg,is_8bit(cosa)?2:4); 613 release_region(cosa->datareg,is_8bit(cosa)?2:4);
601 printk(KERN_NOTICE "cosa%d: allocating resources failed\n", 614 printk(KERN_NOTICE "cosa%d: allocating resources failed\n",
602 cosa->num); 615 cosa->num);
@@ -604,54 +617,19 @@ err_out:
604} 617}
605 618
606 619
607/*---------- SPPP/HDLC netdevice ---------- */ 620/*---------- network device ---------- */
608 621
609static void cosa_setup(struct net_device *d) 622static int cosa_net_attach(struct net_device *dev, unsigned short encoding,
623 unsigned short parity)
610{ 624{
611 d->open = cosa_sppp_open; 625 if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
612 d->stop = cosa_sppp_close; 626 return 0;
613 d->hard_start_xmit = cosa_sppp_tx; 627 return -EINVAL;
614 d->do_ioctl = cosa_sppp_ioctl;
615 d->get_stats = cosa_net_stats;
616 d->tx_timeout = cosa_sppp_timeout;
617 d->watchdog_timeo = TX_TIMEOUT;
618}
619
620static void sppp_channel_init(struct channel_data *chan)
621{
622 struct net_device *d;
623 chan->if_ptr = &chan->pppdev;
624 d = alloc_netdev(0, chan->name, cosa_setup);
625 if (!d) {
626 printk(KERN_WARNING "%s: alloc_netdev failed.\n", chan->name);
627 return;
628 }
629 chan->pppdev.dev = d;
630 d->base_addr = chan->cosa->datareg;
631 d->irq = chan->cosa->irq;
632 d->dma = chan->cosa->dma;
633 d->ml_priv = chan;
634 sppp_attach(&chan->pppdev);
635 if (register_netdev(d)) {
636 printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
637 sppp_detach(d);
638 free_netdev(d);
639 chan->pppdev.dev = NULL;
640 return;
641 }
642}
643
644static void sppp_channel_delete(struct channel_data *chan)
645{
646 unregister_netdev(chan->pppdev.dev);
647 sppp_detach(chan->pppdev.dev);
648 free_netdev(chan->pppdev.dev);
649 chan->pppdev.dev = NULL;
650} 628}
651 629
652static int cosa_sppp_open(struct net_device *d) 630static int cosa_net_open(struct net_device *dev)
653{ 631{
654 struct channel_data *chan = d->ml_priv; 632 struct channel_data *chan = dev_to_chan(dev);
655 int err; 633 int err;
656 unsigned long flags; 634 unsigned long flags;
657 635
@@ -662,36 +640,35 @@ static int cosa_sppp_open(struct net_device *d)
662 } 640 }
663 spin_lock_irqsave(&chan->cosa->lock, flags); 641 spin_lock_irqsave(&chan->cosa->lock, flags);
664 if (chan->usage != 0) { 642 if (chan->usage != 0) {
665 printk(KERN_WARNING "%s: sppp_open called with usage count %d\n", 643 printk(KERN_WARNING "%s: cosa_net_open called with usage count"
666 chan->name, chan->usage); 644 " %d\n", chan->name, chan->usage);
667 spin_unlock_irqrestore(&chan->cosa->lock, flags); 645 spin_unlock_irqrestore(&chan->cosa->lock, flags);
668 return -EBUSY; 646 return -EBUSY;
669 } 647 }
670 chan->setup_rx = sppp_setup_rx; 648 chan->setup_rx = cosa_net_setup_rx;
671 chan->tx_done = sppp_tx_done; 649 chan->tx_done = cosa_net_tx_done;
672 chan->rx_done = sppp_rx_done; 650 chan->rx_done = cosa_net_rx_done;
673 chan->usage=-1; 651 chan->usage = -1;
674 chan->cosa->usage++; 652 chan->cosa->usage++;
675 spin_unlock_irqrestore(&chan->cosa->lock, flags); 653 spin_unlock_irqrestore(&chan->cosa->lock, flags);
676 654
677 err = sppp_open(d); 655 err = hdlc_open(dev);
678 if (err) { 656 if (err) {
679 spin_lock_irqsave(&chan->cosa->lock, flags); 657 spin_lock_irqsave(&chan->cosa->lock, flags);
680 chan->usage=0; 658 chan->usage = 0;
681 chan->cosa->usage--; 659 chan->cosa->usage--;
682
683 spin_unlock_irqrestore(&chan->cosa->lock, flags); 660 spin_unlock_irqrestore(&chan->cosa->lock, flags);
684 return err; 661 return err;
685 } 662 }
686 663
687 netif_start_queue(d); 664 netif_start_queue(dev);
688 cosa_enable_rx(chan); 665 cosa_enable_rx(chan);
689 return 0; 666 return 0;
690} 667}
691 668
692static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) 669static int cosa_net_tx(struct sk_buff *skb, struct net_device *dev)
693{ 670{
694 struct channel_data *chan = dev->ml_priv; 671 struct channel_data *chan = dev_to_chan(dev);
695 672
696 netif_stop_queue(dev); 673 netif_stop_queue(dev);
697 674
@@ -700,16 +677,16 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
700 return 0; 677 return 0;
701} 678}
702 679
703static void cosa_sppp_timeout(struct net_device *dev) 680static void cosa_net_timeout(struct net_device *dev)
704{ 681{
705 struct channel_data *chan = dev->ml_priv; 682 struct channel_data *chan = dev_to_chan(dev);
706 683
707 if (test_bit(RXBIT, &chan->cosa->rxtx)) { 684 if (test_bit(RXBIT, &chan->cosa->rxtx)) {
708 chan->stats.rx_errors++; 685 chan->netdev->stats.rx_errors++;
709 chan->stats.rx_missed_errors++; 686 chan->netdev->stats.rx_missed_errors++;
710 } else { 687 } else {
711 chan->stats.tx_errors++; 688 chan->netdev->stats.tx_errors++;
712 chan->stats.tx_aborted_errors++; 689 chan->netdev->stats.tx_aborted_errors++;
713 } 690 }
714 cosa_kick(chan->cosa); 691 cosa_kick(chan->cosa);
715 if (chan->tx_skb) { 692 if (chan->tx_skb) {
@@ -719,13 +696,13 @@ static void cosa_sppp_timeout(struct net_device *dev)
719 netif_wake_queue(dev); 696 netif_wake_queue(dev);
720} 697}
721 698
722static int cosa_sppp_close(struct net_device *d) 699static int cosa_net_close(struct net_device *dev)
723{ 700{
724 struct channel_data *chan = d->ml_priv; 701 struct channel_data *chan = dev_to_chan(dev);
725 unsigned long flags; 702 unsigned long flags;
726 703
727 netif_stop_queue(d); 704 netif_stop_queue(dev);
728 sppp_close(d); 705 hdlc_close(dev);
729 cosa_disable_rx(chan); 706 cosa_disable_rx(chan);
730 spin_lock_irqsave(&chan->cosa->lock, flags); 707 spin_lock_irqsave(&chan->cosa->lock, flags);
731 if (chan->rx_skb) { 708 if (chan->rx_skb) {
@@ -736,13 +713,13 @@ static int cosa_sppp_close(struct net_device *d)
736 kfree_skb(chan->tx_skb); 713 kfree_skb(chan->tx_skb);
737 chan->tx_skb = NULL; 714 chan->tx_skb = NULL;
738 } 715 }
739 chan->usage=0; 716 chan->usage = 0;
740 chan->cosa->usage--; 717 chan->cosa->usage--;
741 spin_unlock_irqrestore(&chan->cosa->lock, flags); 718 spin_unlock_irqrestore(&chan->cosa->lock, flags);
742 return 0; 719 return 0;
743} 720}
744 721
745static char *sppp_setup_rx(struct channel_data *chan, int size) 722static char *cosa_net_setup_rx(struct channel_data *chan, int size)
746{ 723{
747 /* 724 /*
748 * We can safely fall back to non-dma-able memory, because we have 725 * We can safely fall back to non-dma-able memory, because we have
@@ -754,66 +731,53 @@ static char *sppp_setup_rx(struct channel_data *chan, int size)
754 if (chan->rx_skb == NULL) { 731 if (chan->rx_skb == NULL) {
755 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet\n", 732 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet\n",
756 chan->name); 733 chan->name);
757 chan->stats.rx_dropped++; 734 chan->netdev->stats.rx_dropped++;
758 return NULL; 735 return NULL;
759 } 736 }
760 chan->pppdev.dev->trans_start = jiffies; 737 chan->netdev->trans_start = jiffies;
761 return skb_put(chan->rx_skb, size); 738 return skb_put(chan->rx_skb, size);
762} 739}
763 740
764static int sppp_rx_done(struct channel_data *chan) 741static int cosa_net_rx_done(struct channel_data *chan)
765{ 742{
766 if (!chan->rx_skb) { 743 if (!chan->rx_skb) {
767 printk(KERN_WARNING "%s: rx_done with empty skb!\n", 744 printk(KERN_WARNING "%s: rx_done with empty skb!\n",
768 chan->name); 745 chan->name);
769 chan->stats.rx_errors++; 746 chan->netdev->stats.rx_errors++;
770 chan->stats.rx_frame_errors++; 747 chan->netdev->stats.rx_frame_errors++;
771 return 0; 748 return 0;
772 } 749 }
773 chan->rx_skb->protocol = htons(ETH_P_WAN_PPP); 750 chan->rx_skb->protocol = hdlc_type_trans(chan->rx_skb, chan->netdev);
774 chan->rx_skb->dev = chan->pppdev.dev; 751 chan->rx_skb->dev = chan->netdev;
775 skb_reset_mac_header(chan->rx_skb); 752 skb_reset_mac_header(chan->rx_skb);
776 chan->stats.rx_packets++; 753 chan->netdev->stats.rx_packets++;
777 chan->stats.rx_bytes += chan->cosa->rxsize; 754 chan->netdev->stats.rx_bytes += chan->cosa->rxsize;
778 netif_rx(chan->rx_skb); 755 netif_rx(chan->rx_skb);
779 chan->rx_skb = NULL; 756 chan->rx_skb = NULL;
780 chan->pppdev.dev->last_rx = jiffies; 757 chan->netdev->last_rx = jiffies;
781 return 0; 758 return 0;
782} 759}
783 760
784/* ARGSUSED */ 761/* ARGSUSED */
785static int sppp_tx_done(struct channel_data *chan, int size) 762static int cosa_net_tx_done(struct channel_data *chan, int size)
786{ 763{
787 if (!chan->tx_skb) { 764 if (!chan->tx_skb) {
788 printk(KERN_WARNING "%s: tx_done with empty skb!\n", 765 printk(KERN_WARNING "%s: tx_done with empty skb!\n",
789 chan->name); 766 chan->name);
790 chan->stats.tx_errors++; 767 chan->netdev->stats.tx_errors++;
791 chan->stats.tx_aborted_errors++; 768 chan->netdev->stats.tx_aborted_errors++;
792 return 1; 769 return 1;
793 } 770 }
794 dev_kfree_skb_irq(chan->tx_skb); 771 dev_kfree_skb_irq(chan->tx_skb);
795 chan->tx_skb = NULL; 772 chan->tx_skb = NULL;
796 chan->stats.tx_packets++; 773 chan->netdev->stats.tx_packets++;
797 chan->stats.tx_bytes += size; 774 chan->netdev->stats.tx_bytes += size;
798 netif_wake_queue(chan->pppdev.dev); 775 netif_wake_queue(chan->netdev);
799 return 1; 776 return 1;
800} 777}
801 778
802static struct net_device_stats *cosa_net_stats(struct net_device *dev)
803{
804 struct channel_data *chan = dev->ml_priv;
805 return &chan->stats;
806}
807
808
809/*---------- Character device ---------- */ 779/*---------- Character device ---------- */
810 780
811static void chardev_channel_init(struct channel_data *chan)
812{
813 mutex_init(&chan->rlock);
814 init_MUTEX(&chan->wsem);
815}
816
817static ssize_t cosa_read(struct file *file, 781static ssize_t cosa_read(struct file *file,
818 char __user *buf, size_t count, loff_t *ppos) 782 char __user *buf, size_t count, loff_t *ppos)
819{ 783{
@@ -1223,16 +1187,15 @@ static int cosa_ioctl_common(struct cosa_data *cosa,
1223 return -ENOIOCTLCMD; 1187 return -ENOIOCTLCMD;
1224} 1188}
1225 1189
1226static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, 1190static int cosa_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1227 int cmd)
1228{ 1191{
1229 int rv; 1192 int rv;
1230 struct channel_data *chan = dev->ml_priv; 1193 struct channel_data *chan = dev_to_chan(dev);
1231 rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data); 1194 rv = cosa_ioctl_common(chan->cosa, chan, cmd,
1232 if (rv == -ENOIOCTLCMD) { 1195 (unsigned long)ifr->ifr_data);
1233 return sppp_do_ioctl(dev, ifr, cmd); 1196 if (rv != -ENOIOCTLCMD)
1234 } 1197 return rv;
1235 return rv; 1198 return hdlc_ioctl(dev, ifr, cmd);
1236} 1199}
1237 1200
1238static int cosa_chardev_ioctl(struct inode *inode, struct file *file, 1201static int cosa_chardev_ioctl(struct inode *inode, struct file *file,
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 50ef5b4efd6d..f5d55ad02267 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -103,7 +103,6 @@
103#include <linux/netdevice.h> 103#include <linux/netdevice.h>
104#include <linux/skbuff.h> 104#include <linux/skbuff.h>
105#include <linux/delay.h> 105#include <linux/delay.h>
106#include <net/syncppp.h>
107#include <linux/hdlc.h> 106#include <linux/hdlc.h>
108#include <linux/mutex.h> 107#include <linux/mutex.h>
109 108
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 754f00809e3e..9557ad078ab8 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -47,10 +47,7 @@ MODULE_LICENSE("GPL");
47/* Default parameters for the link 47/* Default parameters for the link
48 */ 48 */
49#define FST_TX_QUEUE_LEN 100 /* At 8Mbps a longer queue length is 49#define FST_TX_QUEUE_LEN 100 /* At 8Mbps a longer queue length is
50 * useful, the syncppp module forces 50 * useful */
51 * this down assuming a slower line I
52 * guess.
53 */
54#define FST_TXQ_DEPTH 16 /* This one is for the buffering 51#define FST_TXQ_DEPTH 16 /* This one is for the buffering
55 * of frames on the way down to the card 52 * of frames on the way down to the card
56 * so that we can keep the card busy 53 * so that we can keep the card busy
diff --git a/drivers/net/wan/farsync.h b/drivers/net/wan/farsync.h
index d871dafa87a1..6b27e7c3d449 100644
--- a/drivers/net/wan/farsync.h
+++ b/drivers/net/wan/farsync.h
@@ -54,9 +54,6 @@
54 54
55 55
56/* Ioctl call command values 56/* Ioctl call command values
57 *
58 * The first three private ioctls are used by the sync-PPP module,
59 * allowing a little room for expansion we start our numbering at 10.
60 */ 57 */
61#define FSTWRITE (SIOCDEVPRIVATE+10) 58#define FSTWRITE (SIOCDEVPRIVATE+10)
62#define FSTCPURESET (SIOCDEVPRIVATE+11) 59#define FSTCPURESET (SIOCDEVPRIVATE+11)
@@ -202,9 +199,6 @@ struct fstioc_info {
202#define J1 7 199#define J1 7
203 200
204/* "proto" */ 201/* "proto" */
205#define FST_HDLC 1 /* Cisco compatible HDLC */
206#define FST_PPP 2 /* Sync PPP */
207#define FST_MONITOR 3 /* Monitor only (raw packet reception) */
208#define FST_RAW 4 /* Two way raw packets */ 202#define FST_RAW 4 /* Two way raw packets */
209#define FST_GEN_HDLC 5 /* Using "Generic HDLC" module */ 203#define FST_GEN_HDLC 5 /* Using "Generic HDLC" module */
210 204
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index e3a536477c7e..1f2a140c9f7c 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -22,20 +22,19 @@
22 * - proto->start() and stop() are called with spin_lock_irq held. 22 * - proto->start() and stop() are called with spin_lock_irq held.
23 */ 23 */
24 24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/poll.h>
29#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/hdlc.h>
30#include <linux/if_arp.h> 27#include <linux/if_arp.h>
28#include <linux/inetdevice.h>
31#include <linux/init.h> 29#include <linux/init.h>
32#include <linux/skbuff.h> 30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/notifier.h>
33#include <linux/pkt_sched.h> 33#include <linux/pkt_sched.h>
34#include <linux/inetdevice.h> 34#include <linux/poll.h>
35#include <linux/lapb.h>
36#include <linux/rtnetlink.h> 35#include <linux/rtnetlink.h>
37#include <linux/notifier.h> 36#include <linux/skbuff.h>
38#include <linux/hdlc.h> 37#include <linux/slab.h>
39#include <net/net_namespace.h> 38#include <net/net_namespace.h>
40 39
41 40
@@ -109,7 +108,7 @@ static int hdlc_device_event(struct notifier_block *this, unsigned long event,
109 108
110 if (dev->get_stats != hdlc_get_stats) 109 if (dev->get_stats != hdlc_get_stats)
111 return NOTIFY_DONE; /* not an HDLC device */ 110 return NOTIFY_DONE; /* not an HDLC device */
112 111
113 if (event != NETDEV_CHANGE) 112 if (event != NETDEV_CHANGE)
114 return NOTIFY_DONE; /* Only interrested in carrier changes */ 113 return NOTIFY_DONE; /* Only interrested in carrier changes */
115 114
@@ -357,7 +356,7 @@ static struct packet_type hdlc_packet_type = {
357 356
358 357
359static struct notifier_block hdlc_notifier = { 358static struct notifier_block hdlc_notifier = {
360 .notifier_call = hdlc_device_event, 359 .notifier_call = hdlc_device_event,
361}; 360};
362 361
363 362
@@ -367,8 +366,8 @@ static int __init hdlc_module_init(void)
367 366
368 printk(KERN_INFO "%s\n", version); 367 printk(KERN_INFO "%s\n", version);
369 if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0) 368 if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0)
370 return result; 369 return result;
371 dev_add_pack(&hdlc_packet_type); 370 dev_add_pack(&hdlc_packet_type);
372 return 0; 371 return 0;
373} 372}
374 373
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 849819c2552d..44e64b15dbd1 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -9,19 +9,18 @@
9 * as published by the Free Software Foundation. 9 * as published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/poll.h>
16#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/hdlc.h>
17#include <linux/if_arp.h> 14#include <linux/if_arp.h>
15#include <linux/inetdevice.h>
18#include <linux/init.h> 16#include <linux/init.h>
19#include <linux/skbuff.h> 17#include <linux/kernel.h>
18#include <linux/module.h>
20#include <linux/pkt_sched.h> 19#include <linux/pkt_sched.h>
21#include <linux/inetdevice.h> 20#include <linux/poll.h>
22#include <linux/lapb.h>
23#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
24#include <linux/hdlc.h> 22#include <linux/skbuff.h>
23#include <linux/slab.h>
25 24
26#undef DEBUG_HARD_HEADER 25#undef DEBUG_HARD_HEADER
27 26
@@ -68,9 +67,9 @@ struct cisco_state {
68static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr); 67static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr);
69 68
70 69
71static inline struct cisco_state * state(hdlc_device *hdlc) 70static inline struct cisco_state* state(hdlc_device *hdlc)
72{ 71{
73 return(struct cisco_state *)(hdlc->state); 72 return (struct cisco_state *)hdlc->state;
74} 73}
75 74
76 75
@@ -172,7 +171,7 @@ static int cisco_rx(struct sk_buff *skb)
172 data->address != CISCO_UNICAST) 171 data->address != CISCO_UNICAST)
173 goto rx_error; 172 goto rx_error;
174 173
175 switch(ntohs(data->protocol)) { 174 switch (ntohs(data->protocol)) {
176 case CISCO_SYS_INFO: 175 case CISCO_SYS_INFO:
177 /* Packet is not needed, drop it. */ 176 /* Packet is not needed, drop it. */
178 dev_kfree_skb_any(skb); 177 dev_kfree_skb_any(skb);
@@ -336,7 +335,7 @@ static struct hdlc_proto proto = {
336static const struct header_ops cisco_header_ops = { 335static const struct header_ops cisco_header_ops = {
337 .create = cisco_hard_header, 336 .create = cisco_hard_header,
338}; 337};
339 338
340static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 339static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
341{ 340{
342 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; 341 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco;
@@ -359,10 +358,10 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
359 return 0; 358 return 0;
360 359
361 case IF_PROTO_CISCO: 360 case IF_PROTO_CISCO:
362 if(!capable(CAP_NET_ADMIN)) 361 if (!capable(CAP_NET_ADMIN))
363 return -EPERM; 362 return -EPERM;
364 363
365 if(dev->flags & IFF_UP) 364 if (dev->flags & IFF_UP)
366 return -EBUSY; 365 return -EBUSY;
367 366
368 if (copy_from_user(&new_settings, cisco_s, size)) 367 if (copy_from_user(&new_settings, cisco_s, size))
@@ -372,7 +371,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
372 new_settings.timeout < 2) 371 new_settings.timeout < 2)
373 return -EINVAL; 372 return -EINVAL;
374 373
375 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); 374 result = hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
376 if (result) 375 if (result)
377 return result; 376 return result;
378 377
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 62e93dac6b13..d3d5055741ad 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -33,20 +33,19 @@
33 33
34*/ 34*/
35 35
36#include <linux/module.h>
37#include <linux/kernel.h>
38#include <linux/slab.h>
39#include <linux/poll.h>
40#include <linux/errno.h> 36#include <linux/errno.h>
37#include <linux/etherdevice.h>
38#include <linux/hdlc.h>
41#include <linux/if_arp.h> 39#include <linux/if_arp.h>
40#include <linux/inetdevice.h>
42#include <linux/init.h> 41#include <linux/init.h>
43#include <linux/skbuff.h> 42#include <linux/kernel.h>
43#include <linux/module.h>
44#include <linux/pkt_sched.h> 44#include <linux/pkt_sched.h>
45#include <linux/inetdevice.h> 45#include <linux/poll.h>
46#include <linux/lapb.h>
47#include <linux/rtnetlink.h> 46#include <linux/rtnetlink.h>
48#include <linux/etherdevice.h> 47#include <linux/skbuff.h>
49#include <linux/hdlc.h> 48#include <linux/slab.h>
50 49
51#undef DEBUG_PKT 50#undef DEBUG_PKT
52#undef DEBUG_ECN 51#undef DEBUG_ECN
@@ -96,7 +95,7 @@ typedef struct {
96 unsigned ea1: 1; 95 unsigned ea1: 1;
97 unsigned cr: 1; 96 unsigned cr: 1;
98 unsigned dlcih: 6; 97 unsigned dlcih: 6;
99 98
100 unsigned ea2: 1; 99 unsigned ea2: 1;
101 unsigned de: 1; 100 unsigned de: 1;
102 unsigned becn: 1; 101 unsigned becn: 1;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 00308337928e..4efe9e6d32d5 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -9,19 +9,18 @@
9 * as published by the Free Software Foundation. 9 * as published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/poll.h>
16#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/hdlc.h>
17#include <linux/if_arp.h> 14#include <linux/if_arp.h>
15#include <linux/inetdevice.h>
18#include <linux/init.h> 16#include <linux/init.h>
19#include <linux/skbuff.h> 17#include <linux/kernel.h>
18#include <linux/module.h>
20#include <linux/pkt_sched.h> 19#include <linux/pkt_sched.h>
21#include <linux/inetdevice.h> 20#include <linux/poll.h>
22#include <linux/lapb.h>
23#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
24#include <linux/hdlc.h> 22#include <linux/skbuff.h>
23#include <linux/slab.h>
25#include <net/syncppp.h> 24#include <net/syncppp.h>
26 25
27struct ppp_state { 26struct ppp_state {
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index bbbb819d764c..8612311748f4 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -9,19 +9,18 @@
9 * as published by the Free Software Foundation. 9 * as published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/poll.h>
16#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/hdlc.h>
17#include <linux/if_arp.h> 14#include <linux/if_arp.h>
15#include <linux/inetdevice.h>
18#include <linux/init.h> 16#include <linux/init.h>
19#include <linux/skbuff.h> 17#include <linux/kernel.h>
18#include <linux/module.h>
20#include <linux/pkt_sched.h> 19#include <linux/pkt_sched.h>
21#include <linux/inetdevice.h> 20#include <linux/poll.h>
22#include <linux/lapb.h>
23#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
24#include <linux/hdlc.h> 22#include <linux/skbuff.h>
23#include <linux/slab.h>
25 24
26 25
27static int raw_ioctl(struct net_device *dev, struct ifreq *ifr); 26static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 26dee600506f..a13fc3207520 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -9,20 +9,19 @@
9 * as published by the Free Software Foundation. 9 * as published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/poll.h>
16#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/etherdevice.h>
14#include <linux/hdlc.h>
17#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/inetdevice.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/skbuff.h> 18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/pkt_sched.h> 20#include <linux/pkt_sched.h>
21#include <linux/inetdevice.h> 21#include <linux/poll.h>
22#include <linux/lapb.h>
23#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
24#include <linux/etherdevice.h> 23#include <linux/skbuff.h>
25#include <linux/hdlc.h> 24#include <linux/slab.h>
26 25
27static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr); 26static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
28 27
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index e808720030ef..8b7e5d2e2ac9 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -9,20 +9,19 @@
9 * as published by the Free Software Foundation. 9 * as published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/slab.h>
15#include <linux/poll.h>
16#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/hdlc.h>
17#include <linux/if_arp.h> 14#include <linux/if_arp.h>
18#include <linux/init.h>
19#include <linux/skbuff.h>
20#include <linux/pkt_sched.h>
21#include <linux/inetdevice.h> 15#include <linux/inetdevice.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
22#include <linux/lapb.h> 18#include <linux/lapb.h>
19#include <linux/module.h>
20#include <linux/pkt_sched.h>
21#include <linux/poll.h>
23#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
24#include <linux/hdlc.h> 23#include <linux/skbuff.h>
25 24#include <linux/slab.h>
26#include <net/x25device.h> 25#include <net/x25device.h>
27 26
28static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); 27static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index f3065d3473fd..e299313f828a 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -16,6 +16,8 @@
16 * touching control registers. 16 * touching control registers.
17 * 17 *
18 * Port B isnt wired (why - beats me) 18 * Port B isnt wired (why - beats me)
19 *
20 * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
19 */ 21 */
20 22
21#include <linux/module.h> 23#include <linux/module.h>
@@ -26,6 +28,7 @@
26#include <linux/netdevice.h> 28#include <linux/netdevice.h>
27#include <linux/if_arp.h> 29#include <linux/if_arp.h>
28#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/hdlc.h>
29#include <linux/ioport.h> 32#include <linux/ioport.h>
30#include <net/arp.h> 33#include <net/arp.h>
31 34
@@ -33,34 +36,31 @@
33#include <asm/io.h> 36#include <asm/io.h>
34#include <asm/dma.h> 37#include <asm/dma.h>
35#include <asm/byteorder.h> 38#include <asm/byteorder.h>
36#include <net/syncppp.h>
37#include "z85230.h" 39#include "z85230.h"
38 40
39static int dma; 41static int dma;
40 42
41struct sv11_device
42{
43 void *if_ptr; /* General purpose pointer (used by SPPP) */
44 struct z8530_dev sync;
45 struct ppp_device netdev;
46};
47
48/* 43/*
49 * Network driver support routines 44 * Network driver support routines
50 */ 45 */
51 46
47static inline struct z8530_dev* dev_to_sv(struct net_device *dev)
48{
49 return (struct z8530_dev *)dev_to_hdlc(dev)->priv;
50}
51
52/* 52/*
53 * Frame receive. Simple for our card as we do sync ppp and there 53 * Frame receive. Simple for our card as we do HDLC and there
54 * is no funny garbage involved 54 * is no funny garbage involved
55 */ 55 */
56 56
57static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) 57static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
58{ 58{
59 /* Drop the CRC - it's not a good idea to try and negotiate it ;) */ 59 /* Drop the CRC - it's not a good idea to try and negotiate it ;) */
60 skb_trim(skb, skb->len-2); 60 skb_trim(skb, skb->len - 2);
61 skb->protocol=__constant_htons(ETH_P_WAN_PPP); 61 skb->protocol = hdlc_type_trans(skb, c->netdevice);
62 skb_reset_mac_header(skb); 62 skb_reset_mac_header(skb);
63 skb->dev=c->netdevice; 63 skb->dev = c->netdevice;
64 /* 64 /*
65 * Send it to the PPP layer. We don't have time to process 65 * Send it to the PPP layer. We don't have time to process
66 * it right now. 66 * it right now.
@@ -68,56 +68,51 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
68 netif_rx(skb); 68 netif_rx(skb);
69 c->netdevice->last_rx = jiffies; 69 c->netdevice->last_rx = jiffies;
70} 70}
71 71
72/* 72/*
73 * We've been placed in the UP state 73 * We've been placed in the UP state
74 */ 74 */
75 75
76static int hostess_open(struct net_device *d) 76static int hostess_open(struct net_device *d)
77{ 77{
78 struct sv11_device *sv11=d->ml_priv; 78 struct z8530_dev *sv11 = dev_to_sv(d);
79 int err = -1; 79 int err = -1;
80 80
81 /* 81 /*
82 * Link layer up 82 * Link layer up
83 */ 83 */
84 switch(dma) 84 switch (dma) {
85 {
86 case 0: 85 case 0:
87 err=z8530_sync_open(d, &sv11->sync.chanA); 86 err = z8530_sync_open(d, &sv11->chanA);
88 break; 87 break;
89 case 1: 88 case 1:
90 err=z8530_sync_dma_open(d, &sv11->sync.chanA); 89 err = z8530_sync_dma_open(d, &sv11->chanA);
91 break; 90 break;
92 case 2: 91 case 2:
93 err=z8530_sync_txdma_open(d, &sv11->sync.chanA); 92 err = z8530_sync_txdma_open(d, &sv11->chanA);
94 break; 93 break;
95 } 94 }
96 95
97 if(err) 96 if (err)
98 return err; 97 return err;
99 /* 98
100 * Begin PPP 99 err = hdlc_open(d);
101 */ 100 if (err) {
102 err=sppp_open(d); 101 switch (dma) {
103 if(err)
104 {
105 switch(dma)
106 {
107 case 0: 102 case 0:
108 z8530_sync_close(d, &sv11->sync.chanA); 103 z8530_sync_close(d, &sv11->chanA);
109 break; 104 break;
110 case 1: 105 case 1:
111 z8530_sync_dma_close(d, &sv11->sync.chanA); 106 z8530_sync_dma_close(d, &sv11->chanA);
112 break; 107 break;
113 case 2: 108 case 2:
114 z8530_sync_txdma_close(d, &sv11->sync.chanA); 109 z8530_sync_txdma_close(d, &sv11->chanA);
115 break; 110 break;
116 } 111 }
117 return err; 112 return err;
118 } 113 }
119 sv11->sync.chanA.rx_function=hostess_input; 114 sv11->chanA.rx_function = hostess_input;
120 115
121 /* 116 /*
122 * Go go go 117 * Go go go
123 */ 118 */
@@ -128,30 +123,24 @@ static int hostess_open(struct net_device *d)
128 123
129static int hostess_close(struct net_device *d) 124static int hostess_close(struct net_device *d)
130{ 125{
131 struct sv11_device *sv11=d->ml_priv; 126 struct z8530_dev *sv11 = dev_to_sv(d);
132 /* 127 /*
133 * Discard new frames 128 * Discard new frames
134 */ 129 */
135 sv11->sync.chanA.rx_function=z8530_null_rx; 130 sv11->chanA.rx_function = z8530_null_rx;
136 /* 131
137 * PPP off 132 hdlc_close(d);
138 */
139 sppp_close(d);
140 /*
141 * Link layer down
142 */
143 netif_stop_queue(d); 133 netif_stop_queue(d);
144 134
145 switch(dma) 135 switch (dma) {
146 {
147 case 0: 136 case 0:
148 z8530_sync_close(d, &sv11->sync.chanA); 137 z8530_sync_close(d, &sv11->chanA);
149 break; 138 break;
150 case 1: 139 case 1:
151 z8530_sync_dma_close(d, &sv11->sync.chanA); 140 z8530_sync_dma_close(d, &sv11->chanA);
152 break; 141 break;
153 case 2: 142 case 2:
154 z8530_sync_txdma_close(d, &sv11->sync.chanA); 143 z8530_sync_txdma_close(d, &sv11->chanA);
155 break; 144 break;
156 } 145 }
157 return 0; 146 return 0;
@@ -159,232 +148,174 @@ static int hostess_close(struct net_device *d)
159 148
160static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) 149static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
161{ 150{
162 /* struct sv11_device *sv11=d->ml_priv; 151 /* struct z8530_dev *sv11=dev_to_sv(d);
163 z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ 152 z8530_ioctl(d,&sv11->chanA,ifr,cmd) */
164 return sppp_do_ioctl(d, ifr,cmd); 153 return hdlc_ioctl(d, ifr, cmd);
165}
166
167static struct net_device_stats *hostess_get_stats(struct net_device *d)
168{
169 struct sv11_device *sv11=d->ml_priv;
170 if(sv11)
171 return z8530_get_stats(&sv11->sync.chanA);
172 else
173 return NULL;
174} 154}
175 155
176/* 156/*
177 * Passed PPP frames, fire them downwind. 157 * Passed network frames, fire them downwind.
178 */ 158 */
179 159
180static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) 160static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d)
181{ 161{
182 struct sv11_device *sv11=d->ml_priv; 162 return z8530_queue_xmit(&dev_to_sv(d)->chanA, skb);
183 return z8530_queue_xmit(&sv11->sync.chanA, skb);
184} 163}
185 164
186static int hostess_neigh_setup(struct neighbour *n) 165static int hostess_attach(struct net_device *dev, unsigned short encoding,
166 unsigned short parity)
187{ 167{
188 if (n->nud_state == NUD_NONE) { 168 if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
189 n->ops = &arp_broken_ops; 169 return 0;
190 n->output = n->ops->output; 170 return -EINVAL;
191 }
192 return 0;
193}
194
195static int hostess_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
196{
197 if (p->tbl->family == AF_INET) {
198 p->neigh_setup = hostess_neigh_setup;
199 p->ucast_probes = 0;
200 p->mcast_probes = 0;
201 }
202 return 0;
203}
204
205static void sv11_setup(struct net_device *dev)
206{
207 dev->open = hostess_open;
208 dev->stop = hostess_close;
209 dev->hard_start_xmit = hostess_queue_xmit;
210 dev->get_stats = hostess_get_stats;
211 dev->do_ioctl = hostess_ioctl;
212 dev->neigh_setup = hostess_neigh_setup_dev;
213} 171}
214 172
215/* 173/*
216 * Description block for a Comtrol Hostess SV11 card 174 * Description block for a Comtrol Hostess SV11 card
217 */ 175 */
218 176
219static struct sv11_device *sv11_init(int iobase, int irq) 177static struct z8530_dev *sv11_init(int iobase, int irq)
220{ 178{
221 struct z8530_dev *dev; 179 struct z8530_dev *sv;
222 struct sv11_device *sv; 180 struct net_device *netdev;
223
224 /* 181 /*
225 * Get the needed I/O space 182 * Get the needed I/O space
226 */ 183 */
227 184
228 if(!request_region(iobase, 8, "Comtrol SV11")) 185 if (!request_region(iobase, 8, "Comtrol SV11")) {
229 { 186 printk(KERN_WARNING "hostess: I/O 0x%X already in use.\n",
230 printk(KERN_WARNING "hostess: I/O 0x%X already in use.\n", iobase); 187 iobase);
231 return NULL; 188 return NULL;
232 } 189 }
233 190
234 sv = kzalloc(sizeof(struct sv11_device), GFP_KERNEL); 191 sv = kzalloc(sizeof(struct z8530_dev), GFP_KERNEL);
235 if(!sv) 192 if (!sv)
236 goto fail3; 193 goto err_kzalloc;
237 194
238 sv->if_ptr=&sv->netdev;
239
240 sv->netdev.dev = alloc_netdev(0, "hdlc%d", sv11_setup);
241 if(!sv->netdev.dev)
242 goto fail2;
243
244 dev=&sv->sync;
245
246 /* 195 /*
247 * Stuff in the I/O addressing 196 * Stuff in the I/O addressing
248 */ 197 */
249 198
250 dev->active = 0; 199 sv->active = 0;
251 200
252 dev->chanA.ctrlio=iobase+1; 201 sv->chanA.ctrlio = iobase + 1;
253 dev->chanA.dataio=iobase+3; 202 sv->chanA.dataio = iobase + 3;
254 dev->chanB.ctrlio=-1; 203 sv->chanB.ctrlio = -1;
255 dev->chanB.dataio=-1; 204 sv->chanB.dataio = -1;
256 dev->chanA.irqs=&z8530_nop; 205 sv->chanA.irqs = &z8530_nop;
257 dev->chanB.irqs=&z8530_nop; 206 sv->chanB.irqs = &z8530_nop;
258 207
259 outb(0, iobase+4); /* DMA off */ 208 outb(0, iobase + 4); /* DMA off */
260 209
261 /* We want a fast IRQ for this device. Actually we'd like an even faster 210 /* We want a fast IRQ for this device. Actually we'd like an even faster
262 IRQ ;) - This is one driver RtLinux is made for */ 211 IRQ ;) - This is one driver RtLinux is made for */
263 212
264 if(request_irq(irq, &z8530_interrupt, IRQF_DISABLED, "Hostess SV11", dev)<0) 213 if (request_irq(irq, &z8530_interrupt, IRQF_DISABLED,
265 { 214 "Hostess SV11", sv) < 0) {
266 printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq); 215 printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq);
267 goto fail1; 216 goto err_irq;
268 } 217 }
269 218
270 dev->irq=irq; 219 sv->irq = irq;
271 dev->chanA.private=sv; 220 sv->chanA.private = sv;
272 dev->chanA.netdevice=sv->netdev.dev; 221 sv->chanA.dev = sv;
273 dev->chanA.dev=dev; 222 sv->chanB.dev = sv;
274 dev->chanB.dev=dev; 223
275 224 if (dma) {
276 if(dma)
277 {
278 /* 225 /*
279 * You can have DMA off or 1 and 3 thats the lot 226 * You can have DMA off or 1 and 3 thats the lot
280 * on the Comtrol. 227 * on the Comtrol.
281 */ 228 */
282 dev->chanA.txdma=3; 229 sv->chanA.txdma = 3;
283 dev->chanA.rxdma=1; 230 sv->chanA.rxdma = 1;
284 outb(0x03|0x08, iobase+4); /* DMA on */ 231 outb(0x03 | 0x08, iobase + 4); /* DMA on */
285 if(request_dma(dev->chanA.txdma, "Hostess SV/11 (TX)")!=0) 232 if (request_dma(sv->chanA.txdma, "Hostess SV/11 (TX)"))
286 goto fail; 233 goto err_txdma;
287 234
288 if(dma==1) 235 if (dma == 1)
289 { 236 if (request_dma(sv->chanA.rxdma, "Hostess SV/11 (RX)"))
290 if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0) 237 goto err_rxdma;
291 goto dmafail;
292 }
293 } 238 }
294 239
295 /* Kill our private IRQ line the hostess can end up chattering 240 /* Kill our private IRQ line the hostess can end up chattering
296 until the configuration is set */ 241 until the configuration is set */
297 disable_irq(irq); 242 disable_irq(irq);
298 243
299 /* 244 /*
300 * Begin normal initialise 245 * Begin normal initialise
301 */ 246 */
302 247
303 if(z8530_init(dev)!=0) 248 if (z8530_init(sv)) {
304 {
305 printk(KERN_ERR "Z8530 series device not found.\n"); 249 printk(KERN_ERR "Z8530 series device not found.\n");
306 enable_irq(irq); 250 enable_irq(irq);
307 goto dmafail2; 251 goto free_dma;
308 } 252 }
309 z8530_channel_load(&dev->chanB, z8530_dead_port); 253 z8530_channel_load(&sv->chanB, z8530_dead_port);
310 if(dev->type==Z85C30) 254 if (sv->type == Z85C30)
311 z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream); 255 z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream);
312 else 256 else
313 z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230); 257 z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream_85230);
314 258
315 enable_irq(irq); 259 enable_irq(irq);
316
317 260
318 /* 261 /*
319 * Now we can take the IRQ 262 * Now we can take the IRQ
320 */ 263 */
321 if(dev_alloc_name(dev->chanA.netdevice,"hdlc%d")>=0)
322 {
323 struct net_device *d=dev->chanA.netdevice;
324 264
325 /* 265 sv->chanA.netdevice = netdev = alloc_hdlcdev(sv);
326 * Initialise the PPP components 266 if (!netdev)
327 */ 267 goto free_dma;
328 d->ml_priv = sv;
329 sppp_attach(&sv->netdev);
330
331 /*
332 * Local fields
333 */
334
335 d->base_addr = iobase;
336 d->irq = irq;
337
338 if(register_netdev(d))
339 {
340 printk(KERN_ERR "%s: unable to register device.\n",
341 d->name);
342 sppp_detach(d);
343 goto dmafail2;
344 }
345 268
346 z8530_describe(dev, "I/O", iobase); 269 dev_to_hdlc(netdev)->attach = hostess_attach;
347 dev->active=1; 270 dev_to_hdlc(netdev)->xmit = hostess_queue_xmit;
348 return sv; 271 netdev->open = hostess_open;
272 netdev->stop = hostess_close;
273 netdev->do_ioctl = hostess_ioctl;
274 netdev->base_addr = iobase;
275 netdev->irq = irq;
276
277 if (register_hdlc_device(netdev)) {
278 printk(KERN_ERR "hostess: unable to register HDLC device.\n");
279 free_netdev(netdev);
280 goto free_dma;
349 } 281 }
350dmafail2: 282
351 if(dma==1) 283 z8530_describe(sv, "I/O", iobase);
352 free_dma(dev->chanA.rxdma); 284 sv->active = 1;
353dmafail: 285 return sv;
354 if(dma) 286
355 free_dma(dev->chanA.txdma); 287free_dma:
356fail: 288 if (dma == 1)
357 free_irq(irq, dev); 289 free_dma(sv->chanA.rxdma);
358fail1: 290err_rxdma:
359 free_netdev(sv->netdev.dev); 291 if (dma)
360fail2: 292 free_dma(sv->chanA.txdma);
293err_txdma:
294 free_irq(irq, sv);
295err_irq:
361 kfree(sv); 296 kfree(sv);
362fail3: 297err_kzalloc:
363 release_region(iobase,8); 298 release_region(iobase, 8);
364 return NULL; 299 return NULL;
365} 300}
366 301
367static void sv11_shutdown(struct sv11_device *dev) 302static void sv11_shutdown(struct z8530_dev *dev)
368{ 303{
369 sppp_detach(dev->netdev.dev); 304 unregister_hdlc_device(dev->chanA.netdevice);
370 unregister_netdev(dev->netdev.dev); 305 z8530_shutdown(dev);
371 z8530_shutdown(&dev->sync); 306 free_irq(dev->irq, dev);
372 free_irq(dev->sync.irq, dev); 307 if (dma) {
373 if(dma) 308 if (dma == 1)
374 { 309 free_dma(dev->chanA.rxdma);
375 if(dma==1) 310 free_dma(dev->chanA.txdma);
376 free_dma(dev->sync.chanA.rxdma);
377 free_dma(dev->sync.chanA.txdma);
378 } 311 }
379 release_region(dev->sync.chanA.ctrlio-1, 8); 312 release_region(dev->chanA.ctrlio - 1, 8);
380 free_netdev(dev->netdev.dev); 313 free_netdev(dev->chanA.netdevice);
381 kfree(dev); 314 kfree(dev);
382} 315}
383 316
384#ifdef MODULE 317static int io = 0x200;
385 318static int irq = 9;
386static int io=0x200;
387static int irq=9;
388 319
389module_param(io, int, 0); 320module_param(io, int, 0);
390MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card"); 321MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
@@ -397,22 +328,17 @@ MODULE_AUTHOR("Alan Cox");
397MODULE_LICENSE("GPL"); 328MODULE_LICENSE("GPL");
398MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11"); 329MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
399 330
400static struct sv11_device *sv11_unit; 331static struct z8530_dev *sv11_unit;
401 332
402int init_module(void) 333int init_module(void)
403{ 334{
404 printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.03.\n"); 335 if ((sv11_unit = sv11_init(io, irq)) == NULL)
405 printk(KERN_INFO "(c) Copyright 2001, Red Hat Inc.\n");
406 if((sv11_unit=sv11_init(io,irq))==NULL)
407 return -ENODEV; 336 return -ENODEV;
408 return 0; 337 return 0;
409} 338}
410 339
411void cleanup_module(void) 340void cleanup_module(void)
412{ 341{
413 if(sv11_unit) 342 if (sv11_unit)
414 sv11_shutdown(sv11_unit); 343 sv11_shutdown(sv11_unit);
415} 344}
416
417#endif
418
diff --git a/drivers/net/wan/lmc/lmc.h b/drivers/net/wan/lmc/lmc.h
index 882e58c1bfd7..4ced7ac16c2c 100644
--- a/drivers/net/wan/lmc/lmc.h
+++ b/drivers/net/wan/lmc/lmc.h
@@ -11,12 +11,12 @@ unsigned lmc_mii_readreg(lmc_softc_t * const sc, unsigned
11 devaddr, unsigned regno); 11 devaddr, unsigned regno);
12void lmc_mii_writereg(lmc_softc_t * const sc, unsigned devaddr, 12void lmc_mii_writereg(lmc_softc_t * const sc, unsigned devaddr,
13 unsigned regno, unsigned data); 13 unsigned regno, unsigned data);
14void lmc_led_on(lmc_softc_t * const, u_int32_t); 14void lmc_led_on(lmc_softc_t * const, u32);
15void lmc_led_off(lmc_softc_t * const, u_int32_t); 15void lmc_led_off(lmc_softc_t * const, u32);
16unsigned lmc_mii_readreg(lmc_softc_t * const, unsigned, unsigned); 16unsigned lmc_mii_readreg(lmc_softc_t * const, unsigned, unsigned);
17void lmc_mii_writereg(lmc_softc_t * const, unsigned, unsigned, unsigned); 17void lmc_mii_writereg(lmc_softc_t * const, unsigned, unsigned, unsigned);
18void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits); 18void lmc_gpio_mkinput(lmc_softc_t * const sc, u32 bits);
19void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits); 19void lmc_gpio_mkoutput(lmc_softc_t * const sc, u32 bits);
20 20
21int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 21int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
22 22
@@ -26,8 +26,7 @@ extern lmc_media_t lmc_t1_media;
26extern lmc_media_t lmc_hssi_media; 26extern lmc_media_t lmc_hssi_media;
27 27
28#ifdef _DBG_EVENTLOG 28#ifdef _DBG_EVENTLOG
29static void lmcEventLog( u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3 ); 29static void lmcEventLog(u32 EventNum, u32 arg2, u32 arg3);
30#endif 30#endif
31 31
32#endif 32#endif
33
diff --git a/drivers/net/wan/lmc/lmc_debug.c b/drivers/net/wan/lmc/lmc_debug.c
index 3b94352b0d03..15049d711f47 100644
--- a/drivers/net/wan/lmc/lmc_debug.c
+++ b/drivers/net/wan/lmc/lmc_debug.c
@@ -1,4 +1,3 @@
1
2#include <linux/types.h> 1#include <linux/types.h>
3#include <linux/netdevice.h> 2#include <linux/netdevice.h>
4#include <linux/interrupt.h> 3#include <linux/interrupt.h>
@@ -48,10 +47,10 @@ void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
48#endif 47#endif
49 48
50#ifdef DEBUG 49#ifdef DEBUG
51u_int32_t lmcEventLogIndex = 0; 50u32 lmcEventLogIndex;
52u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS]; 51u32 lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
53 52
54void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3) 53void lmcEventLog(u32 EventNum, u32 arg2, u32 arg3)
55{ 54{
56 lmcEventLogBuf[lmcEventLogIndex++] = EventNum; 55 lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
57 lmcEventLogBuf[lmcEventLogIndex++] = arg2; 56 lmcEventLogBuf[lmcEventLogIndex++] = arg2;
diff --git a/drivers/net/wan/lmc/lmc_debug.h b/drivers/net/wan/lmc/lmc_debug.h
index cf3563859bf3..2d46f121549f 100644
--- a/drivers/net/wan/lmc/lmc_debug.h
+++ b/drivers/net/wan/lmc/lmc_debug.h
@@ -38,15 +38,15 @@
38 38
39 39
40#ifdef DEBUG 40#ifdef DEBUG
41extern u_int32_t lmcEventLogIndex; 41extern u32 lmcEventLogIndex;
42extern u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS]; 42extern u32 lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
43#define LMC_EVENT_LOG(x, y, z) lmcEventLog((x), (y), (z)) 43#define LMC_EVENT_LOG(x, y, z) lmcEventLog((x), (y), (z))
44#else 44#else
45#define LMC_EVENT_LOG(x,y,z) 45#define LMC_EVENT_LOG(x,y,z)
46#endif /* end ifdef _DBG_EVENTLOG */ 46#endif /* end ifdef _DBG_EVENTLOG */
47 47
48void lmcConsoleLog(char *type, unsigned char *ucData, int iLen); 48void lmcConsoleLog(char *type, unsigned char *ucData, int iLen);
49void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3); 49void lmcEventLog(u32 EventNum, u32 arg2, u32 arg3);
50void lmc_trace(struct net_device *dev, char *msg); 50void lmc_trace(struct net_device *dev, char *msg);
51 51
52#endif 52#endif
diff --git a/drivers/net/wan/lmc/lmc_ioctl.h b/drivers/net/wan/lmc/lmc_ioctl.h
index 57dd861cd3db..72fb113a44ca 100644
--- a/drivers/net/wan/lmc/lmc_ioctl.h
+++ b/drivers/net/wan/lmc/lmc_ioctl.h
@@ -61,7 +61,7 @@
61/* 61/*
62 * IFTYPE defines 62 * IFTYPE defines
63 */ 63 */
64#define LMC_PPP 1 /* use sppp interface */ 64#define LMC_PPP 1 /* use generic HDLC interface */
65#define LMC_NET 2 /* use direct net interface */ 65#define LMC_NET 2 /* use direct net interface */
66#define LMC_RAW 3 /* use direct net interface */ 66#define LMC_RAW 3 /* use direct net interface */
67 67
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 62133cee446a..f80640f5a744 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1,6 +1,7 @@
1 /* 1 /*
2 * Copyright (c) 1997-2000 LAN Media Corporation (LMC) 2 * Copyright (c) 1997-2000 LAN Media Corporation (LMC)
3 * All rights reserved. www.lanmedia.com 3 * All rights reserved. www.lanmedia.com
4 * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
4 * 5 *
5 * This code is written by: 6 * This code is written by:
6 * Andrew Stanley-Jones (asj@cban.com) 7 * Andrew Stanley-Jones (asj@cban.com)
@@ -36,8 +37,6 @@
36 * 37 *
37 */ 38 */
38 39
39/* $Id: lmc_main.c,v 1.36 2000/04/11 05:25:25 asj Exp $ */
40
41#include <linux/kernel.h> 40#include <linux/kernel.h>
42#include <linux/module.h> 41#include <linux/module.h>
43#include <linux/string.h> 42#include <linux/string.h>
@@ -49,6 +48,7 @@
49#include <linux/interrupt.h> 48#include <linux/interrupt.h>
50#include <linux/pci.h> 49#include <linux/pci.h>
51#include <linux/delay.h> 50#include <linux/delay.h>
51#include <linux/hdlc.h>
52#include <linux/init.h> 52#include <linux/init.h>
53#include <linux/in.h> 53#include <linux/in.h>
54#include <linux/if_arp.h> 54#include <linux/if_arp.h>
@@ -57,9 +57,6 @@
57#include <linux/skbuff.h> 57#include <linux/skbuff.h>
58#include <linux/inet.h> 58#include <linux/inet.h>
59#include <linux/bitops.h> 59#include <linux/bitops.h>
60
61#include <net/syncppp.h>
62
63#include <asm/processor.h> /* Processor type for cache alignment. */ 60#include <asm/processor.h> /* Processor type for cache alignment. */
64#include <asm/io.h> 61#include <asm/io.h>
65#include <asm/dma.h> 62#include <asm/dma.h>
@@ -78,8 +75,6 @@
78#include "lmc_debug.h" 75#include "lmc_debug.h"
79#include "lmc_proto.h" 76#include "lmc_proto.h"
80 77
81static int lmc_first_load = 0;
82
83static int LMC_PKT_BUF_SZ = 1542; 78static int LMC_PKT_BUF_SZ = 1542;
84 79
85static struct pci_device_id lmc_pci_tbl[] = { 80static struct pci_device_id lmc_pci_tbl[] = {
@@ -91,11 +86,10 @@ static struct pci_device_id lmc_pci_tbl[] = {
91}; 86};
92 87
93MODULE_DEVICE_TABLE(pci, lmc_pci_tbl); 88MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
94MODULE_LICENSE("GPL"); 89MODULE_LICENSE("GPL v2");
95 90
96 91
97static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev); 92static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
98static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
99static int lmc_rx (struct net_device *dev); 93static int lmc_rx (struct net_device *dev);
100static int lmc_open(struct net_device *dev); 94static int lmc_open(struct net_device *dev);
101static int lmc_close(struct net_device *dev); 95static int lmc_close(struct net_device *dev);
@@ -114,20 +108,14 @@ static void lmc_driver_timeout(struct net_device *dev);
114 * linux reserves 16 device specific IOCTLs. We call them 108 * linux reserves 16 device specific IOCTLs. We call them
115 * LMCIOC* to control various bits of our world. 109 * LMCIOC* to control various bits of our world.
116 */ 110 */
117int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ 111int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
118{ 112{
119 lmc_softc_t *sc; 113 lmc_softc_t *sc = dev_to_sc(dev);
120 lmc_ctl_t ctl; 114 lmc_ctl_t ctl;
121 int ret; 115 int ret = -EOPNOTSUPP;
122 u_int16_t regVal; 116 u16 regVal;
123 unsigned long flags; 117 unsigned long flags;
124 118
125 struct sppp *sp;
126
127 ret = -EOPNOTSUPP;
128
129 sc = dev->priv;
130
131 lmc_trace(dev, "lmc_ioctl in"); 119 lmc_trace(dev, "lmc_ioctl in");
132 120
133 /* 121 /*
@@ -149,7 +137,6 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
149 break; 137 break;
150 138
151 case LMCIOCSINFO: /*fold01*/ 139 case LMCIOCSINFO: /*fold01*/
152 sp = &((struct ppp_device *) dev)->sppp;
153 if (!capable(CAP_NET_ADMIN)) { 140 if (!capable(CAP_NET_ADMIN)) {
154 ret = -EPERM; 141 ret = -EPERM;
155 break; 142 break;
@@ -175,25 +162,20 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
175 sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE; 162 sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE;
176 } 163 }
177 164
178 if (ctl.keepalive_onoff == LMC_CTL_OFF)
179 sp->pp_flags &= ~PP_KEEPALIVE; /* Turn off */
180 else
181 sp->pp_flags |= PP_KEEPALIVE; /* Turn on */
182
183 ret = 0; 165 ret = 0;
184 break; 166 break;
185 167
186 case LMCIOCIFTYPE: /*fold01*/ 168 case LMCIOCIFTYPE: /*fold01*/
187 { 169 {
188 u_int16_t old_type = sc->if_type; 170 u16 old_type = sc->if_type;
189 u_int16_t new_type; 171 u16 new_type;
190 172
191 if (!capable(CAP_NET_ADMIN)) { 173 if (!capable(CAP_NET_ADMIN)) {
192 ret = -EPERM; 174 ret = -EPERM;
193 break; 175 break;
194 } 176 }
195 177
196 if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u_int16_t))) { 178 if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u16))) {
197 ret = -EFAULT; 179 ret = -EFAULT;
198 break; 180 break;
199 } 181 }
@@ -206,15 +188,11 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
206 } 188 }
207 189
208 lmc_proto_close(sc); 190 lmc_proto_close(sc);
209 lmc_proto_detach(sc);
210 191
211 sc->if_type = new_type; 192 sc->if_type = new_type;
212// lmc_proto_init(sc);
213 lmc_proto_attach(sc); 193 lmc_proto_attach(sc);
214 lmc_proto_open(sc); 194 ret = lmc_proto_open(sc);
215 195 break;
216 ret = 0 ;
217 break ;
218 } 196 }
219 197
220 case LMCIOCGETXINFO: /*fold01*/ 198 case LMCIOCGETXINFO: /*fold01*/
@@ -241,51 +219,53 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
241 219
242 break; 220 break;
243 221
244 case LMCIOCGETLMCSTATS: /*fold01*/ 222 case LMCIOCGETLMCSTATS:
245 if (sc->lmc_cardtype == LMC_CARDTYPE_T1){ 223 if (sc->lmc_cardtype == LMC_CARDTYPE_T1) {
246 lmc_mii_writereg (sc, 0, 17, T1FRAMER_FERR_LSB); 224 lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB);
247 sc->stats.framingBitErrorCount += 225 sc->extra_stats.framingBitErrorCount +=
248 lmc_mii_readreg (sc, 0, 18) & 0xff; 226 lmc_mii_readreg(sc, 0, 18) & 0xff;
249 lmc_mii_writereg (sc, 0, 17, T1FRAMER_FERR_MSB); 227 lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_MSB);
250 sc->stats.framingBitErrorCount += 228 sc->extra_stats.framingBitErrorCount +=
251 (lmc_mii_readreg (sc, 0, 18) & 0xff) << 8; 229 (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
252 lmc_mii_writereg (sc, 0, 17, T1FRAMER_LCV_LSB); 230 lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_LSB);
253 sc->stats.lineCodeViolationCount += 231 sc->extra_stats.lineCodeViolationCount +=
254 lmc_mii_readreg (sc, 0, 18) & 0xff; 232 lmc_mii_readreg(sc, 0, 18) & 0xff;
255 lmc_mii_writereg (sc, 0, 17, T1FRAMER_LCV_MSB); 233 lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_MSB);
256 sc->stats.lineCodeViolationCount += 234 sc->extra_stats.lineCodeViolationCount +=
257 (lmc_mii_readreg (sc, 0, 18) & 0xff) << 8; 235 (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
258 lmc_mii_writereg (sc, 0, 17, T1FRAMER_AERR); 236 lmc_mii_writereg(sc, 0, 17, T1FRAMER_AERR);
259 regVal = lmc_mii_readreg (sc, 0, 18) & 0xff; 237 regVal = lmc_mii_readreg(sc, 0, 18) & 0xff;
260 238
261 sc->stats.lossOfFrameCount += 239 sc->extra_stats.lossOfFrameCount +=
262 (regVal & T1FRAMER_LOF_MASK) >> 4; 240 (regVal & T1FRAMER_LOF_MASK) >> 4;
263 sc->stats.changeOfFrameAlignmentCount += 241 sc->extra_stats.changeOfFrameAlignmentCount +=
264 (regVal & T1FRAMER_COFA_MASK) >> 2; 242 (regVal & T1FRAMER_COFA_MASK) >> 2;
265 sc->stats.severelyErroredFrameCount += 243 sc->extra_stats.severelyErroredFrameCount +=
266 regVal & T1FRAMER_SEF_MASK; 244 regVal & T1FRAMER_SEF_MASK;
267 } 245 }
268 246 if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats,
269 if (copy_to_user(ifr->ifr_data, &sc->stats, 247 sizeof(sc->lmc_device->stats)) ||
270 sizeof (struct lmc_statistics))) 248 copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats),
271 ret = -EFAULT; 249 &sc->extra_stats, sizeof(sc->extra_stats)))
272 else 250 ret = -EFAULT;
273 ret = 0; 251 else
274 break; 252 ret = 0;
253 break;
275 254
276 case LMCIOCCLEARLMCSTATS: /*fold01*/ 255 case LMCIOCCLEARLMCSTATS:
277 if (!capable(CAP_NET_ADMIN)){ 256 if (!capable(CAP_NET_ADMIN)) {
278 ret = -EPERM; 257 ret = -EPERM;
279 break; 258 break;
280 } 259 }
281 260
282 memset (&sc->stats, 0, sizeof (struct lmc_statistics)); 261 memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats));
283 sc->stats.check = STATCHECK; 262 memset(&sc->extra_stats, 0, sizeof(sc->extra_stats));
284 sc->stats.version_size = (DRIVER_VERSION << 16) + 263 sc->extra_stats.check = STATCHECK;
285 sizeof (struct lmc_statistics); 264 sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
286 sc->stats.lmc_cardtype = sc->lmc_cardtype; 265 sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
287 ret = 0; 266 sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
288 break; 267 ret = 0;
268 break;
289 269
290 case LMCIOCSETCIRCUIT: /*fold01*/ 270 case LMCIOCSETCIRCUIT: /*fold01*/
291 if (!capable(CAP_NET_ADMIN)){ 271 if (!capable(CAP_NET_ADMIN)){
@@ -330,7 +310,8 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
330 ret = -EFAULT; 310 ret = -EFAULT;
331 break; 311 break;
332 } 312 }
333 if (copy_to_user(ifr->ifr_data + sizeof (u32), lmcEventLogBuf, sizeof (lmcEventLogBuf))) 313 if (copy_to_user(ifr->ifr_data + sizeof(u32), lmcEventLogBuf,
314 sizeof(lmcEventLogBuf)))
334 ret = -EFAULT; 315 ret = -EFAULT;
335 else 316 else
336 ret = 0; 317 ret = 0;
@@ -641,14 +622,12 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
641/* the watchdog process that cruises around */ 622/* the watchdog process that cruises around */
642static void lmc_watchdog (unsigned long data) /*fold00*/ 623static void lmc_watchdog (unsigned long data) /*fold00*/
643{ 624{
644 struct net_device *dev = (struct net_device *) data; 625 struct net_device *dev = (struct net_device *)data;
645 lmc_softc_t *sc; 626 lmc_softc_t *sc = dev_to_sc(dev);
646 int link_status; 627 int link_status;
647 u_int32_t ticks; 628 u32 ticks;
648 unsigned long flags; 629 unsigned long flags;
649 630
650 sc = dev->priv;
651
652 lmc_trace(dev, "lmc_watchdog in"); 631 lmc_trace(dev, "lmc_watchdog in");
653 632
654 spin_lock_irqsave(&sc->lmc_lock, flags); 633 spin_lock_irqsave(&sc->lmc_lock, flags);
@@ -677,22 +656,22 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
677 * check for a transmit interrupt timeout 656 * check for a transmit interrupt timeout
678 * Has the packet xmt vs xmt serviced threshold been exceeded */ 657 * Has the packet xmt vs xmt serviced threshold been exceeded */
679 if (sc->lmc_taint_tx == sc->lastlmc_taint_tx && 658 if (sc->lmc_taint_tx == sc->lastlmc_taint_tx &&
680 sc->stats.tx_packets > sc->lasttx_packets && 659 sc->lmc_device->stats.tx_packets > sc->lasttx_packets &&
681 sc->tx_TimeoutInd == 0) 660 sc->tx_TimeoutInd == 0)
682 { 661 {
683 662
684 /* wait for the watchdog to come around again */ 663 /* wait for the watchdog to come around again */
685 sc->tx_TimeoutInd = 1; 664 sc->tx_TimeoutInd = 1;
686 } 665 }
687 else if (sc->lmc_taint_tx == sc->lastlmc_taint_tx && 666 else if (sc->lmc_taint_tx == sc->lastlmc_taint_tx &&
688 sc->stats.tx_packets > sc->lasttx_packets && 667 sc->lmc_device->stats.tx_packets > sc->lasttx_packets &&
689 sc->tx_TimeoutInd) 668 sc->tx_TimeoutInd)
690 { 669 {
691 670
692 LMC_EVENT_LOG(LMC_EVENT_XMTINTTMO, LMC_CSR_READ (sc, csr_status), 0); 671 LMC_EVENT_LOG(LMC_EVENT_XMTINTTMO, LMC_CSR_READ (sc, csr_status), 0);
693 672
694 sc->tx_TimeoutDisplay = 1; 673 sc->tx_TimeoutDisplay = 1;
695 sc->stats.tx_TimeoutCnt++; 674 sc->extra_stats.tx_TimeoutCnt++;
696 675
697 /* DEC chip is stuck, hit it with a RESET!!!! */ 676 /* DEC chip is stuck, hit it with a RESET!!!! */
698 lmc_running_reset (dev); 677 lmc_running_reset (dev);
@@ -712,13 +691,11 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
712 /* reset the transmit timeout detection flag */ 691 /* reset the transmit timeout detection flag */
713 sc->tx_TimeoutInd = 0; 692 sc->tx_TimeoutInd = 0;
714 sc->lastlmc_taint_tx = sc->lmc_taint_tx; 693 sc->lastlmc_taint_tx = sc->lmc_taint_tx;
715 sc->lasttx_packets = sc->stats.tx_packets; 694 sc->lasttx_packets = sc->lmc_device->stats.tx_packets;
716 } 695 } else {
717 else
718 {
719 sc->tx_TimeoutInd = 0; 696 sc->tx_TimeoutInd = 0;
720 sc->lastlmc_taint_tx = sc->lmc_taint_tx; 697 sc->lastlmc_taint_tx = sc->lmc_taint_tx;
721 sc->lasttx_packets = sc->stats.tx_packets; 698 sc->lasttx_packets = sc->lmc_device->stats.tx_packets;
722 } 699 }
723 700
724 /* --- end time out check ----------------------------------- */ 701 /* --- end time out check ----------------------------------- */
@@ -748,19 +725,7 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
748 sc->last_link_status = 1; 725 sc->last_link_status = 1;
749 /* lmc_reset (sc); Again why reset??? */ 726 /* lmc_reset (sc); Again why reset??? */
750 727
751 /* Inform the world that link protocol is back up. */
752 netif_carrier_on(dev); 728 netif_carrier_on(dev);
753
754 /* Now we have to tell the syncppp that we had an outage
755 * and that it should deal. Calling sppp_reopen here
756 * should do the trick, but we may have to call sppp_close
757 * when the link goes down, and call sppp_open here.
758 * Subject to more testing.
759 * --bbraun
760 */
761
762 lmc_proto_reopen(sc);
763
764 } 729 }
765 730
766 /* Call media specific watchdog functions */ 731 /* Call media specific watchdog functions */
@@ -816,114 +781,93 @@ kick_timer:
816 781
817} 782}
818 783
819static void lmc_setup(struct net_device * const dev) /*fold00*/ 784static int lmc_attach(struct net_device *dev, unsigned short encoding,
785 unsigned short parity)
820{ 786{
821 lmc_trace(dev, "lmc_setup in"); 787 if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
822 788 return 0;
823 dev->type = ARPHRD_HDLC; 789 return -EINVAL;
824 dev->hard_start_xmit = lmc_start_xmit;
825 dev->open = lmc_open;
826 dev->stop = lmc_close;
827 dev->get_stats = lmc_get_stats;
828 dev->do_ioctl = lmc_ioctl;
829 dev->tx_timeout = lmc_driver_timeout;
830 dev->watchdog_timeo = (HZ); /* 1 second */
831
832 lmc_trace(dev, "lmc_setup out");
833} 790}
834 791
835
836static int __devinit lmc_init_one(struct pci_dev *pdev, 792static int __devinit lmc_init_one(struct pci_dev *pdev,
837 const struct pci_device_id *ent) 793 const struct pci_device_id *ent)
838{ 794{
839 struct net_device *dev; 795 lmc_softc_t *sc;
840 lmc_softc_t *sc; 796 struct net_device *dev;
841 u16 subdevice; 797 u16 subdevice;
842 u_int16_t AdapModelNum; 798 u16 AdapModelNum;
843 int err = -ENOMEM; 799 int err;
844 static int cards_found; 800 static int cards_found;
845#ifndef GCOM 801
846 /* We name by type not by vendor */ 802 /* lmc_trace(dev, "lmc_init_one in"); */
847 static const char lmcname[] = "hdlc%d"; 803
848#else 804 err = pci_enable_device(pdev);
849 /* 805 if (err) {
850 * GCOM uses LMC vendor name so that clients can know which card 806 printk(KERN_ERR "lmc: pci enable failed: %d\n", err);
851 * to attach to. 807 return err;
852 */ 808 }
853 static const char lmcname[] = "lmc%d";
854#endif
855
856
857 /*
858 * Allocate our own device structure
859 */
860 dev = alloc_netdev(sizeof(lmc_softc_t), lmcname, lmc_setup);
861 if (!dev) {
862 printk (KERN_ERR "lmc:alloc_netdev for device failed\n");
863 goto out1;
864 }
865
866 lmc_trace(dev, "lmc_init_one in");
867
868 err = pci_enable_device(pdev);
869 if (err) {
870 printk(KERN_ERR "lmc: pci enable failed:%d\n", err);
871 goto out2;
872 }
873
874 if (pci_request_regions(pdev, "lmc")) {
875 printk(KERN_ERR "lmc: pci_request_region failed\n");
876 err = -EIO;
877 goto out3;
878 }
879
880 pci_set_drvdata(pdev, dev);
881
882 if(lmc_first_load == 0){
883 printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",
884 DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
885 lmc_first_load = 1;
886 }
887
888 sc = dev->priv;
889 sc->lmc_device = dev;
890 sc->name = dev->name;
891
892 /* Initialize the sppp layer */
893 /* An ioctl can cause a subsequent detach for raw frame interface */
894 dev->ml_priv = sc;
895 sc->if_type = LMC_PPP;
896 sc->check = 0xBEAFCAFE;
897 dev->base_addr = pci_resource_start(pdev, 0);
898 dev->irq = pdev->irq;
899
900 SET_NETDEV_DEV(dev, &pdev->dev);
901
902 /*
903 * This will get the protocol layer ready and do any 1 time init's
904 * Must have a valid sc and dev structure
905 */
906 lmc_proto_init(sc);
907
908 lmc_proto_attach(sc);
909 809
910 /* 810 err = pci_request_regions(pdev, "lmc");
911 * Why were we changing this??? 811 if (err) {
912 dev->tx_queue_len = 100; 812 printk(KERN_ERR "lmc: pci_request_region failed\n");
913 */ 813 goto err_req_io;
814 }
914 815
915 /* Init the spin lock so can call it latter */ 816 /*
817 * Allocate our own device structure
818 */
819 sc = kzalloc(sizeof(lmc_softc_t), GFP_KERNEL);
820 if (!sc) {
821 err = -ENOMEM;
822 goto err_kzalloc;
823 }
916 824
917 spin_lock_init(&sc->lmc_lock); 825 dev = alloc_hdlcdev(sc);
918 pci_set_master(pdev); 826 if (!dev) {
827 printk(KERN_ERR "lmc:alloc_netdev for device failed\n");
828 goto err_hdlcdev;
829 }
919 830
920 printk ("%s: detected at %lx, irq %d\n", dev->name,
921 dev->base_addr, dev->irq);
922 831
923 if (register_netdev (dev) != 0) { 832 dev->type = ARPHRD_HDLC;
924 printk (KERN_ERR "%s: register_netdev failed.\n", dev->name); 833 dev_to_hdlc(dev)->xmit = lmc_start_xmit;
925 goto out4; 834 dev_to_hdlc(dev)->attach = lmc_attach;
926 } 835 dev->open = lmc_open;
836 dev->stop = lmc_close;
837 dev->get_stats = lmc_get_stats;
838 dev->do_ioctl = lmc_ioctl;
839 dev->tx_timeout = lmc_driver_timeout;
840 dev->watchdog_timeo = HZ; /* 1 second */
841 dev->tx_queue_len = 100;
842 sc->lmc_device = dev;
843 sc->name = dev->name;
844 sc->if_type = LMC_PPP;
845 sc->check = 0xBEAFCAFE;
846 dev->base_addr = pci_resource_start(pdev, 0);
847 dev->irq = pdev->irq;
848 pci_set_drvdata(pdev, dev);
849 SET_NETDEV_DEV(dev, &pdev->dev);
850
851 /*
852 * This will get the protocol layer ready and do any 1 time init's
853 * Must have a valid sc and dev structure
854 */
855 lmc_proto_attach(sc);
856
857 /* Init the spin lock so can call it latter */
858
859 spin_lock_init(&sc->lmc_lock);
860 pci_set_master(pdev);
861
862 printk(KERN_INFO "%s: detected at %lx, irq %d\n", dev->name,
863 dev->base_addr, dev->irq);
864
865 err = register_hdlc_device(dev);
866 if (err) {
867 printk(KERN_ERR "%s: register_netdev failed.\n", dev->name);
868 free_netdev(dev);
869 goto err_hdlcdev;
870 }
927 871
928 sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN; 872 sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;
929 sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT; 873 sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
@@ -939,27 +883,27 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
939 883
940 switch (subdevice) { 884 switch (subdevice) {
941 case PCI_DEVICE_ID_LMC_HSSI: 885 case PCI_DEVICE_ID_LMC_HSSI:
942 printk ("%s: LMC HSSI\n", dev->name); 886 printk(KERN_INFO "%s: LMC HSSI\n", dev->name);
943 sc->lmc_cardtype = LMC_CARDTYPE_HSSI; 887 sc->lmc_cardtype = LMC_CARDTYPE_HSSI;
944 sc->lmc_media = &lmc_hssi_media; 888 sc->lmc_media = &lmc_hssi_media;
945 break; 889 break;
946 case PCI_DEVICE_ID_LMC_DS3: 890 case PCI_DEVICE_ID_LMC_DS3:
947 printk ("%s: LMC DS3\n", dev->name); 891 printk(KERN_INFO "%s: LMC DS3\n", dev->name);
948 sc->lmc_cardtype = LMC_CARDTYPE_DS3; 892 sc->lmc_cardtype = LMC_CARDTYPE_DS3;
949 sc->lmc_media = &lmc_ds3_media; 893 sc->lmc_media = &lmc_ds3_media;
950 break; 894 break;
951 case PCI_DEVICE_ID_LMC_SSI: 895 case PCI_DEVICE_ID_LMC_SSI:
952 printk ("%s: LMC SSI\n", dev->name); 896 printk(KERN_INFO "%s: LMC SSI\n", dev->name);
953 sc->lmc_cardtype = LMC_CARDTYPE_SSI; 897 sc->lmc_cardtype = LMC_CARDTYPE_SSI;
954 sc->lmc_media = &lmc_ssi_media; 898 sc->lmc_media = &lmc_ssi_media;
955 break; 899 break;
956 case PCI_DEVICE_ID_LMC_T1: 900 case PCI_DEVICE_ID_LMC_T1:
957 printk ("%s: LMC T1\n", dev->name); 901 printk(KERN_INFO "%s: LMC T1\n", dev->name);
958 sc->lmc_cardtype = LMC_CARDTYPE_T1; 902 sc->lmc_cardtype = LMC_CARDTYPE_T1;
959 sc->lmc_media = &lmc_t1_media; 903 sc->lmc_media = &lmc_t1_media;
960 break; 904 break;
961 default: 905 default:
962 printk (KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name); 906 printk(KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name);
963 break; 907 break;
964 } 908 }
965 909
@@ -977,32 +921,28 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
977 */ 921 */
978 AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4; 922 AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4;
979 923
980 if ((AdapModelNum == LMC_ADAP_T1 924 if ((AdapModelNum != LMC_ADAP_T1 || /* detect LMC1200 */
981 && subdevice == PCI_DEVICE_ID_LMC_T1) || /* detect LMC1200 */ 925 subdevice != PCI_DEVICE_ID_LMC_T1) &&
982 (AdapModelNum == LMC_ADAP_SSI 926 (AdapModelNum != LMC_ADAP_SSI || /* detect LMC1000 */
983 && subdevice == PCI_DEVICE_ID_LMC_SSI) || /* detect LMC1000 */ 927 subdevice != PCI_DEVICE_ID_LMC_SSI) &&
984 (AdapModelNum == LMC_ADAP_DS3 928 (AdapModelNum != LMC_ADAP_DS3 || /* detect LMC5245 */
985 && subdevice == PCI_DEVICE_ID_LMC_DS3) || /* detect LMC5245 */ 929 subdevice != PCI_DEVICE_ID_LMC_DS3) &&
986 (AdapModelNum == LMC_ADAP_HSSI 930 (AdapModelNum != LMC_ADAP_HSSI || /* detect LMC5200 */
987 && subdevice == PCI_DEVICE_ID_LMC_HSSI)) 931 subdevice != PCI_DEVICE_ID_LMC_HSSI))
988 { /* detect LMC5200 */ 932 printk(KERN_WARNING "%s: Model number (%d) miscompare for PCI"
933 " Subsystem ID = 0x%04x\n",
934 dev->name, AdapModelNum, subdevice);
989 935
990 }
991 else {
992 printk ("%s: Model number (%d) miscompare for PCI Subsystem ID = 0x%04x\n",
993 dev->name, AdapModelNum, subdevice);
994// return (NULL);
995 }
996 /* 936 /*
997 * reset clock 937 * reset clock
998 */ 938 */
999 LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL); 939 LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);
1000 940
1001 sc->board_idx = cards_found++; 941 sc->board_idx = cards_found++;
1002 sc->stats.check = STATCHECK; 942 sc->extra_stats.check = STATCHECK;
1003 sc->stats.version_size = (DRIVER_VERSION << 16) + 943 sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
1004 sizeof (struct lmc_statistics); 944 sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
1005 sc->stats.lmc_cardtype = sc->lmc_cardtype; 945 sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
1006 946
1007 sc->lmc_ok = 0; 947 sc->lmc_ok = 0;
1008 sc->last_link_status = 0; 948 sc->last_link_status = 0;
@@ -1010,58 +950,51 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
1010 lmc_trace(dev, "lmc_init_one out"); 950 lmc_trace(dev, "lmc_init_one out");
1011 return 0; 951 return 0;
1012 952
1013 out4: 953err_hdlcdev:
1014 lmc_proto_detach(sc); 954 pci_set_drvdata(pdev, NULL);
1015 out3: 955 kfree(sc);
1016 if (pdev) { 956err_kzalloc:
1017 pci_release_regions(pdev); 957 pci_release_regions(pdev);
1018 pci_set_drvdata(pdev, NULL); 958err_req_io:
1019 } 959 pci_disable_device(pdev);
1020 out2: 960 return err;
1021 free_netdev(dev);
1022 out1:
1023 return err;
1024} 961}
1025 962
1026/* 963/*
1027 * Called from pci when removing module. 964 * Called from pci when removing module.
1028 */ 965 */
1029static void __devexit lmc_remove_one (struct pci_dev *pdev) 966static void __devexit lmc_remove_one(struct pci_dev *pdev)
1030{ 967{
1031 struct net_device *dev = pci_get_drvdata(pdev); 968 struct net_device *dev = pci_get_drvdata(pdev);
1032 969
1033 if (dev) { 970 if (dev) {
1034 lmc_softc_t *sc = dev->priv; 971 printk(KERN_DEBUG "%s: removing...\n", dev->name);
1035 972 unregister_hdlc_device(dev);
1036 printk("%s: removing...\n", dev->name); 973 free_netdev(dev);
1037 lmc_proto_detach(sc); 974 pci_release_regions(pdev);
1038 unregister_netdev(dev); 975 pci_disable_device(pdev);
1039 free_netdev(dev); 976 pci_set_drvdata(pdev, NULL);
1040 pci_release_regions(pdev); 977 }
1041 pci_disable_device(pdev);
1042 pci_set_drvdata(pdev, NULL);
1043 }
1044} 978}
1045 979
1046/* After this is called, packets can be sent. 980/* After this is called, packets can be sent.
1047 * Does not initialize the addresses 981 * Does not initialize the addresses
1048 */ 982 */
1049static int lmc_open (struct net_device *dev) /*fold00*/ 983static int lmc_open(struct net_device *dev)
1050{ 984{
1051 lmc_softc_t *sc = dev->priv; 985 lmc_softc_t *sc = dev_to_sc(dev);
986 int err;
1052 987
1053 lmc_trace(dev, "lmc_open in"); 988 lmc_trace(dev, "lmc_open in");
1054 989
1055 lmc_led_on(sc, LMC_DS3_LED0); 990 lmc_led_on(sc, LMC_DS3_LED0);
1056 991
1057 lmc_dec_reset (sc); 992 lmc_dec_reset(sc);
1058 lmc_reset (sc); 993 lmc_reset(sc);
1059
1060 LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
1061 LMC_EVENT_LOG(LMC_EVENT_RESET2,
1062 lmc_mii_readreg (sc, 0, 16),
1063 lmc_mii_readreg (sc, 0, 17));
1064 994
995 LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ(sc, csr_status), 0);
996 LMC_EVENT_LOG(LMC_EVENT_RESET2, lmc_mii_readreg(sc, 0, 16),
997 lmc_mii_readreg(sc, 0, 17));
1065 998
1066 if (sc->lmc_ok){ 999 if (sc->lmc_ok){
1067 lmc_trace(dev, "lmc_open lmc_ok out"); 1000 lmc_trace(dev, "lmc_open lmc_ok out");
@@ -1106,14 +1039,14 @@ static int lmc_open (struct net_device *dev) /*fold00*/
1106 1039
1107 /* dev->flags |= IFF_UP; */ 1040 /* dev->flags |= IFF_UP; */
1108 1041
1109 lmc_proto_open(sc); 1042 if ((err = lmc_proto_open(sc)) != 0)
1043 return err;
1110 1044
1111 dev->do_ioctl = lmc_ioctl; 1045 dev->do_ioctl = lmc_ioctl;
1112 1046
1113 1047
1114 netif_start_queue(dev); 1048 netif_start_queue(dev);
1115 1049 sc->extra_stats.tx_tbusy0++;
1116 sc->stats.tx_tbusy0++ ;
1117 1050
1118 /* 1051 /*
1119 * select what interrupts we want to get 1052 * select what interrupts we want to get
@@ -1165,8 +1098,7 @@ static int lmc_open (struct net_device *dev) /*fold00*/
1165 1098
1166static void lmc_running_reset (struct net_device *dev) /*fold00*/ 1099static void lmc_running_reset (struct net_device *dev) /*fold00*/
1167{ 1100{
1168 1101 lmc_softc_t *sc = dev_to_sc(dev);
1169 lmc_softc_t *sc = (lmc_softc_t *) dev->priv;
1170 1102
1171 lmc_trace(dev, "lmc_runnig_reset in"); 1103 lmc_trace(dev, "lmc_runnig_reset in");
1172 1104
@@ -1184,7 +1116,7 @@ static void lmc_running_reset (struct net_device *dev) /*fold00*/
1184 netif_wake_queue(dev); 1116 netif_wake_queue(dev);
1185 1117
1186 sc->lmc_txfull = 0; 1118 sc->lmc_txfull = 0;
1187 sc->stats.tx_tbusy0++ ; 1119 sc->extra_stats.tx_tbusy0++;
1188 1120
1189 sc->lmc_intrmask = TULIP_DEFAULT_INTR_MASK; 1121 sc->lmc_intrmask = TULIP_DEFAULT_INTR_MASK;
1190 LMC_CSR_WRITE (sc, csr_intr, sc->lmc_intrmask); 1122 LMC_CSR_WRITE (sc, csr_intr, sc->lmc_intrmask);
@@ -1200,14 +1132,13 @@ static void lmc_running_reset (struct net_device *dev) /*fold00*/
1200 * This disables the timer for the watchdog and keepalives, 1132 * This disables the timer for the watchdog and keepalives,
1201 * and disables the irq for dev. 1133 * and disables the irq for dev.
1202 */ 1134 */
1203static int lmc_close (struct net_device *dev) /*fold00*/ 1135static int lmc_close(struct net_device *dev)
1204{ 1136{
1205 /* not calling release_region() as we should */ 1137 /* not calling release_region() as we should */
1206 lmc_softc_t *sc; 1138 lmc_softc_t *sc = dev_to_sc(dev);
1207 1139
1208 lmc_trace(dev, "lmc_close in"); 1140 lmc_trace(dev, "lmc_close in");
1209 1141
1210 sc = dev->priv;
1211 sc->lmc_ok = 0; 1142 sc->lmc_ok = 0;
1212 sc->lmc_media->set_link_status (sc, 0); 1143 sc->lmc_media->set_link_status (sc, 0);
1213 del_timer (&sc->timer); 1144 del_timer (&sc->timer);
@@ -1215,7 +1146,7 @@ static int lmc_close (struct net_device *dev) /*fold00*/
1215 lmc_ifdown (dev); 1146 lmc_ifdown (dev);
1216 1147
1217 lmc_trace(dev, "lmc_close out"); 1148 lmc_trace(dev, "lmc_close out");
1218 1149
1219 return 0; 1150 return 0;
1220} 1151}
1221 1152
@@ -1223,16 +1154,16 @@ static int lmc_close (struct net_device *dev) /*fold00*/
1223/* When the interface goes down, this is called */ 1154/* When the interface goes down, this is called */
1224static int lmc_ifdown (struct net_device *dev) /*fold00*/ 1155static int lmc_ifdown (struct net_device *dev) /*fold00*/
1225{ 1156{
1226 lmc_softc_t *sc = dev->priv; 1157 lmc_softc_t *sc = dev_to_sc(dev);
1227 u32 csr6; 1158 u32 csr6;
1228 int i; 1159 int i;
1229 1160
1230 lmc_trace(dev, "lmc_ifdown in"); 1161 lmc_trace(dev, "lmc_ifdown in");
1231 1162
1232 /* Don't let anything else go on right now */ 1163 /* Don't let anything else go on right now */
1233 // dev->start = 0; 1164 // dev->start = 0;
1234 netif_stop_queue(dev); 1165 netif_stop_queue(dev);
1235 sc->stats.tx_tbusy1++ ; 1166 sc->extra_stats.tx_tbusy1++;
1236 1167
1237 /* stop interrupts */ 1168 /* stop interrupts */
1238 /* Clear the interrupt mask */ 1169 /* Clear the interrupt mask */
@@ -1244,8 +1175,8 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
1244 csr6 &= ~LMC_DEC_SR; /* Turn off the Receive bit */ 1175 csr6 &= ~LMC_DEC_SR; /* Turn off the Receive bit */
1245 LMC_CSR_WRITE (sc, csr_command, csr6); 1176 LMC_CSR_WRITE (sc, csr_command, csr6);
1246 1177
1247 sc->stats.rx_missed_errors += 1178 sc->lmc_device->stats.rx_missed_errors +=
1248 LMC_CSR_READ (sc, csr_missed_frames) & 0xffff; 1179 LMC_CSR_READ(sc, csr_missed_frames) & 0xffff;
1249 1180
1250 /* release the interrupt */ 1181 /* release the interrupt */
1251 if(sc->got_irq == 1){ 1182 if(sc->got_irq == 1){
@@ -1276,7 +1207,7 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
1276 lmc_led_off (sc, LMC_MII16_LED_ALL); 1207 lmc_led_off (sc, LMC_MII16_LED_ALL);
1277 1208
1278 netif_wake_queue(dev); 1209 netif_wake_queue(dev);
1279 sc->stats.tx_tbusy0++ ; 1210 sc->extra_stats.tx_tbusy0++;
1280 1211
1281 lmc_trace(dev, "lmc_ifdown out"); 1212 lmc_trace(dev, "lmc_ifdown out");
1282 1213
@@ -1289,7 +1220,7 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
1289static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/ 1220static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
1290{ 1221{
1291 struct net_device *dev = (struct net_device *) dev_instance; 1222 struct net_device *dev = (struct net_device *) dev_instance;
1292 lmc_softc_t *sc; 1223 lmc_softc_t *sc = dev_to_sc(dev);
1293 u32 csr; 1224 u32 csr;
1294 int i; 1225 int i;
1295 s32 stat; 1226 s32 stat;
@@ -1300,8 +1231,6 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
1300 1231
1301 lmc_trace(dev, "lmc_interrupt in"); 1232 lmc_trace(dev, "lmc_interrupt in");
1302 1233
1303 sc = dev->priv;
1304
1305 spin_lock(&sc->lmc_lock); 1234 spin_lock(&sc->lmc_lock);
1306 1235
1307 /* 1236 /*
@@ -1354,7 +1283,7 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
1354 1283
1355 int n_compl = 0 ; 1284 int n_compl = 0 ;
1356 /* reset the transmit timeout detection flag -baz */ 1285 /* reset the transmit timeout detection flag -baz */
1357 sc->stats.tx_NoCompleteCnt = 0; 1286 sc->extra_stats.tx_NoCompleteCnt = 0;
1358 1287
1359 badtx = sc->lmc_taint_tx; 1288 badtx = sc->lmc_taint_tx;
1360 i = badtx % LMC_TXDESCS; 1289 i = badtx % LMC_TXDESCS;
@@ -1378,27 +1307,25 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
1378 if (sc->lmc_txq[i] == NULL) 1307 if (sc->lmc_txq[i] == NULL)
1379 continue; 1308 continue;
1380 1309
1381 /* 1310 /*
1382 * Check the total error summary to look for any errors 1311 * Check the total error summary to look for any errors
1383 */ 1312 */
1384 if (stat & 0x8000) { 1313 if (stat & 0x8000) {
1385 sc->stats.tx_errors++; 1314 sc->lmc_device->stats.tx_errors++;
1386 if (stat & 0x4104) 1315 if (stat & 0x4104)
1387 sc->stats.tx_aborted_errors++; 1316 sc->lmc_device->stats.tx_aborted_errors++;
1388 if (stat & 0x0C00) 1317 if (stat & 0x0C00)
1389 sc->stats.tx_carrier_errors++; 1318 sc->lmc_device->stats.tx_carrier_errors++;
1390 if (stat & 0x0200) 1319 if (stat & 0x0200)
1391 sc->stats.tx_window_errors++; 1320 sc->lmc_device->stats.tx_window_errors++;
1392 if (stat & 0x0002) 1321 if (stat & 0x0002)
1393 sc->stats.tx_fifo_errors++; 1322 sc->lmc_device->stats.tx_fifo_errors++;
1394 } 1323 } else {
1395 else { 1324 sc->lmc_device->stats.tx_bytes += sc->lmc_txring[i].length & 0x7ff;
1396 1325
1397 sc->stats.tx_bytes += sc->lmc_txring[i].length & 0x7ff; 1326 sc->lmc_device->stats.tx_packets++;
1398
1399 sc->stats.tx_packets++;
1400 } 1327 }
1401 1328
1402 // dev_kfree_skb(sc->lmc_txq[i]); 1329 // dev_kfree_skb(sc->lmc_txq[i]);
1403 dev_kfree_skb_irq(sc->lmc_txq[i]); 1330 dev_kfree_skb_irq(sc->lmc_txq[i]);
1404 sc->lmc_txq[i] = NULL; 1331 sc->lmc_txq[i] = NULL;
@@ -1415,13 +1342,13 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
1415 LMC_EVENT_LOG(LMC_EVENT_TBUSY0, n_compl, 0); 1342 LMC_EVENT_LOG(LMC_EVENT_TBUSY0, n_compl, 0);
1416 sc->lmc_txfull = 0; 1343 sc->lmc_txfull = 0;
1417 netif_wake_queue(dev); 1344 netif_wake_queue(dev);
1418 sc->stats.tx_tbusy0++ ; 1345 sc->extra_stats.tx_tbusy0++;
1419 1346
1420 1347
1421#ifdef DEBUG 1348#ifdef DEBUG
1422 sc->stats.dirtyTx = badtx; 1349 sc->extra_stats.dirtyTx = badtx;
1423 sc->stats.lmc_next_tx = sc->lmc_next_tx; 1350 sc->extra_stats.lmc_next_tx = sc->lmc_next_tx;
1424 sc->stats.lmc_txfull = sc->lmc_txfull; 1351 sc->extra_stats.lmc_txfull = sc->lmc_txfull;
1425#endif 1352#endif
1426 sc->lmc_taint_tx = badtx; 1353 sc->lmc_taint_tx = badtx;
1427 1354
@@ -1476,9 +1403,9 @@ lmc_int_fail_out:
1476 return IRQ_RETVAL(handled); 1403 return IRQ_RETVAL(handled);
1477} 1404}
1478 1405
1479static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00*/ 1406static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev)
1480{ 1407{
1481 lmc_softc_t *sc; 1408 lmc_softc_t *sc = dev_to_sc(dev);
1482 u32 flag; 1409 u32 flag;
1483 int entry; 1410 int entry;
1484 int ret = 0; 1411 int ret = 0;
@@ -1486,8 +1413,6 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
1486 1413
1487 lmc_trace(dev, "lmc_start_xmit in"); 1414 lmc_trace(dev, "lmc_start_xmit in");
1488 1415
1489 sc = dev->priv;
1490
1491 spin_lock_irqsave(&sc->lmc_lock, flags); 1416 spin_lock_irqsave(&sc->lmc_lock, flags);
1492 1417
1493 /* normal path, tbusy known to be zero */ 1418 /* normal path, tbusy known to be zero */
@@ -1532,8 +1457,8 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
1532 if (sc->lmc_next_tx - sc->lmc_taint_tx >= LMC_TXDESCS - 1) 1457 if (sc->lmc_next_tx - sc->lmc_taint_tx >= LMC_TXDESCS - 1)
1533 { /* ring full, go busy */ 1458 { /* ring full, go busy */
1534 sc->lmc_txfull = 1; 1459 sc->lmc_txfull = 1;
1535 netif_stop_queue(dev); 1460 netif_stop_queue(dev);
1536 sc->stats.tx_tbusy1++ ; 1461 sc->extra_stats.tx_tbusy1++;
1537 LMC_EVENT_LOG(LMC_EVENT_TBUSY1, entry, 0); 1462 LMC_EVENT_LOG(LMC_EVENT_TBUSY1, entry, 0);
1538 } 1463 }
1539#endif 1464#endif
@@ -1550,7 +1475,7 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
1550 * the watchdog timer handler. -baz 1475 * the watchdog timer handler. -baz
1551 */ 1476 */
1552 1477
1553 sc->stats.tx_NoCompleteCnt++; 1478 sc->extra_stats.tx_NoCompleteCnt++;
1554 sc->lmc_next_tx++; 1479 sc->lmc_next_tx++;
1555 1480
1556 /* give ownership to the chip */ 1481 /* give ownership to the chip */
@@ -1569,9 +1494,9 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
1569} 1494}
1570 1495
1571 1496
1572static int lmc_rx (struct net_device *dev) /*fold00*/ 1497static int lmc_rx(struct net_device *dev)
1573{ 1498{
1574 lmc_softc_t *sc; 1499 lmc_softc_t *sc = dev_to_sc(dev);
1575 int i; 1500 int i;
1576 int rx_work_limit = LMC_RXDESCS; 1501 int rx_work_limit = LMC_RXDESCS;
1577 unsigned int next_rx; 1502 unsigned int next_rx;
@@ -1583,8 +1508,6 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
1583 1508
1584 lmc_trace(dev, "lmc_rx in"); 1509 lmc_trace(dev, "lmc_rx in");
1585 1510
1586 sc = dev->priv;
1587
1588 lmc_led_on(sc, LMC_DS3_LED3); 1511 lmc_led_on(sc, LMC_DS3_LED3);
1589 1512
1590 rxIntLoopCnt = 0; /* debug -baz */ 1513 rxIntLoopCnt = 0; /* debug -baz */
@@ -1597,39 +1520,38 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
1597 rxIntLoopCnt++; /* debug -baz */ 1520 rxIntLoopCnt++; /* debug -baz */
1598 len = ((stat & LMC_RDES_FRAME_LENGTH) >> RDES_FRAME_LENGTH_BIT_NUMBER); 1521 len = ((stat & LMC_RDES_FRAME_LENGTH) >> RDES_FRAME_LENGTH_BIT_NUMBER);
1599 if ((stat & 0x0300) != 0x0300) { /* Check first segment and last segment */ 1522 if ((stat & 0x0300) != 0x0300) { /* Check first segment and last segment */
1600 if ((stat & 0x0000ffff) != 0x7fff) { 1523 if ((stat & 0x0000ffff) != 0x7fff) {
1601 /* Oversized frame */ 1524 /* Oversized frame */
1602 sc->stats.rx_length_errors++; 1525 sc->lmc_device->stats.rx_length_errors++;
1603 goto skip_packet; 1526 goto skip_packet;
1604 } 1527 }
1605 } 1528 }
1606
1607 if(stat & 0x00000008){ /* Catch a dribbling bit error */
1608 sc->stats.rx_errors++;
1609 sc->stats.rx_frame_errors++;
1610 goto skip_packet;
1611 }
1612 1529
1530 if (stat & 0x00000008) { /* Catch a dribbling bit error */
1531 sc->lmc_device->stats.rx_errors++;
1532 sc->lmc_device->stats.rx_frame_errors++;
1533 goto skip_packet;
1534 }
1613 1535
1614 if(stat & 0x00000004){ /* Catch a CRC error by the Xilinx */
1615 sc->stats.rx_errors++;
1616 sc->stats.rx_crc_errors++;
1617 goto skip_packet;
1618 }
1619 1536
1537 if (stat & 0x00000004) { /* Catch a CRC error by the Xilinx */
1538 sc->lmc_device->stats.rx_errors++;
1539 sc->lmc_device->stats.rx_crc_errors++;
1540 goto skip_packet;
1541 }
1620 1542
1621 if (len > LMC_PKT_BUF_SZ){ 1543 if (len > LMC_PKT_BUF_SZ) {
1622 sc->stats.rx_length_errors++; 1544 sc->lmc_device->stats.rx_length_errors++;
1623 localLengthErrCnt++; 1545 localLengthErrCnt++;
1624 goto skip_packet; 1546 goto skip_packet;
1625 } 1547 }
1626 1548
1627 if (len < sc->lmc_crcSize + 2) { 1549 if (len < sc->lmc_crcSize + 2) {
1628 sc->stats.rx_length_errors++; 1550 sc->lmc_device->stats.rx_length_errors++;
1629 sc->stats.rx_SmallPktCnt++; 1551 sc->extra_stats.rx_SmallPktCnt++;
1630 localLengthErrCnt++; 1552 localLengthErrCnt++;
1631 goto skip_packet; 1553 goto skip_packet;
1632 } 1554 }
1633 1555
1634 if(stat & 0x00004000){ 1556 if(stat & 0x00004000){
1635 printk(KERN_WARNING "%s: Receiver descriptor error, receiver out of sync?\n", dev->name); 1557 printk(KERN_WARNING "%s: Receiver descriptor error, receiver out of sync?\n", dev->name);
@@ -1656,8 +1578,8 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
1656 } 1578 }
1657 1579
1658 dev->last_rx = jiffies; 1580 dev->last_rx = jiffies;
1659 sc->stats.rx_packets++; 1581 sc->lmc_device->stats.rx_packets++;
1660 sc->stats.rx_bytes += len; 1582 sc->lmc_device->stats.rx_bytes += len;
1661 1583
1662 LMC_CONSOLE_LOG("recv", skb->data, len); 1584 LMC_CONSOLE_LOG("recv", skb->data, len);
1663 1585
@@ -1679,7 +1601,6 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
1679 1601
1680 skb_put (skb, len); 1602 skb_put (skb, len);
1681 skb->protocol = lmc_proto_type(sc, skb); 1603 skb->protocol = lmc_proto_type(sc, skb);
1682 skb->protocol = htons(ETH_P_WAN_PPP);
1683 skb_reset_mac_header(skb); 1604 skb_reset_mac_header(skb);
1684 /* skb_reset_network_header(skb); */ 1605 /* skb_reset_network_header(skb); */
1685 skb->dev = dev; 1606 skb->dev = dev;
@@ -1704,7 +1625,7 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
1704 * in which care we'll try to allocate the buffer 1625 * in which care we'll try to allocate the buffer
1705 * again. (once a second) 1626 * again. (once a second)
1706 */ 1627 */
1707 sc->stats.rx_BuffAllocErr++; 1628 sc->extra_stats.rx_BuffAllocErr++;
1708 LMC_EVENT_LOG(LMC_EVENT_RCVINT, stat, len); 1629 LMC_EVENT_LOG(LMC_EVENT_RCVINT, stat, len);
1709 sc->failed_recv_alloc = 1; 1630 sc->failed_recv_alloc = 1;
1710 goto skip_out_of_mem; 1631 goto skip_out_of_mem;
@@ -1739,16 +1660,14 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
1739 * descriptors with bogus packets 1660 * descriptors with bogus packets
1740 * 1661 *
1741 if (localLengthErrCnt > LMC_RXDESCS - 3) { 1662 if (localLengthErrCnt > LMC_RXDESCS - 3) {
1742 sc->stats.rx_BadPktSurgeCnt++; 1663 sc->extra_stats.rx_BadPktSurgeCnt++;
1743 LMC_EVENT_LOG(LMC_EVENT_BADPKTSURGE, 1664 LMC_EVENT_LOG(LMC_EVENT_BADPKTSURGE, localLengthErrCnt,
1744 localLengthErrCnt, 1665 sc->extra_stats.rx_BadPktSurgeCnt);
1745 sc->stats.rx_BadPktSurgeCnt);
1746 } */ 1666 } */
1747 1667
1748 /* save max count of receive descriptors serviced */ 1668 /* save max count of receive descriptors serviced */
1749 if (rxIntLoopCnt > sc->stats.rxIntLoopCnt) { 1669 if (rxIntLoopCnt > sc->extra_stats.rxIntLoopCnt)
1750 sc->stats.rxIntLoopCnt = rxIntLoopCnt; /* debug -baz */ 1670 sc->extra_stats.rxIntLoopCnt = rxIntLoopCnt; /* debug -baz */
1751 }
1752 1671
1753#ifdef DEBUG 1672#ifdef DEBUG
1754 if (rxIntLoopCnt == 0) 1673 if (rxIntLoopCnt == 0)
@@ -1775,23 +1694,22 @@ skip_out_of_mem:
1775 return 0; 1694 return 0;
1776} 1695}
1777 1696
1778static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/ 1697static struct net_device_stats *lmc_get_stats(struct net_device *dev)
1779{ 1698{
1780 lmc_softc_t *sc = dev->priv; 1699 lmc_softc_t *sc = dev_to_sc(dev);
1781 unsigned long flags; 1700 unsigned long flags;
1782 1701
1783 lmc_trace(dev, "lmc_get_stats in"); 1702 lmc_trace(dev, "lmc_get_stats in");
1784 1703
1785
1786 spin_lock_irqsave(&sc->lmc_lock, flags); 1704 spin_lock_irqsave(&sc->lmc_lock, flags);
1787 1705
1788 sc->stats.rx_missed_errors += LMC_CSR_READ (sc, csr_missed_frames) & 0xffff; 1706 sc->lmc_device->stats.rx_missed_errors += LMC_CSR_READ(sc, csr_missed_frames) & 0xffff;
1789 1707
1790 spin_unlock_irqrestore(&sc->lmc_lock, flags); 1708 spin_unlock_irqrestore(&sc->lmc_lock, flags);
1791 1709
1792 lmc_trace(dev, "lmc_get_stats out"); 1710 lmc_trace(dev, "lmc_get_stats out");
1793 1711
1794 return (struct net_device_stats *) &sc->stats; 1712 return &sc->lmc_device->stats;
1795} 1713}
1796 1714
1797static struct pci_driver lmc_driver = { 1715static struct pci_driver lmc_driver = {
@@ -1970,7 +1888,7 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
1970 { 1888 {
1971 if (sc->lmc_txq[i] != NULL){ /* have buffer */ 1889 if (sc->lmc_txq[i] != NULL){ /* have buffer */
1972 dev_kfree_skb(sc->lmc_txq[i]); /* free it */ 1890 dev_kfree_skb(sc->lmc_txq[i]); /* free it */
1973 sc->stats.tx_dropped++; /* We just dropped a packet */ 1891 sc->lmc_device->stats.tx_dropped++; /* We just dropped a packet */
1974 } 1892 }
1975 sc->lmc_txq[i] = NULL; 1893 sc->lmc_txq[i] = NULL;
1976 sc->lmc_txring[i].status = 0x00000000; 1894 sc->lmc_txring[i].status = 0x00000000;
@@ -1982,7 +1900,7 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
1982 lmc_trace(sc->lmc_device, "lmc_softreset out"); 1900 lmc_trace(sc->lmc_device, "lmc_softreset out");
1983} 1901}
1984 1902
1985void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/ 1903void lmc_gpio_mkinput(lmc_softc_t * const sc, u32 bits) /*fold00*/
1986{ 1904{
1987 lmc_trace(sc->lmc_device, "lmc_gpio_mkinput in"); 1905 lmc_trace(sc->lmc_device, "lmc_gpio_mkinput in");
1988 sc->lmc_gpio_io &= ~bits; 1906 sc->lmc_gpio_io &= ~bits;
@@ -1990,7 +1908,7 @@ void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
1990 lmc_trace(sc->lmc_device, "lmc_gpio_mkinput out"); 1908 lmc_trace(sc->lmc_device, "lmc_gpio_mkinput out");
1991} 1909}
1992 1910
1993void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/ 1911void lmc_gpio_mkoutput(lmc_softc_t * const sc, u32 bits) /*fold00*/
1994{ 1912{
1995 lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput in"); 1913 lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput in");
1996 sc->lmc_gpio_io |= bits; 1914 sc->lmc_gpio_io |= bits;
@@ -1998,7 +1916,7 @@ void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
1998 lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput out"); 1916 lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput out");
1999} 1917}
2000 1918
2001void lmc_led_on(lmc_softc_t * const sc, u_int32_t led) /*fold00*/ 1919void lmc_led_on(lmc_softc_t * const sc, u32 led) /*fold00*/
2002{ 1920{
2003 lmc_trace(sc->lmc_device, "lmc_led_on in"); 1921 lmc_trace(sc->lmc_device, "lmc_led_on in");
2004 if((~sc->lmc_miireg16) & led){ /* Already on! */ 1922 if((~sc->lmc_miireg16) & led){ /* Already on! */
@@ -2011,7 +1929,7 @@ void lmc_led_on(lmc_softc_t * const sc, u_int32_t led) /*fold00*/
2011 lmc_trace(sc->lmc_device, "lmc_led_on out"); 1929 lmc_trace(sc->lmc_device, "lmc_led_on out");
2012} 1930}
2013 1931
2014void lmc_led_off(lmc_softc_t * const sc, u_int32_t led) /*fold00*/ 1932void lmc_led_off(lmc_softc_t * const sc, u32 led) /*fold00*/
2015{ 1933{
2016 lmc_trace(sc->lmc_device, "lmc_led_off in"); 1934 lmc_trace(sc->lmc_device, "lmc_led_off in");
2017 if(sc->lmc_miireg16 & led){ /* Already set don't do anything */ 1935 if(sc->lmc_miireg16 & led){ /* Already set don't do anything */
@@ -2061,13 +1979,13 @@ static void lmc_reset(lmc_softc_t * const sc) /*fold00*/
2061 */ 1979 */
2062 sc->lmc_media->init(sc); 1980 sc->lmc_media->init(sc);
2063 1981
2064 sc->stats.resetCount++; 1982 sc->extra_stats.resetCount++;
2065 lmc_trace(sc->lmc_device, "lmc_reset out"); 1983 lmc_trace(sc->lmc_device, "lmc_reset out");
2066} 1984}
2067 1985
2068static void lmc_dec_reset(lmc_softc_t * const sc) /*fold00*/ 1986static void lmc_dec_reset(lmc_softc_t * const sc) /*fold00*/
2069{ 1987{
2070 u_int32_t val; 1988 u32 val;
2071 lmc_trace(sc->lmc_device, "lmc_dec_reset in"); 1989 lmc_trace(sc->lmc_device, "lmc_dec_reset in");
2072 1990
2073 /* 1991 /*
@@ -2151,23 +2069,21 @@ static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, /*fold00
2151 lmc_trace(sc->lmc_device, "lmc_initcsrs out"); 2069 lmc_trace(sc->lmc_device, "lmc_initcsrs out");
2152} 2070}
2153 2071
2154static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/ 2072static void lmc_driver_timeout(struct net_device *dev)
2155 lmc_softc_t *sc; 2073{
2074 lmc_softc_t *sc = dev_to_sc(dev);
2156 u32 csr6; 2075 u32 csr6;
2157 unsigned long flags; 2076 unsigned long flags;
2158 2077
2159 lmc_trace(dev, "lmc_driver_timeout in"); 2078 lmc_trace(dev, "lmc_driver_timeout in");
2160 2079
2161 sc = dev->priv;
2162
2163 spin_lock_irqsave(&sc->lmc_lock, flags); 2080 spin_lock_irqsave(&sc->lmc_lock, flags);
2164 2081
2165 printk("%s: Xmitter busy|\n", dev->name); 2082 printk("%s: Xmitter busy|\n", dev->name);
2166 2083
2167 sc->stats.tx_tbusy_calls++ ; 2084 sc->extra_stats.tx_tbusy_calls++;
2168 if (jiffies - dev->trans_start < TX_TIMEOUT) { 2085 if (jiffies - dev->trans_start < TX_TIMEOUT)
2169 goto bug_out; 2086 goto bug_out;
2170 }
2171 2087
2172 /* 2088 /*
2173 * Chip seems to have locked up 2089 * Chip seems to have locked up
@@ -2178,7 +2094,7 @@ static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/
2178 2094
2179 LMC_EVENT_LOG(LMC_EVENT_XMTPRCTMO, 2095 LMC_EVENT_LOG(LMC_EVENT_XMTPRCTMO,
2180 LMC_CSR_READ (sc, csr_status), 2096 LMC_CSR_READ (sc, csr_status),
2181 sc->stats.tx_ProcTimeout); 2097 sc->extra_stats.tx_ProcTimeout);
2182 2098
2183 lmc_running_reset (dev); 2099 lmc_running_reset (dev);
2184 2100
@@ -2195,8 +2111,8 @@ static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/
2195 /* immediate transmit */ 2111 /* immediate transmit */
2196 LMC_CSR_WRITE (sc, csr_txpoll, 0); 2112 LMC_CSR_WRITE (sc, csr_txpoll, 0);
2197 2113
2198 sc->stats.tx_errors++; 2114 sc->lmc_device->stats.tx_errors++;
2199 sc->stats.tx_ProcTimeout++; /* -baz */ 2115 sc->extra_stats.tx_ProcTimeout++; /* -baz */
2200 2116
2201 dev->trans_start = jiffies; 2117 dev->trans_start = jiffies;
2202 2118
diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
index 8aa461c941ce..f327674fc93a 100644
--- a/drivers/net/wan/lmc/lmc_media.c
+++ b/drivers/net/wan/lmc/lmc_media.c
@@ -16,8 +16,6 @@
16#include <linux/inet.h> 16#include <linux/inet.h>
17#include <linux/bitops.h> 17#include <linux/bitops.h>
18 18
19#include <net/syncppp.h>
20
21#include <asm/processor.h> /* Processor type for cache alignment. */ 19#include <asm/processor.h> /* Processor type for cache alignment. */
22#include <asm/io.h> 20#include <asm/io.h>
23#include <asm/dma.h> 21#include <asm/dma.h>
@@ -95,8 +93,7 @@ static void lmc_dummy_set_1 (lmc_softc_t * const, int);
95static void lmc_dummy_set2_1 (lmc_softc_t * const, lmc_ctl_t *); 93static void lmc_dummy_set2_1 (lmc_softc_t * const, lmc_ctl_t *);
96 94
97static inline void write_av9110_bit (lmc_softc_t *, int); 95static inline void write_av9110_bit (lmc_softc_t *, int);
98static void write_av9110 (lmc_softc_t *, u_int32_t, u_int32_t, u_int32_t, 96static void write_av9110(lmc_softc_t *, u32, u32, u32, u32, u32);
99 u_int32_t, u_int32_t);
100 97
101lmc_media_t lmc_ds3_media = { 98lmc_media_t lmc_ds3_media = {
102 lmc_ds3_init, /* special media init stuff */ 99 lmc_ds3_init, /* special media init stuff */
@@ -427,7 +424,7 @@ lmc_ds3_set_scram (lmc_softc_t * const sc, int ie)
427static int 424static int
428lmc_ds3_get_link_status (lmc_softc_t * const sc) 425lmc_ds3_get_link_status (lmc_softc_t * const sc)
429{ 426{
430 u_int16_t link_status, link_status_11; 427 u16 link_status, link_status_11;
431 int ret = 1; 428 int ret = 1;
432 429
433 lmc_mii_writereg (sc, 0, 17, 7); 430 lmc_mii_writereg (sc, 0, 17, 7);
@@ -449,7 +446,7 @@ lmc_ds3_get_link_status (lmc_softc_t * const sc)
449 (link_status & LMC_FRAMER_REG0_OOFS)){ 446 (link_status & LMC_FRAMER_REG0_OOFS)){
450 ret = 0; 447 ret = 0;
451 if(sc->last_led_err[3] != 1){ 448 if(sc->last_led_err[3] != 1){
452 u16 r1; 449 u16 r1;
453 lmc_mii_writereg (sc, 0, 17, 01); /* Turn on Xbit error as our cisco does */ 450 lmc_mii_writereg (sc, 0, 17, 01); /* Turn on Xbit error as our cisco does */
454 r1 = lmc_mii_readreg (sc, 0, 18); 451 r1 = lmc_mii_readreg (sc, 0, 18);
455 r1 &= 0xfe; 452 r1 &= 0xfe;
@@ -462,7 +459,7 @@ lmc_ds3_get_link_status (lmc_softc_t * const sc)
462 else { 459 else {
463 lmc_led_off(sc, LMC_DS3_LED3); /* turn on red LED */ 460 lmc_led_off(sc, LMC_DS3_LED3); /* turn on red LED */
464 if(sc->last_led_err[3] == 1){ 461 if(sc->last_led_err[3] == 1){
465 u16 r1; 462 u16 r1;
466 lmc_mii_writereg (sc, 0, 17, 01); /* Turn off Xbit error */ 463 lmc_mii_writereg (sc, 0, 17, 01); /* Turn off Xbit error */
467 r1 = lmc_mii_readreg (sc, 0, 18); 464 r1 = lmc_mii_readreg (sc, 0, 18);
468 r1 |= 0x01; 465 r1 |= 0x01;
@@ -540,20 +537,19 @@ lmc_ds3_watchdog (lmc_softc_t * const sc)
540 * SSI methods 537 * SSI methods
541 */ 538 */
542 539
543static void 540static void lmc_ssi_init(lmc_softc_t * const sc)
544lmc_ssi_init (lmc_softc_t * const sc)
545{ 541{
546 u_int16_t mii17; 542 u16 mii17;
547 int cable; 543 int cable;
548 544
549 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1000; 545 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1000;
550 546
551 mii17 = lmc_mii_readreg (sc, 0, 17); 547 mii17 = lmc_mii_readreg(sc, 0, 17);
552 548
553 cable = (mii17 & LMC_MII17_SSI_CABLE_MASK) >> LMC_MII17_SSI_CABLE_SHIFT; 549 cable = (mii17 & LMC_MII17_SSI_CABLE_MASK) >> LMC_MII17_SSI_CABLE_SHIFT;
554 sc->ictl.cable_type = cable; 550 sc->ictl.cable_type = cable;
555 551
556 lmc_gpio_mkoutput (sc, LMC_GEP_SSI_TXCLOCK); 552 lmc_gpio_mkoutput(sc, LMC_GEP_SSI_TXCLOCK);
557} 553}
558 554
559static void 555static void
@@ -681,11 +677,11 @@ lmc_ssi_set_speed (lmc_softc_t * const sc, lmc_ctl_t * ctl)
681static int 677static int
682lmc_ssi_get_link_status (lmc_softc_t * const sc) 678lmc_ssi_get_link_status (lmc_softc_t * const sc)
683{ 679{
684 u_int16_t link_status; 680 u16 link_status;
685 u_int32_t ticks; 681 u32 ticks;
686 int ret = 1; 682 int ret = 1;
687 int hw_hdsk = 1; 683 int hw_hdsk = 1;
688 684
689 /* 685 /*
690 * missing CTS? Hmm. If we require CTS on, we may never get the 686 * missing CTS? Hmm. If we require CTS on, we may never get the
691 * link to come up, so omit it in this test. 687 * link to come up, so omit it in this test.
@@ -720,9 +716,9 @@ lmc_ssi_get_link_status (lmc_softc_t * const sc)
720 } 716 }
721 else if (ticks == 0 ) { /* no clock found ? */ 717 else if (ticks == 0 ) { /* no clock found ? */
722 ret = 0; 718 ret = 0;
723 if(sc->last_led_err[3] != 1){ 719 if (sc->last_led_err[3] != 1) {
724 sc->stats.tx_lossOfClockCnt++; 720 sc->extra_stats.tx_lossOfClockCnt++;
725 printk(KERN_WARNING "%s: Lost Clock, Link Down\n", sc->name); 721 printk(KERN_WARNING "%s: Lost Clock, Link Down\n", sc->name);
726 } 722 }
727 sc->last_led_err[3] = 1; 723 sc->last_led_err[3] = 1;
728 lmc_led_on (sc, LMC_MII16_LED3); /* turn ON red LED */ 724 lmc_led_on (sc, LMC_MII16_LED3); /* turn ON red LED */
@@ -838,9 +834,7 @@ write_av9110_bit (lmc_softc_t * sc, int c)
838 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio); 834 LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
839} 835}
840 836
841static void 837static void write_av9110(lmc_softc_t *sc, u32 n, u32 m, u32 v, u32 x, u32 r)
842write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v,
843 u_int32_t x, u_int32_t r)
844{ 838{
845 int i; 839 int i;
846 840
@@ -887,19 +881,13 @@ write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v,
887 | LMC_GEP_SSI_GENERATOR)); 881 | LMC_GEP_SSI_GENERATOR));
888} 882}
889 883
890static void 884static void lmc_ssi_watchdog(lmc_softc_t * const sc)
891lmc_ssi_watchdog (lmc_softc_t * const sc)
892{ 885{
893 u_int16_t mii17 = lmc_mii_readreg (sc, 0, 17); 886 u16 mii17 = lmc_mii_readreg(sc, 0, 17);
894 if (((mii17 >> 3) & 7) == 7) 887 if (((mii17 >> 3) & 7) == 7)
895 { 888 lmc_led_off(sc, LMC_MII16_LED2);
896 lmc_led_off (sc, LMC_MII16_LED2); 889 else
897 } 890 lmc_led_on(sc, LMC_MII16_LED2);
898 else
899 {
900 lmc_led_on (sc, LMC_MII16_LED2);
901 }
902
903} 891}
904 892
905/* 893/*
@@ -929,7 +917,7 @@ lmc_t1_read (lmc_softc_t * const sc, int a)
929static void 917static void
930lmc_t1_init (lmc_softc_t * const sc) 918lmc_t1_init (lmc_softc_t * const sc)
931{ 919{
932 u_int16_t mii16; 920 u16 mii16;
933 int i; 921 int i;
934 922
935 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1200; 923 sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1200;
@@ -1028,7 +1016,7 @@ lmc_t1_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl)
1028 */ static int 1016 */ static int
1029lmc_t1_get_link_status (lmc_softc_t * const sc) 1017lmc_t1_get_link_status (lmc_softc_t * const sc)
1030{ 1018{
1031 u_int16_t link_status; 1019 u16 link_status;
1032 int ret = 1; 1020 int ret = 1;
1033 1021
1034 /* LMC5245 (DS3) & LMC1200 (DS1) LED definitions 1022 /* LMC5245 (DS3) & LMC1200 (DS1) LED definitions
diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
index 85315758198d..be9877ff551e 100644
--- a/drivers/net/wan/lmc/lmc_proto.c
+++ b/drivers/net/wan/lmc/lmc_proto.c
@@ -36,9 +36,6 @@
36#include <linux/workqueue.h> 36#include <linux/workqueue.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/bitops.h> 38#include <linux/bitops.h>
39
40#include <net/syncppp.h>
41
42#include <asm/processor.h> /* Processor type for cache alignment. */ 39#include <asm/processor.h> /* Processor type for cache alignment. */
43#include <asm/io.h> 40#include <asm/io.h>
44#include <asm/dma.h> 41#include <asm/dma.h>
@@ -50,48 +47,6 @@
50#include "lmc_ioctl.h" 47#include "lmc_ioctl.h"
51#include "lmc_proto.h" 48#include "lmc_proto.h"
52 49
53/*
54 * The compile-time variable SPPPSTUP causes the module to be
55 * compiled without referencing any of the sync ppp routines.
56 */
57#ifdef SPPPSTUB
58#define SPPP_detach(d) (void)0
59#define SPPP_open(d) 0
60#define SPPP_reopen(d) (void)0
61#define SPPP_close(d) (void)0
62#define SPPP_attach(d) (void)0
63#define SPPP_do_ioctl(d,i,c) -EOPNOTSUPP
64#else
65#define SPPP_attach(x) sppp_attach((x)->pd)
66#define SPPP_detach(x) sppp_detach((x)->pd->dev)
67#define SPPP_open(x) sppp_open((x)->pd->dev)
68#define SPPP_reopen(x) sppp_reopen((x)->pd->dev)
69#define SPPP_close(x) sppp_close((x)->pd->dev)
70#define SPPP_do_ioctl(x, y, z) sppp_do_ioctl((x)->pd->dev, (y), (z))
71#endif
72
73// init
74void lmc_proto_init(lmc_softc_t *sc) /*FOLD00*/
75{
76 lmc_trace(sc->lmc_device, "lmc_proto_init in");
77 switch(sc->if_type){
78 case LMC_PPP:
79 sc->pd = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
80 if (!sc->pd) {
81 printk("lmc_proto_init(): kmalloc failure!\n");
82 return;
83 }
84 sc->pd->dev = sc->lmc_device;
85 sc->if_ptr = sc->pd;
86 break;
87 case LMC_RAW:
88 break;
89 default:
90 break;
91 }
92 lmc_trace(sc->lmc_device, "lmc_proto_init out");
93}
94
95// attach 50// attach
96void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/ 51void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
97{ 52{
@@ -100,7 +55,6 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
100 case LMC_PPP: 55 case LMC_PPP:
101 { 56 {
102 struct net_device *dev = sc->lmc_device; 57 struct net_device *dev = sc->lmc_device;
103 SPPP_attach(sc);
104 dev->do_ioctl = lmc_ioctl; 58 dev->do_ioctl = lmc_ioctl;
105 } 59 }
106 break; 60 break;
@@ -108,7 +62,7 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
108 { 62 {
109 struct net_device *dev = sc->lmc_device; 63 struct net_device *dev = sc->lmc_device;
110 /* 64 /*
111 * They set a few basics because they don't use sync_ppp 65 * They set a few basics because they don't use HDLC
112 */ 66 */
113 dev->flags |= IFF_POINTOPOINT; 67 dev->flags |= IFF_POINTOPOINT;
114 68
@@ -124,88 +78,39 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
124 lmc_trace(sc->lmc_device, "lmc_proto_attach out"); 78 lmc_trace(sc->lmc_device, "lmc_proto_attach out");
125} 79}
126 80
127// detach 81int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd)
128void lmc_proto_detach(lmc_softc_t *sc) /*FOLD00*/
129{ 82{
130 switch(sc->if_type){ 83 lmc_trace(sc->lmc_device, "lmc_proto_ioctl");
131 case LMC_PPP: 84 if (sc->if_type == LMC_PPP)
132 SPPP_detach(sc); 85 return hdlc_ioctl(sc->lmc_device, ifr, cmd);
133 break; 86 return -EOPNOTSUPP;
134 case LMC_RAW: /* Tell someone we're detaching? */
135 break;
136 default:
137 break;
138 }
139
140} 87}
141 88
142// reopen 89int lmc_proto_open(lmc_softc_t *sc)
143void lmc_proto_reopen(lmc_softc_t *sc) /*FOLD00*/
144{ 90{
145 lmc_trace(sc->lmc_device, "lmc_proto_reopen in"); 91 int ret = 0;
146 switch(sc->if_type){
147 case LMC_PPP:
148 SPPP_reopen(sc);
149 break;
150 case LMC_RAW: /* Reset the interface after being down, prerape to receive packets again */
151 break;
152 default:
153 break;
154 }
155 lmc_trace(sc->lmc_device, "lmc_proto_reopen out");
156}
157 92
93 lmc_trace(sc->lmc_device, "lmc_proto_open in");
158 94
159// ioctl 95 if (sc->if_type == LMC_PPP) {
160int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd) /*FOLD00*/ 96 ret = hdlc_open(sc->lmc_device);
161{ 97 if (ret < 0)
162 lmc_trace(sc->lmc_device, "lmc_proto_ioctl out"); 98 printk(KERN_WARNING "%s: HDLC open failed: %d\n",
163 switch(sc->if_type){ 99 sc->name, ret);
164 case LMC_PPP: 100 }
165 return SPPP_do_ioctl (sc, ifr, cmd); 101
166 break; 102 lmc_trace(sc->lmc_device, "lmc_proto_open out");
167 default: 103 return ret;
168 return -EOPNOTSUPP;
169 break;
170 }
171 lmc_trace(sc->lmc_device, "lmc_proto_ioctl out");
172} 104}
173 105
174// open 106void lmc_proto_close(lmc_softc_t *sc)
175void lmc_proto_open(lmc_softc_t *sc) /*FOLD00*/
176{ 107{
177 int ret; 108 lmc_trace(sc->lmc_device, "lmc_proto_close in");
178 109
179 lmc_trace(sc->lmc_device, "lmc_proto_open in"); 110 if (sc->if_type == LMC_PPP)
180 switch(sc->if_type){ 111 hdlc_close(sc->lmc_device);
181 case LMC_PPP:
182 ret = SPPP_open(sc);
183 if(ret < 0)
184 printk("%s: syncPPP open failed: %d\n", sc->name, ret);
185 break;
186 case LMC_RAW: /* We're about to start getting packets! */
187 break;
188 default:
189 break;
190 }
191 lmc_trace(sc->lmc_device, "lmc_proto_open out");
192}
193
194// close
195 112
196void lmc_proto_close(lmc_softc_t *sc) /*FOLD00*/ 113 lmc_trace(sc->lmc_device, "lmc_proto_close out");
197{
198 lmc_trace(sc->lmc_device, "lmc_proto_close in");
199 switch(sc->if_type){
200 case LMC_PPP:
201 SPPP_close(sc);
202 break;
203 case LMC_RAW: /* Interface going down */
204 break;
205 default:
206 break;
207 }
208 lmc_trace(sc->lmc_device, "lmc_proto_close out");
209} 114}
210 115
211__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/ 116__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
@@ -213,8 +118,8 @@ __be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
213 lmc_trace(sc->lmc_device, "lmc_proto_type in"); 118 lmc_trace(sc->lmc_device, "lmc_proto_type in");
214 switch(sc->if_type){ 119 switch(sc->if_type){
215 case LMC_PPP: 120 case LMC_PPP:
216 return htons(ETH_P_WAN_PPP); 121 return hdlc_type_trans(skb, sc->lmc_device);
217 break; 122 break;
218 case LMC_NET: 123 case LMC_NET:
219 return htons(ETH_P_802_2); 124 return htons(ETH_P_802_2);
220 break; 125 break;
@@ -245,4 +150,3 @@ void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
245 } 150 }
246 lmc_trace(sc->lmc_device, "lmc_proto_netif out"); 151 lmc_trace(sc->lmc_device, "lmc_proto_netif out");
247} 152}
248
diff --git a/drivers/net/wan/lmc/lmc_proto.h b/drivers/net/wan/lmc/lmc_proto.h
index ccaa69e8b3c7..662148c54644 100644
--- a/drivers/net/wan/lmc/lmc_proto.h
+++ b/drivers/net/wan/lmc/lmc_proto.h
@@ -1,16 +1,18 @@
1#ifndef _LMC_PROTO_H_ 1#ifndef _LMC_PROTO_H_
2#define _LMC_PROTO_H_ 2#define _LMC_PROTO_H_
3 3
4void lmc_proto_init(lmc_softc_t *sc); 4#include <linux/hdlc.h>
5
5void lmc_proto_attach(lmc_softc_t *sc); 6void lmc_proto_attach(lmc_softc_t *sc);
6void lmc_proto_detach(lmc_softc_t *sc);
7void lmc_proto_reopen(lmc_softc_t *sc);
8int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd); 7int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd);
9void lmc_proto_open(lmc_softc_t *sc); 8int lmc_proto_open(lmc_softc_t *sc);
10void lmc_proto_close(lmc_softc_t *sc); 9void lmc_proto_close(lmc_softc_t *sc);
11__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb); 10__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
12void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb); 11void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb);
13int lmc_skb_rawpackets(char *buf, char **start, off_t offset, int len, int unused);
14 12
15#endif 13static inline lmc_softc_t* dev_to_sc(struct net_device *dev)
14{
15 return (lmc_softc_t *)dev_to_hdlc(dev)->priv;
16}
16 17
18#endif
diff --git a/drivers/net/wan/lmc/lmc_var.h b/drivers/net/wan/lmc/lmc_var.h
index 6d003a39bfad..65d01978e784 100644
--- a/drivers/net/wan/lmc/lmc_var.h
+++ b/drivers/net/wan/lmc/lmc_var.h
@@ -1,8 +1,6 @@
1#ifndef _LMC_VAR_H_ 1#ifndef _LMC_VAR_H_
2#define _LMC_VAR_H_ 2#define _LMC_VAR_H_
3 3
4/* $Id: lmc_var.h,v 1.17 2000/04/06 12:16:47 asj Exp $ */
5
6 /* 4 /*
7 * Copyright (c) 1997-2000 LAN Media Corporation (LMC) 5 * Copyright (c) 1997-2000 LAN Media Corporation (LMC)
8 * All rights reserved. www.lanmedia.com 6 * All rights reserved. www.lanmedia.com
@@ -19,23 +17,6 @@
19 17
20#include <linux/timer.h> 18#include <linux/timer.h>
21 19
22#ifndef __KERNEL__
23typedef signed char s8;
24typedef unsigned char u8;
25
26typedef signed short s16;
27typedef unsigned short u16;
28
29typedef signed int s32;
30typedef unsigned int u32;
31
32typedef signed long long s64;
33typedef unsigned long long u64;
34
35#define BITS_PER_LONG 32
36
37#endif
38
39/* 20/*
40 * basic definitions used in lmc include files 21 * basic definitions used in lmc include files
41 */ 22 */
@@ -45,9 +26,6 @@ typedef struct lmc___media lmc_media_t;
45typedef struct lmc___ctl lmc_ctl_t; 26typedef struct lmc___ctl lmc_ctl_t;
46 27
47#define lmc_csrptr_t unsigned long 28#define lmc_csrptr_t unsigned long
48#define u_int16_t u16
49#define u_int8_t u8
50#define tulip_uint32_t u32
51 29
52#define LMC_REG_RANGE 0x80 30#define LMC_REG_RANGE 0x80
53 31
@@ -122,45 +100,45 @@ struct lmc_regfile_t {
122 * used to define bits in the second tulip_desc_t field (length) 100 * used to define bits in the second tulip_desc_t field (length)
123 * for the transmit descriptor -baz */ 101 * for the transmit descriptor -baz */
124 102
125#define LMC_TDES_FIRST_BUFFER_SIZE ((u_int32_t)(0x000007FF)) 103#define LMC_TDES_FIRST_BUFFER_SIZE ((u32)(0x000007FF))
126#define LMC_TDES_SECOND_BUFFER_SIZE ((u_int32_t)(0x003FF800)) 104#define LMC_TDES_SECOND_BUFFER_SIZE ((u32)(0x003FF800))
127#define LMC_TDES_HASH_FILTERING ((u_int32_t)(0x00400000)) 105#define LMC_TDES_HASH_FILTERING ((u32)(0x00400000))
128#define LMC_TDES_DISABLE_PADDING ((u_int32_t)(0x00800000)) 106#define LMC_TDES_DISABLE_PADDING ((u32)(0x00800000))
129#define LMC_TDES_SECOND_ADDR_CHAINED ((u_int32_t)(0x01000000)) 107#define LMC_TDES_SECOND_ADDR_CHAINED ((u32)(0x01000000))
130#define LMC_TDES_END_OF_RING ((u_int32_t)(0x02000000)) 108#define LMC_TDES_END_OF_RING ((u32)(0x02000000))
131#define LMC_TDES_ADD_CRC_DISABLE ((u_int32_t)(0x04000000)) 109#define LMC_TDES_ADD_CRC_DISABLE ((u32)(0x04000000))
132#define LMC_TDES_SETUP_PACKET ((u_int32_t)(0x08000000)) 110#define LMC_TDES_SETUP_PACKET ((u32)(0x08000000))
133#define LMC_TDES_INVERSE_FILTERING ((u_int32_t)(0x10000000)) 111#define LMC_TDES_INVERSE_FILTERING ((u32)(0x10000000))
134#define LMC_TDES_FIRST_SEGMENT ((u_int32_t)(0x20000000)) 112#define LMC_TDES_FIRST_SEGMENT ((u32)(0x20000000))
135#define LMC_TDES_LAST_SEGMENT ((u_int32_t)(0x40000000)) 113#define LMC_TDES_LAST_SEGMENT ((u32)(0x40000000))
136#define LMC_TDES_INTERRUPT_ON_COMPLETION ((u_int32_t)(0x80000000)) 114#define LMC_TDES_INTERRUPT_ON_COMPLETION ((u32)(0x80000000))
137 115
138#define TDES_SECOND_BUFFER_SIZE_BIT_NUMBER 11 116#define TDES_SECOND_BUFFER_SIZE_BIT_NUMBER 11
139#define TDES_COLLISION_COUNT_BIT_NUMBER 3 117#define TDES_COLLISION_COUNT_BIT_NUMBER 3
140 118
141/* Constants for the RCV descriptor RDES */ 119/* Constants for the RCV descriptor RDES */
142 120
143#define LMC_RDES_OVERFLOW ((u_int32_t)(0x00000001)) 121#define LMC_RDES_OVERFLOW ((u32)(0x00000001))
144#define LMC_RDES_CRC_ERROR ((u_int32_t)(0x00000002)) 122#define LMC_RDES_CRC_ERROR ((u32)(0x00000002))
145#define LMC_RDES_DRIBBLING_BIT ((u_int32_t)(0x00000004)) 123#define LMC_RDES_DRIBBLING_BIT ((u32)(0x00000004))
146#define LMC_RDES_REPORT_ON_MII_ERR ((u_int32_t)(0x00000008)) 124#define LMC_RDES_REPORT_ON_MII_ERR ((u32)(0x00000008))
147#define LMC_RDES_RCV_WATCHDOG_TIMEOUT ((u_int32_t)(0x00000010)) 125#define LMC_RDES_RCV_WATCHDOG_TIMEOUT ((u32)(0x00000010))
148#define LMC_RDES_FRAME_TYPE ((u_int32_t)(0x00000020)) 126#define LMC_RDES_FRAME_TYPE ((u32)(0x00000020))
149#define LMC_RDES_COLLISION_SEEN ((u_int32_t)(0x00000040)) 127#define LMC_RDES_COLLISION_SEEN ((u32)(0x00000040))
150#define LMC_RDES_FRAME_TOO_LONG ((u_int32_t)(0x00000080)) 128#define LMC_RDES_FRAME_TOO_LONG ((u32)(0x00000080))
151#define LMC_RDES_LAST_DESCRIPTOR ((u_int32_t)(0x00000100)) 129#define LMC_RDES_LAST_DESCRIPTOR ((u32)(0x00000100))
152#define LMC_RDES_FIRST_DESCRIPTOR ((u_int32_t)(0x00000200)) 130#define LMC_RDES_FIRST_DESCRIPTOR ((u32)(0x00000200))
153#define LMC_RDES_MULTICAST_FRAME ((u_int32_t)(0x00000400)) 131#define LMC_RDES_MULTICAST_FRAME ((u32)(0x00000400))
154#define LMC_RDES_RUNT_FRAME ((u_int32_t)(0x00000800)) 132#define LMC_RDES_RUNT_FRAME ((u32)(0x00000800))
155#define LMC_RDES_DATA_TYPE ((u_int32_t)(0x00003000)) 133#define LMC_RDES_DATA_TYPE ((u32)(0x00003000))
156#define LMC_RDES_LENGTH_ERROR ((u_int32_t)(0x00004000)) 134#define LMC_RDES_LENGTH_ERROR ((u32)(0x00004000))
157#define LMC_RDES_ERROR_SUMMARY ((u_int32_t)(0x00008000)) 135#define LMC_RDES_ERROR_SUMMARY ((u32)(0x00008000))
158#define LMC_RDES_FRAME_LENGTH ((u_int32_t)(0x3FFF0000)) 136#define LMC_RDES_FRAME_LENGTH ((u32)(0x3FFF0000))
159#define LMC_RDES_OWN_BIT ((u_int32_t)(0x80000000)) 137#define LMC_RDES_OWN_BIT ((u32)(0x80000000))
160 138
161#define RDES_FRAME_LENGTH_BIT_NUMBER 16 139#define RDES_FRAME_LENGTH_BIT_NUMBER 16
162 140
163#define LMC_RDES_ERROR_MASK ( (u_int32_t)( \ 141#define LMC_RDES_ERROR_MASK ( (u32)( \
164 LMC_RDES_OVERFLOW \ 142 LMC_RDES_OVERFLOW \
165 | LMC_RDES_DRIBBLING_BIT \ 143 | LMC_RDES_DRIBBLING_BIT \
166 | LMC_RDES_REPORT_ON_MII_ERR \ 144 | LMC_RDES_REPORT_ON_MII_ERR \
@@ -172,32 +150,32 @@ struct lmc_regfile_t {
172 */ 150 */
173 151
174typedef struct { 152typedef struct {
175 u_int32_t n; 153 u32 n;
176 u_int32_t m; 154 u32 m;
177 u_int32_t v; 155 u32 v;
178 u_int32_t x; 156 u32 x;
179 u_int32_t r; 157 u32 r;
180 u_int32_t f; 158 u32 f;
181 u_int32_t exact; 159 u32 exact;
182} lmc_av9110_t; 160} lmc_av9110_t;
183 161
184/* 162/*
185 * Common structure passed to the ioctl code. 163 * Common structure passed to the ioctl code.
186 */ 164 */
187struct lmc___ctl { 165struct lmc___ctl {
188 u_int32_t cardtype; 166 u32 cardtype;
189 u_int32_t clock_source; /* HSSI, T1 */ 167 u32 clock_source; /* HSSI, T1 */
190 u_int32_t clock_rate; /* T1 */ 168 u32 clock_rate; /* T1 */
191 u_int32_t crc_length; 169 u32 crc_length;
192 u_int32_t cable_length; /* DS3 */ 170 u32 cable_length; /* DS3 */
193 u_int32_t scrambler_onoff; /* DS3 */ 171 u32 scrambler_onoff; /* DS3 */
194 u_int32_t cable_type; /* T1 */ 172 u32 cable_type; /* T1 */
195 u_int32_t keepalive_onoff; /* protocol */ 173 u32 keepalive_onoff; /* protocol */
196 u_int32_t ticks; /* ticks/sec */ 174 u32 ticks; /* ticks/sec */
197 union { 175 union {
198 lmc_av9110_t ssi; 176 lmc_av9110_t ssi;
199 } cardspec; 177 } cardspec;
200 u_int32_t circuit_type; /* T1 or E1 */ 178 u32 circuit_type; /* T1 or E1 */
201}; 179};
202 180
203 181
@@ -244,108 +222,69 @@ struct lmc___media {
244 222
245#define STATCHECK 0xBEEFCAFE 223#define STATCHECK 0xBEEFCAFE
246 224
247/* Included in this structure are first 225struct lmc_extra_statistics
248 * - standard net_device_stats
249 * - some other counters used for debug and driver performance
250 * evaluation -baz
251 */
252struct lmc_statistics
253{ 226{
254 unsigned long rx_packets; /* total packets received */ 227 u32 version_size;
255 unsigned long tx_packets; /* total packets transmitted */ 228 u32 lmc_cardtype;
256 unsigned long rx_bytes; 229
257 unsigned long tx_bytes; 230 u32 tx_ProcTimeout;
258 231 u32 tx_IntTimeout;
259 unsigned long rx_errors; /* bad packets received */ 232 u32 tx_NoCompleteCnt;
260 unsigned long tx_errors; /* packet transmit problems */ 233 u32 tx_MaxXmtsB4Int;
261 unsigned long rx_dropped; /* no space in linux buffers */ 234 u32 tx_TimeoutCnt;
262 unsigned long tx_dropped; /* no space available in linux */ 235 u32 tx_OutOfSyncPtr;
263 unsigned long multicast; /* multicast packets received */ 236 u32 tx_tbusy0;
264 unsigned long collisions; 237 u32 tx_tbusy1;
265 238 u32 tx_tbusy_calls;
266 /* detailed rx_errors: */ 239 u32 resetCount;
267 unsigned long rx_length_errors; 240 u32 lmc_txfull;
268 unsigned long rx_over_errors; /* receiver ring buff overflow */ 241 u32 tbusy;
269 unsigned long rx_crc_errors; /* recved pkt with crc error */ 242 u32 dirtyTx;
270 unsigned long rx_frame_errors; /* recv'd frame alignment error */ 243 u32 lmc_next_tx;
271 unsigned long rx_fifo_errors; /* recv'r fifo overrun */ 244 u32 otherTypeCnt;
272 unsigned long rx_missed_errors; /* receiver missed packet */ 245 u32 lastType;
273 246 u32 lastTypeOK;
274 /* detailed tx_errors */ 247 u32 txLoopCnt;
275 unsigned long tx_aborted_errors; 248 u32 usedXmtDescripCnt;
276 unsigned long tx_carrier_errors; 249 u32 txIndexCnt;
277 unsigned long tx_fifo_errors; 250 u32 rxIntLoopCnt;
278 unsigned long tx_heartbeat_errors; 251
279 unsigned long tx_window_errors; 252 u32 rx_SmallPktCnt;
280 253 u32 rx_BadPktSurgeCnt;
281 /* for cslip etc */ 254 u32 rx_BuffAllocErr;
282 unsigned long rx_compressed; 255 u32 tx_lossOfClockCnt;
283 unsigned long tx_compressed; 256
284 257 /* T1 error counters */
285 /* ------------------------------------- 258 u32 framingBitErrorCount;
286 * Custom stats & counters follow -baz */ 259 u32 lineCodeViolationCount;
287 u_int32_t version_size; 260
288 u_int32_t lmc_cardtype; 261 u32 lossOfFrameCount;
289 262 u32 changeOfFrameAlignmentCount;
290 u_int32_t tx_ProcTimeout; 263 u32 severelyErroredFrameCount;
291 u_int32_t tx_IntTimeout; 264
292 u_int32_t tx_NoCompleteCnt; 265 u32 check;
293 u_int32_t tx_MaxXmtsB4Int;
294 u_int32_t tx_TimeoutCnt;
295 u_int32_t tx_OutOfSyncPtr;
296 u_int32_t tx_tbusy0;
297 u_int32_t tx_tbusy1;
298 u_int32_t tx_tbusy_calls;
299 u_int32_t resetCount;
300 u_int32_t lmc_txfull;
301 u_int32_t tbusy;
302 u_int32_t dirtyTx;
303 u_int32_t lmc_next_tx;
304 u_int32_t otherTypeCnt;
305 u_int32_t lastType;
306 u_int32_t lastTypeOK;
307 u_int32_t txLoopCnt;
308 u_int32_t usedXmtDescripCnt;
309 u_int32_t txIndexCnt;
310 u_int32_t rxIntLoopCnt;
311
312 u_int32_t rx_SmallPktCnt;
313 u_int32_t rx_BadPktSurgeCnt;
314 u_int32_t rx_BuffAllocErr;
315 u_int32_t tx_lossOfClockCnt;
316
317 /* T1 error counters */
318 u_int32_t framingBitErrorCount;
319 u_int32_t lineCodeViolationCount;
320
321 u_int32_t lossOfFrameCount;
322 u_int32_t changeOfFrameAlignmentCount;
323 u_int32_t severelyErroredFrameCount;
324
325 u_int32_t check;
326}; 266};
327 267
328
329typedef struct lmc_xinfo { 268typedef struct lmc_xinfo {
330 u_int32_t Magic0; /* BEEFCAFE */ 269 u32 Magic0; /* BEEFCAFE */
331 270
332 u_int32_t PciCardType; 271 u32 PciCardType;
333 u_int32_t PciSlotNumber; /* PCI slot number */ 272 u32 PciSlotNumber; /* PCI slot number */
334 273
335 u_int16_t DriverMajorVersion; 274 u16 DriverMajorVersion;
336 u_int16_t DriverMinorVersion; 275 u16 DriverMinorVersion;
337 u_int16_t DriverSubVersion; 276 u16 DriverSubVersion;
338 277
339 u_int16_t XilinxRevisionNumber; 278 u16 XilinxRevisionNumber;
340 u_int16_t MaxFrameSize; 279 u16 MaxFrameSize;
341 280
342 u_int16_t t1_alarm1_status; 281 u16 t1_alarm1_status;
343 u_int16_t t1_alarm2_status; 282 u16 t1_alarm2_status;
344 283
345 int link_status; 284 int link_status;
346 u_int32_t mii_reg16; 285 u32 mii_reg16;
347 286
348 u_int32_t Magic1; /* DEADBEEF */ 287 u32 Magic1; /* DEADBEEF */
349} LMC_XINFO; 288} LMC_XINFO;
350 289
351 290
@@ -353,23 +292,22 @@ typedef struct lmc_xinfo {
353 * forward decl 292 * forward decl
354 */ 293 */
355struct lmc___softc { 294struct lmc___softc {
356 void *if_ptr; /* General purpose pointer (used by SPPP) */
357 char *name; 295 char *name;
358 u8 board_idx; 296 u8 board_idx;
359 struct lmc_statistics stats; 297 struct lmc_extra_statistics extra_stats;
360 struct net_device *lmc_device; 298 struct net_device *lmc_device;
361 299
362 int hang, rxdesc, bad_packet, some_counter; 300 int hang, rxdesc, bad_packet, some_counter;
363 u_int32_t txgo; 301 u32 txgo;
364 struct lmc_regfile_t lmc_csrs; 302 struct lmc_regfile_t lmc_csrs;
365 volatile u_int32_t lmc_txtick; 303 volatile u32 lmc_txtick;
366 volatile u_int32_t lmc_rxtick; 304 volatile u32 lmc_rxtick;
367 u_int32_t lmc_flags; 305 u32 lmc_flags;
368 u_int32_t lmc_intrmask; /* our copy of csr_intr */ 306 u32 lmc_intrmask; /* our copy of csr_intr */
369 u_int32_t lmc_cmdmode; /* our copy of csr_cmdmode */ 307 u32 lmc_cmdmode; /* our copy of csr_cmdmode */
370 u_int32_t lmc_busmode; /* our copy of csr_busmode */ 308 u32 lmc_busmode; /* our copy of csr_busmode */
371 u_int32_t lmc_gpio_io; /* state of in/out settings */ 309 u32 lmc_gpio_io; /* state of in/out settings */
372 u_int32_t lmc_gpio; /* state of outputs */ 310 u32 lmc_gpio; /* state of outputs */
373 struct sk_buff* lmc_txq[LMC_TXDESCS]; 311 struct sk_buff* lmc_txq[LMC_TXDESCS];
374 struct sk_buff* lmc_rxq[LMC_RXDESCS]; 312 struct sk_buff* lmc_rxq[LMC_RXDESCS];
375 volatile 313 volatile
@@ -381,42 +319,41 @@ struct lmc___softc {
381 unsigned int lmc_taint_tx, lmc_taint_rx; 319 unsigned int lmc_taint_tx, lmc_taint_rx;
382 int lmc_tx_start, lmc_txfull; 320 int lmc_tx_start, lmc_txfull;
383 int lmc_txbusy; 321 int lmc_txbusy;
384 u_int16_t lmc_miireg16; 322 u16 lmc_miireg16;
385 int lmc_ok; 323 int lmc_ok;
386 int last_link_status; 324 int last_link_status;
387 int lmc_cardtype; 325 int lmc_cardtype;
388 u_int32_t last_frameerr; 326 u32 last_frameerr;
389 lmc_media_t *lmc_media; 327 lmc_media_t *lmc_media;
390 struct timer_list timer; 328 struct timer_list timer;
391 lmc_ctl_t ictl; 329 lmc_ctl_t ictl;
392 u_int32_t TxDescriptControlInit; 330 u32 TxDescriptControlInit;
393 331
394 int tx_TimeoutInd; /* additional driver state */ 332 int tx_TimeoutInd; /* additional driver state */
395 int tx_TimeoutDisplay; 333 int tx_TimeoutDisplay;
396 unsigned int lastlmc_taint_tx; 334 unsigned int lastlmc_taint_tx;
397 int lasttx_packets; 335 int lasttx_packets;
398 u_int32_t tx_clockState; 336 u32 tx_clockState;
399 u_int32_t lmc_crcSize; 337 u32 lmc_crcSize;
400 LMC_XINFO lmc_xinfo; 338 LMC_XINFO lmc_xinfo;
401 char lmc_yel, lmc_blue, lmc_red; /* for T1 and DS3 */ 339 char lmc_yel, lmc_blue, lmc_red; /* for T1 and DS3 */
402 char lmc_timing; /* for HSSI and SSI */ 340 char lmc_timing; /* for HSSI and SSI */
403 int got_irq; 341 int got_irq;
404 342
405 char last_led_err[4]; 343 char last_led_err[4];
406 344
407 u32 last_int; 345 u32 last_int;
408 u32 num_int; 346 u32 num_int;
409 347
410 spinlock_t lmc_lock; 348 spinlock_t lmc_lock;
411 u_int16_t if_type; /* PPP or NET */ 349 u16 if_type; /* HDLC/PPP or NET */
412 struct ppp_device *pd;
413 350
414 /* Failure cases */ 351 /* Failure cases */
415 u8 failed_ring; 352 u8 failed_ring;
416 u8 failed_recv_alloc; 353 u8 failed_recv_alloc;
417 354
418 /* Structure check */ 355 /* Structure check */
419 u32 check; 356 u32 check;
420}; 357};
421 358
422#define LMC_PCI_TIME 1 359#define LMC_PCI_TIME 1
@@ -512,8 +449,8 @@ struct lmc___softc {
512 | TULIP_STS_TXUNDERFLOW\ 449 | TULIP_STS_TXUNDERFLOW\
513 | TULIP_STS_RXSTOPPED ) 450 | TULIP_STS_RXSTOPPED )
514 451
515#define DESC_OWNED_BY_SYSTEM ((u_int32_t)(0x00000000)) 452#define DESC_OWNED_BY_SYSTEM ((u32)(0x00000000))
516#define DESC_OWNED_BY_DC21X4 ((u_int32_t)(0x80000000)) 453#define DESC_OWNED_BY_DC21X4 ((u32)(0x80000000))
517 454
518#ifndef TULIP_CMD_RECEIVEALL 455#ifndef TULIP_CMD_RECEIVEALL
519#define TULIP_CMD_RECEIVEALL 0x40000000L 456#define TULIP_CMD_RECEIVEALL 0x40000000L
@@ -525,46 +462,9 @@ struct lmc___softc {
525#define LMC_ADAP_SSI 4 462#define LMC_ADAP_SSI 4
526#define LMC_ADAP_T1 5 463#define LMC_ADAP_T1 5
527 464
528#define HDLC_HDR_LEN 4
529#define HDLC_ADDR_LEN 1
530#define HDLC_SLARP 0x8035
531#define LMC_MTU 1500 465#define LMC_MTU 1500
532#define SLARP_LINECHECK 2
533 466
534#define LMC_CRC_LEN_16 2 /* 16-bit CRC */ 467#define LMC_CRC_LEN_16 2 /* 16-bit CRC */
535#define LMC_CRC_LEN_32 4 468#define LMC_CRC_LEN_32 4
536 469
537#ifdef LMC_HDLC
538/* definition of an hdlc header. */
539struct hdlc_hdr
540{
541 u8 address;
542 u8 control;
543 u16 type;
544};
545
546/* definition of a slarp header. */
547struct slarp
548{
549 long code;
550 union sl
551 {
552 struct
553 {
554 ulong address;
555 ulong mask;
556 ushort unused;
557 } add;
558 struct
559 {
560 ulong mysequence;
561 ulong yoursequence;
562 ushort reliability;
563 ulong time;
564 } chk;
565 } t;
566};
567#endif /* LMC_HDLC */
568
569
570#endif /* _LMC_VAR_H_ */ 470#endif /* _LMC_VAR_H_ */
diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h
index 63e9fcf31fb8..2e4f84f6cad4 100644
--- a/drivers/net/wan/pc300.h
+++ b/drivers/net/wan/pc300.h
@@ -100,31 +100,14 @@
100#define _PC300_H 100#define _PC300_H
101 101
102#include <linux/hdlc.h> 102#include <linux/hdlc.h>
103#include <net/syncppp.h>
104#include "hd64572.h" 103#include "hd64572.h"
105#include "pc300-falc-lh.h" 104#include "pc300-falc-lh.h"
106 105
107#ifndef CY_TYPES 106#define PC300_PROTO_MLPPP 1
108#define CY_TYPES
109typedef __u64 ucdouble; /* 64 bits, unsigned */
110typedef __u32 uclong; /* 32 bits, unsigned */
111typedef __u16 ucshort; /* 16 bits, unsigned */
112typedef __u8 ucchar; /* 8 bits, unsigned */
113#endif /* CY_TYPES */
114 107
115#define PC300_PROTO_MLPPP 1
116
117#define PC300_KERNEL "2.4.x" /* Kernel supported by this driver */
118
119#define PC300_DEVNAME "hdlc" /* Dev. name base (for hdlc0, hdlc1, etc.) */
120#define PC300_MAXINDEX 100 /* Max dev. name index (the '0' in hdlc0) */
121
122#define PC300_MAXCARDS 4 /* Max number of cards per system */
123#define PC300_MAXCHAN 2 /* Number of channels per card */ 108#define PC300_MAXCHAN 2 /* Number of channels per card */
124 109
125#define PC300_PLX_WIN 0x80 /* PLX control window size (128b) */
126#define PC300_RAMSIZE 0x40000 /* RAM window size (256Kb) */ 110#define PC300_RAMSIZE 0x40000 /* RAM window size (256Kb) */
127#define PC300_SCASIZE 0x400 /* SCA window size (1Kb) */
128#define PC300_FALCSIZE 0x400 /* FALC window size (1Kb) */ 111#define PC300_FALCSIZE 0x400 /* FALC window size (1Kb) */
129 112
130#define PC300_OSC_CLOCK 24576000 113#define PC300_OSC_CLOCK 24576000
@@ -160,26 +143,14 @@ typedef __u8 ucchar; /* 8 bits, unsigned */
160 * Memory access functions/macros * 143 * Memory access functions/macros *
161 * (required to support Alpha systems) * 144 * (required to support Alpha systems) *
162 ***************************************/ 145 ***************************************/
163#ifdef __KERNEL__ 146#define cpc_writeb(port,val) {writeb((u8)(val),(port)); mb();}
164#define cpc_writeb(port,val) {writeb((ucchar)(val),(port)); mb();}
165#define cpc_writew(port,val) {writew((ushort)(val),(port)); mb();} 147#define cpc_writew(port,val) {writew((ushort)(val),(port)); mb();}
166#define cpc_writel(port,val) {writel((uclong)(val),(port)); mb();} 148#define cpc_writel(port,val) {writel((u32)(val),(port)); mb();}
167 149
168#define cpc_readb(port) readb(port) 150#define cpc_readb(port) readb(port)
169#define cpc_readw(port) readw(port) 151#define cpc_readw(port) readw(port)
170#define cpc_readl(port) readl(port) 152#define cpc_readl(port) readl(port)
171 153
172#else /* __KERNEL__ */
173#define cpc_writeb(port,val) (*(volatile ucchar *)(port) = (ucchar)(val))
174#define cpc_writew(port,val) (*(volatile ucshort *)(port) = (ucshort)(val))
175#define cpc_writel(port,val) (*(volatile uclong *)(port) = (uclong)(val))
176
177#define cpc_readb(port) (*(volatile ucchar *)(port))
178#define cpc_readw(port) (*(volatile ucshort *)(port))
179#define cpc_readl(port) (*(volatile uclong *)(port))
180
181#endif /* __KERNEL__ */
182
183/****** Data Structures *****************************************************/ 154/****** Data Structures *****************************************************/
184 155
185/* 156/*
@@ -188,15 +159,15 @@ typedef __u8 ucchar; /* 8 bits, unsigned */
188 * (memory mapped). 159 * (memory mapped).
189 */ 160 */
190struct RUNTIME_9050 { 161struct RUNTIME_9050 {
191 uclong loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */ 162 u32 loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */
192 uclong loc_rom_range; /* 10h : Local ROM Range */ 163 u32 loc_rom_range; /* 10h : Local ROM Range */
193 uclong loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */ 164 u32 loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */
194 uclong loc_rom_base; /* 24h : Local ROM Base */ 165 u32 loc_rom_base; /* 24h : Local ROM Base */
195 uclong loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */ 166 u32 loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */
196 uclong rom_bus_descr; /* 38h : ROM Bus Descriptor */ 167 u32 rom_bus_descr; /* 38h : ROM Bus Descriptor */
197 uclong cs_base[4]; /* 3C-48h : Chip Select Base Addrs */ 168 u32 cs_base[4]; /* 3C-48h : Chip Select Base Addrs */
198 uclong intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */ 169 u32 intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */
199 uclong init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */ 170 u32 init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */
200}; 171};
201 172
202#define PLX_9050_LINT1_ENABLE 0x01 173#define PLX_9050_LINT1_ENABLE 0x01
@@ -240,66 +211,66 @@ struct RUNTIME_9050 {
240#define PC300_FALC_MAXLOOP 0x0000ffff /* for falc_issue_cmd() */ 211#define PC300_FALC_MAXLOOP 0x0000ffff /* for falc_issue_cmd() */
241 212
242typedef struct falc { 213typedef struct falc {
243 ucchar sync; /* If true FALC is synchronized */ 214 u8 sync; /* If true FALC is synchronized */
244 ucchar active; /* if TRUE then already active */ 215 u8 active; /* if TRUE then already active */
245 ucchar loop_active; /* if TRUE a line loopback UP was received */ 216 u8 loop_active; /* if TRUE a line loopback UP was received */
246 ucchar loop_gen; /* if TRUE a line loopback UP was issued */ 217 u8 loop_gen; /* if TRUE a line loopback UP was issued */
247 218
248 ucchar num_channels; 219 u8 num_channels;
249 ucchar offset; /* 1 for T1, 0 for E1 */ 220 u8 offset; /* 1 for T1, 0 for E1 */
250 ucchar full_bandwidth; 221 u8 full_bandwidth;
251 222
252 ucchar xmb_cause; 223 u8 xmb_cause;
253 ucchar multiframe_mode; 224 u8 multiframe_mode;
254 225
255 /* Statistics */ 226 /* Statistics */
256 ucshort pden; /* Pulse Density violation count */ 227 u16 pden; /* Pulse Density violation count */
257 ucshort los; /* Loss of Signal count */ 228 u16 los; /* Loss of Signal count */
258 ucshort losr; /* Loss of Signal recovery count */ 229 u16 losr; /* Loss of Signal recovery count */
259 ucshort lfa; /* Loss of frame alignment count */ 230 u16 lfa; /* Loss of frame alignment count */
260 ucshort farec; /* Frame Alignment Recovery count */ 231 u16 farec; /* Frame Alignment Recovery count */
261 ucshort lmfa; /* Loss of multiframe alignment count */ 232 u16 lmfa; /* Loss of multiframe alignment count */
262 ucshort ais; /* Remote Alarm indication Signal count */ 233 u16 ais; /* Remote Alarm indication Signal count */
263 ucshort sec; /* One-second timer */ 234 u16 sec; /* One-second timer */
264 ucshort es; /* Errored second */ 235 u16 es; /* Errored second */
265 ucshort rai; /* remote alarm received */ 236 u16 rai; /* remote alarm received */
266 ucshort bec; 237 u16 bec;
267 ucshort fec; 238 u16 fec;
268 ucshort cvc; 239 u16 cvc;
269 ucshort cec; 240 u16 cec;
270 ucshort ebc; 241 u16 ebc;
271 242
272 /* Status */ 243 /* Status */
273 ucchar red_alarm; 244 u8 red_alarm;
274 ucchar blue_alarm; 245 u8 blue_alarm;
275 ucchar loss_fa; 246 u8 loss_fa;
276 ucchar yellow_alarm; 247 u8 yellow_alarm;
277 ucchar loss_mfa; 248 u8 loss_mfa;
278 ucchar prbs; 249 u8 prbs;
279} falc_t; 250} falc_t;
280 251
281typedef struct falc_status { 252typedef struct falc_status {
282 ucchar sync; /* If true FALC is synchronized */ 253 u8 sync; /* If true FALC is synchronized */
283 ucchar red_alarm; 254 u8 red_alarm;
284 ucchar blue_alarm; 255 u8 blue_alarm;
285 ucchar loss_fa; 256 u8 loss_fa;
286 ucchar yellow_alarm; 257 u8 yellow_alarm;
287 ucchar loss_mfa; 258 u8 loss_mfa;
288 ucchar prbs; 259 u8 prbs;
289} falc_status_t; 260} falc_status_t;
290 261
291typedef struct rsv_x21_status { 262typedef struct rsv_x21_status {
292 ucchar dcd; 263 u8 dcd;
293 ucchar dsr; 264 u8 dsr;
294 ucchar cts; 265 u8 cts;
295 ucchar rts; 266 u8 rts;
296 ucchar dtr; 267 u8 dtr;
297} rsv_x21_status_t; 268} rsv_x21_status_t;
298 269
299typedef struct pc300stats { 270typedef struct pc300stats {
300 int hw_type; 271 int hw_type;
301 uclong line_on; 272 u32 line_on;
302 uclong line_off; 273 u32 line_off;
303 struct net_device_stats gen_stats; 274 struct net_device_stats gen_stats;
304 falc_t te_stats; 275 falc_t te_stats;
305} pc300stats_t; 276} pc300stats_t;
@@ -317,28 +288,19 @@ typedef struct pc300loopback {
317 288
318typedef struct pc300patterntst { 289typedef struct pc300patterntst {
319 char patrntst_on; /* 0 - off; 1 - on; 2 - read num_errors */ 290 char patrntst_on; /* 0 - off; 1 - on; 2 - read num_errors */
320 ucshort num_errors; 291 u16 num_errors;
321} pc300patterntst_t; 292} pc300patterntst_t;
322 293
323typedef struct pc300dev { 294typedef struct pc300dev {
324 void *if_ptr; /* General purpose pointer */
325 struct pc300ch *chan; 295 struct pc300ch *chan;
326 ucchar trace_on; 296 u8 trace_on;
327 uclong line_on; /* DCD(X.21, RSV) / sync(TE) change counters */ 297 u32 line_on; /* DCD(X.21, RSV) / sync(TE) change counters */
328 uclong line_off; 298 u32 line_off;
329#ifdef __KERNEL__
330 char name[16]; 299 char name[16];
331 struct net_device *dev; 300 struct net_device *dev;
332
333 void *private;
334 struct sk_buff *tx_skb;
335 union { /* This union has all the protocol-specific structures */
336 struct ppp_device pppdev;
337 }ifu;
338#ifdef CONFIG_PC300_MLPPP 301#ifdef CONFIG_PC300_MLPPP
339 void *cpc_tty; /* information to PC300 TTY driver */ 302 void *cpc_tty; /* information to PC300 TTY driver */
340#endif 303#endif
341#endif /* __KERNEL__ */
342}pc300dev_t; 304}pc300dev_t;
343 305
344typedef struct pc300hw { 306typedef struct pc300hw {
@@ -346,43 +308,42 @@ typedef struct pc300hw {
346 int bus; /* Bus (PCI, PMC, etc.) */ 308 int bus; /* Bus (PCI, PMC, etc.) */
347 int nchan; /* number of channels */ 309 int nchan; /* number of channels */
348 int irq; /* interrupt request level */ 310 int irq; /* interrupt request level */
349 uclong clock; /* Board clock */ 311 u32 clock; /* Board clock */
350 ucchar cpld_id; /* CPLD ID (TE only) */ 312 u8 cpld_id; /* CPLD ID (TE only) */
351 ucshort cpld_reg1; /* CPLD reg 1 (TE only) */ 313 u16 cpld_reg1; /* CPLD reg 1 (TE only) */
352 ucshort cpld_reg2; /* CPLD reg 2 (TE only) */ 314 u16 cpld_reg2; /* CPLD reg 2 (TE only) */
353 ucshort gpioc_reg; /* PLX GPIOC reg */ 315 u16 gpioc_reg; /* PLX GPIOC reg */
354 ucshort intctl_reg; /* PLX Int Ctrl/Status reg */ 316 u16 intctl_reg; /* PLX Int Ctrl/Status reg */
355 uclong iophys; /* PLX registers I/O base */ 317 u32 iophys; /* PLX registers I/O base */
356 uclong iosize; /* PLX registers I/O size */ 318 u32 iosize; /* PLX registers I/O size */
357 uclong plxphys; /* PLX registers MMIO base (physical) */ 319 u32 plxphys; /* PLX registers MMIO base (physical) */
358 void __iomem * plxbase; /* PLX registers MMIO base (virtual) */ 320 void __iomem * plxbase; /* PLX registers MMIO base (virtual) */
359 uclong plxsize; /* PLX registers MMIO size */ 321 u32 plxsize; /* PLX registers MMIO size */
360 uclong scaphys; /* SCA registers MMIO base (physical) */ 322 u32 scaphys; /* SCA registers MMIO base (physical) */
361 void __iomem * scabase; /* SCA registers MMIO base (virtual) */ 323 void __iomem * scabase; /* SCA registers MMIO base (virtual) */
362 uclong scasize; /* SCA registers MMIO size */ 324 u32 scasize; /* SCA registers MMIO size */
363 uclong ramphys; /* On-board RAM MMIO base (physical) */ 325 u32 ramphys; /* On-board RAM MMIO base (physical) */
364 void __iomem * rambase; /* On-board RAM MMIO base (virtual) */ 326 void __iomem * rambase; /* On-board RAM MMIO base (virtual) */
365 uclong alloc_ramsize; /* RAM MMIO size allocated by the PCI bridge */ 327 u32 alloc_ramsize; /* RAM MMIO size allocated by the PCI bridge */
366 uclong ramsize; /* On-board RAM MMIO size */ 328 u32 ramsize; /* On-board RAM MMIO size */
367 uclong falcphys; /* FALC registers MMIO base (physical) */ 329 u32 falcphys; /* FALC registers MMIO base (physical) */
368 void __iomem * falcbase;/* FALC registers MMIO base (virtual) */ 330 void __iomem * falcbase;/* FALC registers MMIO base (virtual) */
369 uclong falcsize; /* FALC registers MMIO size */ 331 u32 falcsize; /* FALC registers MMIO size */
370} pc300hw_t; 332} pc300hw_t;
371 333
372typedef struct pc300chconf { 334typedef struct pc300chconf {
373 sync_serial_settings phys_settings; /* Clock type/rate (in bps), 335 sync_serial_settings phys_settings; /* Clock type/rate (in bps),
374 loopback mode */ 336 loopback mode */
375 raw_hdlc_proto proto_settings; /* Encoding, parity (CRC) */ 337 raw_hdlc_proto proto_settings; /* Encoding, parity (CRC) */
376 uclong media; /* HW media (RS232, V.35, etc.) */ 338 u32 media; /* HW media (RS232, V.35, etc.) */
377 uclong proto; /* Protocol (PPP, X.25, etc.) */ 339 u32 proto; /* Protocol (PPP, X.25, etc.) */
378 ucchar monitor; /* Monitor mode (0 = off, !0 = on) */
379 340
380 /* TE-specific parameters */ 341 /* TE-specific parameters */
381 ucchar lcode; /* Line Code (AMI, B8ZS, etc.) */ 342 u8 lcode; /* Line Code (AMI, B8ZS, etc.) */
382 ucchar fr_mode; /* Frame Mode (ESF, D4, etc.) */ 343 u8 fr_mode; /* Frame Mode (ESF, D4, etc.) */
383 ucchar lbo; /* Line Build Out */ 344 u8 lbo; /* Line Build Out */
384 ucchar rx_sens; /* Rx Sensitivity (long- or short-haul) */ 345 u8 rx_sens; /* Rx Sensitivity (long- or short-haul) */
385 uclong tslot_bitmap; /* bit[i]=1 => timeslot _i_ is active */ 346 u32 tslot_bitmap; /* bit[i]=1 => timeslot _i_ is active */
386} pc300chconf_t; 347} pc300chconf_t;
387 348
388typedef struct pc300ch { 349typedef struct pc300ch {
@@ -390,20 +351,18 @@ typedef struct pc300ch {
390 int channel; 351 int channel;
391 pc300dev_t d; 352 pc300dev_t d;
392 pc300chconf_t conf; 353 pc300chconf_t conf;
393 ucchar tx_first_bd; /* First TX DMA block descr. w/ data */ 354 u8 tx_first_bd; /* First TX DMA block descr. w/ data */
394 ucchar tx_next_bd; /* Next free TX DMA block descriptor */ 355 u8 tx_next_bd; /* Next free TX DMA block descriptor */
395 ucchar rx_first_bd; /* First free RX DMA block descriptor */ 356 u8 rx_first_bd; /* First free RX DMA block descriptor */
396 ucchar rx_last_bd; /* Last free RX DMA block descriptor */ 357 u8 rx_last_bd; /* Last free RX DMA block descriptor */
397 ucchar nfree_tx_bd; /* Number of free TX DMA block descriptors */ 358 u8 nfree_tx_bd; /* Number of free TX DMA block descriptors */
398 falc_t falc; /* FALC structure (TE only) */ 359 falc_t falc; /* FALC structure (TE only) */
399} pc300ch_t; 360} pc300ch_t;
400 361
401typedef struct pc300 { 362typedef struct pc300 {
402 pc300hw_t hw; /* hardware config. */ 363 pc300hw_t hw; /* hardware config. */
403 pc300ch_t chan[PC300_MAXCHAN]; 364 pc300ch_t chan[PC300_MAXCHAN];
404#ifdef __KERNEL__
405 spinlock_t card_lock; 365 spinlock_t card_lock;
406#endif /* __KERNEL__ */
407} pc300_t; 366} pc300_t;
408 367
409typedef struct pc300conf { 368typedef struct pc300conf {
@@ -471,12 +430,7 @@ enum pc300_loopback_cmds {
471#define PC300_TX_QUEUE_LEN 100 430#define PC300_TX_QUEUE_LEN 100
472#define PC300_DEF_MTU 1600 431#define PC300_DEF_MTU 1600
473 432
474#ifdef __KERNEL__
475/* Function Prototypes */ 433/* Function Prototypes */
476void tx_dma_start(pc300_t *, int);
477int cpc_open(struct net_device *dev); 434int cpc_open(struct net_device *dev);
478int cpc_set_media(hdlc_device *, int);
479#endif /* __KERNEL__ */
480 435
481#endif /* _PC300_H */ 436#endif /* _PC300_H */
482
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 334170527755..d0a8d1e352ac 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -227,8 +227,6 @@ static char rcsid[] =
227#include <linux/netdevice.h> 227#include <linux/netdevice.h>
228#include <linux/spinlock.h> 228#include <linux/spinlock.h>
229#include <linux/if.h> 229#include <linux/if.h>
230
231#include <net/syncppp.h>
232#include <net/arp.h> 230#include <net/arp.h>
233 231
234#include <asm/io.h> 232#include <asm/io.h>
@@ -285,8 +283,8 @@ static void rx_dma_buf_init(pc300_t *, int);
285static void tx_dma_buf_check(pc300_t *, int); 283static void tx_dma_buf_check(pc300_t *, int);
286static void rx_dma_buf_check(pc300_t *, int); 284static void rx_dma_buf_check(pc300_t *, int);
287static irqreturn_t cpc_intr(int, void *); 285static irqreturn_t cpc_intr(int, void *);
288static int clock_rate_calc(uclong, uclong, int *); 286static int clock_rate_calc(u32, u32, int *);
289static uclong detect_ram(pc300_t *); 287static u32 detect_ram(pc300_t *);
290static void plx_init(pc300_t *); 288static void plx_init(pc300_t *);
291static void cpc_trace(struct net_device *, struct sk_buff *, char); 289static void cpc_trace(struct net_device *, struct sk_buff *, char);
292static int cpc_attach(struct net_device *, unsigned short, unsigned short); 290static int cpc_attach(struct net_device *, unsigned short, unsigned short);
@@ -311,10 +309,10 @@ static void tx_dma_buf_pt_init(pc300_t * card, int ch)
311 + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); 309 + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
312 310
313 for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { 311 for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) {
314 cpc_writel(&ptdescr->next, (uclong) (DMA_TX_BD_BASE + 312 cpc_writel(&ptdescr->next, (u32)(DMA_TX_BD_BASE +
315 (ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t))); 313 (ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t)));
316 cpc_writel(&ptdescr->ptbuf, 314 cpc_writel(&ptdescr->ptbuf,
317 (uclong) (DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN)); 315 (u32)(DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN));
318 } 316 }
319} 317}
320 318
@@ -341,10 +339,10 @@ static void rx_dma_buf_pt_init(pc300_t * card, int ch)
341 + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); 339 + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
342 340
343 for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { 341 for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) {
344 cpc_writel(&ptdescr->next, (uclong) (DMA_RX_BD_BASE + 342 cpc_writel(&ptdescr->next, (u32)(DMA_RX_BD_BASE +
345 (ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t))); 343 (ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t)));
346 cpc_writel(&ptdescr->ptbuf, 344 cpc_writel(&ptdescr->ptbuf,
347 (uclong) (DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN)); 345 (u32)(DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN));
348 } 346 }
349} 347}
350 348
@@ -367,8 +365,8 @@ static void tx_dma_buf_check(pc300_t * card, int ch)
367{ 365{
368 volatile pcsca_bd_t __iomem *ptdescr; 366 volatile pcsca_bd_t __iomem *ptdescr;
369 int i; 367 int i;
370 ucshort first_bd = card->chan[ch].tx_first_bd; 368 u16 first_bd = card->chan[ch].tx_first_bd;
371 ucshort next_bd = card->chan[ch].tx_next_bd; 369 u16 next_bd = card->chan[ch].tx_next_bd;
372 370
373 printk("#CH%d: f_bd = %d(0x%08zx), n_bd = %d(0x%08zx)\n", ch, 371 printk("#CH%d: f_bd = %d(0x%08zx), n_bd = %d(0x%08zx)\n", ch,
374 first_bd, TX_BD_ADDR(ch, first_bd), 372 first_bd, TX_BD_ADDR(ch, first_bd),
@@ -392,9 +390,9 @@ static void tx1_dma_buf_check(pc300_t * card, int ch)
392{ 390{
393 volatile pcsca_bd_t __iomem *ptdescr; 391 volatile pcsca_bd_t __iomem *ptdescr;
394 int i; 392 int i;
395 ucshort first_bd = card->chan[ch].tx_first_bd; 393 u16 first_bd = card->chan[ch].tx_first_bd;
396 ucshort next_bd = card->chan[ch].tx_next_bd; 394 u16 next_bd = card->chan[ch].tx_next_bd;
397 uclong scabase = card->hw.scabase; 395 u32 scabase = card->hw.scabase;
398 396
399 printk ("\nnfree_tx_bd = %d \n", card->chan[ch].nfree_tx_bd); 397 printk ("\nnfree_tx_bd = %d \n", card->chan[ch].nfree_tx_bd);
400 printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch, 398 printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch,
@@ -413,13 +411,13 @@ static void tx1_dma_buf_check(pc300_t * card, int ch)
413 printk("\n"); 411 printk("\n");
414} 412}
415#endif 413#endif
416 414
417static void rx_dma_buf_check(pc300_t * card, int ch) 415static void rx_dma_buf_check(pc300_t * card, int ch)
418{ 416{
419 volatile pcsca_bd_t __iomem *ptdescr; 417 volatile pcsca_bd_t __iomem *ptdescr;
420 int i; 418 int i;
421 ucshort first_bd = card->chan[ch].rx_first_bd; 419 u16 first_bd = card->chan[ch].rx_first_bd;
422 ucshort last_bd = card->chan[ch].rx_last_bd; 420 u16 last_bd = card->chan[ch].rx_last_bd;
423 int ch_factor; 421 int ch_factor;
424 422
425 ch_factor = ch * N_DMA_RX_BUF; 423 ch_factor = ch * N_DMA_RX_BUF;
@@ -440,9 +438,9 @@ static void rx_dma_buf_check(pc300_t * card, int ch)
440static int dma_get_rx_frame_size(pc300_t * card, int ch) 438static int dma_get_rx_frame_size(pc300_t * card, int ch)
441{ 439{
442 volatile pcsca_bd_t __iomem *ptdescr; 440 volatile pcsca_bd_t __iomem *ptdescr;
443 ucshort first_bd = card->chan[ch].rx_first_bd; 441 u16 first_bd = card->chan[ch].rx_first_bd;
444 int rcvd = 0; 442 int rcvd = 0;
445 volatile ucchar status; 443 volatile u8 status;
446 444
447 ptdescr = (card->hw.rambase + RX_BD_ADDR(ch, first_bd)); 445 ptdescr = (card->hw.rambase + RX_BD_ADDR(ch, first_bd));
448 while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { 446 while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
@@ -462,12 +460,12 @@ static int dma_get_rx_frame_size(pc300_t * card, int ch)
462 * dma_buf_write: writes a frame to the Tx DMA buffers 460 * dma_buf_write: writes a frame to the Tx DMA buffers
463 * NOTE: this function writes one frame at a time. 461 * NOTE: this function writes one frame at a time.
464 */ 462 */
465static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len) 463static int dma_buf_write(pc300_t *card, int ch, u8 *ptdata, int len)
466{ 464{
467 int i, nchar; 465 int i, nchar;
468 volatile pcsca_bd_t __iomem *ptdescr; 466 volatile pcsca_bd_t __iomem *ptdescr;
469 int tosend = len; 467 int tosend = len;
470 ucchar nbuf = ((len - 1) / BD_DEF_LEN) + 1; 468 u8 nbuf = ((len - 1) / BD_DEF_LEN) + 1;
471 469
472 if (nbuf >= card->chan[ch].nfree_tx_bd) { 470 if (nbuf >= card->chan[ch].nfree_tx_bd) {
473 return -ENOMEM; 471 return -ENOMEM;
@@ -509,7 +507,7 @@ static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
509 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; 507 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
510 volatile pcsca_bd_t __iomem *ptdescr; 508 volatile pcsca_bd_t __iomem *ptdescr;
511 int rcvd = 0; 509 int rcvd = 0;
512 volatile ucchar status; 510 volatile u8 status;
513 511
514 ptdescr = (card->hw.rambase + 512 ptdescr = (card->hw.rambase +
515 RX_BD_ADDR(ch, chan->rx_first_bd)); 513 RX_BD_ADDR(ch, chan->rx_first_bd));
@@ -563,8 +561,8 @@ static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
563static void tx_dma_stop(pc300_t * card, int ch) 561static void tx_dma_stop(pc300_t * card, int ch)
564{ 562{
565 void __iomem *scabase = card->hw.scabase; 563 void __iomem *scabase = card->hw.scabase;
566 ucchar drr_ena_bit = 1 << (5 + 2 * ch); 564 u8 drr_ena_bit = 1 << (5 + 2 * ch);
567 ucchar drr_rst_bit = 1 << (1 + 2 * ch); 565 u8 drr_rst_bit = 1 << (1 + 2 * ch);
568 566
569 /* Disable DMA */ 567 /* Disable DMA */
570 cpc_writeb(scabase + DRR, drr_ena_bit); 568 cpc_writeb(scabase + DRR, drr_ena_bit);
@@ -574,8 +572,8 @@ static void tx_dma_stop(pc300_t * card, int ch)
574static void rx_dma_stop(pc300_t * card, int ch) 572static void rx_dma_stop(pc300_t * card, int ch)
575{ 573{
576 void __iomem *scabase = card->hw.scabase; 574 void __iomem *scabase = card->hw.scabase;
577 ucchar drr_ena_bit = 1 << (4 + 2 * ch); 575 u8 drr_ena_bit = 1 << (4 + 2 * ch);
578 ucchar drr_rst_bit = 1 << (2 * ch); 576 u8 drr_rst_bit = 1 << (2 * ch);
579 577
580 /* Disable DMA */ 578 /* Disable DMA */
581 cpc_writeb(scabase + DRR, drr_ena_bit); 579 cpc_writeb(scabase + DRR, drr_ena_bit);
@@ -607,7 +605,7 @@ static void rx_dma_start(pc300_t * card, int ch)
607/*************************/ 605/*************************/
608/*** FALC Routines ***/ 606/*** FALC Routines ***/
609/*************************/ 607/*************************/
610static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd) 608static void falc_issue_cmd(pc300_t *card, int ch, u8 cmd)
611{ 609{
612 void __iomem *falcbase = card->hw.falcbase; 610 void __iomem *falcbase = card->hw.falcbase;
613 unsigned long i = 0; 611 unsigned long i = 0;
@@ -675,7 +673,7 @@ static void falc_intr_enable(pc300_t * card, int ch)
675static void falc_open_timeslot(pc300_t * card, int ch, int timeslot) 673static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
676{ 674{
677 void __iomem *falcbase = card->hw.falcbase; 675 void __iomem *falcbase = card->hw.falcbase;
678 ucchar tshf = card->chan[ch].falc.offset; 676 u8 tshf = card->chan[ch].falc.offset;
679 677
680 cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), 678 cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch),
681 cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & 679 cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) &
@@ -691,7 +689,7 @@ static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
691static void falc_close_timeslot(pc300_t * card, int ch, int timeslot) 689static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
692{ 690{
693 void __iomem *falcbase = card->hw.falcbase; 691 void __iomem *falcbase = card->hw.falcbase;
694 ucchar tshf = card->chan[ch].falc.offset; 692 u8 tshf = card->chan[ch].falc.offset;
695 693
696 cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), 694 cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch),
697 cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | 695 cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) |
@@ -812,7 +810,7 @@ static void falc_init_t1(pc300_t * card, int ch)
812 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; 810 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
813 falc_t *pfalc = (falc_t *) & chan->falc; 811 falc_t *pfalc = (falc_t *) & chan->falc;
814 void __iomem *falcbase = card->hw.falcbase; 812 void __iomem *falcbase = card->hw.falcbase;
815 ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); 813 u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
816 814
817 /* Switch to T1 mode (PCM 24) */ 815 /* Switch to T1 mode (PCM 24) */
818 cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD); 816 cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD);
@@ -981,7 +979,7 @@ static void falc_init_e1(pc300_t * card, int ch)
981 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; 979 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
982 falc_t *pfalc = (falc_t *) & chan->falc; 980 falc_t *pfalc = (falc_t *) & chan->falc;
983 void __iomem *falcbase = card->hw.falcbase; 981 void __iomem *falcbase = card->hw.falcbase;
984 ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); 982 u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
985 983
986 /* Switch to E1 mode (PCM 30) */ 984 /* Switch to E1 mode (PCM 30) */
987 cpc_writeb(falcbase + F_REG(FMR1, ch), 985 cpc_writeb(falcbase + F_REG(FMR1, ch),
@@ -1187,7 +1185,7 @@ static void te_config(pc300_t * card, int ch)
1187 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; 1185 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
1188 falc_t *pfalc = (falc_t *) & chan->falc; 1186 falc_t *pfalc = (falc_t *) & chan->falc;
1189 void __iomem *falcbase = card->hw.falcbase; 1187 void __iomem *falcbase = card->hw.falcbase;
1190 ucchar dummy; 1188 u8 dummy;
1191 unsigned long flags; 1189 unsigned long flags;
1192 1190
1193 memset(pfalc, 0, sizeof(falc_t)); 1191 memset(pfalc, 0, sizeof(falc_t));
@@ -1403,7 +1401,7 @@ static void falc_update_stats(pc300_t * card, int ch)
1403 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; 1401 pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
1404 falc_t *pfalc = (falc_t *) & chan->falc; 1402 falc_t *pfalc = (falc_t *) & chan->falc;
1405 void __iomem *falcbase = card->hw.falcbase; 1403 void __iomem *falcbase = card->hw.falcbase;
1406 ucshort counter; 1404 u16 counter;
1407 1405
1408 counter = cpc_readb(falcbase + F_REG(FECL, ch)); 1406 counter = cpc_readb(falcbase + F_REG(FECL, ch));
1409 counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8; 1407 counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8;
@@ -1729,7 +1727,7 @@ static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
1729 * Description: This routine returns the bit error counter value 1727 * Description: This routine returns the bit error counter value
1730 *---------------------------------------------------------------------------- 1728 *----------------------------------------------------------------------------
1731 */ 1729 */
1732static ucshort falc_pattern_test_error(pc300_t * card, int ch) 1730static u16 falc_pattern_test_error(pc300_t * card, int ch)
1733{ 1731{
1734 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; 1732 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
1735 falc_t *pfalc = (falc_t *) & chan->falc; 1733 falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1776,7 +1774,7 @@ static void cpc_tx_timeout(struct net_device *dev)
1776 pc300_t *card = (pc300_t *) chan->card; 1774 pc300_t *card = (pc300_t *) chan->card;
1777 int ch = chan->channel; 1775 int ch = chan->channel;
1778 unsigned long flags; 1776 unsigned long flags;
1779 ucchar ilar; 1777 u8 ilar;
1780 1778
1781 dev->stats.tx_errors++; 1779 dev->stats.tx_errors++;
1782 dev->stats.tx_aborted_errors++; 1780 dev->stats.tx_aborted_errors++;
@@ -1807,11 +1805,7 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
1807 int i; 1805 int i;
1808#endif 1806#endif
1809 1807
1810 if (chan->conf.monitor) { 1808 if (!netif_carrier_ok(dev)) {
1811 /* In monitor mode no Tx is done: ignore packet */
1812 dev_kfree_skb(skb);
1813 return 0;
1814 } else if (!netif_carrier_ok(dev)) {
1815 /* DCD must be OFF: drop packet */ 1809 /* DCD must be OFF: drop packet */
1816 dev_kfree_skb(skb); 1810 dev_kfree_skb(skb);
1817 dev->stats.tx_errors++; 1811 dev->stats.tx_errors++;
@@ -1836,7 +1830,7 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
1836 } 1830 }
1837 1831
1838 /* Write buffer to DMA buffers */ 1832 /* Write buffer to DMA buffers */
1839 if (dma_buf_write(card, ch, (ucchar *) skb->data, skb->len) != 0) { 1833 if (dma_buf_write(card, ch, (u8 *)skb->data, skb->len) != 0) {
1840// printk("%s: write error. Dropping TX packet.\n", dev->name); 1834// printk("%s: write error. Dropping TX packet.\n", dev->name);
1841 netif_stop_queue(dev); 1835 netif_stop_queue(dev);
1842 dev_kfree_skb(skb); 1836 dev_kfree_skb(skb);
@@ -2001,7 +1995,7 @@ static void sca_tx_intr(pc300dev_t *dev)
2001static void sca_intr(pc300_t * card) 1995static void sca_intr(pc300_t * card)
2002{ 1996{
2003 void __iomem *scabase = card->hw.scabase; 1997 void __iomem *scabase = card->hw.scabase;
2004 volatile uclong status; 1998 volatile u32 status;
2005 int ch; 1999 int ch;
2006 int intr_count = 0; 2000 int intr_count = 0;
2007 unsigned char dsr_rx; 2001 unsigned char dsr_rx;
@@ -2016,7 +2010,7 @@ static void sca_intr(pc300_t * card)
2016 2010
2017 /**** Reception ****/ 2011 /**** Reception ****/
2018 if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) { 2012 if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) {
2019 ucchar drx_stat = cpc_readb(scabase + DSR_RX(ch)); 2013 u8 drx_stat = cpc_readb(scabase + DSR_RX(ch));
2020 2014
2021 /* Clear RX interrupts */ 2015 /* Clear RX interrupts */
2022 cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE); 2016 cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE);
@@ -2090,7 +2084,7 @@ static void sca_intr(pc300_t * card)
2090 2084
2091 /**** Transmission ****/ 2085 /**** Transmission ****/
2092 if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) { 2086 if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) {
2093 ucchar dtx_stat = cpc_readb(scabase + DSR_TX(ch)); 2087 u8 dtx_stat = cpc_readb(scabase + DSR_TX(ch));
2094 2088
2095 /* Clear TX interrupts */ 2089 /* Clear TX interrupts */
2096 cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE); 2090 cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE);
@@ -2134,7 +2128,7 @@ static void sca_intr(pc300_t * card)
2134 2128
2135 /**** MSCI ****/ 2129 /**** MSCI ****/
2136 if (status & IR0_M(IR0_RXINTA, ch)) { 2130 if (status & IR0_M(IR0_RXINTA, ch)) {
2137 ucchar st1 = cpc_readb(scabase + M_REG(ST1, ch)); 2131 u8 st1 = cpc_readb(scabase + M_REG(ST1, ch));
2138 2132
2139 /* Clear MSCI interrupts */ 2133 /* Clear MSCI interrupts */
2140 cpc_writeb(scabase + M_REG(ST1, ch), st1); 2134 cpc_writeb(scabase + M_REG(ST1, ch), st1);
@@ -2176,7 +2170,7 @@ static void sca_intr(pc300_t * card)
2176 } 2170 }
2177} 2171}
2178 2172
2179static void falc_t1_loop_detection(pc300_t * card, int ch, ucchar frs1) 2173static void falc_t1_loop_detection(pc300_t *card, int ch, u8 frs1)
2180{ 2174{
2181 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; 2175 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
2182 falc_t *pfalc = (falc_t *) & chan->falc; 2176 falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2201,7 +2195,7 @@ static void falc_t1_loop_detection(pc300_t * card, int ch, ucchar frs1)
2201 } 2195 }
2202} 2196}
2203 2197
2204static void falc_e1_loop_detection(pc300_t * card, int ch, ucchar rsp) 2198static void falc_e1_loop_detection(pc300_t *card, int ch, u8 rsp)
2205{ 2199{
2206 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; 2200 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
2207 falc_t *pfalc = (falc_t *) & chan->falc; 2201 falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2231,8 +2225,8 @@ static void falc_t1_intr(pc300_t * card, int ch)
2231 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; 2225 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
2232 falc_t *pfalc = (falc_t *) & chan->falc; 2226 falc_t *pfalc = (falc_t *) & chan->falc;
2233 void __iomem *falcbase = card->hw.falcbase; 2227 void __iomem *falcbase = card->hw.falcbase;
2234 ucchar isr0, isr3, gis; 2228 u8 isr0, isr3, gis;
2235 ucchar dummy; 2229 u8 dummy;
2236 2230
2237 while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { 2231 while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
2238 if (gis & GIS_ISR0) { 2232 if (gis & GIS_ISR0) {
@@ -2278,8 +2272,8 @@ static void falc_e1_intr(pc300_t * card, int ch)
2278 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; 2272 pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
2279 falc_t *pfalc = (falc_t *) & chan->falc; 2273 falc_t *pfalc = (falc_t *) & chan->falc;
2280 void __iomem *falcbase = card->hw.falcbase; 2274 void __iomem *falcbase = card->hw.falcbase;
2281 ucchar isr1, isr2, isr3, gis, rsp; 2275 u8 isr1, isr2, isr3, gis, rsp;
2282 ucchar dummy; 2276 u8 dummy;
2283 2277
2284 while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { 2278 while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
2285 rsp = cpc_readb(falcbase + F_REG(RSP, ch)); 2279 rsp = cpc_readb(falcbase + F_REG(RSP, ch));
@@ -2361,7 +2355,7 @@ static void falc_intr(pc300_t * card)
2361static irqreturn_t cpc_intr(int irq, void *dev_id) 2355static irqreturn_t cpc_intr(int irq, void *dev_id)
2362{ 2356{
2363 pc300_t *card = dev_id; 2357 pc300_t *card = dev_id;
2364 volatile ucchar plx_status; 2358 volatile u8 plx_status;
2365 2359
2366 if (!card) { 2360 if (!card) {
2367#ifdef PC300_DEBUG_INTR 2361#ifdef PC300_DEBUG_INTR
@@ -2400,7 +2394,7 @@ static irqreturn_t cpc_intr(int irq, void *dev_id)
2400 2394
2401static void cpc_sca_status(pc300_t * card, int ch) 2395static void cpc_sca_status(pc300_t * card, int ch)
2402{ 2396{
2403 ucchar ilar; 2397 u8 ilar;
2404 void __iomem *scabase = card->hw.scabase; 2398 void __iomem *scabase = card->hw.scabase;
2405 unsigned long flags; 2399 unsigned long flags;
2406 2400
@@ -2818,7 +2812,7 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2818 } 2812 }
2819} 2813}
2820 2814
2821static int clock_rate_calc(uclong rate, uclong clock, int *br_io) 2815static int clock_rate_calc(u32 rate, u32 clock, int *br_io)
2822{ 2816{
2823 int br, tc; 2817 int br, tc;
2824 int br_pwr, error; 2818 int br_pwr, error;
@@ -2855,12 +2849,12 @@ static int ch_config(pc300dev_t * d)
2855 void __iomem *scabase = card->hw.scabase; 2849 void __iomem *scabase = card->hw.scabase;
2856 void __iomem *plxbase = card->hw.plxbase; 2850 void __iomem *plxbase = card->hw.plxbase;
2857 int ch = chan->channel; 2851 int ch = chan->channel;
2858 uclong clkrate = chan->conf.phys_settings.clock_rate; 2852 u32 clkrate = chan->conf.phys_settings.clock_rate;
2859 uclong clktype = chan->conf.phys_settings.clock_type; 2853 u32 clktype = chan->conf.phys_settings.clock_type;
2860 ucshort encoding = chan->conf.proto_settings.encoding; 2854 u16 encoding = chan->conf.proto_settings.encoding;
2861 ucshort parity = chan->conf.proto_settings.parity; 2855 u16 parity = chan->conf.proto_settings.parity;
2862 ucchar md0, md2; 2856 u8 md0, md2;
2863 2857
2864 /* Reset the channel */ 2858 /* Reset the channel */
2865 cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST); 2859 cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST);
2866 2860
@@ -3152,19 +3146,10 @@ int cpc_open(struct net_device *dev)
3152 printk("pc300: cpc_open"); 3146 printk("pc300: cpc_open");
3153#endif 3147#endif
3154 3148
3155#ifdef FIXME
3156 if (hdlc->proto.id == IF_PROTO_PPP) {
3157 d->if_ptr = &hdlc->state.ppp.pppdev;
3158 }
3159#endif
3160
3161 result = hdlc_open(dev); 3149 result = hdlc_open(dev);
3162 if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) { 3150
3163 dev->priv = d; 3151 if (result)
3164 }
3165 if (result) {
3166 return result; 3152 return result;
3167 }
3168 3153
3169 sprintf(ifr.ifr_name, "%s", dev->name); 3154 sprintf(ifr.ifr_name, "%s", dev->name);
3170 result = cpc_opench(d); 3155 result = cpc_opench(d);
@@ -3197,9 +3182,7 @@ static int cpc_close(struct net_device *dev)
3197 CPC_UNLOCK(card, flags); 3182 CPC_UNLOCK(card, flags);
3198 3183
3199 hdlc_close(dev); 3184 hdlc_close(dev);
3200 if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) { 3185
3201 d->if_ptr = NULL;
3202 }
3203#ifdef CONFIG_PC300_MLPPP 3186#ifdef CONFIG_PC300_MLPPP
3204 if (chan->conf.proto == PC300_PROTO_MLPPP) { 3187 if (chan->conf.proto == PC300_PROTO_MLPPP) {
3205 cpc_tty_unregister_service(d); 3188 cpc_tty_unregister_service(d);
@@ -3210,16 +3193,16 @@ static int cpc_close(struct net_device *dev)
3210 return 0; 3193 return 0;
3211} 3194}
3212 3195
3213static uclong detect_ram(pc300_t * card) 3196static u32 detect_ram(pc300_t * card)
3214{ 3197{
3215 uclong i; 3198 u32 i;
3216 ucchar data; 3199 u8 data;
3217 void __iomem *rambase = card->hw.rambase; 3200 void __iomem *rambase = card->hw.rambase;
3218 3201
3219 card->hw.ramsize = PC300_RAMSIZE; 3202 card->hw.ramsize = PC300_RAMSIZE;
3220 /* Let's find out how much RAM is present on this board */ 3203 /* Let's find out how much RAM is present on this board */
3221 for (i = 0; i < card->hw.ramsize; i++) { 3204 for (i = 0; i < card->hw.ramsize; i++) {
3222 data = (ucchar) (i & 0xff); 3205 data = (u8)(i & 0xff);
3223 cpc_writeb(rambase + i, data); 3206 cpc_writeb(rambase + i, data);
3224 if (cpc_readb(rambase + i) != data) { 3207 if (cpc_readb(rambase + i) != data) {
3225 break; 3208 break;
@@ -3296,7 +3279,7 @@ static void cpc_init_card(pc300_t * card)
3296 cpc_writeb(card->hw.scabase + DMER, 0x80); 3279 cpc_writeb(card->hw.scabase + DMER, 0x80);
3297 3280
3298 if (card->hw.type == PC300_TE) { 3281 if (card->hw.type == PC300_TE) {
3299 ucchar reg1; 3282 u8 reg1;
3300 3283
3301 /* Check CPLD version */ 3284 /* Check CPLD version */
3302 reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1); 3285 reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1);
@@ -3360,7 +3343,6 @@ static void cpc_init_card(pc300_t * card)
3360 chan->nfree_tx_bd = N_DMA_TX_BUF; 3343 chan->nfree_tx_bd = N_DMA_TX_BUF;
3361 3344
3362 d->chan = chan; 3345 d->chan = chan;
3363 d->tx_skb = NULL;
3364 d->trace_on = 0; 3346 d->trace_on = 0;
3365 d->line_on = 0; 3347 d->line_on = 0;
3366 d->line_off = 0; 3348 d->line_off = 0;
@@ -3431,7 +3413,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
3431{ 3413{
3432 static int first_time = 1; 3414 static int first_time = 1;
3433 int err, eeprom_outdated = 0; 3415 int err, eeprom_outdated = 0;
3434 ucshort device_id; 3416 u16 device_id;
3435 pc300_t *card; 3417 pc300_t *card;
3436 3418
3437 if (first_time) { 3419 if (first_time) {
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 44a89df1b8bf..c0235844a4d5 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -8,6 +8,7 @@
8 * 8 *
9 * (c) Copyright 1999, 2001 Alan Cox 9 * (c) Copyright 1999, 2001 Alan Cox
10 * (c) Copyright 2001 Red Hat Inc. 10 * (c) Copyright 2001 Red Hat Inc.
11 * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
11 * 12 *
12 */ 13 */
13 14
@@ -19,6 +20,7 @@
19#include <linux/netdevice.h> 20#include <linux/netdevice.h>
20#include <linux/if_arp.h> 21#include <linux/if_arp.h>
21#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/hdlc.h>
22#include <linux/ioport.h> 24#include <linux/ioport.h>
23#include <linux/init.h> 25#include <linux/init.h>
24#include <net/arp.h> 26#include <net/arp.h>
@@ -27,22 +29,19 @@
27#include <asm/io.h> 29#include <asm/io.h>
28#include <asm/dma.h> 30#include <asm/dma.h>
29#include <asm/byteorder.h> 31#include <asm/byteorder.h>
30#include <net/syncppp.h>
31#include "z85230.h" 32#include "z85230.h"
32 33
33 34
34struct slvl_device 35struct slvl_device
35{ 36{
36 void *if_ptr; /* General purpose pointer (used by SPPP) */
37 struct z8530_channel *chan; 37 struct z8530_channel *chan;
38 struct ppp_device pppdev;
39 int channel; 38 int channel;
40}; 39};
41 40
42 41
43struct slvl_board 42struct slvl_board
44{ 43{
45 struct slvl_device *dev[2]; 44 struct slvl_device dev[2];
46 struct z8530_dev board; 45 struct z8530_dev board;
47 int iobase; 46 int iobase;
48}; 47};
@@ -51,72 +50,69 @@ struct slvl_board
51 * Network driver support routines 50 * Network driver support routines
52 */ 51 */
53 52
53static inline struct slvl_device* dev_to_chan(struct net_device *dev)
54{
55 return (struct slvl_device *)dev_to_hdlc(dev)->priv;
56}
57
54/* 58/*
55 * Frame receive. Simple for our card as we do sync ppp and there 59 * Frame receive. Simple for our card as we do HDLC and there
56 * is no funny garbage involved 60 * is no funny garbage involved
57 */ 61 */
58 62
59static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb) 63static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb)
60{ 64{
61 /* Drop the CRC - it's not a good idea to try and negotiate it ;) */ 65 /* Drop the CRC - it's not a good idea to try and negotiate it ;) */
62 skb_trim(skb, skb->len-2); 66 skb_trim(skb, skb->len - 2);
63 skb->protocol=htons(ETH_P_WAN_PPP); 67 skb->protocol = hdlc_type_trans(skb, c->netdevice);
64 skb_reset_mac_header(skb); 68 skb_reset_mac_header(skb);
65 skb->dev=c->netdevice; 69 skb->dev = c->netdevice;
66 /*
67 * Send it to the PPP layer. We don't have time to process
68 * it right now.
69 */
70 netif_rx(skb); 70 netif_rx(skb);
71 c->netdevice->last_rx = jiffies; 71 c->netdevice->last_rx = jiffies;
72} 72}
73 73
74/* 74/*
75 * We've been placed in the UP state 75 * We've been placed in the UP state
76 */ 76 */
77 77
78static int sealevel_open(struct net_device *d) 78static int sealevel_open(struct net_device *d)
79{ 79{
80 struct slvl_device *slvl=d->priv; 80 struct slvl_device *slvl = dev_to_chan(d);
81 int err = -1; 81 int err = -1;
82 int unit = slvl->channel; 82 int unit = slvl->channel;
83 83
84 /* 84 /*
85 * Link layer up. 85 * Link layer up.
86 */ 86 */
87 87
88 switch(unit) 88 switch (unit)
89 { 89 {
90 case 0: 90 case 0:
91 err=z8530_sync_dma_open(d, slvl->chan); 91 err = z8530_sync_dma_open(d, slvl->chan);
92 break; 92 break;
93 case 1: 93 case 1:
94 err=z8530_sync_open(d, slvl->chan); 94 err = z8530_sync_open(d, slvl->chan);
95 break; 95 break;
96 } 96 }
97 97
98 if(err) 98 if (err)
99 return err; 99 return err;
100 /* 100
101 * Begin PPP 101 err = hdlc_open(d);
102 */ 102 if (err) {
103 err=sppp_open(d); 103 switch (unit) {
104 if(err)
105 {
106 switch(unit)
107 {
108 case 0: 104 case 0:
109 z8530_sync_dma_close(d, slvl->chan); 105 z8530_sync_dma_close(d, slvl->chan);
110 break; 106 break;
111 case 1: 107 case 1:
112 z8530_sync_close(d, slvl->chan); 108 z8530_sync_close(d, slvl->chan);
113 break; 109 break;
114 } 110 }
115 return err; 111 return err;
116 } 112 }
117 113
118 slvl->chan->rx_function=sealevel_input; 114 slvl->chan->rx_function = sealevel_input;
119 115
120 /* 116 /*
121 * Go go go 117 * Go go go
122 */ 118 */
@@ -126,26 +122,19 @@ static int sealevel_open(struct net_device *d)
126 122
127static int sealevel_close(struct net_device *d) 123static int sealevel_close(struct net_device *d)
128{ 124{
129 struct slvl_device *slvl=d->priv; 125 struct slvl_device *slvl = dev_to_chan(d);
130 int unit = slvl->channel; 126 int unit = slvl->channel;
131 127
132 /* 128 /*
133 * Discard new frames 129 * Discard new frames
134 */ 130 */
135
136 slvl->chan->rx_function=z8530_null_rx;
137
138 /*
139 * PPP off
140 */
141 sppp_close(d);
142 /*
143 * Link layer down
144 */
145 131
132 slvl->chan->rx_function = z8530_null_rx;
133
134 hdlc_close(d);
146 netif_stop_queue(d); 135 netif_stop_queue(d);
147 136
148 switch(unit) 137 switch (unit)
149 { 138 {
150 case 0: 139 case 0:
151 z8530_sync_dma_close(d, slvl->chan); 140 z8530_sync_dma_close(d, slvl->chan);
@@ -159,210 +148,153 @@ static int sealevel_close(struct net_device *d)
159 148
160static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) 149static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
161{ 150{
162 /* struct slvl_device *slvl=d->priv; 151 /* struct slvl_device *slvl=dev_to_chan(d);
163 z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) */ 152 z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) */
164 return sppp_do_ioctl(d, ifr,cmd); 153 return hdlc_ioctl(d, ifr, cmd);
165}
166
167static struct net_device_stats *sealevel_get_stats(struct net_device *d)
168{
169 struct slvl_device *slvl=d->priv;
170 if(slvl)
171 return z8530_get_stats(slvl->chan);
172 else
173 return NULL;
174} 154}
175 155
176/* 156/*
177 * Passed PPP frames, fire them downwind. 157 * Passed network frames, fire them downwind.
178 */ 158 */
179 159
180static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d) 160static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d)
181{ 161{
182 struct slvl_device *slvl=d->priv; 162 return z8530_queue_xmit(dev_to_chan(d)->chan, skb);
183 return z8530_queue_xmit(slvl->chan, skb);
184} 163}
185 164
186static int sealevel_neigh_setup(struct neighbour *n) 165static int sealevel_attach(struct net_device *dev, unsigned short encoding,
166 unsigned short parity)
187{ 167{
188 if (n->nud_state == NUD_NONE) { 168 if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
189 n->ops = &arp_broken_ops; 169 return 0;
190 n->output = n->ops->output; 170 return -EINVAL;
191 }
192 return 0;
193} 171}
194 172
195static int sealevel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p) 173static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
196{ 174{
197 if (p->tbl->family == AF_INET) { 175 struct net_device *dev = alloc_hdlcdev(sv);
198 p->neigh_setup = sealevel_neigh_setup; 176 if (!dev)
199 p->ucast_probes = 0; 177 return -1;
200 p->mcast_probes = 0; 178
179 dev_to_hdlc(dev)->attach = sealevel_attach;
180 dev_to_hdlc(dev)->xmit = sealevel_queue_xmit;
181 dev->open = sealevel_open;
182 dev->stop = sealevel_close;
183 dev->do_ioctl = sealevel_ioctl;
184 dev->base_addr = iobase;
185 dev->irq = irq;
186
187 if (register_hdlc_device(dev)) {
188 printk(KERN_ERR "sealevel: unable to register HDLC device\n");
189 free_netdev(dev);
190 return -1;
201 } 191 }
202 return 0;
203}
204 192
205static int sealevel_attach(struct net_device *dev) 193 sv->chan->netdevice = dev;
206{
207 struct slvl_device *sv = dev->priv;
208 sppp_attach(&sv->pppdev);
209 return 0; 194 return 0;
210} 195}
211 196
212static void sealevel_detach(struct net_device *dev)
213{
214 sppp_detach(dev);
215}
216
217static void slvl_setup(struct net_device *d)
218{
219 d->open = sealevel_open;
220 d->stop = sealevel_close;
221 d->init = sealevel_attach;
222 d->uninit = sealevel_detach;
223 d->hard_start_xmit = sealevel_queue_xmit;
224 d->get_stats = sealevel_get_stats;
225 d->set_multicast_list = NULL;
226 d->do_ioctl = sealevel_ioctl;
227 d->neigh_setup = sealevel_neigh_setup_dev;
228 d->set_mac_address = NULL;
229
230}
231
232static inline struct slvl_device *slvl_alloc(int iobase, int irq)
233{
234 struct net_device *d;
235 struct slvl_device *sv;
236
237 d = alloc_netdev(sizeof(struct slvl_device), "hdlc%d",
238 slvl_setup);
239
240 if (!d)
241 return NULL;
242
243 sv = d->priv;
244 d->ml_priv = sv;
245 sv->if_ptr = &sv->pppdev;
246 sv->pppdev.dev = d;
247 d->base_addr = iobase;
248 d->irq = irq;
249
250 return sv;
251}
252
253 197
254/* 198/*
255 * Allocate and setup Sealevel board. 199 * Allocate and setup Sealevel board.
256 */ 200 */
257 201
258static __init struct slvl_board *slvl_init(int iobase, int irq, 202static __init struct slvl_board *slvl_init(int iobase, int irq,
259 int txdma, int rxdma, int slow) 203 int txdma, int rxdma, int slow)
260{ 204{
261 struct z8530_dev *dev; 205 struct z8530_dev *dev;
262 struct slvl_board *b; 206 struct slvl_board *b;
263 207
264 /* 208 /*
265 * Get the needed I/O space 209 * Get the needed I/O space
266 */ 210 */
267 211
268 if(!request_region(iobase, 8, "Sealevel 4021")) 212 if (!request_region(iobase, 8, "Sealevel 4021")) {
269 { 213 printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n",
270 printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n", iobase); 214 iobase);
271 return NULL; 215 return NULL;
272 } 216 }
273
274 b = kzalloc(sizeof(struct slvl_board), GFP_KERNEL);
275 if(!b)
276 goto fail3;
277 217
278 if (!(b->dev[0]= slvl_alloc(iobase, irq))) 218 b = kzalloc(sizeof(struct slvl_board), GFP_KERNEL);
279 goto fail2; 219 if (!b)
220 goto err_kzalloc;
280 221
281 b->dev[0]->chan = &b->board.chanA; 222 b->dev[0].chan = &b->board.chanA;
282 b->dev[0]->channel = 0; 223 b->dev[0].channel = 0;
283
284 if (!(b->dev[1] = slvl_alloc(iobase, irq)))
285 goto fail1_0;
286 224
287 b->dev[1]->chan = &b->board.chanB; 225 b->dev[1].chan = &b->board.chanB;
288 b->dev[1]->channel = 1; 226 b->dev[1].channel = 1;
289 227
290 dev = &b->board; 228 dev = &b->board;
291 229
292 /* 230 /*
293 * Stuff in the I/O addressing 231 * Stuff in the I/O addressing
294 */ 232 */
295 233
296 dev->active = 0; 234 dev->active = 0;
297 235
298 b->iobase = iobase; 236 b->iobase = iobase;
299 237
300 /* 238 /*
301 * Select 8530 delays for the old board 239 * Select 8530 delays for the old board
302 */ 240 */
303 241
304 if(slow) 242 if (slow)
305 iobase |= Z8530_PORT_SLEEP; 243 iobase |= Z8530_PORT_SLEEP;
306 244
307 dev->chanA.ctrlio=iobase+1; 245 dev->chanA.ctrlio = iobase + 1;
308 dev->chanA.dataio=iobase; 246 dev->chanA.dataio = iobase;
309 dev->chanB.ctrlio=iobase+3; 247 dev->chanB.ctrlio = iobase + 3;
310 dev->chanB.dataio=iobase+2; 248 dev->chanB.dataio = iobase + 2;
311 249
312 dev->chanA.irqs=&z8530_nop; 250 dev->chanA.irqs = &z8530_nop;
313 dev->chanB.irqs=&z8530_nop; 251 dev->chanB.irqs = &z8530_nop;
314 252
315 /* 253 /*
316 * Assert DTR enable DMA 254 * Assert DTR enable DMA
317 */ 255 */
318 256
319 outb(3|(1<<7), b->iobase+4); 257 outb(3 | (1 << 7), b->iobase + 4);
320 258
321 259
322 /* We want a fast IRQ for this device. Actually we'd like an even faster 260 /* We want a fast IRQ for this device. Actually we'd like an even faster
323 IRQ ;) - This is one driver RtLinux is made for */ 261 IRQ ;) - This is one driver RtLinux is made for */
324 262
325 if(request_irq(irq, &z8530_interrupt, IRQF_DISABLED, "SeaLevel", dev)<0) 263 if (request_irq(irq, &z8530_interrupt, IRQF_DISABLED,
326 { 264 "SeaLevel", dev) < 0) {
327 printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq); 265 printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq);
328 goto fail1_1; 266 goto err_request_irq;
329 } 267 }
330 268
331 dev->irq=irq; 269 dev->irq = irq;
332 dev->chanA.private=&b->dev[0]; 270 dev->chanA.private = &b->dev[0];
333 dev->chanB.private=&b->dev[1]; 271 dev->chanB.private = &b->dev[1];
334 dev->chanA.netdevice=b->dev[0]->pppdev.dev; 272 dev->chanA.dev = dev;
335 dev->chanB.netdevice=b->dev[1]->pppdev.dev; 273 dev->chanB.dev = dev;
336 dev->chanA.dev=dev; 274
337 dev->chanB.dev=dev; 275 dev->chanA.txdma = 3;
338 276 dev->chanA.rxdma = 1;
339 dev->chanA.txdma=3; 277 if (request_dma(dev->chanA.txdma, "SeaLevel (TX)"))
340 dev->chanA.rxdma=1; 278 goto err_dma_tx;
341 if(request_dma(dev->chanA.txdma, "SeaLevel (TX)")!=0) 279
342 goto fail; 280 if (request_dma(dev->chanA.rxdma, "SeaLevel (RX)"))
343 281 goto err_dma_rx;
344 if(request_dma(dev->chanA.rxdma, "SeaLevel (RX)")!=0) 282
345 goto dmafail;
346
347 disable_irq(irq); 283 disable_irq(irq);
348 284
349 /* 285 /*
350 * Begin normal initialise 286 * Begin normal initialise
351 */ 287 */
352 288
353 if(z8530_init(dev)!=0) 289 if (z8530_init(dev) != 0) {
354 {
355 printk(KERN_ERR "Z8530 series device not found.\n"); 290 printk(KERN_ERR "Z8530 series device not found.\n");
356 enable_irq(irq); 291 enable_irq(irq);
357 goto dmafail2; 292 goto free_hw;
358 } 293 }
359 if(dev->type==Z85C30) 294 if (dev->type == Z85C30) {
360 {
361 z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream); 295 z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
362 z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream); 296 z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream);
363 } 297 } else {
364 else
365 {
366 z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230); 298 z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230);
367 z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream_85230); 299 z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream_85230);
368 } 300 }
@@ -370,36 +302,31 @@ static __init struct slvl_board *slvl_init(int iobase, int irq,
370 /* 302 /*
371 * Now we can take the IRQ 303 * Now we can take the IRQ
372 */ 304 */
373 305
374 enable_irq(irq); 306 enable_irq(irq);
375 307
376 if (register_netdev(b->dev[0]->pppdev.dev)) 308 if (slvl_setup(&b->dev[0], iobase, irq))
377 goto dmafail2; 309 goto free_hw;
378 310 if (slvl_setup(&b->dev[1], iobase, irq))
379 if (register_netdev(b->dev[1]->pppdev.dev)) 311 goto free_netdev0;
380 goto fail_unit;
381 312
382 z8530_describe(dev, "I/O", iobase); 313 z8530_describe(dev, "I/O", iobase);
383 dev->active=1; 314 dev->active = 1;
384 return b; 315 return b;
385 316
386fail_unit: 317free_netdev0:
387 unregister_netdev(b->dev[0]->pppdev.dev); 318 unregister_hdlc_device(b->dev[0].chan->netdevice);
388 319 free_netdev(b->dev[0].chan->netdevice);
389dmafail2: 320free_hw:
390 free_dma(dev->chanA.rxdma); 321 free_dma(dev->chanA.rxdma);
391dmafail: 322err_dma_rx:
392 free_dma(dev->chanA.txdma); 323 free_dma(dev->chanA.txdma);
393fail: 324err_dma_tx:
394 free_irq(irq, dev); 325 free_irq(irq, dev);
395fail1_1: 326err_request_irq:
396 free_netdev(b->dev[1]->pppdev.dev);
397fail1_0:
398 free_netdev(b->dev[0]->pppdev.dev);
399fail2:
400 kfree(b); 327 kfree(b);
401fail3: 328err_kzalloc:
402 release_region(iobase,8); 329 release_region(iobase, 8);
403 return NULL; 330 return NULL;
404} 331}
405 332
@@ -408,14 +335,14 @@ static void __exit slvl_shutdown(struct slvl_board *b)
408 int u; 335 int u;
409 336
410 z8530_shutdown(&b->board); 337 z8530_shutdown(&b->board);
411 338
412 for(u=0; u<2; u++) 339 for (u = 0; u < 2; u++)
413 { 340 {
414 struct net_device *d = b->dev[u]->pppdev.dev; 341 struct net_device *d = b->dev[u].chan->netdevice;
415 unregister_netdev(d); 342 unregister_hdlc_device(d);
416 free_netdev(d); 343 free_netdev(d);
417 } 344 }
418 345
419 free_irq(b->board.irq, &b->board); 346 free_irq(b->board.irq, &b->board);
420 free_dma(b->board.chanA.rxdma); 347 free_dma(b->board.chanA.rxdma);
421 free_dma(b->board.chanA.txdma); 348 free_dma(b->board.chanA.txdma);
@@ -451,10 +378,6 @@ static struct slvl_board *slvl_unit;
451 378
452static int __init slvl_init_module(void) 379static int __init slvl_init_module(void)
453{ 380{
454#ifdef MODULE
455 printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.02.\n");
456 printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");
457#endif
458 slvl_unit = slvl_init(io, irq, txdma, rxdma, slow); 381 slvl_unit = slvl_init(io, irq, txdma, rxdma, slow);
459 382
460 return slvl_unit ? 0 : -ENODEV; 383 return slvl_unit ? 0 : -ENODEV;
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 29b4b94e4947..327d58589e12 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -230,13 +230,6 @@ static void sppp_input (struct net_device *dev, struct sk_buff *skb)
230 skb->dev=dev; 230 skb->dev=dev;
231 skb_reset_mac_header(skb); 231 skb_reset_mac_header(skb);
232 232
233 if (dev->flags & IFF_RUNNING)
234 {
235 /* Count received bytes, add FCS and one flag */
236 sp->ibytes+= skb->len + 3;
237 sp->ipkts++;
238 }
239
240 if (!pskb_may_pull(skb, PPP_HEADER_LEN)) { 233 if (!pskb_may_pull(skb, PPP_HEADER_LEN)) {
241 /* Too small packet, drop it. */ 234 /* Too small packet, drop it. */
242 if (sp->pp_flags & PP_DEBUG) 235 if (sp->pp_flags & PP_DEBUG)
@@ -832,7 +825,6 @@ static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
832 sppp_print_bytes ((u8*) (lh+1), len); 825 sppp_print_bytes ((u8*) (lh+1), len);
833 printk (">\n"); 826 printk (">\n");
834 } 827 }
835 sp->obytes += skb->len;
836 /* Control is high priority so it doesn't get queued behind data */ 828 /* Control is high priority so it doesn't get queued behind data */
837 skb->priority=TC_PRIO_CONTROL; 829 skb->priority=TC_PRIO_CONTROL;
838 skb->dev = dev; 830 skb->dev = dev;
@@ -875,7 +867,6 @@ static void sppp_cisco_send (struct sppp *sp, int type, u32 par1, u32 par2)
875 printk (KERN_WARNING "%s: cisco output: <%xh %xh %xh %xh %xh-%xh>\n", 867 printk (KERN_WARNING "%s: cisco output: <%xh %xh %xh %xh %xh-%xh>\n",
876 dev->name, ntohl (ch->type), ch->par1, 868 dev->name, ntohl (ch->type), ch->par1,
877 ch->par2, ch->rel, ch->time0, ch->time1); 869 ch->par2, ch->rel, ch->time0, ch->time1);
878 sp->obytes += skb->len;
879 skb->priority=TC_PRIO_CONTROL; 870 skb->priority=TC_PRIO_CONTROL;
880 skb->dev = dev; 871 skb->dev = dev;
881 skb_queue_tail(&tx_queue, skb); 872 skb_queue_tail(&tx_queue, skb);
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 98ef400908b8..243bd8d918fe 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -43,6 +43,7 @@
43#include <linux/netdevice.h> 43#include <linux/netdevice.h>
44#include <linux/if_arp.h> 44#include <linux/if_arp.h>
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/hdlc.h>
46#include <linux/ioport.h> 47#include <linux/ioport.h>
47#include <linux/init.h> 48#include <linux/init.h>
48#include <asm/dma.h> 49#include <asm/dma.h>
@@ -51,7 +52,6 @@
51#define RT_UNLOCK 52#define RT_UNLOCK
52#include <linux/spinlock.h> 53#include <linux/spinlock.h>
53 54
54#include <net/syncppp.h>
55#include "z85230.h" 55#include "z85230.h"
56 56
57 57
@@ -440,51 +440,46 @@ static void z8530_tx(struct z8530_channel *c)
440 * A status event occurred in PIO synchronous mode. There are several 440 * A status event occurred in PIO synchronous mode. There are several
441 * reasons the chip will bother us here. A transmit underrun means we 441 * reasons the chip will bother us here. A transmit underrun means we
442 * failed to feed the chip fast enough and just broke a packet. A DCD 442 * failed to feed the chip fast enough and just broke a packet. A DCD
443 * change is a line up or down. We communicate that back to the protocol 443 * change is a line up or down.
444 * layer for synchronous PPP to renegotiate.
445 */ 444 */
446 445
447static void z8530_status(struct z8530_channel *chan) 446static void z8530_status(struct z8530_channel *chan)
448{ 447{
449 u8 status, altered; 448 u8 status, altered;
450 449
451 status=read_zsreg(chan, R0); 450 status = read_zsreg(chan, R0);
452 altered=chan->status^status; 451 altered = chan->status ^ status;
453 452
454 chan->status=status; 453 chan->status = status;
455 454
456 if(status&TxEOM) 455 if (status & TxEOM) {
457 {
458/* printk("%s: Tx underrun.\n", chan->dev->name); */ 456/* printk("%s: Tx underrun.\n", chan->dev->name); */
459 chan->stats.tx_fifo_errors++; 457 chan->netdevice->stats.tx_fifo_errors++;
460 write_zsctrl(chan, ERR_RES); 458 write_zsctrl(chan, ERR_RES);
461 z8530_tx_done(chan); 459 z8530_tx_done(chan);
462 } 460 }
463 461
464 if(altered&chan->dcdcheck) 462 if (altered & chan->dcdcheck)
465 { 463 {
466 if(status&chan->dcdcheck) 464 if (status & chan->dcdcheck) {
467 {
468 printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); 465 printk(KERN_INFO "%s: DCD raised\n", chan->dev->name);
469 write_zsreg(chan, R3, chan->regs[3]|RxENABLE); 466 write_zsreg(chan, R3, chan->regs[3] | RxENABLE);
470 if(chan->netdevice && 467 if (chan->netdevice)
471 ((chan->netdevice->type == ARPHRD_HDLC) || 468 netif_carrier_on(chan->netdevice);
472 (chan->netdevice->type == ARPHRD_PPP))) 469 } else {
473 sppp_reopen(chan->netdevice);
474 }
475 else
476 {
477 printk(KERN_INFO "%s: DCD lost\n", chan->dev->name); 470 printk(KERN_INFO "%s: DCD lost\n", chan->dev->name);
478 write_zsreg(chan, R3, chan->regs[3]&~RxENABLE); 471 write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE);
479 z8530_flush_fifo(chan); 472 z8530_flush_fifo(chan);
473 if (chan->netdevice)
474 netif_carrier_off(chan->netdevice);
480 } 475 }
481 476
482 } 477 }
483 write_zsctrl(chan, RES_EXT_INT); 478 write_zsctrl(chan, RES_EXT_INT);
484 write_zsctrl(chan, RES_H_IUS); 479 write_zsctrl(chan, RES_H_IUS);
485} 480}
486 481
487struct z8530_irqhandler z8530_sync= 482struct z8530_irqhandler z8530_sync =
488{ 483{
489 z8530_rx, 484 z8530_rx,
490 z8530_tx, 485 z8530_tx,
@@ -556,8 +551,7 @@ static void z8530_dma_tx(struct z8530_channel *chan)
556 * 551 *
557 * A status event occurred on the Z8530. We receive these for two reasons 552 * A status event occurred on the Z8530. We receive these for two reasons
558 * when in DMA mode. Firstly if we finished a packet transfer we get one 553 * when in DMA mode. Firstly if we finished a packet transfer we get one
559 * and kick the next packet out. Secondly we may see a DCD change and 554 * and kick the next packet out. Secondly we may see a DCD change.
560 * have to poke the protocol layer.
561 * 555 *
562 */ 556 */
563 557
@@ -586,24 +580,21 @@ static void z8530_dma_status(struct z8530_channel *chan)
586 } 580 }
587 } 581 }
588 582
589 if(altered&chan->dcdcheck) 583 if (altered & chan->dcdcheck)
590 { 584 {
591 if(status&chan->dcdcheck) 585 if (status & chan->dcdcheck) {
592 {
593 printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); 586 printk(KERN_INFO "%s: DCD raised\n", chan->dev->name);
594 write_zsreg(chan, R3, chan->regs[3]|RxENABLE); 587 write_zsreg(chan, R3, chan->regs[3] | RxENABLE);
595 if(chan->netdevice && 588 if (chan->netdevice)
596 ((chan->netdevice->type == ARPHRD_HDLC) || 589 netif_carrier_on(chan->netdevice);
597 (chan->netdevice->type == ARPHRD_PPP))) 590 } else {
598 sppp_reopen(chan->netdevice);
599 }
600 else
601 {
602 printk(KERN_INFO "%s:DCD lost\n", chan->dev->name); 591 printk(KERN_INFO "%s:DCD lost\n", chan->dev->name);
603 write_zsreg(chan, R3, chan->regs[3]&~RxENABLE); 592 write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE);
604 z8530_flush_fifo(chan); 593 z8530_flush_fifo(chan);
594 if (chan->netdevice)
595 netif_carrier_off(chan->netdevice);
605 } 596 }
606 } 597 }
607 598
608 write_zsctrl(chan, RES_EXT_INT); 599 write_zsctrl(chan, RES_EXT_INT);
609 write_zsctrl(chan, RES_H_IUS); 600 write_zsctrl(chan, RES_H_IUS);
@@ -1459,10 +1450,10 @@ static void z8530_tx_begin(struct z8530_channel *c)
1459 /* 1450 /*
1460 * Check if we crapped out. 1451 * Check if we crapped out.
1461 */ 1452 */
1462 if(get_dma_residue(c->txdma)) 1453 if (get_dma_residue(c->txdma))
1463 { 1454 {
1464 c->stats.tx_dropped++; 1455 c->netdevice->stats.tx_dropped++;
1465 c->stats.tx_fifo_errors++; 1456 c->netdevice->stats.tx_fifo_errors++;
1466 } 1457 }
1467 release_dma_lock(flags); 1458 release_dma_lock(flags);
1468 } 1459 }
@@ -1534,21 +1525,21 @@ static void z8530_tx_begin(struct z8530_channel *c)
1534 * packet. This code is fairly timing sensitive. 1525 * packet. This code is fairly timing sensitive.
1535 * 1526 *
1536 * Called with the register lock held. 1527 * Called with the register lock held.
1537 */ 1528 */
1538 1529
1539static void z8530_tx_done(struct z8530_channel *c) 1530static void z8530_tx_done(struct z8530_channel *c)
1540{ 1531{
1541 struct sk_buff *skb; 1532 struct sk_buff *skb;
1542 1533
1543 /* Actually this can happen.*/ 1534 /* Actually this can happen.*/
1544 if(c->tx_skb==NULL) 1535 if (c->tx_skb == NULL)
1545 return; 1536 return;
1546 1537
1547 skb=c->tx_skb; 1538 skb = c->tx_skb;
1548 c->tx_skb=NULL; 1539 c->tx_skb = NULL;
1549 z8530_tx_begin(c); 1540 z8530_tx_begin(c);
1550 c->stats.tx_packets++; 1541 c->netdevice->stats.tx_packets++;
1551 c->stats.tx_bytes+=skb->len; 1542 c->netdevice->stats.tx_bytes += skb->len;
1552 dev_kfree_skb_irq(skb); 1543 dev_kfree_skb_irq(skb);
1553} 1544}
1554 1545
@@ -1558,7 +1549,7 @@ static void z8530_tx_done(struct z8530_channel *c)
1558 * @skb: The buffer 1549 * @skb: The buffer
1559 * 1550 *
1560 * We point the receive handler at this function when idle. Instead 1551 * We point the receive handler at this function when idle. Instead
1561 * of syncppp processing the frames we get to throw them away. 1552 * of processing the frames we get to throw them away.
1562 */ 1553 */
1563 1554
1564void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb) 1555void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb)
@@ -1635,10 +1626,11 @@ static void z8530_rx_done(struct z8530_channel *c)
1635 else 1626 else
1636 /* Can't occur as we dont reenable the DMA irq until 1627 /* Can't occur as we dont reenable the DMA irq until
1637 after the flip is done */ 1628 after the flip is done */
1638 printk(KERN_WARNING "%s: DMA flip overrun!\n", c->netdevice->name); 1629 printk(KERN_WARNING "%s: DMA flip overrun!\n",
1639 1630 c->netdevice->name);
1631
1640 release_dma_lock(flags); 1632 release_dma_lock(flags);
1641 1633
1642 /* 1634 /*
1643 * Shove the old buffer into an sk_buff. We can't DMA 1635 * Shove the old buffer into an sk_buff. We can't DMA
1644 * directly into one on a PC - it might be above the 16Mb 1636 * directly into one on a PC - it might be above the 16Mb
@@ -1646,27 +1638,23 @@ static void z8530_rx_done(struct z8530_channel *c)
1646 * can avoid the copy. Optimisation 2 - make the memcpy 1638 * can avoid the copy. Optimisation 2 - make the memcpy
1647 * a copychecksum. 1639 * a copychecksum.
1648 */ 1640 */
1649 1641
1650 skb=dev_alloc_skb(ct); 1642 skb = dev_alloc_skb(ct);
1651 if(skb==NULL) 1643 if (skb == NULL) {
1652 { 1644 c->netdevice->stats.rx_dropped++;
1653 c->stats.rx_dropped++; 1645 printk(KERN_WARNING "%s: Memory squeeze.\n",
1654 printk(KERN_WARNING "%s: Memory squeeze.\n", c->netdevice->name); 1646 c->netdevice->name);
1655 } 1647 } else {
1656 else
1657 {
1658 skb_put(skb, ct); 1648 skb_put(skb, ct);
1659 skb_copy_to_linear_data(skb, rxb, ct); 1649 skb_copy_to_linear_data(skb, rxb, ct);
1660 c->stats.rx_packets++; 1650 c->netdevice->stats.rx_packets++;
1661 c->stats.rx_bytes+=ct; 1651 c->netdevice->stats.rx_bytes += ct;
1662 } 1652 }
1663 c->dma_ready=1; 1653 c->dma_ready = 1;
1664 } 1654 } else {
1665 else 1655 RT_LOCK;
1666 { 1656 skb = c->skb;
1667 RT_LOCK; 1657
1668 skb=c->skb;
1669
1670 /* 1658 /*
1671 * The game we play for non DMA is similar. We want to 1659 * The game we play for non DMA is similar. We want to
1672 * get the controller set up for the next packet as fast 1660 * get the controller set up for the next packet as fast
@@ -1677,48 +1665,39 @@ static void z8530_rx_done(struct z8530_channel *c)
1677 * if you build a system where the sync irq isnt blocked 1665 * if you build a system where the sync irq isnt blocked
1678 * by the kernel IRQ disable then you need only block the 1666 * by the kernel IRQ disable then you need only block the
1679 * sync IRQ for the RT_LOCK area. 1667 * sync IRQ for the RT_LOCK area.
1680 * 1668 *
1681 */ 1669 */
1682 ct=c->count; 1670 ct=c->count;
1683 1671
1684 c->skb = c->skb2; 1672 c->skb = c->skb2;
1685 c->count = 0; 1673 c->count = 0;
1686 c->max = c->mtu; 1674 c->max = c->mtu;
1687 if(c->skb) 1675 if (c->skb) {
1688 {
1689 c->dptr = c->skb->data; 1676 c->dptr = c->skb->data;
1690 c->max = c->mtu; 1677 c->max = c->mtu;
1691 } 1678 } else {
1692 else 1679 c->count = 0;
1693 {
1694 c->count= 0;
1695 c->max = 0; 1680 c->max = 0;
1696 } 1681 }
1697 RT_UNLOCK; 1682 RT_UNLOCK;
1698 1683
1699 c->skb2 = dev_alloc_skb(c->mtu); 1684 c->skb2 = dev_alloc_skb(c->mtu);
1700 if(c->skb2==NULL) 1685 if (c->skb2 == NULL)
1701 printk(KERN_WARNING "%s: memory squeeze.\n", 1686 printk(KERN_WARNING "%s: memory squeeze.\n",
1702 c->netdevice->name); 1687 c->netdevice->name);
1703 else 1688 else
1704 { 1689 skb_put(c->skb2, c->mtu);
1705 skb_put(c->skb2,c->mtu); 1690 c->netdevice->stats.rx_packets++;
1706 } 1691 c->netdevice->stats.rx_bytes += ct;
1707 c->stats.rx_packets++;
1708 c->stats.rx_bytes+=ct;
1709
1710 } 1692 }
1711 /* 1693 /*
1712 * If we received a frame we must now process it. 1694 * If we received a frame we must now process it.
1713 */ 1695 */
1714 if(skb) 1696 if (skb) {
1715 {
1716 skb_trim(skb, ct); 1697 skb_trim(skb, ct);
1717 c->rx_function(c,skb); 1698 c->rx_function(c, skb);
1718 } 1699 } else {
1719 else 1700 c->netdevice->stats.rx_dropped++;
1720 {
1721 c->stats.rx_dropped++;
1722 printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name); 1701 printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name);
1723 } 1702 }
1724} 1703}
@@ -1730,7 +1709,7 @@ static void z8530_rx_done(struct z8530_channel *c)
1730 * Returns true if the buffer cross a DMA boundary on a PC. The poor 1709 * Returns true if the buffer cross a DMA boundary on a PC. The poor
1731 * thing can only DMA within a 64K block not across the edges of it. 1710 * thing can only DMA within a 64K block not across the edges of it.
1732 */ 1711 */
1733 1712
1734static inline int spans_boundary(struct sk_buff *skb) 1713static inline int spans_boundary(struct sk_buff *skb)
1735{ 1714{
1736 unsigned long a=(unsigned long)skb->data; 1715 unsigned long a=(unsigned long)skb->data;
@@ -1799,24 +1778,6 @@ int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
1799 1778
1800EXPORT_SYMBOL(z8530_queue_xmit); 1779EXPORT_SYMBOL(z8530_queue_xmit);
1801 1780
1802/**
1803 * z8530_get_stats - Get network statistics
1804 * @c: The channel to use
1805 *
1806 * Get the statistics block. We keep the statistics in software as
1807 * the chip doesn't do it for us.
1808 *
1809 * Locking is ignored here - we could lock for a copy but its
1810 * not likely to be that big an issue
1811 */
1812
1813struct net_device_stats *z8530_get_stats(struct z8530_channel *c)
1814{
1815 return &c->stats;
1816}
1817
1818EXPORT_SYMBOL(z8530_get_stats);
1819
1820/* 1781/*
1821 * Module support 1782 * Module support
1822 */ 1783 */
diff --git a/drivers/net/wan/z85230.h b/drivers/net/wan/z85230.h
index 158aea7b8eac..4f372396c512 100644
--- a/drivers/net/wan/z85230.h
+++ b/drivers/net/wan/z85230.h
@@ -325,7 +325,6 @@ struct z8530_channel
325 325
326 void *private; /* For our owner */ 326 void *private; /* For our owner */
327 struct net_device *netdevice; /* Network layer device */ 327 struct net_device *netdevice; /* Network layer device */
328 struct net_device_stats stats; /* Network layer statistics */
329 328
330 /* 329 /*
331 * Async features 330 * Async features
@@ -366,13 +365,13 @@ struct z8530_channel
366 unsigned char tx_active; /* character is being xmitted */ 365 unsigned char tx_active; /* character is being xmitted */
367 unsigned char tx_stopped; /* output is suspended */ 366 unsigned char tx_stopped; /* output is suspended */
368 367
369 spinlock_t *lock; /* Devicr lock */ 368 spinlock_t *lock; /* Device lock */
370}; 369};
371 370
372/* 371/*
373 * Each Z853x0 device. 372 * Each Z853x0 device.
374 */ 373 */
375 374
376struct z8530_dev 375struct z8530_dev
377{ 376{
378 char *name; /* Device instance name */ 377 char *name; /* Device instance name */
@@ -408,7 +407,6 @@ extern int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *);
408extern int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *); 407extern int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *);
409extern int z8530_channel_load(struct z8530_channel *, u8 *); 408extern int z8530_channel_load(struct z8530_channel *, u8 *);
410extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb); 409extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb);
411extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c);
412extern void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb); 410extern void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb);
413 411
414 412
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 4c7ff61a1a9c..9931b5ab59cd 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -695,6 +695,7 @@ config MAC80211_HWSIM
695 695
696source "drivers/net/wireless/p54/Kconfig" 696source "drivers/net/wireless/p54/Kconfig"
697source "drivers/net/wireless/ath5k/Kconfig" 697source "drivers/net/wireless/ath5k/Kconfig"
698source "drivers/net/wireless/ath9k/Kconfig"
698source "drivers/net/wireless/iwlwifi/Kconfig" 699source "drivers/net/wireless/iwlwifi/Kconfig"
699source "drivers/net/wireless/hostap/Kconfig" 700source "drivers/net/wireless/hostap/Kconfig"
700source "drivers/net/wireless/b43/Kconfig" 701source "drivers/net/wireless/b43/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 54a4f6f1db67..59aa89ec6e81 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -62,5 +62,6 @@ obj-$(CONFIG_RT2X00) += rt2x00/
62obj-$(CONFIG_P54_COMMON) += p54/ 62obj-$(CONFIG_P54_COMMON) += p54/
63 63
64obj-$(CONFIG_ATH5K) += ath5k/ 64obj-$(CONFIG_ATH5K) += ath5k/
65obj-$(CONFIG_ATH9K) += ath9k/
65 66
66obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o 67obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index ebf19bc11f5b..b20a45aa8680 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -40,7 +40,6 @@
40 * 40 *
41 */ 41 */
42 42
43#include <linux/version.h>
44#include <linux/module.h> 43#include <linux/module.h>
45#include <linux/delay.h> 44#include <linux/delay.h>
46#include <linux/hardirq.h> 45#include <linux/hardirq.h>
@@ -95,8 +94,6 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
95 { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */ 94 { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
96 { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */ 95 { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
97 { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/ 96 { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/
98 { PCI_VDEVICE(ATHEROS, 0x0023), .driver_data = AR5K_AR5212 }, /* 5416 */
99 { PCI_VDEVICE(ATHEROS, 0x0024), .driver_data = AR5K_AR5212 }, /* 5418 */
100 { 0 } 97 { 0 }
101}; 98};
102MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); 99MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
@@ -589,7 +586,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
589 ath5k_stop_hw(sc); 586 ath5k_stop_hw(sc);
590 587
591 free_irq(pdev->irq, sc); 588 free_irq(pdev->irq, sc);
592 pci_disable_msi(pdev);
593 pci_save_state(pdev); 589 pci_save_state(pdev);
594 pci_disable_device(pdev); 590 pci_disable_device(pdev);
595 pci_set_power_state(pdev, PCI_D3hot); 591 pci_set_power_state(pdev, PCI_D3hot);
@@ -618,12 +614,10 @@ ath5k_pci_resume(struct pci_dev *pdev)
618 */ 614 */
619 pci_write_config_byte(pdev, 0x41, 0); 615 pci_write_config_byte(pdev, 0x41, 0);
620 616
621 pci_enable_msi(pdev);
622
623 err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); 617 err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
624 if (err) { 618 if (err) {
625 ATH5K_ERR(sc, "request_irq failed\n"); 619 ATH5K_ERR(sc, "request_irq failed\n");
626 goto err_msi; 620 goto err_no_irq;
627 } 621 }
628 622
629 err = ath5k_init(sc); 623 err = ath5k_init(sc);
@@ -644,8 +638,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
644 return 0; 638 return 0;
645err_irq: 639err_irq:
646 free_irq(pdev->irq, sc); 640 free_irq(pdev->irq, sc);
647err_msi: 641err_no_irq:
648 pci_disable_msi(pdev);
649 pci_disable_device(pdev); 642 pci_disable_device(pdev);
650 return err; 643 return err;
651} 644}
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig
new file mode 100644
index 000000000000..9e19dcceb3a2
--- /dev/null
+++ b/drivers/net/wireless/ath9k/Kconfig
@@ -0,0 +1,8 @@
1config ATH9K
2 tristate "Atheros 802.11n wireless cards support"
3 depends on PCI && MAC80211 && WLAN_80211
4 ---help---
5 This module adds support for wireless adapters based on
6 Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
7
8 If you choose to build a module, it'll be called ath9k.
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile
new file mode 100644
index 000000000000..a6411517e5f8
--- /dev/null
+++ b/drivers/net/wireless/ath9k/Makefile
@@ -0,0 +1,11 @@
1ath9k-y += hw.o \
2 phy.o \
3 regd.o \
4 beacon.o \
5 main.o \
6 recv.o \
7 xmit.o \
8 rc.o \
9 core.o
10
11obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
new file mode 100644
index 000000000000..d1b0fbae5a32
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -0,0 +1,1021 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef ATH9K_H
18#define ATH9K_H
19
20#include <linux/io.h>
21
22#define ATHEROS_VENDOR_ID 0x168c
23
24#define AR5416_DEVID_PCI 0x0023
25#define AR5416_DEVID_PCIE 0x0024
26#define AR9160_DEVID_PCI 0x0027
27#define AR9280_DEVID_PCI 0x0029
28#define AR9280_DEVID_PCIE 0x002a
29
30#define AR5416_AR9100_DEVID 0x000b
31
32#define AR_SUBVENDOR_ID_NOG 0x0e11
33#define AR_SUBVENDOR_ID_NEW_A 0x7065
34
35#define ATH9K_TXERR_XRETRY 0x01
36#define ATH9K_TXERR_FILT 0x02
37#define ATH9K_TXERR_FIFO 0x04
38#define ATH9K_TXERR_XTXOP 0x08
39#define ATH9K_TXERR_TIMER_EXPIRED 0x10
40
41#define ATH9K_TX_BA 0x01
42#define ATH9K_TX_PWRMGMT 0x02
43#define ATH9K_TX_DESC_CFG_ERR 0x04
44#define ATH9K_TX_DATA_UNDERRUN 0x08
45#define ATH9K_TX_DELIM_UNDERRUN 0x10
46#define ATH9K_TX_SW_ABORTED 0x40
47#define ATH9K_TX_SW_FILTERED 0x80
48
49#define NBBY 8
50
51struct ath_tx_status {
52 u32 ts_tstamp;
53 u16 ts_seqnum;
54 u8 ts_status;
55 u8 ts_ratecode;
56 u8 ts_rateindex;
57 int8_t ts_rssi;
58 u8 ts_shortretry;
59 u8 ts_longretry;
60 u8 ts_virtcol;
61 u8 ts_antenna;
62 u8 ts_flags;
63 int8_t ts_rssi_ctl0;
64 int8_t ts_rssi_ctl1;
65 int8_t ts_rssi_ctl2;
66 int8_t ts_rssi_ext0;
67 int8_t ts_rssi_ext1;
68 int8_t ts_rssi_ext2;
69 u8 pad[3];
70 u32 ba_low;
71 u32 ba_high;
72 u32 evm0;
73 u32 evm1;
74 u32 evm2;
75};
76
77struct ath_rx_status {
78 u32 rs_tstamp;
79 u16 rs_datalen;
80 u8 rs_status;
81 u8 rs_phyerr;
82 int8_t rs_rssi;
83 u8 rs_keyix;
84 u8 rs_rate;
85 u8 rs_antenna;
86 u8 rs_more;
87 int8_t rs_rssi_ctl0;
88 int8_t rs_rssi_ctl1;
89 int8_t rs_rssi_ctl2;
90 int8_t rs_rssi_ext0;
91 int8_t rs_rssi_ext1;
92 int8_t rs_rssi_ext2;
93 u8 rs_isaggr;
94 u8 rs_moreaggr;
95 u8 rs_num_delims;
96 u8 rs_flags;
97 u32 evm0;
98 u32 evm1;
99 u32 evm2;
100};
101
102#define ATH9K_RXERR_CRC 0x01
103#define ATH9K_RXERR_PHY 0x02
104#define ATH9K_RXERR_FIFO 0x04
105#define ATH9K_RXERR_DECRYPT 0x08
106#define ATH9K_RXERR_MIC 0x10
107
108#define ATH9K_RX_MORE 0x01
109#define ATH9K_RX_MORE_AGGR 0x02
110#define ATH9K_RX_GI 0x04
111#define ATH9K_RX_2040 0x08
112#define ATH9K_RX_DELIM_CRC_PRE 0x10
113#define ATH9K_RX_DELIM_CRC_POST 0x20
114#define ATH9K_RX_DECRYPT_BUSY 0x40
115
116#define ATH9K_RXKEYIX_INVALID ((u8)-1)
117#define ATH9K_TXKEYIX_INVALID ((u32)-1)
118
119struct ath_desc {
120 u32 ds_link;
121 u32 ds_data;
122 u32 ds_ctl0;
123 u32 ds_ctl1;
124 u32 ds_hw[20];
125 union {
126 struct ath_tx_status tx;
127 struct ath_rx_status rx;
128 void *stats;
129 } ds_us;
130 void *ds_vdata;
131} __packed;
132
133#define ds_txstat ds_us.tx
134#define ds_rxstat ds_us.rx
135#define ds_stat ds_us.stats
136
137#define ATH9K_TXDESC_CLRDMASK 0x0001
138#define ATH9K_TXDESC_NOACK 0x0002
139#define ATH9K_TXDESC_RTSENA 0x0004
140#define ATH9K_TXDESC_CTSENA 0x0008
141#define ATH9K_TXDESC_INTREQ 0x0010
142#define ATH9K_TXDESC_VEOL 0x0020
143#define ATH9K_TXDESC_EXT_ONLY 0x0040
144#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
145#define ATH9K_TXDESC_VMF 0x0100
146#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
147
148#define ATH9K_RXDESC_INTREQ 0x0020
149
150enum wireless_mode {
151 ATH9K_MODE_11A = 0,
152 ATH9K_MODE_11B = 2,
153 ATH9K_MODE_11G = 3,
154 ATH9K_MODE_11NA_HT20 = 6,
155 ATH9K_MODE_11NG_HT20 = 7,
156 ATH9K_MODE_11NA_HT40PLUS = 8,
157 ATH9K_MODE_11NA_HT40MINUS = 9,
158 ATH9K_MODE_11NG_HT40PLUS = 10,
159 ATH9K_MODE_11NG_HT40MINUS = 11,
160 ATH9K_MODE_MAX
161};
162
163enum ath9k_hw_caps {
164 ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
165 ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
166 ATH9K_HW_CAP_MIC_CKIP = BIT(2),
167 ATH9K_HW_CAP_MIC_TKIP = BIT(3),
168 ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4),
169 ATH9K_HW_CAP_CIPHER_CKIP = BIT(5),
170 ATH9K_HW_CAP_CIPHER_TKIP = BIT(6),
171 ATH9K_HW_CAP_VEOL = BIT(7),
172 ATH9K_HW_CAP_BSSIDMASK = BIT(8),
173 ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9),
174 ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10),
175 ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11),
176 ATH9K_HW_CAP_HT = BIT(12),
177 ATH9K_HW_CAP_GTT = BIT(13),
178 ATH9K_HW_CAP_FASTCC = BIT(14),
179 ATH9K_HW_CAP_RFSILENT = BIT(15),
180 ATH9K_HW_CAP_WOW = BIT(16),
181 ATH9K_HW_CAP_CST = BIT(17),
182 ATH9K_HW_CAP_ENHANCEDPM = BIT(18),
183 ATH9K_HW_CAP_AUTOSLEEP = BIT(19),
184 ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20),
185 ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21),
186};
187
188enum ath9k_capability_type {
189 ATH9K_CAP_CIPHER = 0,
190 ATH9K_CAP_TKIP_MIC,
191 ATH9K_CAP_TKIP_SPLIT,
192 ATH9K_CAP_PHYCOUNTERS,
193 ATH9K_CAP_DIVERSITY,
194 ATH9K_CAP_TXPOW,
195 ATH9K_CAP_PHYDIAG,
196 ATH9K_CAP_MCAST_KEYSRCH,
197 ATH9K_CAP_TSF_ADJUST,
198 ATH9K_CAP_WME_TKIPMIC,
199 ATH9K_CAP_RFSILENT,
200 ATH9K_CAP_ANT_CFG_2GHZ,
201 ATH9K_CAP_ANT_CFG_5GHZ
202};
203
204struct ath9k_hw_capabilities {
205 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
206 DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
207 u16 total_queues;
208 u16 keycache_size;
209 u16 low_5ghz_chan, high_5ghz_chan;
210 u16 low_2ghz_chan, high_2ghz_chan;
211 u16 num_mr_retries;
212 u16 rts_aggr_limit;
213 u8 tx_chainmask;
214 u8 rx_chainmask;
215 u16 tx_triglevel_max;
216 u16 reg_cap;
217 u8 num_gpio_pins;
218 u8 num_antcfg_2ghz;
219 u8 num_antcfg_5ghz;
220};
221
222struct ath9k_ops_config {
223 int dma_beacon_response_time;
224 int sw_beacon_response_time;
225 int additional_swba_backoff;
226 int ack_6mb;
227 int cwm_ignore_extcca;
228 u8 pcie_powersave_enable;
229 u8 pcie_l1skp_enable;
230 u8 pcie_clock_req;
231 u32 pcie_waen;
232 int pcie_power_reset;
233 u8 pcie_restore;
234 u8 analog_shiftreg;
235 u8 ht_enable;
236 u32 ofdm_trig_low;
237 u32 ofdm_trig_high;
238 u32 cck_trig_high;
239 u32 cck_trig_low;
240 u32 enable_ani;
241 u8 noise_immunity_level;
242 u32 ofdm_weaksignal_det;
243 u32 cck_weaksignal_thr;
244 u8 spur_immunity_level;
245 u8 firstep_level;
246 int8_t rssi_thr_high;
247 int8_t rssi_thr_low;
248 u16 diversity_control;
249 u16 antenna_switch_swap;
250 int serialize_regmode;
251 int intr_mitigation;
252#define SPUR_DISABLE 0
253#define SPUR_ENABLE_IOCTL 1
254#define SPUR_ENABLE_EEPROM 2
255#define AR_EEPROM_MODAL_SPURS 5
256#define AR_SPUR_5413_1 1640
257#define AR_SPUR_5413_2 1200
258#define AR_NO_SPUR 0x8000
259#define AR_BASE_FREQ_2GHZ 2300
260#define AR_BASE_FREQ_5GHZ 4900
261#define AR_SPUR_FEEQ_BOUND_HT40 19
262#define AR_SPUR_FEEQ_BOUND_HT20 10
263 int spurmode;
264 u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
265};
266
267enum ath9k_tx_queue {
268 ATH9K_TX_QUEUE_INACTIVE = 0,
269 ATH9K_TX_QUEUE_DATA,
270 ATH9K_TX_QUEUE_BEACON,
271 ATH9K_TX_QUEUE_CAB,
272 ATH9K_TX_QUEUE_UAPSD,
273 ATH9K_TX_QUEUE_PSPOLL
274};
275
276#define ATH9K_NUM_TX_QUEUES 10
277
278enum ath9k_tx_queue_subtype {
279 ATH9K_WME_AC_BK = 0,
280 ATH9K_WME_AC_BE,
281 ATH9K_WME_AC_VI,
282 ATH9K_WME_AC_VO,
283 ATH9K_WME_UPSD
284};
285
286enum ath9k_tx_queue_flags {
287 TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
288 TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
289 TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
290 TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
291 TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
292 TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
293 TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
294 TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
295 TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
296};
297
298#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
299
300#define ATH9K_DECOMP_MASK_SIZE 128
301#define ATH9K_READY_TIME_LO_BOUND 50
302#define ATH9K_READY_TIME_HI_BOUND 96
303
304enum ath9k_pkt_type {
305 ATH9K_PKT_TYPE_NORMAL = 0,
306 ATH9K_PKT_TYPE_ATIM,
307 ATH9K_PKT_TYPE_PSPOLL,
308 ATH9K_PKT_TYPE_BEACON,
309 ATH9K_PKT_TYPE_PROBE_RESP,
310 ATH9K_PKT_TYPE_CHIRP,
311 ATH9K_PKT_TYPE_GRP_POLL,
312};
313
314struct ath9k_tx_queue_info {
315 u32 tqi_ver;
316 enum ath9k_tx_queue tqi_type;
317 enum ath9k_tx_queue_subtype tqi_subtype;
318 enum ath9k_tx_queue_flags tqi_qflags;
319 u32 tqi_priority;
320 u32 tqi_aifs;
321 u32 tqi_cwmin;
322 u32 tqi_cwmax;
323 u16 tqi_shretry;
324 u16 tqi_lgretry;
325 u32 tqi_cbrPeriod;
326 u32 tqi_cbrOverflowLimit;
327 u32 tqi_burstTime;
328 u32 tqi_readyTime;
329 u32 tqi_physCompBuf;
330 u32 tqi_intFlags;
331};
332
333enum ath9k_rx_filter {
334 ATH9K_RX_FILTER_UCAST = 0x00000001,
335 ATH9K_RX_FILTER_MCAST = 0x00000002,
336 ATH9K_RX_FILTER_BCAST = 0x00000004,
337 ATH9K_RX_FILTER_CONTROL = 0x00000008,
338 ATH9K_RX_FILTER_BEACON = 0x00000010,
339 ATH9K_RX_FILTER_PROM = 0x00000020,
340 ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
341 ATH9K_RX_FILTER_PSPOLL = 0x00004000,
342 ATH9K_RX_FILTER_PHYERR = 0x00000100,
343 ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
344};
345
346enum ath9k_int {
347 ATH9K_INT_RX = 0x00000001,
348 ATH9K_INT_RXDESC = 0x00000002,
349 ATH9K_INT_RXNOFRM = 0x00000008,
350 ATH9K_INT_RXEOL = 0x00000010,
351 ATH9K_INT_RXORN = 0x00000020,
352 ATH9K_INT_TX = 0x00000040,
353 ATH9K_INT_TXDESC = 0x00000080,
354 ATH9K_INT_TIM_TIMER = 0x00000100,
355 ATH9K_INT_TXURN = 0x00000800,
356 ATH9K_INT_MIB = 0x00001000,
357 ATH9K_INT_RXPHY = 0x00004000,
358 ATH9K_INT_RXKCM = 0x00008000,
359 ATH9K_INT_SWBA = 0x00010000,
360 ATH9K_INT_BMISS = 0x00040000,
361 ATH9K_INT_BNR = 0x00100000,
362 ATH9K_INT_TIM = 0x00200000,
363 ATH9K_INT_DTIM = 0x00400000,
364 ATH9K_INT_DTIMSYNC = 0x00800000,
365 ATH9K_INT_GPIO = 0x01000000,
366 ATH9K_INT_CABEND = 0x02000000,
367 ATH9K_INT_CST = 0x10000000,
368 ATH9K_INT_GTT = 0x20000000,
369 ATH9K_INT_FATAL = 0x40000000,
370 ATH9K_INT_GLOBAL = 0x80000000,
371 ATH9K_INT_BMISC = ATH9K_INT_TIM |
372 ATH9K_INT_DTIM |
373 ATH9K_INT_DTIMSYNC |
374 ATH9K_INT_CABEND,
375 ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
376 ATH9K_INT_RXDESC |
377 ATH9K_INT_RXEOL |
378 ATH9K_INT_RXORN |
379 ATH9K_INT_TXURN |
380 ATH9K_INT_TXDESC |
381 ATH9K_INT_MIB |
382 ATH9K_INT_RXPHY |
383 ATH9K_INT_RXKCM |
384 ATH9K_INT_SWBA |
385 ATH9K_INT_BMISS |
386 ATH9K_INT_GPIO,
387 ATH9K_INT_NOCARD = 0xffffffff
388};
389
390struct ath9k_rate_table {
391 int rateCount;
392 u8 rateCodeToIndex[256];
393 struct {
394 u8 valid;
395 u8 phy;
396 u32 rateKbps;
397 u8 rateCode;
398 u8 shortPreamble;
399 u8 dot11Rate;
400 u8 controlRate;
401 u16 lpAckDuration;
402 u16 spAckDuration;
403 } info[32];
404};
405
406#define ATH9K_RATESERIES_RTS_CTS 0x0001
407#define ATH9K_RATESERIES_2040 0x0002
408#define ATH9K_RATESERIES_HALFGI 0x0004
409
410struct ath9k_11n_rate_series {
411 u32 Tries;
412 u32 Rate;
413 u32 PktDuration;
414 u32 ChSel;
415 u32 RateFlags;
416};
417
418#define CHANNEL_CW_INT 0x00002
419#define CHANNEL_CCK 0x00020
420#define CHANNEL_OFDM 0x00040
421#define CHANNEL_2GHZ 0x00080
422#define CHANNEL_5GHZ 0x00100
423#define CHANNEL_PASSIVE 0x00200
424#define CHANNEL_DYN 0x00400
425#define CHANNEL_HALF 0x04000
426#define CHANNEL_QUARTER 0x08000
427#define CHANNEL_HT20 0x10000
428#define CHANNEL_HT40PLUS 0x20000
429#define CHANNEL_HT40MINUS 0x40000
430
431#define CHANNEL_INTERFERENCE 0x01
432#define CHANNEL_DFS 0x02
433#define CHANNEL_4MS_LIMIT 0x04
434#define CHANNEL_DFS_CLEAR 0x08
435#define CHANNEL_DISALLOW_ADHOC 0x10
436#define CHANNEL_PER_11D_ADHOC 0x20
437
438#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
439#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
440#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
441#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
442#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
443#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
444#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
445#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
446#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
447#define CHANNEL_ALL \
448 (CHANNEL_OFDM| \
449 CHANNEL_CCK| \
450 CHANNEL_2GHZ | \
451 CHANNEL_5GHZ | \
452 CHANNEL_HT20 | \
453 CHANNEL_HT40PLUS | \
454 CHANNEL_HT40MINUS)
455
456struct ath9k_channel {
457 u16 channel;
458 u32 channelFlags;
459 u8 privFlags;
460 int8_t maxRegTxPower;
461 int8_t maxTxPower;
462 int8_t minTxPower;
463 u32 chanmode;
464 int32_t CalValid;
465 bool oneTimeCalsDone;
466 int8_t iCoff;
467 int8_t qCoff;
468 int16_t rawNoiseFloor;
469 int8_t antennaMax;
470 u32 regDmnFlags;
471 u32 conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
472#ifdef ATH_NF_PER_CHAN
473 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
474#endif
475};
476
477#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
478 (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
479 (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
480 (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
481#define IS_CHAN_B(_c) (((_c)->channelFlags & CHANNEL_B) == CHANNEL_B)
482#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
483 (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
484 (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
485 (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
486#define IS_CHAN_CCK(_c) (((_c)->channelFlags & CHANNEL_CCK) != 0)
487#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
488#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
489#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
490#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
491#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
492#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
493
494/* These macros check chanmode and not channelFlags */
495#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
496 ((_c)->chanmode == CHANNEL_G_HT20))
497#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
498 ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
499 ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
500 ((_c)->chanmode == CHANNEL_G_HT40MINUS))
501#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
502
503#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
504#define IS_CHAN_A_5MHZ_SPACED(_c) \
505 ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
506 (((_c)->channel % 20) != 0) && \
507 (((_c)->channel % 10) != 0))
508
509struct ath9k_keyval {
510 u8 kv_type;
511 u8 kv_pad;
512 u16 kv_len;
513 u8 kv_val[16];
514 u8 kv_mic[8];
515 u8 kv_txmic[8];
516};
517
518enum ath9k_key_type {
519 ATH9K_KEY_TYPE_CLEAR,
520 ATH9K_KEY_TYPE_WEP,
521 ATH9K_KEY_TYPE_AES,
522 ATH9K_KEY_TYPE_TKIP,
523};
524
525enum ath9k_cipher {
526 ATH9K_CIPHER_WEP = 0,
527 ATH9K_CIPHER_AES_OCB = 1,
528 ATH9K_CIPHER_AES_CCM = 2,
529 ATH9K_CIPHER_CKIP = 3,
530 ATH9K_CIPHER_TKIP = 4,
531 ATH9K_CIPHER_CLR = 5,
532 ATH9K_CIPHER_MIC = 127
533};
534
535#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
536#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
537#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
538#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
539#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
540#define AR_EEPROM_EEPCAP_MAXQCU_S 4
541#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
542#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
543#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
544
545#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
546#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
547#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
548#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
549#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
550#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
551
552#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
553#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
554
555#define SD_NO_CTL 0xE0
556#define NO_CTL 0xff
557#define CTL_MODE_M 7
558#define CTL_11A 0
559#define CTL_11B 1
560#define CTL_11G 2
561#define CTL_2GHT20 5
562#define CTL_5GHT20 6
563#define CTL_2GHT40 7
564#define CTL_5GHT40 8
565
566#define AR_EEPROM_MAC(i) (0x1d+(i))
567#define EEP_SCALE 100
568#define EEP_DELTA 10
569
570#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
571#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
572#define AR_EEPROM_RFSILENT_POLARITY 0x0002
573#define AR_EEPROM_RFSILENT_POLARITY_S 1
574
575#define CTRY_DEBUG 0x1ff
576#define CTRY_DEFAULT 0
577
578enum reg_ext_bitmap {
579 REG_EXT_JAPAN_MIDBAND = 1,
580 REG_EXT_FCC_DFS_HT40 = 2,
581 REG_EXT_JAPAN_NONDFS_HT40 = 3,
582 REG_EXT_JAPAN_DFS_HT40 = 4
583};
584
585struct ath9k_country_entry {
586 u16 countryCode;
587 u16 regDmnEnum;
588 u16 regDmn5G;
589 u16 regDmn2G;
590 u8 isMultidomain;
591 u8 iso[3];
592};
593
594#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg)
595#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg)
596
597#define SM(_v, _f) (((_v) << _f##_S) & _f)
598#define MS(_v, _f) (((_v) & _f) >> _f##_S)
599#define REG_RMW(_a, _r, _set, _clr) \
600 REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
601#define REG_RMW_FIELD(_a, _r, _f, _v) \
602 REG_WRITE(_a, _r, \
603 (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
604#define REG_SET_BIT(_a, _r, _f) \
605 REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
606#define REG_CLR_BIT(_a, _r, _f) \
607 REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
608
609#define ATH9K_COMP_BUF_MAX_SIZE 9216
610#define ATH9K_COMP_BUF_ALIGN_SIZE 512
611
612#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
613
614#define INIT_AIFS 2
615#define INIT_CWMIN 15
616#define INIT_CWMIN_11B 31
617#define INIT_CWMAX 1023
618#define INIT_SH_RETRY 10
619#define INIT_LG_RETRY 10
620#define INIT_SSH_RETRY 32
621#define INIT_SLG_RETRY 32
622
623#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
624
625#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
626#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
627
628#define IEEE80211_WEP_IVLEN 3
629#define IEEE80211_WEP_KIDLEN 1
630#define IEEE80211_WEP_CRCLEN 4
631#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
632 (IEEE80211_WEP_IVLEN + \
633 IEEE80211_WEP_KIDLEN + \
634 IEEE80211_WEP_CRCLEN))
635#define IEEE80211_MAX_LEN (2300 + FCS_LEN + \
636 (IEEE80211_WEP_IVLEN + \
637 IEEE80211_WEP_KIDLEN + \
638 IEEE80211_WEP_CRCLEN))
639
640#define MAX_REG_ADD_COUNT 129
641#define MAX_RATE_POWER 63
642
643enum ath9k_power_mode {
644 ATH9K_PM_AWAKE = 0,
645 ATH9K_PM_FULL_SLEEP,
646 ATH9K_PM_NETWORK_SLEEP,
647 ATH9K_PM_UNDEFINED
648};
649
650struct ath9k_mib_stats {
651 u32 ackrcv_bad;
652 u32 rts_bad;
653 u32 rts_good;
654 u32 fcs_bad;
655 u32 beacons;
656};
657
658enum ath9k_ant_setting {
659 ATH9K_ANT_VARIABLE = 0,
660 ATH9K_ANT_FIXED_A,
661 ATH9K_ANT_FIXED_B
662};
663
664enum ath9k_opmode {
665 ATH9K_M_STA = 1,
666 ATH9K_M_IBSS = 0,
667 ATH9K_M_HOSTAP = 6,
668 ATH9K_M_MONITOR = 8
669};
670
671#define ATH9K_SLOT_TIME_6 6
672#define ATH9K_SLOT_TIME_9 9
673#define ATH9K_SLOT_TIME_20 20
674
675enum ath9k_ht_macmode {
676 ATH9K_HT_MACMODE_20 = 0,
677 ATH9K_HT_MACMODE_2040 = 1,
678};
679
680enum ath9k_ht_extprotspacing {
681 ATH9K_HT_EXTPROTSPACING_20 = 0,
682 ATH9K_HT_EXTPROTSPACING_25 = 1,
683};
684
685struct ath9k_ht_cwm {
686 enum ath9k_ht_macmode ht_macmode;
687 enum ath9k_ht_extprotspacing ht_extprotspacing;
688};
689
690enum ath9k_ani_cmd {
691 ATH9K_ANI_PRESENT = 0x1,
692 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
693 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
694 ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
695 ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
696 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
697 ATH9K_ANI_MODE = 0x40,
698 ATH9K_ANI_PHYERR_RESET = 0x80,
699 ATH9K_ANI_ALL = 0xff
700};
701
702enum phytype {
703 PHY_DS,
704 PHY_FH,
705 PHY_OFDM,
706 PHY_HT,
707};
708#define PHY_CCK PHY_DS
709
710enum start_adhoc_option {
711 START_ADHOC_NO_11A,
712 START_ADHOC_PER_11D,
713 START_ADHOC_IN_11A,
714 START_ADHOC_IN_11B,
715};
716
717enum ath9k_tp_scale {
718 ATH9K_TP_SCALE_MAX = 0,
719 ATH9K_TP_SCALE_50,
720 ATH9K_TP_SCALE_25,
721 ATH9K_TP_SCALE_12,
722 ATH9K_TP_SCALE_MIN
723};
724
725enum ser_reg_mode {
726 SER_REG_MODE_OFF = 0,
727 SER_REG_MODE_ON = 1,
728 SER_REG_MODE_AUTO = 2,
729};
730
731#define AR_PHY_CCA_MAX_GOOD_VALUE -85
732#define AR_PHY_CCA_MAX_HIGH_VALUE -62
733#define AR_PHY_CCA_MIN_BAD_VALUE -121
734#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
735#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
736
737#define ATH9K_NF_CAL_HIST_MAX 5
738#define NUM_NF_READINGS 6
739
740struct ath9k_nfcal_hist {
741 int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
742 u8 currIndex;
743 int16_t privNF;
744 u8 invalidNFcount;
745};
746
747struct ath9k_beacon_state {
748 u32 bs_nexttbtt;
749 u32 bs_nextdtim;
750 u32 bs_intval;
751#define ATH9K_BEACON_PERIOD 0x0000ffff
752#define ATH9K_BEACON_ENA 0x00800000
753#define ATH9K_BEACON_RESET_TSF 0x01000000
754 u32 bs_dtimperiod;
755 u16 bs_cfpperiod;
756 u16 bs_cfpmaxduration;
757 u32 bs_cfpnext;
758 u16 bs_timoffset;
759 u16 bs_bmissthreshold;
760 u32 bs_sleepduration;
761};
762
763struct ath9k_node_stats {
764 u32 ns_avgbrssi;
765 u32 ns_avgrssi;
766 u32 ns_avgtxrssi;
767 u32 ns_avgtxrate;
768};
769
770#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
771
772enum ath9k_gpio_output_mux_type {
773 ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT,
774 ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
775 ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
776 ATH9K_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
777 ATH9K_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
778 ATH9K_GPIO_OUTPUT_MUX_NUM_ENTRIES
779};
780
781enum {
782 ATH9K_RESET_POWER_ON,
783 ATH9K_RESET_WARM,
784 ATH9K_RESET_COLD,
785};
786
787#define AH_USE_EEPROM 0x1
788
789struct ath_hal {
790 u32 ah_magic;
791 u16 ah_devid;
792 u16 ah_subvendorid;
793 struct ath_softc *ah_sc;
794 void __iomem *ah_sh;
795 u16 ah_countryCode;
796 u32 ah_macVersion;
797 u16 ah_macRev;
798 u16 ah_phyRev;
799 u16 ah_analog5GhzRev;
800 u16 ah_analog2GhzRev;
801 u8 ah_decompMask[ATH9K_DECOMP_MASK_SIZE];
802 u32 ah_flags;
803 enum ath9k_opmode ah_opmode;
804 struct ath9k_ops_config ah_config;
805 struct ath9k_hw_capabilities ah_caps;
806 int16_t ah_powerLimit;
807 u16 ah_maxPowerLevel;
808 u32 ah_tpScale;
809 u16 ah_currentRD;
810 u16 ah_currentRDExt;
811 u16 ah_currentRDInUse;
812 u16 ah_currentRD5G;
813 u16 ah_currentRD2G;
814 char ah_iso[4];
815 enum start_adhoc_option ah_adHocMode;
816 bool ah_commonMode;
817 struct ath9k_channel ah_channels[150];
818 u32 ah_nchan;
819 struct ath9k_channel *ah_curchan;
820 u16 ah_rfsilent;
821 bool ah_rfkillEnabled;
822 bool ah_isPciExpress;
823 u16 ah_txTrigLevel;
824#ifndef ATH_NF_PER_CHAN
825 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
826#endif
827};
828
829struct chan_centers {
830 u16 synth_center;
831 u16 ctl_center;
832 u16 ext_center;
833};
834
835int ath_hal_getcapability(struct ath_hal *ah,
836 enum ath9k_capability_type type,
837 u32 capability,
838 u32 *result);
839const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
840 u32 mode);
841void ath9k_hw_detach(struct ath_hal *ah);
842struct ath_hal *ath9k_hw_attach(u16 devid,
843 struct ath_softc *sc,
844 void __iomem *mem,
845 int *error);
846bool ath9k_regd_init_channels(struct ath_hal *ah,
847 u32 maxchans, u32 *nchans,
848 u8 *regclassids,
849 u32 maxregids, u32 *nregids,
850 u16 cc,
851 bool enableOutdoor,
852 bool enableExtendedChannels);
853u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
854enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah,
855 enum ath9k_int ints);
856bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
857 struct ath9k_channel *chan,
858 enum ath9k_ht_macmode macmode,
859 u8 txchainmask, u8 rxchainmask,
860 enum ath9k_ht_extprotspacing extprotspacing,
861 bool bChannelChange,
862 int *status);
863bool ath9k_hw_phy_disable(struct ath_hal *ah);
864void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
865 bool *isCalDone);
866void ath9k_hw_ani_monitor(struct ath_hal *ah,
867 const struct ath9k_node_stats *stats,
868 struct ath9k_channel *chan);
869bool ath9k_hw_calibrate(struct ath_hal *ah,
870 struct ath9k_channel *chan,
871 u8 rxchainmask,
872 bool longcal,
873 bool *isCalDone);
874int16_t ath9k_hw_getchan_noise(struct ath_hal *ah,
875 struct ath9k_channel *chan);
876void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
877 u16 assocId);
878void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
879void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
880 u16 assocId);
881bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
882void ath9k_hw_reset_tsf(struct ath_hal *ah);
883bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
884bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
885 const u8 *mac);
886bool ath9k_hw_set_keycache_entry(struct ath_hal *ah,
887 u16 entry,
888 const struct ath9k_keyval *k,
889 const u8 *mac,
890 int xorKey);
891bool ath9k_hw_set_tsfadjust(struct ath_hal *ah,
892 u32 setting);
893void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
894bool ath9k_hw_intrpend(struct ath_hal *ah);
895bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
896bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah,
897 bool bIncTrigLevel);
898void ath9k_hw_procmibevent(struct ath_hal *ah,
899 const struct ath9k_node_stats *stats);
900bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
901void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
902bool ath9k_hw_phycounters(struct ath_hal *ah);
903bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry);
904bool ath9k_hw_getcapability(struct ath_hal *ah,
905 enum ath9k_capability_type type,
906 u32 capability,
907 u32 *result);
908bool ath9k_hw_setcapability(struct ath_hal *ah,
909 enum ath9k_capability_type type,
910 u32 capability,
911 u32 setting,
912 int *status);
913u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
914void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
915void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
916bool ath9k_hw_setbssidmask(struct ath_hal *ah,
917 const u8 *mask);
918bool ath9k_hw_setpower(struct ath_hal *ah,
919 enum ath9k_power_mode mode);
920enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
921u64 ath9k_hw_gettsf64(struct ath_hal *ah);
922u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
923bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
924bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
925 enum ath9k_ant_setting settings,
926 struct ath9k_channel *chan,
927 u8 *tx_chainmask,
928 u8 *rx_chainmask,
929 u8 *antenna_cfgd);
930void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
931int ath9k_hw_select_antconfig(struct ath_hal *ah,
932 u32 cfg);
933bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
934 u32 txdp);
935bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
936u16 ath9k_hw_computetxtime(struct ath_hal *ah,
937 const struct ath9k_rate_table *rates,
938 u32 frameLen, u16 rateix,
939 bool shortPreamble);
940void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
941 struct ath_desc *lastds,
942 u32 durUpdateEn, u32 rtsctsRate,
943 u32 rtsctsDuration,
944 struct ath9k_11n_rate_series series[],
945 u32 nseries, u32 flags);
946void ath9k_hw_set11n_burstduration(struct ath_hal *ah,
947 struct ath_desc *ds,
948 u32 burstDuration);
949void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
950u32 ath9k_hw_reverse_bits(u32 val, u32 n);
951bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
952u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
953u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
954 struct ath9k_channel *chan);
955u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
956bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
957 struct ath9k_tx_queue_info *qinfo);
958bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
959 const struct ath9k_tx_queue_info *qinfo);
960struct ath9k_channel *ath9k_regd_check_channel(struct ath_hal *ah,
961 const struct ath9k_channel *c);
962void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
963 u32 pktLen, enum ath9k_pkt_type type,
964 u32 txPower, u32 keyIx,
965 enum ath9k_key_type keyType, u32 flags);
966bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
967 u32 segLen, bool firstSeg,
968 bool lastSeg,
969 const struct ath_desc *ds0);
970u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
971 u32 *rxc_pcnt,
972 u32 *rxf_pcnt,
973 u32 *txf_pcnt);
974void ath9k_hw_dmaRegDump(struct ath_hal *ah);
975void ath9k_hw_beaconinit(struct ath_hal *ah,
976 u32 next_beacon, u32 beacon_period);
977void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
978 const struct ath9k_beacon_state *bs);
979bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
980 u32 size, u32 flags);
981void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp);
982void ath9k_hw_rxena(struct ath_hal *ah);
983void ath9k_hw_setopmode(struct ath_hal *ah);
984bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
985void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
986 u32 filter1);
987u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
988void ath9k_hw_startpcureceive(struct ath_hal *ah);
989void ath9k_hw_stoppcurecv(struct ath_hal *ah);
990bool ath9k_hw_stopdmarecv(struct ath_hal *ah);
991int ath9k_hw_rxprocdesc(struct ath_hal *ah,
992 struct ath_desc *ds, u32 pa,
993 struct ath_desc *nds, u64 tsf);
994u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
995int ath9k_hw_txprocdesc(struct ath_hal *ah,
996 struct ath_desc *ds);
997void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
998 u32 numDelims);
999void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
1000 u32 aggrLen);
1001void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
1002bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
1003void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
1004void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
1005void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah,
1006 struct ath_desc *ds, u32 vmf);
1007bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
1008bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
1009int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
1010 const struct ath9k_tx_queue_info *qinfo);
1011u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
1012const char *ath9k_hw_probe(u16 vendorid, u16 devid);
1013bool ath9k_hw_disable(struct ath_hal *ah);
1014void ath9k_hw_rfdetach(struct ath_hal *ah);
1015void ath9k_hw_get_channel_centers(struct ath_hal *ah,
1016 struct ath9k_channel *chan,
1017 struct chan_centers *centers);
1018bool ath9k_get_channel_edges(struct ath_hal *ah,
1019 u16 flags, u16 *low,
1020 u16 *high);
1021#endif
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
new file mode 100644
index 000000000000..caf569401a34
--- /dev/null
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -0,0 +1,979 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 /* Implementation of beacon processing. */
18
19#include <asm/unaligned.h>
20#include "core.h"
21
22/*
23 * Configure parameters for the beacon queue
24 *
25 * This function will modify certain transmit queue properties depending on
26 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
27 * settings and channel width min/max
28*/
29
30static int ath_beaconq_config(struct ath_softc *sc)
31{
32 struct ath_hal *ah = sc->sc_ah;
33 struct ath9k_tx_queue_info qi;
34
35 ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi);
36 if (sc->sc_opmode == ATH9K_M_HOSTAP) {
37 /* Always burst out beacon and CAB traffic. */
38 qi.tqi_aifs = 1;
39 qi.tqi_cwmin = 0;
40 qi.tqi_cwmax = 0;
41 } else {
42 /* Adhoc mode; important thing is to use 2x cwmin. */
43 qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
44 qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
45 qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
46 }
47
48 if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) {
49 DPRINTF(sc, ATH_DBG_FATAL,
50 "%s: unable to update h/w beacon queue parameters\n",
51 __func__);
52 return 0;
53 } else {
54 ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
55 return 1;
56 }
57}
58
59/*
60 * Setup the beacon frame for transmit.
61 *
62 * Associates the beacon frame buffer with a transmit descriptor. Will set
63 * up all required antenna switch parameters, rate codes, and channel flags.
64 * Beacons are always sent out at the lowest rate, and are not retried.
65*/
66
67static void ath_beacon_setup(struct ath_softc *sc,
68 struct ath_vap *avp, struct ath_buf *bf)
69{
70 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
71 struct ath_hal *ah = sc->sc_ah;
72 struct ath_desc *ds;
73 int flags, antenna;
74 const struct ath9k_rate_table *rt;
75 u8 rix, rate;
76 int ctsrate = 0;
77 int ctsduration = 0;
78 struct ath9k_11n_rate_series series[4];
79
80 DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n",
81 __func__, skb, skb->len);
82
83 /* setup descriptors */
84 ds = bf->bf_desc;
85
86 flags = ATH9K_TXDESC_NOACK;
87
88 if (sc->sc_opmode == ATH9K_M_IBSS &&
89 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
90 ds->ds_link = bf->bf_daddr; /* self-linked */
91 flags |= ATH9K_TXDESC_VEOL;
92 /* Let hardware handle antenna switching. */
93 antenna = 0;
94 } else {
95 ds->ds_link = 0;
96 /*
97 * Switch antenna every beacon.
98 * Should only switch every beacon period, not for every
99 * SWBA's
100 * XXX assumes two antenna
101 */
102 antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
103 }
104
105 ds->ds_data = bf->bf_buf_addr;
106
107 /*
108 * Calculate rate code.
109 * XXX everything at min xmit rate
110 */
111 rix = 0;
112 rt = sc->sc_currates;
113 rate = rt->info[rix].rateCode;
114 if (sc->sc_flags & ATH_PREAMBLE_SHORT)
115 rate |= rt->info[rix].shortPreamble;
116
117 ath9k_hw_set11n_txdesc(ah, ds
118 , skb->len + FCS_LEN /* frame length */
119 , ATH9K_PKT_TYPE_BEACON /* Atheros packet type */
120 , avp->av_btxctl.txpower /* txpower XXX */
121 , ATH9K_TXKEYIX_INVALID /* no encryption */
122 , ATH9K_KEY_TYPE_CLEAR /* no encryption */
123 , flags /* no ack, veol for beacons */
124 );
125
126 /* NB: beacon's BufLen must be a multiple of 4 bytes */
127 ath9k_hw_filltxdesc(ah, ds
128 , roundup(skb->len, 4) /* buffer length */
129 , true /* first segment */
130 , true /* last segment */
131 , ds /* first descriptor */
132 );
133
134 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
135 series[0].Tries = 1;
136 series[0].Rate = rate;
137 series[0].ChSel = sc->sc_tx_chainmask;
138 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
139 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
140 ctsrate, ctsduration, series, 4, 0);
141}
142
143/* Move everything from the vap's mcast queue to the hardware cab queue.
144 * Caller must hold mcasq lock and cabq lock
145 * XXX MORE_DATA bit?
146 */
147static void empty_mcastq_into_cabq(struct ath_hal *ah,
148 struct ath_txq *mcastq, struct ath_txq *cabq)
149{
150 struct ath_buf *bfmcast;
151
152 BUG_ON(list_empty(&mcastq->axq_q));
153
154 bfmcast = list_first_entry(&mcastq->axq_q, struct ath_buf, list);
155
156 /* link the descriptors */
157 if (!cabq->axq_link)
158 ath9k_hw_puttxbuf(ah, cabq->axq_qnum, bfmcast->bf_daddr);
159 else
160 *cabq->axq_link = bfmcast->bf_daddr;
161
162 /* append the private vap mcast list to the cabq */
163
164 cabq->axq_depth += mcastq->axq_depth;
165 cabq->axq_totalqueued += mcastq->axq_totalqueued;
166 cabq->axq_linkbuf = mcastq->axq_linkbuf;
167 cabq->axq_link = mcastq->axq_link;
168 list_splice_tail_init(&mcastq->axq_q, &cabq->axq_q);
169 mcastq->axq_depth = 0;
170 mcastq->axq_totalqueued = 0;
171 mcastq->axq_linkbuf = NULL;
172 mcastq->axq_link = NULL;
173}
174
175/* This is only run at DTIM. We move everything from the vap's mcast queue
176 * to the hardware cab queue. Caller must hold the mcastq lock. */
177static void trigger_mcastq(struct ath_hal *ah,
178 struct ath_txq *mcastq, struct ath_txq *cabq)
179{
180 spin_lock_bh(&cabq->axq_lock);
181
182 if (!list_empty(&mcastq->axq_q))
183 empty_mcastq_into_cabq(ah, mcastq, cabq);
184
185 /* cabq is gated by beacon so it is safe to start here */
186 if (!list_empty(&cabq->axq_q))
187 ath9k_hw_txstart(ah, cabq->axq_qnum);
188
189 spin_unlock_bh(&cabq->axq_lock);
190}
191
192/*
193 * Generate beacon frame and queue cab data for a vap.
194 *
195 * Updates the contents of the beacon frame. It is assumed that the buffer for
196 * the beacon frame has been allocated in the ATH object, and simply needs to
197 * be filled for this cycle. Also, any CAB (crap after beacon?) traffic will
198 * be added to the beacon frame at this point.
199*/
200static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
201{
202 struct ath_hal *ah = sc->sc_ah;
203 struct ath_buf *bf;
204 struct ath_vap *avp;
205 struct sk_buff *skb;
206 int cabq_depth;
207 int mcastq_depth;
208 int is_beacon_dtim = 0;
209 unsigned int curlen;
210 struct ath_txq *cabq;
211 struct ath_txq *mcastq;
212 avp = sc->sc_vaps[if_id];
213
214 mcastq = &avp->av_mcastq;
215 cabq = sc->sc_cabq;
216
217 ASSERT(avp);
218
219 if (avp->av_bcbuf == NULL) {
220 DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
221 __func__, avp, avp->av_bcbuf);
222 return NULL;
223 }
224 bf = avp->av_bcbuf;
225 skb = (struct sk_buff *) bf->bf_mpdu;
226
227 /*
228 * Update dynamic beacon contents. If this returns
229 * non-zero then we need to remap the memory because
230 * the beacon frame changed size (probably because
231 * of the TIM bitmap).
232 */
233 curlen = skb->len;
234
235 /* XXX: spin_lock_bh should not be used here, but sparse bitches
236 * otherwise. We should fix sparse :) */
237 spin_lock_bh(&mcastq->axq_lock);
238 mcastq_depth = avp->av_mcastq.axq_depth;
239
240 if (ath_update_beacon(sc, if_id, &avp->av_boff, skb, mcastq_depth) ==
241 1) {
242 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
243 get_dma_mem_context(bf, bf_dmacontext));
244 bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
245 get_dma_mem_context(bf, bf_dmacontext));
246 } else {
247 pci_dma_sync_single_for_cpu(sc->pdev,
248 bf->bf_buf_addr,
249 skb_tailroom(skb),
250 PCI_DMA_TODEVICE);
251 }
252
253 /*
254 * if the CABQ traffic from previous DTIM is pending and the current
255 * beacon is also a DTIM.
256 * 1) if there is only one vap let the cab traffic continue.
257 * 2) if there are more than one vap and we are using staggered
258 * beacons, then drain the cabq by dropping all the frames in
259 * the cabq so that the current vaps cab traffic can be scheduled.
260 */
261 spin_lock_bh(&cabq->axq_lock);
262 cabq_depth = cabq->axq_depth;
263 spin_unlock_bh(&cabq->axq_lock);
264
265 is_beacon_dtim = avp->av_boff.bo_tim[4] & 1;
266
267 if (mcastq_depth && is_beacon_dtim && cabq_depth) {
268 /*
269 * Unlock the cabq lock as ath_tx_draintxq acquires
270 * the lock again which is a common function and that
271 * acquires txq lock inside.
272 */
273 if (sc->sc_nvaps > 1) {
274 ath_tx_draintxq(sc, cabq, false);
275 DPRINTF(sc, ATH_DBG_BEACON,
276 "%s: flush previous cabq traffic\n", __func__);
277 }
278 }
279
280 /* Construct tx descriptor. */
281 ath_beacon_setup(sc, avp, bf);
282
283 /*
284 * Enable the CAB queue before the beacon queue to
285 * insure cab frames are triggered by this beacon.
286 */
287 if (is_beacon_dtim)
288 trigger_mcastq(ah, mcastq, cabq);
289
290 spin_unlock_bh(&mcastq->axq_lock);
291 return bf;
292}
293
294/*
295 * Startup beacon transmission for adhoc mode when they are sent entirely
296 * by the hardware using the self-linked descriptor + veol trick.
297*/
298
299static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
300{
301 struct ath_hal *ah = sc->sc_ah;
302 struct ath_buf *bf;
303 struct ath_vap *avp;
304 struct sk_buff *skb;
305
306 avp = sc->sc_vaps[if_id];
307 ASSERT(avp);
308
309 if (avp->av_bcbuf == NULL) {
310 DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
311 __func__, avp, avp != NULL ? avp->av_bcbuf : NULL);
312 return;
313 }
314 bf = avp->av_bcbuf;
315 skb = (struct sk_buff *) bf->bf_mpdu;
316
317 /* Construct tx descriptor. */
318 ath_beacon_setup(sc, avp, bf);
319
320 /* NB: caller is known to have already stopped tx dma */
321 ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
322 ath9k_hw_txstart(ah, sc->sc_bhalq);
323 DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__,
324 sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
325}
326
327/*
328 * Setup a h/w transmit queue for beacons.
329 *
330 * This function allocates an information structure (struct ath9k_txq_info)
331 * on the stack, sets some specific parameters (zero out channel width
332 * min/max, and enable aifs). The info structure does not need to be
333 * persistant.
334*/
335
336int ath_beaconq_setup(struct ath_hal *ah)
337{
338 struct ath9k_tx_queue_info qi;
339
340 memzero(&qi, sizeof(qi));
341 qi.tqi_aifs = 1;
342 qi.tqi_cwmin = 0;
343 qi.tqi_cwmax = 0;
344 /* NB: don't enable any interrupts */
345 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
346}
347
348
349/*
350 * Allocate and setup an initial beacon frame.
351 *
352 * Allocate a beacon state variable for a specific VAP instance created on
353 * the ATH interface. This routine also calculates the beacon "slot" for
354 * staggared beacons in the mBSSID case.
355*/
356
357int ath_beacon_alloc(struct ath_softc *sc, int if_id)
358{
359 struct ath_vap *avp;
360 struct ieee80211_hdr *wh;
361 struct ath_buf *bf;
362 struct sk_buff *skb;
363
364 avp = sc->sc_vaps[if_id];
365 ASSERT(avp);
366
367 /* Allocate a beacon descriptor if we haven't done so. */
368 if (!avp->av_bcbuf) {
369 /*
370 * Allocate beacon state for hostap/ibss. We know
371 * a buffer is available.
372 */
373
374 avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
375 struct ath_buf, list);
376 list_del(&avp->av_bcbuf->list);
377
378 if (sc->sc_opmode == ATH9K_M_HOSTAP ||
379 !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
380 int slot;
381 /*
382 * Assign the vap to a beacon xmit slot. As
383 * above, this cannot fail to find one.
384 */
385 avp->av_bslot = 0;
386 for (slot = 0; slot < ATH_BCBUF; slot++)
387 if (sc->sc_bslot[slot] == ATH_IF_ID_ANY) {
388 /*
389 * XXX hack, space out slots to better
390 * deal with misses
391 */
392 if (slot+1 < ATH_BCBUF &&
393 sc->sc_bslot[slot+1] ==
394 ATH_IF_ID_ANY) {
395 avp->av_bslot = slot+1;
396 break;
397 }
398 avp->av_bslot = slot;
399 /* NB: keep looking for a double slot */
400 }
401 BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY);
402 sc->sc_bslot[avp->av_bslot] = if_id;
403 sc->sc_nbcnvaps++;
404 }
405 }
406
407 /* release the previous beacon frame , if it already exists. */
408 bf = avp->av_bcbuf;
409 if (bf->bf_mpdu != NULL) {
410 skb = (struct sk_buff *)bf->bf_mpdu;
411 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
412 get_dma_mem_context(bf, bf_dmacontext));
413 dev_kfree_skb_any(skb);
414 bf->bf_mpdu = NULL;
415 }
416
417 /*
418 * NB: the beacon data buffer must be 32-bit aligned;
419 * we assume the wbuf routines will return us something
420 * with this alignment (perhaps should assert).
421 * FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and
422 * avp->av_btxctl.shortPreamble
423 */
424 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
425 if (skb == NULL) {
426 DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n",
427 __func__);
428 return -ENOMEM;
429 }
430
431 /*
432 * Calculate a TSF adjustment factor required for
433 * staggered beacons. Note that we assume the format
434 * of the beacon frame leaves the tstamp field immediately
435 * following the header.
436 */
437 if (avp->av_bslot > 0) {
438 u64 tsfadjust;
439 __le64 val;
440 int intval;
441
442 /* FIXME: Use default value for now: Sujith */
443
444 intval = ATH_DEFAULT_BINTVAL;
445
446 /*
447 * The beacon interval is in TU's; the TSF in usecs.
448 * We figure out how many TU's to add to align the
449 * timestamp then convert to TSF units and handle
450 * byte swapping before writing it in the frame.
451 * The hardware will then add this each time a beacon
452 * frame is sent. Note that we align vap's 1..N
453 * and leave vap 0 untouched. This means vap 0
454 * has a timestamp in one beacon interval while the
455 * others get a timestamp aligned to the next interval.
456 */
457 tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
458 val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */
459
460 DPRINTF(sc, ATH_DBG_BEACON,
461 "%s: %s beacons, bslot %d intval %u tsfadjust %llu\n",
462 __func__, "stagger",
463 avp->av_bslot, intval, (unsigned long long)tsfadjust);
464
465 wh = (struct ieee80211_hdr *)skb->data;
466 memcpy(&wh[1], &val, sizeof(val));
467 }
468
469 bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
470 get_dma_mem_context(bf, bf_dmacontext));
471 bf->bf_mpdu = skb;
472
473 return 0;
474}
475
476/*
477 * Reclaim beacon resources and return buffer to the pool.
478 *
479 * Checks the VAP to put the beacon frame buffer back to the ATH object
480 * queue, and de-allocates any wbuf frames that were sent as CAB traffic.
481*/
482
483void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
484{
485 if (avp->av_bcbuf != NULL) {
486 struct ath_buf *bf;
487
488 if (avp->av_bslot != -1) {
489 sc->sc_bslot[avp->av_bslot] = ATH_IF_ID_ANY;
490 sc->sc_nbcnvaps--;
491 }
492
493 bf = avp->av_bcbuf;
494 if (bf->bf_mpdu != NULL) {
495 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
496 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
497 get_dma_mem_context(bf, bf_dmacontext));
498 dev_kfree_skb_any(skb);
499 bf->bf_mpdu = NULL;
500 }
501 list_add_tail(&bf->list, &sc->sc_bbuf);
502
503 avp->av_bcbuf = NULL;
504 }
505}
506
507/*
508 * Reclaim beacon resources and return buffer to the pool.
509 *
510 * This function will free any wbuf frames that are still attached to the
511 * beacon buffers in the ATH object. Note that this does not de-allocate
512 * any wbuf objects that are in the transmit queue and have not yet returned
513 * to the ATH object.
514*/
515
516void ath_beacon_free(struct ath_softc *sc)
517{
518 struct ath_buf *bf;
519
520 list_for_each_entry(bf, &sc->sc_bbuf, list) {
521 if (bf->bf_mpdu != NULL) {
522 struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
523 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
524 get_dma_mem_context(bf, bf_dmacontext));
525 dev_kfree_skb_any(skb);
526 bf->bf_mpdu = NULL;
527 }
528 }
529}
530
531/*
532 * Tasklet for Sending Beacons
533 *
534 * Transmit one or more beacon frames at SWBA. Dynamic updates to the frame
535 * contents are done as needed and the slot time is also adjusted based on
536 * current state.
537 *
538 * This tasklet is not scheduled, it's called in ISR context.
539*/
540
541void ath9k_beacon_tasklet(unsigned long data)
542{
543#define TSF_TO_TU(_h,_l) \
544 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
545
546 struct ath_softc *sc = (struct ath_softc *)data;
547 struct ath_hal *ah = sc->sc_ah;
548 struct ath_buf *bf = NULL;
549 int slot, if_id;
550 u32 bfaddr;
551 u32 rx_clear = 0, rx_frame = 0, tx_frame = 0;
552 u32 show_cycles = 0;
553 u32 bc = 0; /* beacon count */
554 u64 tsf;
555 u32 tsftu;
556 u16 intval;
557
558 if (sc->sc_noreset) {
559 show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
560 &rx_clear,
561 &rx_frame,
562 &tx_frame);
563 }
564
565 /*
566 * Check if the previous beacon has gone out. If
567 * not don't try to post another, skip this period
568 * and wait for the next. Missed beacons indicate
569 * a problem and should not occur. If we miss too
570 * many consecutive beacons reset the device.
571 */
572 if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) {
573 sc->sc_bmisscount++;
574 /* XXX: doth needs the chanchange IE countdown decremented.
575 * We should consider adding a mac80211 call to indicate
576 * a beacon miss so appropriate action could be taken
577 * (in that layer).
578 */
579 if (sc->sc_bmisscount < BSTUCK_THRESH) {
580 if (sc->sc_noreset) {
581 DPRINTF(sc, ATH_DBG_BEACON,
582 "%s: missed %u consecutive beacons\n",
583 __func__, sc->sc_bmisscount);
584 if (show_cycles) {
585 /*
586 * Display cycle counter stats
587 * from HW to aide in debug of
588 * stickiness.
589 */
590 DPRINTF(sc,
591 ATH_DBG_BEACON,
592 "%s: busy times: rx_clear=%d, "
593 "rx_frame=%d, tx_frame=%d\n",
594 __func__, rx_clear, rx_frame,
595 tx_frame);
596 } else {
597 DPRINTF(sc,
598 ATH_DBG_BEACON,
599 "%s: unable to obtain "
600 "busy times\n", __func__);
601 }
602 } else {
603 DPRINTF(sc, ATH_DBG_BEACON,
604 "%s: missed %u consecutive beacons\n",
605 __func__, sc->sc_bmisscount);
606 }
607 } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
608 if (sc->sc_noreset) {
609 if (sc->sc_bmisscount == BSTUCK_THRESH) {
610 DPRINTF(sc,
611 ATH_DBG_BEACON,
612 "%s: beacon is officially "
613 "stuck\n", __func__);
614 ath9k_hw_dmaRegDump(ah);
615 }
616 } else {
617 DPRINTF(sc, ATH_DBG_BEACON,
618 "%s: beacon is officially stuck\n",
619 __func__);
620 ath_bstuck_process(sc);
621 }
622 }
623
624 return;
625 }
626 if (sc->sc_bmisscount != 0) {
627 if (sc->sc_noreset) {
628 DPRINTF(sc,
629 ATH_DBG_BEACON,
630 "%s: resume beacon xmit after %u misses\n",
631 __func__, sc->sc_bmisscount);
632 } else {
633 DPRINTF(sc, ATH_DBG_BEACON,
634 "%s: resume beacon xmit after %u misses\n",
635 __func__, sc->sc_bmisscount);
636 }
637 sc->sc_bmisscount = 0;
638 }
639
640 /*
641 * Generate beacon frames. we are sending frames
642 * staggered so calculate the slot for this frame based
643 * on the tsf to safeguard against missing an swba.
644 */
645
646 /* FIXME: Use default value for now - Sujith */
647 intval = ATH_DEFAULT_BINTVAL;
648
649 tsf = ath9k_hw_gettsf64(ah);
650 tsftu = TSF_TO_TU(tsf>>32, tsf);
651 slot = ((tsftu % intval) * ATH_BCBUF) / intval;
652 if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
653 DPRINTF(sc, ATH_DBG_BEACON,
654 "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
655 __func__, slot, (unsigned long long) tsf, tsftu,
656 intval, if_id);
657 bfaddr = 0;
658 if (if_id != ATH_IF_ID_ANY) {
659 bf = ath_beacon_generate(sc, if_id);
660 if (bf != NULL) {
661 bfaddr = bf->bf_daddr;
662 bc = 1;
663 }
664 }
665 /*
666 * Handle slot time change when a non-ERP station joins/leaves
667 * an 11g network. The 802.11 layer notifies us via callback,
668 * we mark updateslot, then wait one beacon before effecting
669 * the change. This gives associated stations at least one
670 * beacon interval to note the state change.
671 *
672 * NB: The slot time change state machine is clocked according
673 * to whether we are bursting or staggering beacons. We
674 * recognize the request to update and record the current
675 * slot then don't transition until that slot is reached
676 * again. If we miss a beacon for that slot then we'll be
677 * slow to transition but we'll be sure at least one beacon
678 * interval has passed. When bursting slot is always left
679 * set to ATH_BCBUF so this check is a noop.
680 */
681 /* XXX locking */
682 if (sc->sc_updateslot == UPDATE) {
683 sc->sc_updateslot = COMMIT; /* commit next beacon */
684 sc->sc_slotupdate = slot;
685 } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot)
686 ath_setslottime(sc); /* commit change to hardware */
687
688 if (bfaddr != 0) {
689 /*
690 * Stop any current dma and put the new frame(s) on the queue.
691 * This should never fail since we check above that no frames
692 * are still pending on the queue.
693 */
694 if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
695 DPRINTF(sc, ATH_DBG_FATAL,
696 "%s: beacon queue %u did not stop?\n",
697 __func__, sc->sc_bhalq);
698 /* NB: the HAL still stops DMA, so proceed */
699 }
700
701 /* NB: cabq traffic should already be queued and primed */
702 ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr);
703 ath9k_hw_txstart(ah, sc->sc_bhalq);
704
705 sc->ast_be_xmit += bc; /* XXX per-vap? */
706 }
707#undef TSF_TO_TU
708}
709
710/*
711 * Tasklet for Beacon Stuck processing
712 *
713 * Processing for Beacon Stuck.
714 * Basically calls the ath_internal_reset function to reset the chip.
715*/
716
717void ath_bstuck_process(struct ath_softc *sc)
718{
719 DPRINTF(sc, ATH_DBG_BEACON,
720 "%s: stuck beacon; resetting (bmiss count %u)\n",
721 __func__, sc->sc_bmisscount);
722 ath_internal_reset(sc);
723}
724
725/*
726 * Configure the beacon and sleep timers.
727 *
728 * When operating as an AP this resets the TSF and sets
729 * up the hardware to notify us when we need to issue beacons.
730 *
731 * When operating in station mode this sets up the beacon
732 * timers according to the timestamp of the last received
733 * beacon and the current TSF, configures PCF and DTIM
734 * handling, programs the sleep registers so the hardware
735 * will wakeup in time to receive beacons, and configures
736 * the beacon miss handling so we'll receive a BMISS
737 * interrupt when we stop seeing beacons from the AP
738 * we've associated with.
739 */
740
741void ath_beacon_config(struct ath_softc *sc, int if_id)
742{
743#define TSF_TO_TU(_h,_l) \
744 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
745 struct ath_hal *ah = sc->sc_ah;
746 u32 nexttbtt, intval;
747 struct ath_beacon_config conf;
748 enum ath9k_opmode av_opmode;
749
750 if (if_id != ATH_IF_ID_ANY)
751 av_opmode = sc->sc_vaps[if_id]->av_opmode;
752 else
753 av_opmode = sc->sc_opmode;
754
755 memzero(&conf, sizeof(struct ath_beacon_config));
756
757 /* FIXME: Use default values for now - Sujith */
758 /* Query beacon configuration first */
759 /*
760 * Protocol stack doesn't support dynamic beacon configuration,
761 * use default configurations.
762 */
763 conf.beacon_interval = ATH_DEFAULT_BINTVAL;
764 conf.listen_interval = 1;
765 conf.dtim_period = conf.beacon_interval;
766 conf.dtim_count = 1;
767 conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
768
769 /* extract tstamp from last beacon and convert to TU */
770 nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4),
771 get_unaligned_le32(conf.u.last_tstamp));
772 /* XXX conditionalize multi-bss support? */
773 if (sc->sc_opmode == ATH9K_M_HOSTAP) {
774 /*
775 * For multi-bss ap support beacons are either staggered
776 * evenly over N slots or burst together. For the former
777 * arrange for the SWBA to be delivered for each slot.
778 * Slots that are not occupied will generate nothing.
779 */
780 /* NB: the beacon interval is kept internally in TU's */
781 intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
782 intval /= ATH_BCBUF; /* for staggered beacons */
783 } else {
784 intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
785 }
786
787 if (nexttbtt == 0) /* e.g. for ap mode */
788 nexttbtt = intval;
789 else if (intval) /* NB: can be 0 for monitor mode */
790 nexttbtt = roundup(nexttbtt, intval);
791 DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
792 __func__, nexttbtt, intval, conf.beacon_interval);
793 /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
794 if (sc->sc_opmode == ATH9K_M_STA) {
795 struct ath9k_beacon_state bs;
796 u64 tsf;
797 u32 tsftu;
798 int dtimperiod, dtimcount, sleepduration;
799 int cfpperiod, cfpcount;
800
801 /*
802 * Setup dtim and cfp parameters according to
803 * last beacon we received (which may be none).
804 */
805 dtimperiod = conf.dtim_period;
806 if (dtimperiod <= 0) /* NB: 0 if not known */
807 dtimperiod = 1;
808 dtimcount = conf.dtim_count;
809 if (dtimcount >= dtimperiod) /* NB: sanity check */
810 dtimcount = 0; /* XXX? */
811 cfpperiod = 1; /* NB: no PCF support yet */
812 cfpcount = 0;
813
814 sleepduration = conf.listen_interval * intval;
815 if (sleepduration <= 0)
816 sleepduration = intval;
817
818#define FUDGE 2
819 /*
820 * Pull nexttbtt forward to reflect the current
821 * TSF and calculate dtim+cfp state for the result.
822 */
823 tsf = ath9k_hw_gettsf64(ah);
824 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
825 do {
826 nexttbtt += intval;
827 if (--dtimcount < 0) {
828 dtimcount = dtimperiod - 1;
829 if (--cfpcount < 0)
830 cfpcount = cfpperiod - 1;
831 }
832 } while (nexttbtt < tsftu);
833#undef FUDGE
834 memzero(&bs, sizeof(bs));
835 bs.bs_intval = intval;
836 bs.bs_nexttbtt = nexttbtt;
837 bs.bs_dtimperiod = dtimperiod*intval;
838 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
839 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
840 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
841 bs.bs_cfpmaxduration = 0;
842 /*
843 * Calculate the number of consecutive beacons to miss
844 * before taking a BMISS interrupt. The configuration
845 * is specified in TU so we only need calculate based
846 * on the beacon interval. Note that we clamp the
847 * result to at most 15 beacons.
848 */
849 if (sleepduration > intval) {
850 bs.bs_bmissthreshold =
851 conf.listen_interval *
852 ATH_DEFAULT_BMISS_LIMIT / 2;
853 } else {
854 bs.bs_bmissthreshold =
855 DIV_ROUND_UP(conf.bmiss_timeout, intval);
856 if (bs.bs_bmissthreshold > 15)
857 bs.bs_bmissthreshold = 15;
858 else if (bs.bs_bmissthreshold <= 0)
859 bs.bs_bmissthreshold = 1;
860 }
861
862 /*
863 * Calculate sleep duration. The configuration is
864 * given in ms. We insure a multiple of the beacon
865 * period is used. Also, if the sleep duration is
866 * greater than the DTIM period then it makes senses
867 * to make it a multiple of that.
868 *
869 * XXX fixed at 100ms
870 */
871
872 bs.bs_sleepduration =
873 roundup(IEEE80211_MS_TO_TU(100), sleepduration);
874 if (bs.bs_sleepduration > bs.bs_dtimperiod)
875 bs.bs_sleepduration = bs.bs_dtimperiod;
876
877 DPRINTF(sc, ATH_DBG_BEACON,
878 "%s: tsf %llu "
879 "tsf:tu %u "
880 "intval %u "
881 "nexttbtt %u "
882 "dtim %u "
883 "nextdtim %u "
884 "bmiss %u "
885 "sleep %u "
886 "cfp:period %u "
887 "maxdur %u "
888 "next %u "
889 "timoffset %u\n"
890 , __func__
891 , (unsigned long long)tsf, tsftu
892 , bs.bs_intval
893 , bs.bs_nexttbtt
894 , bs.bs_dtimperiod
895 , bs.bs_nextdtim
896 , bs.bs_bmissthreshold
897 , bs.bs_sleepduration
898 , bs.bs_cfpperiod
899 , bs.bs_cfpmaxduration
900 , bs.bs_cfpnext
901 , bs.bs_timoffset
902 );
903
904 ath9k_hw_set_interrupts(ah, 0);
905 ath9k_hw_set_sta_beacon_timers(ah, &bs);
906 sc->sc_imask |= ATH9K_INT_BMISS;
907 ath9k_hw_set_interrupts(ah, sc->sc_imask);
908 } else {
909 u64 tsf;
910 u32 tsftu;
911 ath9k_hw_set_interrupts(ah, 0);
912 if (nexttbtt == intval)
913 intval |= ATH9K_BEACON_RESET_TSF;
914 if (sc->sc_opmode == ATH9K_M_IBSS) {
915 /*
916 * Pull nexttbtt forward to reflect the current
917 * TSF .
918 */
919#define FUDGE 2
920 if (!(intval & ATH9K_BEACON_RESET_TSF)) {
921 tsf = ath9k_hw_gettsf64(ah);
922 tsftu = TSF_TO_TU((u32)(tsf>>32),
923 (u32)tsf) + FUDGE;
924 do {
925 nexttbtt += intval;
926 } while (nexttbtt < tsftu);
927 }
928#undef FUDGE
929 DPRINTF(sc, ATH_DBG_BEACON,
930 "%s: IBSS nexttbtt %u intval %u (%u)\n",
931 __func__, nexttbtt,
932 intval & ~ATH9K_BEACON_RESET_TSF,
933 conf.beacon_interval);
934
935 /*
936 * In IBSS mode enable the beacon timers but only
937 * enable SWBA interrupts if we need to manually
938 * prepare beacon frames. Otherwise we use a
939 * self-linked tx descriptor and let the hardware
940 * deal with things.
941 */
942 intval |= ATH9K_BEACON_ENA;
943 if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
944 sc->sc_imask |= ATH9K_INT_SWBA;
945 ath_beaconq_config(sc);
946 } else if (sc->sc_opmode == ATH9K_M_HOSTAP) {
947 /*
948 * In AP mode we enable the beacon timers and
949 * SWBA interrupts to prepare beacon frames.
950 */
951 intval |= ATH9K_BEACON_ENA;
952 sc->sc_imask |= ATH9K_INT_SWBA; /* beacon prepare */
953 ath_beaconq_config(sc);
954 }
955 ath9k_hw_beaconinit(ah, nexttbtt, intval);
956 sc->sc_bmisscount = 0;
957 ath9k_hw_set_interrupts(ah, sc->sc_imask);
958 /*
959 * When using a self-linked beacon descriptor in
960 * ibss mode load it once here.
961 */
962 if (sc->sc_opmode == ATH9K_M_IBSS &&
963 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
964 ath_beacon_start_adhoc(sc, 0);
965 }
966#undef TSF_TO_TU
967}
968
969/* Function to collect beacon rssi data and resync beacon if necessary */
970
971void ath_beacon_sync(struct ath_softc *sc, int if_id)
972{
973 /*
974 * Resync beacon timers using the tsf of the
975 * beacon frame we just received.
976 */
977 ath_beacon_config(sc, if_id);
978 sc->sc_beacons = 1;
979}
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
new file mode 100644
index 000000000000..f6c45288d0e7
--- /dev/null
+++ b/drivers/net/wireless/ath9k/core.c
@@ -0,0 +1,1923 @@
1/*
2 * Copyright (c) 2008, Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 /* Implementation of the main "ATH" layer. */
18
19#include "core.h"
20#include "regd.h"
21
22static int ath_outdoor; /* enable outdoor use */
23
24static const u8 ath_bcast_mac[ETH_ALEN] =
25 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
26
27static u32 ath_chainmask_sel_up_rssi_thres =
28 ATH_CHAINMASK_SEL_UP_RSSI_THRES;
29static u32 ath_chainmask_sel_down_rssi_thres =
30 ATH_CHAINMASK_SEL_DOWN_RSSI_THRES;
31static u32 ath_chainmask_sel_period =
32 ATH_CHAINMASK_SEL_TIMEOUT;
33
34/* return bus cachesize in 4B word units */
35
36static void bus_read_cachesize(struct ath_softc *sc, int *csz)
37{
38 u8 u8tmp;
39
40 pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
41 *csz = (int)u8tmp;
42
43 /*
44 * This check was put in to avoid "unplesant" consequences if
45 * the bootrom has not fully initialized all PCI devices.
46 * Sometimes the cache line size register is not set
47 */
48
49 if (*csz == 0)
50 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
51}
52
53/*
54 * Set current operating mode
55 *
56 * This function initializes and fills the rate table in the ATH object based
57 * on the operating mode. The blink rates are also set up here, although
58 * they have been superceeded by the ath_led module.
59*/
60
61static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
62{
63 const struct ath9k_rate_table *rt;
64 int i;
65
66 memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
67 rt = ath9k_hw_getratetable(sc->sc_ah, mode);
68 BUG_ON(!rt);
69
70 for (i = 0; i < rt->rateCount; i++)
71 sc->sc_rixmap[rt->info[i].rateCode] = (u8) i;
72
73 memzero(sc->sc_hwmap, sizeof(sc->sc_hwmap));
74 for (i = 0; i < 256; i++) {
75 u8 ix = rt->rateCodeToIndex[i];
76
77 if (ix == 0xff)
78 continue;
79
80 sc->sc_hwmap[i].ieeerate =
81 rt->info[ix].dot11Rate & IEEE80211_RATE_VAL;
82 sc->sc_hwmap[i].rateKbps = rt->info[ix].rateKbps;
83
84 if (rt->info[ix].shortPreamble ||
85 rt->info[ix].phy == PHY_OFDM) {
86 /* XXX: Handle this */
87 }
88
89 /* NB: this uses the last entry if the rate isn't found */
90 /* XXX beware of overlow */
91 }
92 sc->sc_currates = rt;
93 sc->sc_curmode = mode;
94 /*
95 * All protection frames are transmited at 2Mb/s for
96 * 11g, otherwise at 1Mb/s.
97 * XXX select protection rate index from rate table.
98 */
99 sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0);
100}
101
102/*
103 * Set up rate table (legacy rates)
104 */
105static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
106{
107 struct ath_hal *ah = sc->sc_ah;
108 const struct ath9k_rate_table *rt = NULL;
109 struct ieee80211_supported_band *sband;
110 struct ieee80211_rate *rate;
111 int i, maxrates;
112
113 switch (band) {
114 case IEEE80211_BAND_2GHZ:
115 rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11G);
116 break;
117 case IEEE80211_BAND_5GHZ:
118 rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11A);
119 break;
120 default:
121 break;
122 }
123
124 if (rt == NULL)
125 return;
126
127 sband = &sc->sbands[band];
128 rate = sc->rates[band];
129
130 if (rt->rateCount > ATH_RATE_MAX)
131 maxrates = ATH_RATE_MAX;
132 else
133 maxrates = rt->rateCount;
134
135 for (i = 0; i < maxrates; i++) {
136 rate[i].bitrate = rt->info[i].rateKbps / 100;
137 rate[i].hw_value = rt->info[i].rateCode;
138 sband->n_bitrates++;
139 DPRINTF(sc, ATH_DBG_CONFIG,
140 "%s: Rate: %2dMbps, ratecode: %2d\n",
141 __func__,
142 rate[i].bitrate / 10,
143 rate[i].hw_value);
144 }
145}
146
147/*
148 * Set up channel list
149 */
150static int ath_setup_channels(struct ath_softc *sc)
151{
152 struct ath_hal *ah = sc->sc_ah;
153 int nchan, i, a = 0, b = 0;
154 u8 regclassids[ATH_REGCLASSIDS_MAX];
155 u32 nregclass = 0;
156 struct ieee80211_supported_band *band_2ghz;
157 struct ieee80211_supported_band *band_5ghz;
158 struct ieee80211_channel *chan_2ghz;
159 struct ieee80211_channel *chan_5ghz;
160 struct ath9k_channel *c;
161
162 /* Fill in ah->ah_channels */
163 if (!ath9k_regd_init_channels(ah,
164 ATH_CHAN_MAX,
165 (u32 *)&nchan,
166 regclassids,
167 ATH_REGCLASSIDS_MAX,
168 &nregclass,
169 CTRY_DEFAULT,
170 false,
171 1)) {
172 u32 rd = ah->ah_currentRD;
173
174 DPRINTF(sc, ATH_DBG_FATAL,
175 "%s: unable to collect channel list; "
176 "regdomain likely %u country code %u\n",
177 __func__, rd, CTRY_DEFAULT);
178 return -EINVAL;
179 }
180
181 band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
182 band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
183 chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ];
184 chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ];
185
186 for (i = 0; i < nchan; i++) {
187 c = &ah->ah_channels[i];
188 if (IS_CHAN_2GHZ(c)) {
189 chan_2ghz[a].band = IEEE80211_BAND_2GHZ;
190 chan_2ghz[a].center_freq = c->channel;
191 chan_2ghz[a].max_power = c->maxTxPower;
192
193 if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
194 chan_2ghz[a].flags |=
195 IEEE80211_CHAN_NO_IBSS;
196 if (c->channelFlags & CHANNEL_PASSIVE)
197 chan_2ghz[a].flags |=
198 IEEE80211_CHAN_PASSIVE_SCAN;
199
200 band_2ghz->n_channels = ++a;
201
202 DPRINTF(sc, ATH_DBG_CONFIG,
203 "%s: 2MHz channel: %d, "
204 "channelFlags: 0x%x\n",
205 __func__,
206 c->channel,
207 c->channelFlags);
208 } else if (IS_CHAN_5GHZ(c)) {
209 chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
210 chan_5ghz[b].center_freq = c->channel;
211 chan_5ghz[b].max_power = c->maxTxPower;
212
213 if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
214 chan_5ghz[b].flags |=
215 IEEE80211_CHAN_NO_IBSS;
216 if (c->channelFlags & CHANNEL_PASSIVE)
217 chan_5ghz[b].flags |=
218 IEEE80211_CHAN_PASSIVE_SCAN;
219
220 band_5ghz->n_channels = ++b;
221
222 DPRINTF(sc, ATH_DBG_CONFIG,
223 "%s: 5MHz channel: %d, "
224 "channelFlags: 0x%x\n",
225 __func__,
226 c->channel,
227 c->channelFlags);
228 }
229 }
230
231 return 0;
232}
233
234/*
235 * Determine mode from channel flags
236 *
237 * This routine will provide the enumerated WIRELESSS_MODE value based
238 * on the settings of the channel flags. If ho valid set of flags
239 * exist, the lowest mode (11b) is selected.
240*/
241
242static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
243{
244 if (chan->chanmode == CHANNEL_A)
245 return ATH9K_MODE_11A;
246 else if (chan->chanmode == CHANNEL_G)
247 return ATH9K_MODE_11G;
248 else if (chan->chanmode == CHANNEL_B)
249 return ATH9K_MODE_11B;
250 else if (chan->chanmode == CHANNEL_A_HT20)
251 return ATH9K_MODE_11NA_HT20;
252 else if (chan->chanmode == CHANNEL_G_HT20)
253 return ATH9K_MODE_11NG_HT20;
254 else if (chan->chanmode == CHANNEL_A_HT40PLUS)
255 return ATH9K_MODE_11NA_HT40PLUS;
256 else if (chan->chanmode == CHANNEL_A_HT40MINUS)
257 return ATH9K_MODE_11NA_HT40MINUS;
258 else if (chan->chanmode == CHANNEL_G_HT40PLUS)
259 return ATH9K_MODE_11NG_HT40PLUS;
260 else if (chan->chanmode == CHANNEL_G_HT40MINUS)
261 return ATH9K_MODE_11NG_HT40MINUS;
262
263 /* NB: should not get here */
264 return ATH9K_MODE_11B;
265}
266
267/*
268 * Stop the device, grabbing the top-level lock to protect
269 * against concurrent entry through ath_init (which can happen
270 * if another thread does a system call and the thread doing the
271 * stop is preempted).
272 */
273
274static int ath_stop(struct ath_softc *sc)
275{
276 struct ath_hal *ah = sc->sc_ah;
277
278 DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %u\n",
279 __func__, sc->sc_invalid);
280
281 /*
282 * Shutdown the hardware and driver:
283 * stop output from above
284 * reset 802.11 state machine
285 * (sends station deassoc/deauth frames)
286 * turn off timers
287 * disable interrupts
288 * clear transmit machinery
289 * clear receive machinery
290 * turn off the radio
291 * reclaim beacon resources
292 *
293 * Note that some of this work is not possible if the
294 * hardware is gone (invalid).
295 */
296
297 if (!sc->sc_invalid)
298 ath9k_hw_set_interrupts(ah, 0);
299 ath_draintxq(sc, false);
300 if (!sc->sc_invalid) {
301 ath_stoprecv(sc);
302 ath9k_hw_phy_disable(ah);
303 } else
304 sc->sc_rxlink = NULL;
305
306 return 0;
307}
308
309/*
310 * Start Scan
311 *
312 * This function is called when starting a channel scan. It will perform
313 * power save wakeup processing, set the filter for the scan, and get the
314 * chip ready to send broadcast packets out during the scan.
315*/
316
317void ath_scan_start(struct ath_softc *sc)
318{
319 struct ath_hal *ah = sc->sc_ah;
320 u32 rfilt;
321 u32 now = (u32) jiffies_to_msecs(get_timestamp());
322
323 sc->sc_scanning = 1;
324 rfilt = ath_calcrxfilter(sc);
325 ath9k_hw_setrxfilter(ah, rfilt);
326 ath9k_hw_write_associd(ah, ath_bcast_mac, 0);
327
328 /* Restore previous power management state. */
329
330 DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0\n",
331 now / 1000, now % 1000, __func__, rfilt);
332}
333
334/*
335 * Scan End
336 *
337 * This routine is called by the upper layer when the scan is completed. This
338 * will set the filters back to normal operating mode, set the BSSID to the
339 * correct value, and restore the power save state.
340*/
341
342void ath_scan_end(struct ath_softc *sc)
343{
344 struct ath_hal *ah = sc->sc_ah;
345 u32 rfilt;
346 u32 now = (u32) jiffies_to_msecs(get_timestamp());
347
348 sc->sc_scanning = 0;
349 /* Request for a full reset due to rx packet filter changes */
350 sc->sc_full_reset = 1;
351 rfilt = ath_calcrxfilter(sc);
352 ath9k_hw_setrxfilter(ah, rfilt);
353 ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
354
355 DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0x%x\n",
356 now / 1000, now % 1000, __func__, rfilt, sc->sc_curaid);
357}
358
359/*
360 * Set the current channel
361 *
362 * Set/change channels. If the channel is really being changed, it's done
363 * by reseting the chip. To accomplish this we must first cleanup any pending
364 * DMA, then restart stuff after a la ath_init.
365*/
366int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
367{
368 struct ath_hal *ah = sc->sc_ah;
369 bool fastcc = true, stopped;
370 enum ath9k_ht_macmode ht_macmode;
371
372 if (sc->sc_invalid) /* if the device is invalid or removed */
373 return -EIO;
374
375 DPRINTF(sc, ATH_DBG_CONFIG,
376 "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n",
377 __func__,
378 ath9k_hw_mhz2ieee(ah, sc->sc_curchan.channel,
379 sc->sc_curchan.channelFlags),
380 sc->sc_curchan.channel,
381 ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags),
382 hchan->channel, hchan->channelFlags);
383
384 ht_macmode = ath_cwm_macmode(sc);
385
386 if (hchan->channel != sc->sc_curchan.channel ||
387 hchan->channelFlags != sc->sc_curchan.channelFlags ||
388 sc->sc_update_chainmask || sc->sc_full_reset) {
389 int status;
390 /*
391 * This is only performed if the channel settings have
392 * actually changed.
393 *
394 * To switch channels clear any pending DMA operations;
395 * wait long enough for the RX fifo to drain, reset the
396 * hardware at the new frequency, and then re-enable
397 * the relevant bits of the h/w.
398 */
399 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
400 ath_draintxq(sc, false); /* clear pending tx frames */
401 stopped = ath_stoprecv(sc); /* turn off frame recv */
402
403 /* XXX: do not flush receive queue here. We don't want
404 * to flush data frames already in queue because of
405 * changing channel. */
406
407 if (!stopped || sc->sc_full_reset)
408 fastcc = false;
409
410 spin_lock_bh(&sc->sc_resetlock);
411 if (!ath9k_hw_reset(ah, sc->sc_opmode, hchan,
412 ht_macmode, sc->sc_tx_chainmask,
413 sc->sc_rx_chainmask,
414 sc->sc_ht_extprotspacing,
415 fastcc, &status)) {
416 DPRINTF(sc, ATH_DBG_FATAL,
417 "%s: unable to reset channel %u (%uMhz) "
418 "flags 0x%x hal status %u\n", __func__,
419 ath9k_hw_mhz2ieee(ah, hchan->channel,
420 hchan->channelFlags),
421 hchan->channel, hchan->channelFlags, status);
422 spin_unlock_bh(&sc->sc_resetlock);
423 return -EIO;
424 }
425 spin_unlock_bh(&sc->sc_resetlock);
426
427 sc->sc_curchan = *hchan;
428 sc->sc_update_chainmask = 0;
429 sc->sc_full_reset = 0;
430
431 /* Re-enable rx framework */
432 if (ath_startrecv(sc) != 0) {
433 DPRINTF(sc, ATH_DBG_FATAL,
434 "%s: unable to restart recv logic\n", __func__);
435 return -EIO;
436 }
437 /*
438 * Change channels and update the h/w rate map
439 * if we're switching; e.g. 11a to 11b/g.
440 */
441 ath_setcurmode(sc, ath_chan2mode(hchan));
442
443 ath_update_txpow(sc); /* update tx power state */
444 /*
445 * Re-enable interrupts.
446 */
447 ath9k_hw_set_interrupts(ah, sc->sc_imask);
448 }
449 return 0;
450}
451
452/**********************/
453/* Chainmask Handling */
454/**********************/
455
456static void ath_chainmask_sel_timertimeout(unsigned long data)
457{
458 struct ath_chainmask_sel *cm = (struct ath_chainmask_sel *)data;
459 cm->switch_allowed = 1;
460}
461
462/* Start chainmask select timer */
463static void ath_chainmask_sel_timerstart(struct ath_chainmask_sel *cm)
464{
465 cm->switch_allowed = 0;
466 mod_timer(&cm->timer, ath_chainmask_sel_period);
467}
468
469/* Stop chainmask select timer */
470static void ath_chainmask_sel_timerstop(struct ath_chainmask_sel *cm)
471{
472 cm->switch_allowed = 0;
473 del_timer_sync(&cm->timer);
474}
475
476static void ath_chainmask_sel_init(struct ath_softc *sc, struct ath_node *an)
477{
478 struct ath_chainmask_sel *cm = &an->an_chainmask_sel;
479
480 memzero(cm, sizeof(struct ath_chainmask_sel));
481
482 cm->cur_tx_mask = sc->sc_tx_chainmask;
483 cm->cur_rx_mask = sc->sc_rx_chainmask;
484 cm->tx_avgrssi = ATH_RSSI_DUMMY_MARKER;
485 setup_timer(&cm->timer,
486 ath_chainmask_sel_timertimeout, (unsigned long) cm);
487}
488
489int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an)
490{
491 struct ath_chainmask_sel *cm = &an->an_chainmask_sel;
492
493 /*
494 * Disable auto-swtiching in one of the following if conditions.
495 * sc_chainmask_auto_sel is used for internal global auto-switching
496 * enabled/disabled setting
497 */
498 if (sc->sc_ah->ah_caps.tx_chainmask != ATH_CHAINMASK_SEL_3X3) {
499 cm->cur_tx_mask = sc->sc_tx_chainmask;
500 return cm->cur_tx_mask;
501 }
502
503 if (cm->tx_avgrssi == ATH_RSSI_DUMMY_MARKER)
504 return cm->cur_tx_mask;
505
506 if (cm->switch_allowed) {
507 /* Switch down from tx 3 to tx 2. */
508 if (cm->cur_tx_mask == ATH_CHAINMASK_SEL_3X3 &&
509 ATH_RSSI_OUT(cm->tx_avgrssi) >=
510 ath_chainmask_sel_down_rssi_thres) {
511 cm->cur_tx_mask = sc->sc_tx_chainmask;
512
513 /* Don't let another switch happen until
514 * this timer expires */
515 ath_chainmask_sel_timerstart(cm);
516 }
517 /* Switch up from tx 2 to 3. */
518 else if (cm->cur_tx_mask == sc->sc_tx_chainmask &&
519 ATH_RSSI_OUT(cm->tx_avgrssi) <=
520 ath_chainmask_sel_up_rssi_thres) {
521 cm->cur_tx_mask = ATH_CHAINMASK_SEL_3X3;
522
523 /* Don't let another switch happen
524 * until this timer expires */
525 ath_chainmask_sel_timerstart(cm);
526 }
527 }
528
529 return cm->cur_tx_mask;
530}
531
532/*
533 * Update tx/rx chainmask. For legacy association,
534 * hard code chainmask to 1x1, for 11n association, use
535 * the chainmask configuration.
536 */
537
538void ath_update_chainmask(struct ath_softc *sc, int is_ht)
539{
540 sc->sc_update_chainmask = 1;
541 if (is_ht) {
542 sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask;
543 sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask;
544 } else {
545 sc->sc_tx_chainmask = 1;
546 sc->sc_rx_chainmask = 1;
547 }
548
549 DPRINTF(sc, ATH_DBG_CONFIG, "%s: tx chmask: %d, rx chmask: %d\n",
550 __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask);
551}
552
553/******************/
554/* VAP management */
555/******************/
556
557/*
558 * VAP in Listen mode
559 *
560 * This routine brings the VAP out of the down state into a "listen" state
561 * where it waits for association requests. This is used in AP and AdHoc
562 * modes.
563*/
564
565int ath_vap_listen(struct ath_softc *sc, int if_id)
566{
567 struct ath_hal *ah = sc->sc_ah;
568 struct ath_vap *avp;
569 u32 rfilt = 0;
570 DECLARE_MAC_BUF(mac);
571
572 avp = sc->sc_vaps[if_id];
573 if (avp == NULL) {
574 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
575 __func__, if_id);
576 return -EINVAL;
577 }
578
579#ifdef CONFIG_SLOW_ANT_DIV
580 ath_slow_ant_div_stop(&sc->sc_antdiv);
581#endif
582
583 /* update ratectrl about the new state */
584 ath_rate_newstate(sc, avp);
585
586 rfilt = ath_calcrxfilter(sc);
587 ath9k_hw_setrxfilter(ah, rfilt);
588
589 if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS) {
590 memcpy(sc->sc_curbssid, ath_bcast_mac, ETH_ALEN);
591 ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
592 } else
593 sc->sc_curaid = 0;
594
595 DPRINTF(sc, ATH_DBG_CONFIG,
596 "%s: RX filter 0x%x bssid %s aid 0x%x\n",
597 __func__, rfilt, print_mac(mac,
598 sc->sc_curbssid), sc->sc_curaid);
599
600 /*
601 * XXXX
602 * Disable BMISS interrupt when we're not associated
603 */
604 ath9k_hw_set_interrupts(ah,
605 sc->sc_imask & ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
606 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
607 /* need to reconfigure the beacons when it moves to RUN */
608 sc->sc_beacons = 0;
609
610 return 0;
611}
612
613int ath_vap_attach(struct ath_softc *sc,
614 int if_id,
615 struct ieee80211_vif *if_data,
616 enum ath9k_opmode opmode)
617{
618 struct ath_vap *avp;
619
620 if (if_id >= ATH_BCBUF || sc->sc_vaps[if_id] != NULL) {
621 DPRINTF(sc, ATH_DBG_FATAL,
622 "%s: Invalid interface id = %u\n", __func__, if_id);
623 return -EINVAL;
624 }
625
626 switch (opmode) {
627 case ATH9K_M_STA:
628 case ATH9K_M_IBSS:
629 case ATH9K_M_MONITOR:
630 break;
631 case ATH9K_M_HOSTAP:
632 /* XXX not right, beacon buffer is allocated on RUN trans */
633 if (list_empty(&sc->sc_bbuf))
634 return -ENOMEM;
635 break;
636 default:
637 return -EINVAL;
638 }
639
640 /* create ath_vap */
641 avp = kmalloc(sizeof(struct ath_vap), GFP_KERNEL);
642 if (avp == NULL)
643 return -ENOMEM;
644
645 memzero(avp, sizeof(struct ath_vap));
646 avp->av_if_data = if_data;
647 /* Set the VAP opmode */
648 avp->av_opmode = opmode;
649 avp->av_bslot = -1;
650 INIT_LIST_HEAD(&avp->av_mcastq.axq_q);
651 INIT_LIST_HEAD(&avp->av_mcastq.axq_acq);
652 spin_lock_init(&avp->av_mcastq.axq_lock);
653
654 ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
655
656 sc->sc_vaps[if_id] = avp;
657 sc->sc_nvaps++;
658 /* Set the device opmode */
659 sc->sc_opmode = opmode;
660
661 /* default VAP configuration */
662 avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
663 avp->av_config.av_fixed_retryset = 0x03030303;
664
665 return 0;
666}
667
668int ath_vap_detach(struct ath_softc *sc, int if_id)
669{
670 struct ath_hal *ah = sc->sc_ah;
671 struct ath_vap *avp;
672
673 avp = sc->sc_vaps[if_id];
674 if (avp == NULL) {
675 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
676 __func__, if_id);
677 return -EINVAL;
678 }
679
680 /*
681 * Quiesce the hardware while we remove the vap. In
682 * particular we need to reclaim all references to the
683 * vap state by any frames pending on the tx queues.
684 *
685 * XXX can we do this w/o affecting other vap's?
686 */
687 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
688 ath_draintxq(sc, false); /* stop xmit side */
689 ath_stoprecv(sc); /* stop recv side */
690 ath_flushrecv(sc); /* flush recv queue */
691
692 /* Reclaim any pending mcast bufs on the vap. */
693 ath_tx_draintxq(sc, &avp->av_mcastq, false);
694
695 kfree(avp);
696 sc->sc_vaps[if_id] = NULL;
697 sc->sc_nvaps--;
698
699 return 0;
700}
701
702int ath_vap_config(struct ath_softc *sc,
703 int if_id, struct ath_vap_config *if_config)
704{
705 struct ath_vap *avp;
706
707 if (if_id >= ATH_BCBUF) {
708 DPRINTF(sc, ATH_DBG_FATAL,
709 "%s: Invalid interface id = %u\n", __func__, if_id);
710 return -EINVAL;
711 }
712
713 avp = sc->sc_vaps[if_id];
714 ASSERT(avp != NULL);
715
716 if (avp)
717 memcpy(&avp->av_config, if_config, sizeof(avp->av_config));
718
719 return 0;
720}
721
722/********/
723/* Core */
724/********/
725
726int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
727{
728 struct ath_hal *ah = sc->sc_ah;
729 int status;
730 int error = 0;
731 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
732
733 DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n", __func__, sc->sc_opmode);
734
735 /*
736 * Stop anything previously setup. This is safe
737 * whether this is the first time through or not.
738 */
739 ath_stop(sc);
740
741 /* Initialize chanmask selection */
742 sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
743 sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
744
745 /* Reset SERDES registers */
746 ath9k_hw_configpcipowersave(ah, 0);
747
748 /*
749 * The basic interface to setting the hardware in a good
750 * state is ``reset''. On return the hardware is known to
751 * be powered up and with interrupts disabled. This must
752 * be followed by initialization of the appropriate bits
753 * and then setup of the interrupt mask.
754 */
755 sc->sc_curchan = *initial_chan;
756
757 spin_lock_bh(&sc->sc_resetlock);
758 if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan, ht_macmode,
759 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
760 sc->sc_ht_extprotspacing, false, &status)) {
761 DPRINTF(sc, ATH_DBG_FATAL,
762 "%s: unable to reset hardware; hal status %u "
763 "(freq %u flags 0x%x)\n", __func__, status,
764 sc->sc_curchan.channel, sc->sc_curchan.channelFlags);
765 error = -EIO;
766 spin_unlock_bh(&sc->sc_resetlock);
767 goto done;
768 }
769 spin_unlock_bh(&sc->sc_resetlock);
770 /*
771 * This is needed only to setup initial state
772 * but it's best done after a reset.
773 */
774 ath_update_txpow(sc);
775
776 /*
777 * Setup the hardware after reset:
778 * The receive engine is set going.
779 * Frame transmit is handled entirely
780 * in the frame output path; there's nothing to do
781 * here except setup the interrupt mask.
782 */
783 if (ath_startrecv(sc) != 0) {
784 DPRINTF(sc, ATH_DBG_FATAL,
785 "%s: unable to start recv logic\n", __func__);
786 error = -EIO;
787 goto done;
788 }
789 /* Setup our intr mask. */
790 sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX
791 | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
792 | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
793
794 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT)
795 sc->sc_imask |= ATH9K_INT_GTT;
796
797 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
798 sc->sc_imask |= ATH9K_INT_CST;
799
800 /*
801 * Enable MIB interrupts when there are hardware phy counters.
802 * Note we only do this (at the moment) for station mode.
803 */
804 if (ath9k_hw_phycounters(ah) &&
805 ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS)))
806 sc->sc_imask |= ATH9K_INT_MIB;
807 /*
808 * Some hardware processes the TIM IE and fires an
809 * interrupt when the TIM bit is set. For hardware
810 * that does, if not overridden by configuration,
811 * enable the TIM interrupt when operating as station.
812 */
813 if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
814 (sc->sc_opmode == ATH9K_M_STA) &&
815 !sc->sc_config.swBeaconProcess)
816 sc->sc_imask |= ATH9K_INT_TIM;
817 /*
818 * Don't enable interrupts here as we've not yet built our
819 * vap and node data structures, which will be needed as soon
820 * as we start receiving.
821 */
822 ath_setcurmode(sc, ath_chan2mode(initial_chan));
823
824 /* XXX: we must make sure h/w is ready and clear invalid flag
825 * before turning on interrupt. */
826 sc->sc_invalid = 0;
827done:
828 return error;
829}
830
831/*
832 * Reset the hardware w/o losing operational state. This is
833 * basically a more efficient way of doing ath_stop, ath_init,
834 * followed by state transitions to the current 802.11
835 * operational state. Used to recover from errors rx overrun
836 * and to reset the hardware when rf gain settings must be reset.
837 */
838
839static int ath_reset_start(struct ath_softc *sc, u32 flag)
840{
841 struct ath_hal *ah = sc->sc_ah;
842
843 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
844 ath_draintxq(sc, flag & RESET_RETRY_TXQ); /* stop xmit side */
845 ath_stoprecv(sc); /* stop recv side */
846 ath_flushrecv(sc); /* flush recv queue */
847
848 return 0;
849}
850
851static int ath_reset_end(struct ath_softc *sc, u32 flag)
852{
853 struct ath_hal *ah = sc->sc_ah;
854
855 if (ath_startrecv(sc) != 0) /* restart recv */
856 DPRINTF(sc, ATH_DBG_FATAL,
857 "%s: unable to start recv logic\n", __func__);
858
859 /*
860 * We may be doing a reset in response to a request
861 * that changes the channel so update any state that
862 * might change as a result.
863 */
864 ath_setcurmode(sc, ath_chan2mode(&sc->sc_curchan));
865
866 ath_update_txpow(sc); /* update tx power state */
867
868 if (sc->sc_beacons)
869 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
870 ath9k_hw_set_interrupts(ah, sc->sc_imask);
871
872 /* Restart the txq */
873 if (flag & RESET_RETRY_TXQ) {
874 int i;
875 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
876 if (ATH_TXQ_SETUP(sc, i)) {
877 spin_lock_bh(&sc->sc_txq[i].axq_lock);
878 ath_txq_schedule(sc, &sc->sc_txq[i]);
879 spin_unlock_bh(&sc->sc_txq[i].axq_lock);
880 }
881 }
882 }
883 return 0;
884}
885
886int ath_reset(struct ath_softc *sc)
887{
888 struct ath_hal *ah = sc->sc_ah;
889 int status;
890 int error = 0;
891 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
892
893 /* NB: indicate channel change so we do a full reset */
894 spin_lock_bh(&sc->sc_resetlock);
895 if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan,
896 ht_macmode,
897 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
898 sc->sc_ht_extprotspacing, false, &status)) {
899 DPRINTF(sc, ATH_DBG_FATAL,
900 "%s: unable to reset hardware; hal status %u\n",
901 __func__, status);
902 error = -EIO;
903 }
904 spin_unlock_bh(&sc->sc_resetlock);
905
906 return error;
907}
908
909int ath_suspend(struct ath_softc *sc)
910{
911 struct ath_hal *ah = sc->sc_ah;
912
913 /* No I/O if device has been surprise removed */
914 if (sc->sc_invalid)
915 return -EIO;
916
917 /* Shut off the interrupt before setting sc->sc_invalid to '1' */
918 ath9k_hw_set_interrupts(ah, 0);
919
920 /* XXX: we must make sure h/w will not generate any interrupt
921 * before setting the invalid flag. */
922 sc->sc_invalid = 1;
923
924 /* disable HAL and put h/w to sleep */
925 ath9k_hw_disable(sc->sc_ah);
926
927 ath9k_hw_configpcipowersave(sc->sc_ah, 1);
928
929 return 0;
930}
931
932/* Interrupt handler. Most of the actual processing is deferred.
933 * It's the caller's responsibility to ensure the chip is awake. */
934
935irqreturn_t ath_isr(int irq, void *dev)
936{
937 struct ath_softc *sc = dev;
938 struct ath_hal *ah = sc->sc_ah;
939 enum ath9k_int status;
940 bool sched = false;
941
942 do {
943 if (sc->sc_invalid) {
944 /*
945 * The hardware is not ready/present, don't
946 * touch anything. Note this can happen early
947 * on if the IRQ is shared.
948 */
949 return IRQ_NONE;
950 }
951 if (!ath9k_hw_intrpend(ah)) { /* shared irq, not for us */
952 return IRQ_NONE;
953 }
954
955 /*
956 * Figure out the reason(s) for the interrupt. Note
957 * that the hal returns a pseudo-ISR that may include
958 * bits we haven't explicitly enabled so we mask the
959 * value to insure we only process bits we requested.
960 */
961 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
962
963 status &= sc->sc_imask; /* discard unasked-for bits */
964
965 /*
966 * If there are no status bits set, then this interrupt was not
967 * for me (should have been caught above).
968 */
969
970 if (!status)
971 return IRQ_NONE;
972
973 sc->sc_intrstatus = status;
974
975 if (status & ATH9K_INT_FATAL) {
976 /* need a chip reset */
977 sched = true;
978 } else if (status & ATH9K_INT_RXORN) {
979 /* need a chip reset */
980 sched = true;
981 } else {
982 if (status & ATH9K_INT_SWBA) {
983 /* schedule a tasklet for beacon handling */
984 tasklet_schedule(&sc->bcon_tasklet);
985 }
986 if (status & ATH9K_INT_RXEOL) {
987 /*
988 * NB: the hardware should re-read the link when
989 * RXE bit is written, but it doesn't work
990 * at least on older hardware revs.
991 */
992 sched = true;
993 }
994
995 if (status & ATH9K_INT_TXURN)
996 /* bump tx trigger level */
997 ath9k_hw_updatetxtriglevel(ah, true);
998 /* XXX: optimize this */
999 if (status & ATH9K_INT_RX)
1000 sched = true;
1001 if (status & ATH9K_INT_TX)
1002 sched = true;
1003 if (status & ATH9K_INT_BMISS)
1004 sched = true;
1005 /* carrier sense timeout */
1006 if (status & ATH9K_INT_CST)
1007 sched = true;
1008 if (status & ATH9K_INT_MIB) {
1009 /*
1010 * Disable interrupts until we service the MIB
1011 * interrupt; otherwise it will continue to
1012 * fire.
1013 */
1014 ath9k_hw_set_interrupts(ah, 0);
1015 /*
1016 * Let the hal handle the event. We assume
1017 * it will clear whatever condition caused
1018 * the interrupt.
1019 */
1020 ath9k_hw_procmibevent(ah, &sc->sc_halstats);
1021 ath9k_hw_set_interrupts(ah, sc->sc_imask);
1022 }
1023 if (status & ATH9K_INT_TIM_TIMER) {
1024 if (!(ah->ah_caps.hw_caps &
1025 ATH9K_HW_CAP_AUTOSLEEP)) {
1026 /* Clear RxAbort bit so that we can
1027 * receive frames */
1028 ath9k_hw_setrxabort(ah, 0);
1029 sched = true;
1030 }
1031 }
1032 }
1033 } while (0);
1034
1035 if (sched) {
1036 /* turn off every interrupt except SWBA */
1037 ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
1038 tasklet_schedule(&sc->intr_tq);
1039 }
1040
1041 return IRQ_HANDLED;
1042}
1043
1044/* Deferred interrupt processing */
1045
1046static void ath9k_tasklet(unsigned long data)
1047{
1048 struct ath_softc *sc = (struct ath_softc *)data;
1049 u32 status = sc->sc_intrstatus;
1050
1051 if (status & ATH9K_INT_FATAL) {
1052 /* need a chip reset */
1053 ath_internal_reset(sc);
1054 return;
1055 } else {
1056
1057 if (status &
1058 (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
1059 /* XXX: fill me in */
1060 /*
1061 if (status & ATH9K_INT_RXORN) {
1062 }
1063 if (status & ATH9K_INT_RXEOL) {
1064 }
1065 */
1066 spin_lock_bh(&sc->sc_rxflushlock);
1067 ath_rx_tasklet(sc, 0);
1068 spin_unlock_bh(&sc->sc_rxflushlock);
1069 }
1070 /* XXX: optimize this */
1071 if (status & ATH9K_INT_TX)
1072 ath_tx_tasklet(sc);
1073 /* XXX: fill me in */
1074 /*
1075 if (status & ATH9K_INT_BMISS) {
1076 }
1077 if (status & (ATH9K_INT_TIM | ATH9K_INT_DTIMSYNC)) {
1078 if (status & ATH9K_INT_TIM) {
1079 }
1080 if (status & ATH9K_INT_DTIMSYNC) {
1081 }
1082 }
1083 */
1084 }
1085
1086 /* re-enable hardware interrupt */
1087 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
1088}
1089
1090int ath_init(u16 devid, struct ath_softc *sc)
1091{
1092 struct ath_hal *ah = NULL;
1093 int status;
1094 int error = 0, i;
1095 int csz = 0;
1096 u32 rd;
1097
1098 /* XXX: hardware will not be ready until ath_open() being called */
1099 sc->sc_invalid = 1;
1100
1101 sc->sc_debug = DBG_DEFAULT;
1102 DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid);
1103
1104 /* Initialize tasklet */
1105 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
1106 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
1107 (unsigned long)sc);
1108
1109 /*
1110 * Cache line size is used to size and align various
1111 * structures used to communicate with the hardware.
1112 */
1113 bus_read_cachesize(sc, &csz);
1114 /* XXX assert csz is non-zero */
1115 sc->sc_cachelsz = csz << 2; /* convert to bytes */
1116
1117 spin_lock_init(&sc->sc_resetlock);
1118
1119 ah = ath9k_hw_attach(devid, sc, sc->mem, &status);
1120 if (ah == NULL) {
1121 DPRINTF(sc, ATH_DBG_FATAL,
1122 "%s: unable to attach hardware; HAL status %u\n",
1123 __func__, status);
1124 error = -ENXIO;
1125 goto bad;
1126 }
1127 sc->sc_ah = ah;
1128
1129 /* Get the chipset-specific aggr limit. */
1130 sc->sc_rtsaggrlimit = ah->ah_caps.rts_aggr_limit;
1131
1132 /* Get the hardware key cache size. */
1133 sc->sc_keymax = ah->ah_caps.keycache_size;
1134 if (sc->sc_keymax > ATH_KEYMAX) {
1135 DPRINTF(sc, ATH_DBG_KEYCACHE,
1136 "%s: Warning, using only %u entries in %u key cache\n",
1137 __func__, ATH_KEYMAX, sc->sc_keymax);
1138 sc->sc_keymax = ATH_KEYMAX;
1139 }
1140
1141 /*
1142 * Reset the key cache since some parts do not
1143 * reset the contents on initial power up.
1144 */
1145 for (i = 0; i < sc->sc_keymax; i++)
1146 ath9k_hw_keyreset(ah, (u16) i);
1147 /*
1148 * Mark key cache slots associated with global keys
1149 * as in use. If we knew TKIP was not to be used we
1150 * could leave the +32, +64, and +32+64 slots free.
1151 * XXX only for splitmic.
1152 */
1153 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
1154 set_bit(i, sc->sc_keymap);
1155 set_bit(i + 32, sc->sc_keymap);
1156 set_bit(i + 64, sc->sc_keymap);
1157 set_bit(i + 32 + 64, sc->sc_keymap);
1158 }
1159 /*
1160 * Collect the channel list using the default country
1161 * code and including outdoor channels. The 802.11 layer
1162 * is resposible for filtering this list based on settings
1163 * like the phy mode.
1164 */
1165 rd = ah->ah_currentRD;
1166
1167 error = ath_setup_channels(sc);
1168 if (error)
1169 goto bad;
1170
1171 /* default to STA mode */
1172 sc->sc_opmode = ATH9K_M_MONITOR;
1173
1174 /* Setup rate tables */
1175
1176 ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
1177 ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
1178
1179 /* NB: setup here so ath_rate_update is happy */
1180 ath_setcurmode(sc, ATH9K_MODE_11A);
1181
1182 /*
1183 * Allocate hardware transmit queues: one queue for
1184 * beacon frames and one data queue for each QoS
1185 * priority. Note that the hal handles reseting
1186 * these queues at the needed time.
1187 */
1188 sc->sc_bhalq = ath_beaconq_setup(ah);
1189 if (sc->sc_bhalq == -1) {
1190 DPRINTF(sc, ATH_DBG_FATAL,
1191 "%s: unable to setup a beacon xmit queue\n", __func__);
1192 error = -EIO;
1193 goto bad2;
1194 }
1195 sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
1196 if (sc->sc_cabq == NULL) {
1197 DPRINTF(sc, ATH_DBG_FATAL,
1198 "%s: unable to setup CAB xmit queue\n", __func__);
1199 error = -EIO;
1200 goto bad2;
1201 }
1202
1203 sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
1204 ath_cabq_update(sc);
1205
1206 for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++)
1207 sc->sc_haltype2q[i] = -1;
1208
1209 /* Setup data queues */
1210 /* NB: ensure BK queue is the lowest priority h/w queue */
1211 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
1212 DPRINTF(sc, ATH_DBG_FATAL,
1213 "%s: unable to setup xmit queue for BK traffic\n",
1214 __func__);
1215 error = -EIO;
1216 goto bad2;
1217 }
1218
1219 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
1220 DPRINTF(sc, ATH_DBG_FATAL,
1221 "%s: unable to setup xmit queue for BE traffic\n",
1222 __func__);
1223 error = -EIO;
1224 goto bad2;
1225 }
1226 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
1227 DPRINTF(sc, ATH_DBG_FATAL,
1228 "%s: unable to setup xmit queue for VI traffic\n",
1229 __func__);
1230 error = -EIO;
1231 goto bad2;
1232 }
1233 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
1234 DPRINTF(sc, ATH_DBG_FATAL,
1235 "%s: unable to setup xmit queue for VO traffic\n",
1236 __func__);
1237 error = -EIO;
1238 goto bad2;
1239 }
1240
1241 sc->sc_rc = ath_rate_attach(ah);
1242 if (sc->sc_rc == NULL) {
1243 error = EIO;
1244 goto bad2;
1245 }
1246
1247 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1248 ATH9K_CIPHER_TKIP, NULL)) {
1249 /*
1250 * Whether we should enable h/w TKIP MIC.
1251 * XXX: if we don't support WME TKIP MIC, then we wouldn't
1252 * report WMM capable, so it's always safe to turn on
1253 * TKIP MIC in this case.
1254 */
1255 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
1256 0, 1, NULL);
1257 }
1258
1259 /*
1260 * Check whether the separate key cache entries
1261 * are required to handle both tx+rx MIC keys.
1262 * With split mic keys the number of stations is limited
1263 * to 27 otherwise 59.
1264 */
1265 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1266 ATH9K_CIPHER_TKIP, NULL)
1267 && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1268 ATH9K_CIPHER_MIC, NULL)
1269 && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
1270 0, NULL))
1271 sc->sc_splitmic = 1;
1272
1273 /* turn on mcast key search if possible */
1274 if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
1275 (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
1276 1, NULL);
1277
1278 sc->sc_config.txpowlimit = ATH_TXPOWER_MAX;
1279 sc->sc_config.txpowlimit_override = 0;
1280
1281 /* 11n Capabilities */
1282 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
1283 sc->sc_txaggr = 1;
1284 sc->sc_rxaggr = 1;
1285 }
1286
1287 sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
1288 sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
1289
1290 /* Configuration for rx chain detection */
1291 sc->sc_rxchaindetect_ref = 0;
1292 sc->sc_rxchaindetect_thresh5GHz = 35;
1293 sc->sc_rxchaindetect_thresh2GHz = 35;
1294 sc->sc_rxchaindetect_delta5GHz = 30;
1295 sc->sc_rxchaindetect_delta2GHz = 30;
1296
1297 ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
1298 sc->sc_defant = ath9k_hw_getdefantenna(ah);
1299
1300 ath9k_hw_getmac(ah, sc->sc_myaddr);
1301 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
1302 ath9k_hw_getbssidmask(ah, sc->sc_bssidmask);
1303 ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);
1304 ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
1305 }
1306 sc->sc_slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
1307
1308 /* initialize beacon slots */
1309 for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++)
1310 sc->sc_bslot[i] = ATH_IF_ID_ANY;
1311
1312 /* save MISC configurations */
1313 sc->sc_config.swBeaconProcess = 1;
1314
1315#ifdef CONFIG_SLOW_ANT_DIV
1316 /* range is 40 - 255, we use something in the middle */
1317 ath_slow_ant_div_init(&sc->sc_antdiv, sc, 0x127);
1318#endif
1319
1320 return 0;
1321bad2:
1322 /* cleanup tx queues */
1323 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1324 if (ATH_TXQ_SETUP(sc, i))
1325 ath_tx_cleanupq(sc, &sc->sc_txq[i]);
1326bad:
1327 if (ah)
1328 ath9k_hw_detach(ah);
1329 return error;
1330}
1331
1332void ath_deinit(struct ath_softc *sc)
1333{
1334 struct ath_hal *ah = sc->sc_ah;
1335 int i;
1336
1337 DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__);
1338
1339 ath_stop(sc);
1340 if (!sc->sc_invalid)
1341 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
1342 ath_rate_detach(sc->sc_rc);
1343 /* cleanup tx queues */
1344 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1345 if (ATH_TXQ_SETUP(sc, i))
1346 ath_tx_cleanupq(sc, &sc->sc_txq[i]);
1347 ath9k_hw_detach(ah);
1348}
1349
1350/*******************/
1351/* Node Management */
1352/*******************/
1353
1354struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id)
1355{
1356 struct ath_vap *avp;
1357 struct ath_node *an;
1358 DECLARE_MAC_BUF(mac);
1359
1360 avp = sc->sc_vaps[if_id];
1361 ASSERT(avp != NULL);
1362
1363 /* mac80211 sta_notify callback is from an IRQ context, so no sleep */
1364 an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC);
1365 if (an == NULL)
1366 return NULL;
1367 memzero(an, sizeof(*an));
1368
1369 an->an_sc = sc;
1370 memcpy(an->an_addr, addr, ETH_ALEN);
1371 atomic_set(&an->an_refcnt, 1);
1372
1373 /* set up per-node tx/rx state */
1374 ath_tx_node_init(sc, an);
1375 ath_rx_node_init(sc, an);
1376
1377 ath_chainmask_sel_init(sc, an);
1378 ath_chainmask_sel_timerstart(&an->an_chainmask_sel);
1379 list_add(&an->list, &sc->node_list);
1380
1381 return an;
1382}
1383
1384void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag)
1385{
1386 unsigned long flags;
1387
1388 DECLARE_MAC_BUF(mac);
1389
1390 ath_chainmask_sel_timerstop(&an->an_chainmask_sel);
1391 an->an_flags |= ATH_NODE_CLEAN;
1392 ath_tx_node_cleanup(sc, an, bh_flag);
1393 ath_rx_node_cleanup(sc, an);
1394
1395 ath_tx_node_free(sc, an);
1396 ath_rx_node_free(sc, an);
1397
1398 spin_lock_irqsave(&sc->node_lock, flags);
1399
1400 list_del(&an->list);
1401
1402 spin_unlock_irqrestore(&sc->node_lock, flags);
1403
1404 kfree(an);
1405}
1406
1407/* Finds a node and increases the refcnt if found */
1408
1409struct ath_node *ath_node_get(struct ath_softc *sc, u8 *addr)
1410{
1411 struct ath_node *an = NULL, *an_found = NULL;
1412
1413 if (list_empty(&sc->node_list)) /* FIXME */
1414 goto out;
1415 list_for_each_entry(an, &sc->node_list, list) {
1416 if (!compare_ether_addr(an->an_addr, addr)) {
1417 atomic_inc(&an->an_refcnt);
1418 an_found = an;
1419 break;
1420 }
1421 }
1422out:
1423 return an_found;
1424}
1425
1426/* Decrements the refcnt and if it drops to zero, detach the node */
1427
1428void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag)
1429{
1430 if (atomic_dec_and_test(&an->an_refcnt))
1431 ath_node_detach(sc, an, bh_flag);
1432}
1433
1434/* Finds a node, doesn't increment refcnt. Caller must hold sc->node_lock */
1435struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr)
1436{
1437 struct ath_node *an = NULL, *an_found = NULL;
1438
1439 if (list_empty(&sc->node_list))
1440 return NULL;
1441
1442 list_for_each_entry(an, &sc->node_list, list)
1443 if (!compare_ether_addr(an->an_addr, addr)) {
1444 an_found = an;
1445 break;
1446 }
1447
1448 return an_found;
1449}
1450
1451/*
1452 * Set up New Node
1453 *
1454 * Setup driver-specific state for a newly associated node. This routine
1455 * really only applies if compression or XR are enabled, there is no code
1456 * covering any other cases.
1457*/
1458
1459void ath_newassoc(struct ath_softc *sc,
1460 struct ath_node *an, int isnew, int isuapsd)
1461{
1462 int tidno;
1463
1464 /* if station reassociates, tear down the aggregation state. */
1465 if (!isnew) {
1466 for (tidno = 0; tidno < WME_NUM_TID; tidno++) {
1467 if (sc->sc_txaggr)
1468 ath_tx_aggr_teardown(sc, an, tidno);
1469 if (sc->sc_rxaggr)
1470 ath_rx_aggr_teardown(sc, an, tidno);
1471 }
1472 }
1473 an->an_flags = 0;
1474}
1475
1476/**************/
1477/* Encryption */
1478/**************/
1479
1480void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot)
1481{
1482 ath9k_hw_keyreset(sc->sc_ah, keyix);
1483 if (freeslot)
1484 clear_bit(keyix, sc->sc_keymap);
1485}
1486
1487int ath_keyset(struct ath_softc *sc,
1488 u16 keyix,
1489 struct ath9k_keyval *hk,
1490 const u8 mac[ETH_ALEN])
1491{
1492 bool status;
1493
1494 status = ath9k_hw_set_keycache_entry(sc->sc_ah,
1495 keyix, hk, mac, false);
1496
1497 return status != false;
1498}
1499
1500/***********************/
1501/* TX Power/Regulatory */
1502/***********************/
1503
1504/*
1505 * Set Transmit power in HAL
1506 *
1507 * This routine makes the actual HAL calls to set the new transmit power
1508 * limit.
1509*/
1510
1511void ath_update_txpow(struct ath_softc *sc)
1512{
1513 struct ath_hal *ah = sc->sc_ah;
1514 u32 txpow;
1515
1516 if (sc->sc_curtxpow != sc->sc_config.txpowlimit) {
1517 ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit);
1518 /* read back in case value is clamped */
1519 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
1520 sc->sc_curtxpow = txpow;
1521 }
1522}
1523
1524/* Return the current country and domain information */
1525void ath_get_currentCountry(struct ath_softc *sc,
1526 struct ath9k_country_entry *ctry)
1527{
1528 ath9k_regd_get_current_country(sc->sc_ah, ctry);
1529
1530 /* If HAL not specific yet, since it is band dependent,
1531 * use the one we passed in. */
1532 if (ctry->countryCode == CTRY_DEFAULT) {
1533 ctry->iso[0] = 0;
1534 ctry->iso[1] = 0;
1535 } else if (ctry->iso[0] && ctry->iso[1]) {
1536 if (!ctry->iso[2]) {
1537 if (ath_outdoor)
1538 ctry->iso[2] = 'O';
1539 else
1540 ctry->iso[2] = 'I';
1541 }
1542 }
1543}
1544
1545/**************************/
1546/* Slow Antenna Diversity */
1547/**************************/
1548
1549void ath_slow_ant_div_init(struct ath_antdiv *antdiv,
1550 struct ath_softc *sc,
1551 int32_t rssitrig)
1552{
1553 int trig;
1554
1555 /* antdivf_rssitrig can range from 40 - 0xff */
1556 trig = (rssitrig > 0xff) ? 0xff : rssitrig;
1557 trig = (rssitrig < 40) ? 40 : rssitrig;
1558
1559 antdiv->antdiv_sc = sc;
1560 antdiv->antdivf_rssitrig = trig;
1561}
1562
1563void ath_slow_ant_div_start(struct ath_antdiv *antdiv,
1564 u8 num_antcfg,
1565 const u8 *bssid)
1566{
1567 antdiv->antdiv_num_antcfg =
1568 num_antcfg < ATH_ANT_DIV_MAX_CFG ?
1569 num_antcfg : ATH_ANT_DIV_MAX_CFG;
1570 antdiv->antdiv_state = ATH_ANT_DIV_IDLE;
1571 antdiv->antdiv_curcfg = 0;
1572 antdiv->antdiv_bestcfg = 0;
1573 antdiv->antdiv_laststatetsf = 0;
1574
1575 memcpy(antdiv->antdiv_bssid, bssid, sizeof(antdiv->antdiv_bssid));
1576
1577 antdiv->antdiv_start = 1;
1578}
1579
1580void ath_slow_ant_div_stop(struct ath_antdiv *antdiv)
1581{
1582 antdiv->antdiv_start = 0;
1583}
1584
1585static int32_t ath_find_max_val(int32_t *val,
1586 u8 num_val, u8 *max_index)
1587{
1588 u32 MaxVal = *val++;
1589 u32 cur_index = 0;
1590
1591 *max_index = 0;
1592 while (++cur_index < num_val) {
1593 if (*val > MaxVal) {
1594 MaxVal = *val;
1595 *max_index = cur_index;
1596 }
1597
1598 val++;
1599 }
1600
1601 return MaxVal;
1602}
1603
1604void ath_slow_ant_div(struct ath_antdiv *antdiv,
1605 struct ieee80211_hdr *hdr,
1606 struct ath_rx_status *rx_stats)
1607{
1608 struct ath_softc *sc = antdiv->antdiv_sc;
1609 struct ath_hal *ah = sc->sc_ah;
1610 u64 curtsf = 0;
1611 u8 bestcfg, curcfg = antdiv->antdiv_curcfg;
1612 __le16 fc = hdr->frame_control;
1613
1614 if (antdiv->antdiv_start && ieee80211_is_beacon(fc)
1615 && !compare_ether_addr(hdr->addr3, antdiv->antdiv_bssid)) {
1616 antdiv->antdiv_lastbrssi[curcfg] = rx_stats->rs_rssi;
1617 antdiv->antdiv_lastbtsf[curcfg] = ath9k_hw_gettsf64(sc->sc_ah);
1618 curtsf = antdiv->antdiv_lastbtsf[curcfg];
1619 } else {
1620 return;
1621 }
1622
1623 switch (antdiv->antdiv_state) {
1624 case ATH_ANT_DIV_IDLE:
1625 if ((antdiv->antdiv_lastbrssi[curcfg] <
1626 antdiv->antdivf_rssitrig)
1627 && ((curtsf - antdiv->antdiv_laststatetsf) >
1628 ATH_ANT_DIV_MIN_IDLE_US)) {
1629
1630 curcfg++;
1631 if (curcfg == antdiv->antdiv_num_antcfg)
1632 curcfg = 0;
1633
1634 if (!ath9k_hw_select_antconfig(ah, curcfg)) {
1635 antdiv->antdiv_bestcfg = antdiv->antdiv_curcfg;
1636 antdiv->antdiv_curcfg = curcfg;
1637 antdiv->antdiv_laststatetsf = curtsf;
1638 antdiv->antdiv_state = ATH_ANT_DIV_SCAN;
1639 }
1640 }
1641 break;
1642
1643 case ATH_ANT_DIV_SCAN:
1644 if ((curtsf - antdiv->antdiv_laststatetsf) <
1645 ATH_ANT_DIV_MIN_SCAN_US)
1646 break;
1647
1648 curcfg++;
1649 if (curcfg == antdiv->antdiv_num_antcfg)
1650 curcfg = 0;
1651
1652 if (curcfg == antdiv->antdiv_bestcfg) {
1653 ath_find_max_val(antdiv->antdiv_lastbrssi,
1654 antdiv->antdiv_num_antcfg, &bestcfg);
1655 if (!ath9k_hw_select_antconfig(ah, bestcfg)) {
1656 antdiv->antdiv_bestcfg = bestcfg;
1657 antdiv->antdiv_curcfg = bestcfg;
1658 antdiv->antdiv_laststatetsf = curtsf;
1659 antdiv->antdiv_state = ATH_ANT_DIV_IDLE;
1660 }
1661 } else {
1662 if (!ath9k_hw_select_antconfig(ah, curcfg)) {
1663 antdiv->antdiv_curcfg = curcfg;
1664 antdiv->antdiv_laststatetsf = curtsf;
1665 antdiv->antdiv_state = ATH_ANT_DIV_SCAN;
1666 }
1667 }
1668
1669 break;
1670 }
1671}
1672
1673/***********************/
1674/* Descriptor Handling */
1675/***********************/
1676
1677/*
1678 * Set up DMA descriptors
1679 *
1680 * This function will allocate both the DMA descriptor structure, and the
1681 * buffers it contains. These are used to contain the descriptors used
1682 * by the system.
1683*/
1684
1685int ath_descdma_setup(struct ath_softc *sc,
1686 struct ath_descdma *dd,
1687 struct list_head *head,
1688 const char *name,
1689 int nbuf,
1690 int ndesc)
1691{
1692#define DS2PHYS(_dd, _ds) \
1693 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
1694#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
1695#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
1696
1697 struct ath_desc *ds;
1698 struct ath_buf *bf;
1699 int i, bsize, error;
1700
1701 DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA: %u buffers %u desc/buf\n",
1702 __func__, name, nbuf, ndesc);
1703
1704 /* ath_desc must be a multiple of DWORDs */
1705 if ((sizeof(struct ath_desc) % 4) != 0) {
1706 DPRINTF(sc, ATH_DBG_FATAL, "%s: ath_desc not DWORD aligned\n",
1707 __func__);
1708 ASSERT((sizeof(struct ath_desc) % 4) == 0);
1709 error = -ENOMEM;
1710 goto fail;
1711 }
1712
1713 dd->dd_name = name;
1714 dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
1715
1716 /*
1717 * Need additional DMA memory because we can't use
1718 * descriptors that cross the 4K page boundary. Assume
1719 * one skipped descriptor per 4K page.
1720 */
1721 if (!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
1722 u32 ndesc_skipped =
1723 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
1724 u32 dma_len;
1725
1726 while (ndesc_skipped) {
1727 dma_len = ndesc_skipped * sizeof(struct ath_desc);
1728 dd->dd_desc_len += dma_len;
1729
1730 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
1731 };
1732 }
1733
1734 /* allocate descriptors */
1735 dd->dd_desc = pci_alloc_consistent(sc->pdev,
1736 dd->dd_desc_len,
1737 &dd->dd_desc_paddr);
1738 if (dd->dd_desc == NULL) {
1739 error = -ENOMEM;
1740 goto fail;
1741 }
1742 ds = dd->dd_desc;
1743 DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA map: %p (%u) -> %llx (%u)\n",
1744 __func__, dd->dd_name, ds, (u32) dd->dd_desc_len,
1745 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
1746
1747 /* allocate buffers */
1748 bsize = sizeof(struct ath_buf) * nbuf;
1749 bf = kmalloc(bsize, GFP_KERNEL);
1750 if (bf == NULL) {
1751 error = -ENOMEM;
1752 goto fail2;
1753 }
1754 memzero(bf, bsize);
1755 dd->dd_bufptr = bf;
1756
1757 INIT_LIST_HEAD(head);
1758 for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
1759 bf->bf_desc = ds;
1760 bf->bf_daddr = DS2PHYS(dd, ds);
1761
1762 if (!(sc->sc_ah->ah_caps.hw_caps &
1763 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
1764 /*
1765 * Skip descriptor addresses which can cause 4KB
1766 * boundary crossing (addr + length) with a 32 dword
1767 * descriptor fetch.
1768 */
1769 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
1770 ASSERT((caddr_t) bf->bf_desc <
1771 ((caddr_t) dd->dd_desc +
1772 dd->dd_desc_len));
1773
1774 ds += ndesc;
1775 bf->bf_desc = ds;
1776 bf->bf_daddr = DS2PHYS(dd, ds);
1777 }
1778 }
1779 list_add_tail(&bf->list, head);
1780 }
1781 return 0;
1782fail2:
1783 pci_free_consistent(sc->pdev,
1784 dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
1785fail:
1786 memzero(dd, sizeof(*dd));
1787 return error;
1788#undef ATH_DESC_4KB_BOUND_CHECK
1789#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
1790#undef DS2PHYS
1791}
1792
1793/*
1794 * Cleanup DMA descriptors
1795 *
1796 * This function will free the DMA block that was allocated for the descriptor
1797 * pool. Since this was allocated as one "chunk", it is freed in the same
1798 * manner.
1799*/
1800
1801void ath_descdma_cleanup(struct ath_softc *sc,
1802 struct ath_descdma *dd,
1803 struct list_head *head)
1804{
1805 /* Free memory associated with descriptors */
1806 pci_free_consistent(sc->pdev,
1807 dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
1808
1809 INIT_LIST_HEAD(head);
1810 kfree(dd->dd_bufptr);
1811 memzero(dd, sizeof(*dd));
1812}
1813
1814/*************/
1815/* Utilities */
1816/*************/
1817
1818void ath_internal_reset(struct ath_softc *sc)
1819{
1820 ath_reset_start(sc, 0);
1821 ath_reset(sc);
1822 ath_reset_end(sc, 0);
1823}
1824
1825int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
1826{
1827 int qnum;
1828
1829 switch (queue) {
1830 case 0:
1831 qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO];
1832 break;
1833 case 1:
1834 qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI];
1835 break;
1836 case 2:
1837 qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
1838 break;
1839 case 3:
1840 qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK];
1841 break;
1842 default:
1843 qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
1844 break;
1845 }
1846
1847 return qnum;
1848}
1849
1850int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
1851{
1852 int qnum;
1853
1854 switch (queue) {
1855 case ATH9K_WME_AC_VO:
1856 qnum = 0;
1857 break;
1858 case ATH9K_WME_AC_VI:
1859 qnum = 1;
1860 break;
1861 case ATH9K_WME_AC_BE:
1862 qnum = 2;
1863 break;
1864 case ATH9K_WME_AC_BK:
1865 qnum = 3;
1866 break;
1867 default:
1868 qnum = -1;
1869 break;
1870 }
1871
1872 return qnum;
1873}
1874
1875
1876/*
1877 * Expand time stamp to TSF
1878 *
1879 * Extend 15-bit time stamp from rx descriptor to
1880 * a full 64-bit TSF using the current h/w TSF.
1881*/
1882
1883u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
1884{
1885 u64 tsf;
1886
1887 tsf = ath9k_hw_gettsf64(sc->sc_ah);
1888 if ((tsf & 0x7fff) < rstamp)
1889 tsf -= 0x8000;
1890 return (tsf & ~0x7fff) | rstamp;
1891}
1892
1893/*
1894 * Set Default Antenna
1895 *
1896 * Call into the HAL to set the default antenna to use. Not really valid for
1897 * MIMO technology.
1898*/
1899
1900void ath_setdefantenna(void *context, u32 antenna)
1901{
1902 struct ath_softc *sc = (struct ath_softc *)context;
1903 struct ath_hal *ah = sc->sc_ah;
1904
1905 /* XXX block beacon interrupts */
1906 ath9k_hw_setantenna(ah, antenna);
1907 sc->sc_defant = antenna;
1908 sc->sc_rxotherant = 0;
1909}
1910
1911/*
1912 * Set Slot Time
1913 *
1914 * This will wake up the chip if required, and set the slot time for the
1915 * frame (maximum transmit time). Slot time is assumed to be already set
1916 * in the ATH object member sc_slottime
1917*/
1918
1919void ath_setslottime(struct ath_softc *sc)
1920{
1921 ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime);
1922 sc->sc_updateslot = OK;
1923}
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
new file mode 100644
index 000000000000..673b3d81133a
--- /dev/null
+++ b/drivers/net/wireless/ath9k/core.h
@@ -0,0 +1,1072 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef CORE_H
18#define CORE_H
19
20#include <linux/version.h>
21#include <linux/autoconf.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/spinlock.h>
25#include <linux/errno.h>
26#include <linux/skbuff.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/ip.h>
30#include <linux/tcp.h>
31#include <linux/in.h>
32#include <linux/delay.h>
33#include <linux/wait.h>
34#include <linux/pci.h>
35#include <linux/interrupt.h>
36#include <linux/sched.h>
37#include <linux/list.h>
38#include <asm/byteorder.h>
39#include <linux/scatterlist.h>
40#include <asm/page.h>
41#include <net/mac80211.h>
42
43#include "ath9k.h"
44#include "rc.h"
45
46struct ath_node;
47
48/******************/
49/* Utility macros */
50/******************/
51
52/* Macro to expand scalars to 64-bit objects */
53
54#define ito64(x) (sizeof(x) == 8) ? \
55 (((unsigned long long int)(x)) & (0xff)) : \
56 (sizeof(x) == 16) ? \
57 (((unsigned long long int)(x)) & 0xffff) : \
58 ((sizeof(x) == 32) ? \
59 (((unsigned long long int)(x)) & 0xffffffff) : \
60 (unsigned long long int)(x))
61
62/* increment with wrap-around */
63#define INCR(_l, _sz) do { \
64 (_l)++; \
65 (_l) &= ((_sz) - 1); \
66 } while (0)
67
68/* decrement with wrap-around */
69#define DECR(_l, _sz) do { \
70 (_l)--; \
71 (_l) &= ((_sz) - 1); \
72 } while (0)
73
74#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
75
76#define ASSERT(exp) do { \
77 if (unlikely(!(exp))) { \
78 BUG(); \
79 } \
80 } while (0)
81
82/* XXX: remove */
83#define memzero(_buf, _len) memset(_buf, 0, _len)
84
85#define get_dma_mem_context(var, field) (&((var)->field))
86#define copy_dma_mem_context(dst, src) (*dst = *src)
87
88#define ATH9K_BH_STATUS_INTACT 0
89#define ATH9K_BH_STATUS_CHANGE 1
90
91#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i))
92
93static inline unsigned long get_timestamp(void)
94{
95 return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ);
96}
97
98/*************/
99/* Debugging */
100/*************/
101
102enum ATH_DEBUG {
103 ATH_DBG_RESET = 0x00000001,
104 ATH_DBG_PHY_IO = 0x00000002,
105 ATH_DBG_REG_IO = 0x00000004,
106 ATH_DBG_QUEUE = 0x00000008,
107 ATH_DBG_EEPROM = 0x00000010,
108 ATH_DBG_NF_CAL = 0x00000020,
109 ATH_DBG_CALIBRATE = 0x00000040,
110 ATH_DBG_CHANNEL = 0x00000080,
111 ATH_DBG_INTERRUPT = 0x00000100,
112 ATH_DBG_REGULATORY = 0x00000200,
113 ATH_DBG_ANI = 0x00000400,
114 ATH_DBG_POWER_MGMT = 0x00000800,
115 ATH_DBG_XMIT = 0x00001000,
116 ATH_DBG_BEACON = 0x00002000,
117 ATH_DBG_RATE = 0x00004000,
118 ATH_DBG_CONFIG = 0x00008000,
119 ATH_DBG_KEYCACHE = 0x00010000,
120 ATH_DBG_AGGR = 0x00020000,
121 ATH_DBG_FATAL = 0x00040000,
122 ATH_DBG_ANY = 0xffffffff
123};
124
125#define DBG_DEFAULT (ATH_DBG_FATAL)
126
127#define DPRINTF(sc, _m, _fmt, ...) do { \
128 if (sc->sc_debug & (_m)) \
129 printk(_fmt , ##__VA_ARGS__); \
130 } while (0)
131
132/***************************/
133/* Load-time Configuration */
134/***************************/
135
136/* Per-instance load-time (note: NOT run-time) configurations
137 * for Atheros Device */
138struct ath_config {
139 u32 ath_aggr_prot;
140 u16 txpowlimit;
141 u16 txpowlimit_override;
142 u8 cabqReadytime; /* Cabq Readytime % */
143 u8 swBeaconProcess; /* Process received beacons in SW (vs HW) */
144};
145
146/***********************/
147/* Chainmask Selection */
148/***********************/
149
150#define ATH_CHAINMASK_SEL_TIMEOUT 6000
151/* Default - Number of last RSSI values that is used for
152 * chainmask selection */
153#define ATH_CHAINMASK_SEL_RSSI_CNT 10
154/* Means use 3x3 chainmask instead of configured chainmask */
155#define ATH_CHAINMASK_SEL_3X3 7
156/* Default - Rssi threshold below which we have to switch to 3x3 */
157#define ATH_CHAINMASK_SEL_UP_RSSI_THRES 20
158/* Default - Rssi threshold above which we have to switch to
159 * user configured values */
160#define ATH_CHAINMASK_SEL_DOWN_RSSI_THRES 35
161/* Struct to store the chainmask select related info */
162struct ath_chainmask_sel {
163 struct timer_list timer;
164 int cur_tx_mask; /* user configured or 3x3 */
165 int cur_rx_mask; /* user configured or 3x3 */
166 int tx_avgrssi;
167 u8 switch_allowed:1, /* timer will set this */
168 cm_sel_enabled : 1;
169};
170
171int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an);
172void ath_update_chainmask(struct ath_softc *sc, int is_ht);
173
174/*************************/
175/* Descriptor Management */
176/*************************/
177
178/* Number of descriptors per buffer. The only case where we see skbuff
179chains is due to FF aggregation in the driver. */
180#define ATH_TXDESC 1
181/* if there's more fragment for this MSDU */
182#define ATH_BF_MORE_MPDU 1
183#define ATH_TXBUF_RESET(_bf) do { \
184 (_bf)->bf_status = 0; \
185 (_bf)->bf_lastbf = NULL; \
186 (_bf)->bf_lastfrm = NULL; \
187 (_bf)->bf_next = NULL; \
188 memzero(&((_bf)->bf_state), \
189 sizeof(struct ath_buf_state)); \
190 } while (0)
191
192struct ath_buf_state {
193 int bfs_nframes; /* # frames in aggregate */
194 u16 bfs_al; /* length of aggregate */
195 u16 bfs_frmlen; /* length of frame */
196 int bfs_seqno; /* sequence number */
197 int bfs_tidno; /* tid of this frame */
198 int bfs_retries; /* current retries */
199 struct ath_rc_series bfs_rcs[4]; /* rate series */
200 u8 bfs_isdata:1; /* is a data frame/aggregate */
201 u8 bfs_isaggr:1; /* is an aggregate */
202 u8 bfs_isampdu:1; /* is an a-mpdu, aggregate or not */
203 u8 bfs_ht:1; /* is an HT frame */
204 u8 bfs_isretried:1; /* is retried */
205 u8 bfs_isxretried:1; /* is excessive retried */
206 u8 bfs_shpreamble:1; /* is short preamble */
207 u8 bfs_isbar:1; /* is a BAR */
208 u8 bfs_ispspoll:1; /* is a PS-Poll */
209 u8 bfs_aggrburst:1; /* is a aggr burst */
210 u8 bfs_calcairtime:1; /* requests airtime be calculated
211 when set for tx frame */
212 int bfs_rifsburst_elem; /* RIFS burst/bar */
213 int bfs_nrifsubframes; /* # of elements in burst */
214 /* key type use to encrypt this frame */
215 enum ath9k_key_type bfs_keytype;
216};
217
218#define bf_nframes bf_state.bfs_nframes
219#define bf_al bf_state.bfs_al
220#define bf_frmlen bf_state.bfs_frmlen
221#define bf_retries bf_state.bfs_retries
222#define bf_seqno bf_state.bfs_seqno
223#define bf_tidno bf_state.bfs_tidno
224#define bf_rcs bf_state.bfs_rcs
225#define bf_isdata bf_state.bfs_isdata
226#define bf_isaggr bf_state.bfs_isaggr
227#define bf_isampdu bf_state.bfs_isampdu
228#define bf_ht bf_state.bfs_ht
229#define bf_isretried bf_state.bfs_isretried
230#define bf_isxretried bf_state.bfs_isxretried
231#define bf_shpreamble bf_state.bfs_shpreamble
232#define bf_rifsburst_elem bf_state.bfs_rifsburst_elem
233#define bf_nrifsubframes bf_state.bfs_nrifsubframes
234#define bf_keytype bf_state.bfs_keytype
235#define bf_isbar bf_state.bfs_isbar
236#define bf_ispspoll bf_state.bfs_ispspoll
237#define bf_aggrburst bf_state.bfs_aggrburst
238#define bf_calcairtime bf_state.bfs_calcairtime
239
240/*
241 * Abstraction of a contiguous buffer to transmit/receive. There is only
242 * a single hw descriptor encapsulated here.
243 */
244
245struct ath_buf {
246 struct list_head list;
247 struct list_head *last;
248 struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
249 an aggregate) */
250 struct ath_buf *bf_lastfrm; /* last buf of this frame */
251 struct ath_buf *bf_next; /* next subframe in the aggregate */
252 struct ath_buf *bf_rifslast; /* last buf for RIFS burst */
253 void *bf_mpdu; /* enclosing frame structure */
254 void *bf_node; /* pointer to the node */
255 struct ath_desc *bf_desc; /* virtual addr of desc */
256 dma_addr_t bf_daddr; /* physical addr of desc */
257 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
258 u32 bf_status;
259 u16 bf_flags; /* tx descriptor flags */
260 struct ath_buf_state bf_state; /* buffer state */
261 dma_addr_t bf_dmacontext;
262};
263
264/*
265 * reset the rx buffer.
266 * any new fields added to the athbuf and require
267 * reset need to be added to this macro.
268 * currently bf_status is the only one requires that
269 * requires reset.
270 */
271#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
272
273/* hw processing complete, desc processed by hal */
274#define ATH_BUFSTATUS_DONE 0x00000001
275/* hw processing complete, desc hold for hw */
276#define ATH_BUFSTATUS_STALE 0x00000002
277/* Rx-only: OS is done with this packet and it's ok to queued it to hw */
278#define ATH_BUFSTATUS_FREE 0x00000004
279
280/* DMA state for tx/rx descriptors */
281
282struct ath_descdma {
283 const char *dd_name;
284 struct ath_desc *dd_desc; /* descriptors */
285 dma_addr_t dd_desc_paddr; /* physical addr of dd_desc */
286 u32 dd_desc_len; /* size of dd_desc */
287 struct ath_buf *dd_bufptr; /* associated buffers */
288 dma_addr_t dd_dmacontext;
289};
290
291/* Abstraction of a received RX MPDU/MMPDU, or a RX fragment */
292
293struct ath_rx_context {
294 struct ath_buf *ctx_rxbuf; /* associated ath_buf for rx */
295};
296#define ATH_RX_CONTEXT(skb) ((struct ath_rx_context *)skb->cb)
297
298int ath_descdma_setup(struct ath_softc *sc,
299 struct ath_descdma *dd,
300 struct list_head *head,
301 const char *name,
302 int nbuf,
303 int ndesc);
304int ath_desc_alloc(struct ath_softc *sc);
305void ath_desc_free(struct ath_softc *sc);
306void ath_descdma_cleanup(struct ath_softc *sc,
307 struct ath_descdma *dd,
308 struct list_head *head);
309
310/******/
311/* RX */
312/******/
313
314#define ATH_MAX_ANTENNA 3
315#define ATH_RXBUF 512
316#define ATH_RX_TIMEOUT 40 /* 40 milliseconds */
317#define WME_NUM_TID 16
318#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */
319#define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */
320
321enum ATH_RX_TYPE {
322 ATH_RX_NON_CONSUMED = 0,
323 ATH_RX_CONSUMED
324};
325
326/* per frame rx status block */
327struct ath_recv_status {
328 u64 tsf; /* mac tsf */
329 int8_t rssi; /* RSSI (noise floor ajusted) */
330 int8_t rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
331 int8_t rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
332 int8_t abs_rssi; /* absolute RSSI */
333 u8 rateieee; /* data rate received (IEEE rate code) */
334 u8 ratecode; /* phy rate code */
335 int rateKbps; /* data rate received (Kbps) */
336 int antenna; /* rx antenna */
337 int flags; /* status of associated skb */
338#define ATH_RX_FCS_ERROR 0x01
339#define ATH_RX_MIC_ERROR 0x02
340#define ATH_RX_DECRYPT_ERROR 0x04
341#define ATH_RX_RSSI_VALID 0x08
342/* if any of ctl,extn chainrssis are valid */
343#define ATH_RX_CHAIN_RSSI_VALID 0x10
344/* if extn chain rssis are valid */
345#define ATH_RX_RSSI_EXTN_VALID 0x20
346/* set if 40Mhz, clear if 20Mhz */
347#define ATH_RX_40MHZ 0x40
348/* set if short GI, clear if full GI */
349#define ATH_RX_SHORT_GI 0x80
350};
351
352struct ath_rxbuf {
353 struct sk_buff *rx_wbuf;
354 unsigned long rx_time; /* system time when received */
355 struct ath_recv_status rx_status; /* cached rx status */
356};
357
358/* Per-TID aggregate receiver state for a node */
359struct ath_arx_tid {
360 struct ath_node *an;
361 struct ath_rxbuf *rxbuf; /* re-ordering buffer */
362 struct timer_list timer;
363 spinlock_t tidlock;
364 int baw_head; /* seq_next at head */
365 int baw_tail; /* tail of block-ack window */
366 int seq_reset; /* need to reset start sequence */
367 int addba_exchangecomplete;
368 u16 seq_next; /* next expected sequence */
369 u16 baw_size; /* block-ack window size */
370};
371
372/* Per-node receiver aggregate state */
373struct ath_arx {
374 struct ath_arx_tid tid[WME_NUM_TID];
375};
376
377int ath_startrecv(struct ath_softc *sc);
378bool ath_stoprecv(struct ath_softc *sc);
379void ath_flushrecv(struct ath_softc *sc);
380u32 ath_calcrxfilter(struct ath_softc *sc);
381void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an);
382void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an);
383void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
384void ath_handle_rx_intr(struct ath_softc *sc);
385int ath_rx_init(struct ath_softc *sc, int nbufs);
386void ath_rx_cleanup(struct ath_softc *sc);
387int ath_rx_tasklet(struct ath_softc *sc, int flush);
388int ath_rx_input(struct ath_softc *sc,
389 struct ath_node *node,
390 int is_ampdu,
391 struct sk_buff *skb,
392 struct ath_recv_status *rx_status,
393 enum ATH_RX_TYPE *status);
394int ath__rx_indicate(struct ath_softc *sc,
395 struct sk_buff *skb,
396 struct ath_recv_status *status,
397 u16 keyix);
398int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
399 struct ath_recv_status *status);
400
401/******/
402/* TX */
403/******/
404
405#define ATH_FRAG_PER_MSDU 1
406#define ATH_TXBUF (512/ATH_FRAG_PER_MSDU)
407/* max number of transmit attempts (tries) */
408#define ATH_TXMAXTRY 13
409/* max number of 11n transmit attempts (tries) */
410#define ATH_11N_TXMAXTRY 10
411/* max number of tries for management and control frames */
412#define ATH_MGT_TXMAXTRY 4
413#define WME_BA_BMP_SIZE 64
414#define WME_MAX_BA WME_BA_BMP_SIZE
415#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
416#define TID_TO_WME_AC(_tid) \
417 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
418 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
419 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
420 WME_AC_VO)
421
422
423/* Wireless Multimedia Extension Defines */
424#define WME_AC_BE 0 /* best effort */
425#define WME_AC_BK 1 /* background */
426#define WME_AC_VI 2 /* video */
427#define WME_AC_VO 3 /* voice */
428#define WME_NUM_AC 4
429
430enum ATH_SM_PWRSAV{
431 ATH_SM_ENABLE,
432 ATH_SM_PWRSAV_STATIC,
433 ATH_SM_PWRSAV_DYNAMIC,
434};
435
436/*
437 * Data transmit queue state. One of these exists for each
438 * hardware transmit queue. Packets sent to us from above
439 * are assigned to queues based on their priority. Not all
440 * devices support a complete set of hardware transmit queues.
441 * For those devices the array sc_ac2q will map multiple
442 * priorities to fewer hardware queues (typically all to one
443 * hardware queue).
444 */
445struct ath_txq {
446 u32 axq_qnum; /* hardware q number */
447 u32 *axq_link; /* link ptr in last TX desc */
448 struct list_head axq_q; /* transmit queue */
449 spinlock_t axq_lock;
450 unsigned long axq_lockflags; /* intr state when must cli */
451 u32 axq_depth; /* queue depth */
452 u8 axq_aggr_depth; /* aggregates queued */
453 u32 axq_totalqueued; /* total ever queued */
454
455 /* count to determine if descriptor should generate int on this txq. */
456 u32 axq_intrcnt;
457
458 bool stopped; /* Is mac80211 queue stopped ? */
459 struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
460
461 /* first desc of the last descriptor that contains CTS */
462 struct ath_desc *axq_lastdsWithCTS;
463
464 /* final desc of the gating desc that determines whether
465 lastdsWithCTS has been DMA'ed or not */
466 struct ath_desc *axq_gatingds;
467
468 struct list_head axq_acq;
469};
470
471/* per TID aggregate tx state for a destination */
472struct ath_atx_tid {
473 struct list_head list; /* round-robin tid entry */
474 struct list_head buf_q; /* pending buffers */
475 struct ath_node *an;
476 struct ath_atx_ac *ac;
477 struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; /* active tx frames */
478 u16 seq_start;
479 u16 seq_next;
480 u16 baw_size;
481 int tidno;
482 int baw_head; /* first un-acked tx buffer */
483 int baw_tail; /* next unused tx buffer slot */
484 int sched;
485 int paused;
486 int cleanup_inprogress;
487 u32 addba_exchangecomplete:1;
488 int32_t addba_exchangeinprogress;
489 int addba_exchangeattempts;
490};
491
492/* per access-category aggregate tx state for a destination */
493struct ath_atx_ac {
494 int sched; /* dest-ac is scheduled */
495 int qnum; /* H/W queue number associated
496 with this AC */
497 struct list_head list; /* round-robin txq entry */
498 struct list_head tid_q; /* queue of TIDs with buffers */
499};
500
501/* per dest tx state */
502struct ath_atx {
503 struct ath_atx_tid tid[WME_NUM_TID];
504 struct ath_atx_ac ac[WME_NUM_AC];
505};
506
507/* per-frame tx control block */
508struct ath_tx_control {
509 struct ath_node *an;
510 int if_id;
511 int qnum;
512 u32 ht:1;
513 u32 ps:1;
514 u32 use_minrate:1;
515 enum ath9k_pkt_type atype;
516 enum ath9k_key_type keytype;
517 u32 flags;
518 u16 seqno;
519 u16 tidno;
520 u16 txpower;
521 u16 frmlen;
522 u32 keyix;
523 int min_rate;
524 int mcast_rate;
525 u16 nextfraglen;
526 struct ath_softc *dev;
527 dma_addr_t dmacontext;
528};
529
530/* per frame tx status block */
531struct ath_xmit_status {
532 int retries; /* number of retries to successufully
533 transmit this frame */
534 int flags; /* status of transmit */
535#define ATH_TX_ERROR 0x01
536#define ATH_TX_XRETRY 0x02
537#define ATH_TX_BAR 0x04
538};
539
540struct ath_tx_stat {
541 int rssi; /* RSSI (noise floor ajusted) */
542 int rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
543 int rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
544 int rateieee; /* data rate xmitted (IEEE rate code) */
545 int rateKbps; /* data rate xmitted (Kbps) */
546 int ratecode; /* phy rate code */
547 int flags; /* validity flags */
548/* if any of ctl,extn chain rssis are valid */
549#define ATH_TX_CHAIN_RSSI_VALID 0x01
550/* if extn chain rssis are valid */
551#define ATH_TX_RSSI_EXTN_VALID 0x02
552 u32 airtime; /* time on air per final tx rate */
553};
554
555struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
556void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
557int ath_tx_setup(struct ath_softc *sc, int haltype);
558void ath_draintxq(struct ath_softc *sc, bool retry_tx);
559void ath_tx_draintxq(struct ath_softc *sc,
560 struct ath_txq *txq, bool retry_tx);
561void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
562void ath_tx_node_cleanup(struct ath_softc *sc,
563 struct ath_node *an, bool bh_flag);
564void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an);
565void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
566int ath_tx_init(struct ath_softc *sc, int nbufs);
567int ath_tx_cleanup(struct ath_softc *sc);
568int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
569int ath_txq_update(struct ath_softc *sc, int qnum,
570 struct ath9k_tx_queue_info *q);
571int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb);
572void ath_tx_tasklet(struct ath_softc *sc);
573u32 ath_txq_depth(struct ath_softc *sc, int qnum);
574u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
575void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth);
576void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
577 struct ath_xmit_status *tx_status, struct ath_node *an);
578
579/**********************/
580/* Node / Aggregation */
581/**********************/
582
583/* indicates the node is clened up */
584#define ATH_NODE_CLEAN 0x1
585/* indicates the node is 80211 power save */
586#define ATH_NODE_PWRSAVE 0x2
587
588#define ADDBA_TIMEOUT 200 /* 200 milliseconds */
589#define ADDBA_EXCHANGE_ATTEMPTS 10
590#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */
591#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
592/* number of delimiters for encryption padding */
593#define ATH_AGGR_ENCRYPTDELIM 10
594/* minimum h/w qdepth to be sustained to maximize aggregation */
595#define ATH_AGGR_MIN_QDEPTH 2
596#define ATH_AMPDU_SUBFRAME_DEFAULT 32
597#define IEEE80211_SEQ_SEQ_SHIFT 4
598#define IEEE80211_SEQ_MAX 4096
599#define IEEE80211_MIN_AMPDU_BUF 0x8
600
601/* return whether a bit at index _n in bitmap _bm is set
602 * _sz is the size of the bitmap */
603#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
604 ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
605
606/* return block-ack bitmap index given sequence and starting sequence */
607#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
608
609/* returns delimiter padding required given the packet length */
610#define ATH_AGGR_GET_NDELIM(_len) \
611 (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
612 (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
613
614#define BAW_WITHIN(_start, _bawsz, _seqno) \
615 ((((_seqno) - (_start)) & 4095) < (_bawsz))
616
617#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
618#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
619#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
620#define ATH_AN_2_TID(_an, _tidno) (&(_an)->an_aggr.tx.tid[(_tidno)])
621
622enum ATH_AGGR_STATUS {
623 ATH_AGGR_DONE,
624 ATH_AGGR_BAW_CLOSED,
625 ATH_AGGR_LIMITED,
626 ATH_AGGR_SHORTPKT,
627 ATH_AGGR_8K_LIMITED,
628};
629
630enum ATH_AGGR_CHECK {
631 AGGR_NOT_REQUIRED,
632 AGGR_REQUIRED,
633 AGGR_CLEANUP_PROGRESS,
634 AGGR_EXCHANGE_PROGRESS,
635 AGGR_EXCHANGE_DONE
636};
637
638struct aggr_rifs_param {
639 int param_max_frames;
640 int param_max_len;
641 int param_rl;
642 int param_al;
643 struct ath_rc_series *param_rcs;
644};
645
646/* Per-node aggregation state */
647struct ath_node_aggr {
648 struct ath_atx tx; /* node transmit state */
649 struct ath_arx rx; /* node receive state */
650};
651
652/* driver-specific node state */
653struct ath_node {
654 struct list_head list;
655 struct ath_softc *an_sc;
656 atomic_t an_refcnt;
657 struct ath_chainmask_sel an_chainmask_sel;
658 struct ath_node_aggr an_aggr;
659 u8 an_smmode; /* SM Power save mode */
660 u8 an_flags;
661 u8 an_addr[ETH_ALEN];
662};
663
664void ath_tx_resume_tid(struct ath_softc *sc,
665 struct ath_atx_tid *tid);
666enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
667 struct ath_node *an, u8 tidno);
668void ath_tx_aggr_teardown(struct ath_softc *sc,
669 struct ath_node *an, u8 tidno);
670void ath_rx_aggr_teardown(struct ath_softc *sc,
671 struct ath_node *an, u8 tidno);
672int ath_rx_aggr_start(struct ath_softc *sc,
673 const u8 *addr,
674 u16 tid,
675 u16 *ssn);
676int ath_rx_aggr_stop(struct ath_softc *sc,
677 const u8 *addr,
678 u16 tid);
679int ath_tx_aggr_start(struct ath_softc *sc,
680 const u8 *addr,
681 u16 tid,
682 u16 *ssn);
683int ath_tx_aggr_stop(struct ath_softc *sc,
684 const u8 *addr,
685 u16 tid);
686void ath_newassoc(struct ath_softc *sc,
687 struct ath_node *node, int isnew, int isuapsd);
688struct ath_node *ath_node_attach(struct ath_softc *sc,
689 u8 addr[ETH_ALEN], int if_id);
690void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag);
691struct ath_node *ath_node_get(struct ath_softc *sc, u8 addr[ETH_ALEN]);
692void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag);
693struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr);
694
695/*******************/
696/* Beacon Handling */
697/*******************/
698
699/*
700 * Regardless of the number of beacons we stagger, (i.e. regardless of the
701 * number of BSSIDs) if a given beacon does not go out even after waiting this
702 * number of beacon intervals, the game's up.
703 */
704#define BSTUCK_THRESH (9 * ATH_BCBUF)
705#define ATH_BCBUF 4 /* number of beacon buffers */
706#define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */
707#define ATH_DEFAULT_BMISS_LIMIT 10
708#define ATH_BEACON_AIFS_DEFAULT 0 /* Default aifs for ap beacon q */
709#define ATH_BEACON_CWMIN_DEFAULT 0 /* Default cwmin for ap beacon q */
710#define ATH_BEACON_CWMAX_DEFAULT 0 /* Default cwmax for ap beacon q */
711#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
712
713/* beacon configuration */
714struct ath_beacon_config {
715 u16 beacon_interval;
716 u16 listen_interval;
717 u16 dtim_period;
718 u16 bmiss_timeout;
719 u8 dtim_count;
720 u8 tim_offset;
721 union {
722 u64 last_tsf;
723 u8 last_tstamp[8];
724 } u; /* last received beacon/probe response timestamp of this BSS. */
725};
726
727/* offsets in a beacon frame for
728 * quick acess of beacon content by low-level driver */
729struct ath_beacon_offset {
730 u8 *bo_tim; /* start of atim/dtim */
731};
732
733void ath9k_beacon_tasklet(unsigned long data);
734void ath_beacon_config(struct ath_softc *sc, int if_id);
735int ath_beaconq_setup(struct ath_hal *ah);
736int ath_beacon_alloc(struct ath_softc *sc, int if_id);
737void ath_bstuck_process(struct ath_softc *sc);
738void ath_beacon_tasklet(struct ath_softc *sc, int *needmark);
739void ath_beacon_free(struct ath_softc *sc);
740void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
741void ath_beacon_sync(struct ath_softc *sc, int if_id);
742void ath_update_beacon_info(struct ath_softc *sc, int avgbrssi);
743void ath_get_beaconconfig(struct ath_softc *sc,
744 int if_id,
745 struct ath_beacon_config *conf);
746int ath_update_beacon(struct ath_softc *sc,
747 int if_id,
748 struct ath_beacon_offset *bo,
749 struct sk_buff *skb,
750 int mcast);
751/********/
752/* VAPs */
753/********/
754
755/*
756 * Define the scheme that we select MAC address for multiple
757 * BSS on the same radio. The very first VAP will just use the MAC
758 * address from the EEPROM. For the next 3 VAPs, we set the
759 * U/L bit (bit 1) in MAC address, and use the next two bits as the
760 * index of the VAP.
761 */
762
763#define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
764 ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
765
766/* VAP configuration (from protocol layer) */
767struct ath_vap_config {
768 u32 av_fixed_rateset;
769 u32 av_fixed_retryset;
770};
771
772/* driver-specific vap state */
773struct ath_vap {
774 struct ieee80211_vif *av_if_data;
775 enum ath9k_opmode av_opmode; /* VAP operational mode */
776 struct ath_buf *av_bcbuf; /* beacon buffer */
777 struct ath_beacon_offset av_boff; /* dynamic update state */
778 struct ath_tx_control av_btxctl; /* txctl information for beacon */
779 int av_bslot; /* beacon slot index */
780 struct ath_txq av_mcastq; /* multicast transmit queue */
781 struct ath_vap_config av_config;/* vap configuration parameters*/
782 struct ath_rate_node *rc_node;
783};
784
785int ath_vap_attach(struct ath_softc *sc,
786 int if_id,
787 struct ieee80211_vif *if_data,
788 enum ath9k_opmode opmode);
789int ath_vap_detach(struct ath_softc *sc, int if_id);
790int ath_vap_config(struct ath_softc *sc,
791 int if_id, struct ath_vap_config *if_config);
792int ath_vap_listen(struct ath_softc *sc, int if_id);
793
794/*********************/
795/* Antenna diversity */
796/*********************/
797
798#define ATH_ANT_DIV_MAX_CFG 2
799#define ATH_ANT_DIV_MIN_IDLE_US 1000000 /* us */
800#define ATH_ANT_DIV_MIN_SCAN_US 50000 /* us */
801
802enum ATH_ANT_DIV_STATE{
803 ATH_ANT_DIV_IDLE,
804 ATH_ANT_DIV_SCAN, /* evaluating antenna */
805};
806
807struct ath_antdiv {
808 struct ath_softc *antdiv_sc;
809 u8 antdiv_start;
810 enum ATH_ANT_DIV_STATE antdiv_state;
811 u8 antdiv_num_antcfg;
812 u8 antdiv_curcfg;
813 u8 antdiv_bestcfg;
814 int32_t antdivf_rssitrig;
815 int32_t antdiv_lastbrssi[ATH_ANT_DIV_MAX_CFG];
816 u64 antdiv_lastbtsf[ATH_ANT_DIV_MAX_CFG];
817 u64 antdiv_laststatetsf;
818 u8 antdiv_bssid[ETH_ALEN];
819};
820
821void ath_slow_ant_div_init(struct ath_antdiv *antdiv,
822 struct ath_softc *sc, int32_t rssitrig);
823void ath_slow_ant_div_start(struct ath_antdiv *antdiv,
824 u8 num_antcfg,
825 const u8 *bssid);
826void ath_slow_ant_div_stop(struct ath_antdiv *antdiv);
827void ath_slow_ant_div(struct ath_antdiv *antdiv,
828 struct ieee80211_hdr *wh,
829 struct ath_rx_status *rx_stats);
830void ath_setdefantenna(void *sc, u32 antenna);
831
832/********************/
833/* Main driver core */
834/********************/
835
836/*
837 * Default cache line size, in bytes.
838 * Used when PCI device not fully initialized by bootrom/BIOS
839*/
840#define DEFAULT_CACHELINE 32
841#define ATH_DEFAULT_NOISE_FLOOR -95
842#define ATH_REGCLASSIDS_MAX 10
843#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
844#define ATH_PREAMBLE_SHORT (1<<0)
845#define ATH_PROTECT_ENABLE (1<<1)
846#define ATH_MAX_SW_RETRIES 10
847/* Num farmes difference in tx to flip default recv */
848#define ATH_ANTENNA_DIFF 2
849#define ATH_CHAN_MAX 255
850#define IEEE80211_WEP_NKID 4 /* number of key ids */
851#define IEEE80211_RATE_VAL 0x7f
852/*
853 * The key cache is used for h/w cipher state and also for
854 * tracking station state such as the current tx antenna.
855 * We also setup a mapping table between key cache slot indices
856 * and station state to short-circuit node lookups on rx.
857 * Different parts have different size key caches. We handle
858 * up to ATH_KEYMAX entries (could dynamically allocate state).
859 */
860#define ATH_KEYMAX 128 /* max key cache size we handle */
861
862#define RESET_RETRY_TXQ 0x00000001
863#define ATH_IF_ID_ANY 0xff
864
865#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
866
867#define RSSI_LPF_THRESHOLD -20
868#define ATH_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */
869#define ATH_RATE_DUMMY_MARKER 0
870#define ATH_RSSI_LPF_LEN 10
871#define ATH_RSSI_DUMMY_MARKER 0x127
872
873#define ATH_EP_MUL(x, mul) ((x) * (mul))
874#define ATH_EP_RND(x, mul) \
875 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
876#define ATH_RSSI_OUT(x) \
877 (((x) != ATH_RSSI_DUMMY_MARKER) ? \
878 (ATH_EP_RND((x), ATH_RSSI_EP_MULTIPLIER)) : ATH_RSSI_DUMMY_MARKER)
879#define ATH_RSSI_IN(x) \
880 (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
881#define ATH_LPF_RSSI(x, y, len) \
882 ((x != ATH_RSSI_DUMMY_MARKER) ? \
883 (((x) * ((len) - 1) + (y)) / (len)) : (y))
884#define ATH_RSSI_LPF(x, y) do { \
885 if ((y) >= RSSI_LPF_THRESHOLD) \
886 x = ATH_LPF_RSSI((x), \
887 ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
888 } while (0)
889
890
891enum PROT_MODE {
892 PROT_M_NONE = 0,
893 PROT_M_RTSCTS,
894 PROT_M_CTSONLY
895};
896
897enum RATE_TYPE {
898 NORMAL_RATE = 0,
899 HALF_RATE,
900 QUARTER_RATE
901};
902
903struct ath_ht_info {
904 enum ath9k_ht_macmode tx_chan_width;
905 u16 maxampdu;
906 u8 mpdudensity;
907 u8 ext_chan_offset;
908};
909
910struct ath_softc {
911 struct ieee80211_hw *hw;
912 struct pci_dev *pdev;
913 void __iomem *mem;
914 struct tasklet_struct intr_tq;
915 struct tasklet_struct bcon_tasklet;
916 struct ath_config sc_config; /* load-time parameters */
917 int sc_debug;
918 struct ath_hal *sc_ah;
919 struct ath_rate_softc *sc_rc; /* tx rate control support */
920 u32 sc_intrstatus;
921 enum ath9k_opmode sc_opmode; /* current operating mode */
922
923 u8 sc_invalid; /* being detached */
924 u8 sc_beacons; /* beacons running */
925 u8 sc_scanning; /* scanning active */
926 u8 sc_txaggr; /* enable 11n tx aggregation */
927 u8 sc_rxaggr; /* enable 11n rx aggregation */
928 u8 sc_update_chainmask; /* change chain mask */
929 u8 sc_full_reset; /* force full reset */
930 enum wireless_mode sc_curmode; /* current phy mode */
931 u16 sc_curtxpow;
932 u16 sc_curaid;
933 u8 sc_curbssid[ETH_ALEN];
934 u8 sc_myaddr[ETH_ALEN];
935 enum PROT_MODE sc_protmode;
936 u8 sc_mcastantenna;
937 u8 sc_txantenna; /* data tx antenna (fixed or auto) */
938 u8 sc_nbcnvaps; /* # of vaps sending beacons */
939 u16 sc_nvaps; /* # of active virtual ap's */
940 struct ath_vap *sc_vaps[ATH_BCBUF];
941 enum ath9k_int sc_imask;
942 u8 sc_bssidmask[ETH_ALEN];
943 u8 sc_defant; /* current default antenna */
944 u8 sc_rxotherant; /* rx's on non-default antenna */
945 u16 sc_cachelsz;
946 int sc_slotupdate; /* slot to next advance fsm */
947 int sc_slottime;
948 u8 sc_noreset;
949 int sc_bslot[ATH_BCBUF];
950 struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */
951 struct list_head node_list;
952 struct ath_ht_info sc_ht_info;
953 int16_t sc_noise_floor; /* signal noise floor in dBm */
954 enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
955 u8 sc_tx_chainmask;
956 u8 sc_rx_chainmask;
957 u8 sc_rxchaindetect_ref;
958 u8 sc_rxchaindetect_thresh5GHz;
959 u8 sc_rxchaindetect_thresh2GHz;
960 u8 sc_rxchaindetect_delta5GHz;
961 u8 sc_rxchaindetect_delta2GHz;
962 u32 sc_rtsaggrlimit; /* Chipset specific aggr limit */
963 u32 sc_flags;
964#ifdef CONFIG_SLOW_ANT_DIV
965 struct ath_antdiv sc_antdiv;
966#endif
967 enum {
968 OK, /* no change needed */
969 UPDATE, /* update pending */
970 COMMIT /* beacon sent, commit change */
971 } sc_updateslot; /* slot time update fsm */
972
973 /* Crypto */
974 u32 sc_keymax; /* size of key cache */
975 DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */
976 u8 sc_splitmic; /* split TKIP MIC keys */
977 int sc_keytype;
978
979 /* RX */
980 struct list_head sc_rxbuf;
981 struct ath_descdma sc_rxdma;
982 int sc_rxbufsize; /* rx size based on mtu */
983 u32 *sc_rxlink; /* link ptr in last RX desc */
984 u32 sc_rxflush; /* rx flush in progress */
985 u64 sc_lastrx; /* tsf of last rx'd frame */
986
987 /* TX */
988 struct list_head sc_txbuf;
989 struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES];
990 struct ath_descdma sc_txdma;
991 u32 sc_txqsetup;
992 u32 sc_txintrperiod; /* tx interrupt batching */
993 int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
994 u32 sc_ant_tx[8]; /* recent tx frames/antenna */
995
996 /* Beacon */
997 struct ath9k_tx_queue_info sc_beacon_qi;
998 struct ath_descdma sc_bdma;
999 struct ath_txq *sc_cabq;
1000 struct list_head sc_bbuf;
1001 u32 sc_bhalq;
1002 u32 sc_bmisscount;
1003 u32 ast_be_xmit; /* beacons transmitted */
1004
1005 /* Rate */
1006 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
1007 const struct ath9k_rate_table *sc_currates;
1008 u8 sc_rixmap[256]; /* IEEE to h/w rate table ix */
1009 u8 sc_protrix; /* protection rate index */
1010 struct {
1011 u32 rateKbps; /* transfer rate in kbs */
1012 u8 ieeerate; /* IEEE rate */
1013 } sc_hwmap[256]; /* h/w rate ix mappings */
1014
1015 /* Channel, Band */
1016 struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
1017 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
1018 struct ath9k_channel sc_curchan;
1019
1020 /* Locks */
1021 spinlock_t sc_rxflushlock;
1022 spinlock_t sc_rxbuflock;
1023 spinlock_t sc_txbuflock;
1024 spinlock_t sc_resetlock;
1025 spinlock_t node_lock;
1026};
1027
1028int ath_init(u16 devid, struct ath_softc *sc);
1029void ath_deinit(struct ath_softc *sc);
1030int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan);
1031int ath_suspend(struct ath_softc *sc);
1032irqreturn_t ath_isr(int irq, void *dev);
1033int ath_reset(struct ath_softc *sc);
1034void ath_scan_start(struct ath_softc *sc);
1035void ath_scan_end(struct ath_softc *sc);
1036int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan);
1037void ath_setup_rate(struct ath_softc *sc,
1038 enum wireless_mode wMode,
1039 enum RATE_TYPE type,
1040 const struct ath9k_rate_table *rt);
1041
1042/*********************/
1043/* Utility Functions */
1044/*********************/
1045
1046void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot);
1047int ath_keyset(struct ath_softc *sc,
1048 u16 keyix,
1049 struct ath9k_keyval *hk,
1050 const u8 mac[ETH_ALEN]);
1051int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
1052int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
1053void ath_setslottime(struct ath_softc *sc);
1054void ath_update_txpow(struct ath_softc *sc);
1055int ath_cabq_update(struct ath_softc *);
1056void ath_get_currentCountry(struct ath_softc *sc,
1057 struct ath9k_country_entry *ctry);
1058u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp);
1059void ath_internal_reset(struct ath_softc *sc);
1060u32 ath_chan2flags(struct ieee80211_channel *chan, struct ath_softc *sc);
1061dma_addr_t ath_skb_map_single(struct ath_softc *sc,
1062 struct sk_buff *skb,
1063 int direction,
1064 dma_addr_t *pa);
1065void ath_skb_unmap_single(struct ath_softc *sc,
1066 struct sk_buff *skb,
1067 int direction,
1068 dma_addr_t *pa);
1069void ath_mcast_merge(struct ath_softc *sc, u32 mfilt[2]);
1070enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc);
1071
1072#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
new file mode 100644
index 000000000000..a17eb130f574
--- /dev/null
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -0,0 +1,8575 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/io.h>
18#include <asm/unaligned.h>
19
20#include "core.h"
21#include "hw.h"
22#include "reg.h"
23#include "phy.h"
24#include "initvals.h"
25
26static void ath9k_hw_iqcal_collect(struct ath_hal *ah);
27static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains);
28static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah);
29static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah,
30 u8 numChains);
31static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah);
32static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah,
33 u8 numChains);
34
35static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
36static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
37
38static const struct hal_percal_data iq_cal_multi_sample = {
39 IQ_MISMATCH_CAL,
40 MAX_CAL_SAMPLES,
41 PER_MIN_LOG_COUNT,
42 ath9k_hw_iqcal_collect,
43 ath9k_hw_iqcalibrate
44};
45static const struct hal_percal_data iq_cal_single_sample = {
46 IQ_MISMATCH_CAL,
47 MIN_CAL_SAMPLES,
48 PER_MAX_LOG_COUNT,
49 ath9k_hw_iqcal_collect,
50 ath9k_hw_iqcalibrate
51};
52static const struct hal_percal_data adc_gain_cal_multi_sample = {
53 ADC_GAIN_CAL,
54 MAX_CAL_SAMPLES,
55 PER_MIN_LOG_COUNT,
56 ath9k_hw_adc_gaincal_collect,
57 ath9k_hw_adc_gaincal_calibrate
58};
59static const struct hal_percal_data adc_gain_cal_single_sample = {
60 ADC_GAIN_CAL,
61 MIN_CAL_SAMPLES,
62 PER_MAX_LOG_COUNT,
63 ath9k_hw_adc_gaincal_collect,
64 ath9k_hw_adc_gaincal_calibrate
65};
66static const struct hal_percal_data adc_dc_cal_multi_sample = {
67 ADC_DC_CAL,
68 MAX_CAL_SAMPLES,
69 PER_MIN_LOG_COUNT,
70 ath9k_hw_adc_dccal_collect,
71 ath9k_hw_adc_dccal_calibrate
72};
73static const struct hal_percal_data adc_dc_cal_single_sample = {
74 ADC_DC_CAL,
75 MIN_CAL_SAMPLES,
76 PER_MAX_LOG_COUNT,
77 ath9k_hw_adc_dccal_collect,
78 ath9k_hw_adc_dccal_calibrate
79};
80static const struct hal_percal_data adc_init_dc_cal = {
81 ADC_DC_INIT_CAL,
82 MIN_CAL_SAMPLES,
83 INIT_LOG_COUNT,
84 ath9k_hw_adc_dccal_collect,
85 ath9k_hw_adc_dccal_calibrate
86};
87
88static const struct ath_hal ar5416hal = {
89 AR5416_MAGIC,
90 0,
91 0,
92 NULL,
93 NULL,
94 CTRY_DEFAULT,
95 0,
96 0,
97 0,
98 0,
99 0,
100 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 },
109};
110
111static struct ath9k_rate_table ar5416_11a_table = {
112 8,
113 {0},
114 {
115 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
116 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
117 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
118 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
119 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
120 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
121 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
122 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
123 },
124};
125
126static struct ath9k_rate_table ar5416_11b_table = {
127 4,
128 {0},
129 {
130 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
131 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
132 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
133 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
134 },
135};
136
137static struct ath9k_rate_table ar5416_11g_table = {
138 12,
139 {0},
140 {
141 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
142 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
143 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
144 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
145
146 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
147 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
148 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
149 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
150 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
151 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
152 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
153 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
154 },
155};
156
157static struct ath9k_rate_table ar5416_11ng_table = {
158 28,
159 {0},
160 {
161 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
162 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
163 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
164 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
165
166 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
167 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
168 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
169 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
170 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
171 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
172 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
173 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
174 {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
175 {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
176 {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
177 {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
178 {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
179 {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
180 {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
181 {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
182 {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
183 {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
184 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
185 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
186 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
187 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
188 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
189 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
190 },
191};
192
193static struct ath9k_rate_table ar5416_11na_table = {
194 24,
195 {0},
196 {
197 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
198 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
199 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
200 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
201 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
202 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
203 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
204 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
205 {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
206 {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
207 {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
208 {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
209 {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
210 {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
211 {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
212 {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
213 {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
214 {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
215 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
216 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
217 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
218 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
219 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
220 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
221 },
222};
223
224static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
225 const struct ath9k_channel *chan)
226{
227 if (IS_CHAN_CCK(chan))
228 return ATH9K_MODE_11A;
229 if (IS_CHAN_G(chan))
230 return ATH9K_MODE_11G;
231 return ATH9K_MODE_11A;
232}
233
234static bool ath9k_hw_wait(struct ath_hal *ah,
235 u32 reg,
236 u32 mask,
237 u32 val)
238{
239 int i;
240
241 for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
242 if ((REG_READ(ah, reg) & mask) == val)
243 return true;
244
245 udelay(AH_TIME_QUANTUM);
246 }
247 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
248 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
249 __func__, reg, REG_READ(ah, reg), mask, val);
250 return false;
251}
252
253static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off,
254 u16 *data)
255{
256 (void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
257
258 if (!ath9k_hw_wait(ah,
259 AR_EEPROM_STATUS_DATA,
260 AR_EEPROM_STATUS_DATA_BUSY |
261 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
262 return false;
263 }
264
265 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
266 AR_EEPROM_STATUS_DATA_VAL);
267
268 return true;
269}
270
271static int ath9k_hw_flash_map(struct ath_hal *ah)
272{
273 struct ath_hal_5416 *ahp = AH5416(ah);
274
275 ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
276
277 if (!ahp->ah_cal_mem) {
278 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
279 "%s: cannot remap eeprom region \n", __func__);
280 return -EIO;
281 }
282
283 return 0;
284}
285
286static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off,
287 u16 *data)
288{
289 struct ath_hal_5416 *ahp = AH5416(ah);
290
291 *data = ioread16(ahp->ah_cal_mem + off);
292 return true;
293}
294
295static void ath9k_hw_read_revisions(struct ath_hal *ah)
296{
297 u32 val;
298
299 val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
300
301 if (val == 0xFF) {
302 val = REG_READ(ah, AR_SREV);
303
304 ah->ah_macVersion =
305 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
306
307 ah->ah_macRev = MS(val, AR_SREV_REVISION2);
308 ah->ah_isPciExpress =
309 (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
310
311 } else {
312 if (!AR_SREV_9100(ah))
313 ah->ah_macVersion = MS(val, AR_SREV_VERSION);
314
315 ah->ah_macRev = val & AR_SREV_REVISION;
316
317 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
318 ah->ah_isPciExpress = true;
319 }
320}
321
322u32 ath9k_hw_reverse_bits(u32 val, u32 n)
323{
324 u32 retval;
325 int i;
326
327 for (i = 0, retval = 0; i < n; i++) {
328 retval = (retval << 1) | (val & 1);
329 val >>= 1;
330 }
331 return retval;
332}
333
334static void ath9k_hw_set_defaults(struct ath_hal *ah)
335{
336 int i;
337
338 ah->ah_config.dma_beacon_response_time = 2;
339 ah->ah_config.sw_beacon_response_time = 10;
340 ah->ah_config.additional_swba_backoff = 0;
341 ah->ah_config.ack_6mb = 0x0;
342 ah->ah_config.cwm_ignore_extcca = 0;
343 ah->ah_config.pcie_powersave_enable = 0;
344 ah->ah_config.pcie_l1skp_enable = 0;
345 ah->ah_config.pcie_clock_req = 0;
346 ah->ah_config.pcie_power_reset = 0x100;
347 ah->ah_config.pcie_restore = 0;
348 ah->ah_config.pcie_waen = 0;
349 ah->ah_config.analog_shiftreg = 1;
350 ah->ah_config.ht_enable = 1;
351 ah->ah_config.ofdm_trig_low = 200;
352 ah->ah_config.ofdm_trig_high = 500;
353 ah->ah_config.cck_trig_high = 200;
354 ah->ah_config.cck_trig_low = 100;
355 ah->ah_config.enable_ani = 0;
356 ah->ah_config.noise_immunity_level = 4;
357 ah->ah_config.ofdm_weaksignal_det = 1;
358 ah->ah_config.cck_weaksignal_thr = 0;
359 ah->ah_config.spur_immunity_level = 2;
360 ah->ah_config.firstep_level = 0;
361 ah->ah_config.rssi_thr_high = 40;
362 ah->ah_config.rssi_thr_low = 7;
363 ah->ah_config.diversity_control = 0;
364 ah->ah_config.antenna_switch_swap = 0;
365
366 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
367 ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
368 ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
369 }
370
371 ah->ah_config.intr_mitigation = 0;
372}
373
374static inline void ath9k_hw_override_ini(struct ath_hal *ah,
375 struct ath9k_channel *chan)
376{
377 if (!AR_SREV_5416_V20_OR_LATER(ah)
378 || AR_SREV_9280_10_OR_LATER(ah))
379 return;
380
381 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
382}
383
384static inline void ath9k_hw_init_bb(struct ath_hal *ah,
385 struct ath9k_channel *chan)
386{
387 u32 synthDelay;
388
389 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
390 if (IS_CHAN_CCK(chan))
391 synthDelay = (4 * synthDelay) / 22;
392 else
393 synthDelay /= 10;
394
395 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
396
397 udelay(synthDelay + BASE_ACTIVATE_DELAY);
398}
399
400static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
401 enum ath9k_opmode opmode)
402{
403 struct ath_hal_5416 *ahp = AH5416(ah);
404
405 ahp->ah_maskReg = AR_IMR_TXERR |
406 AR_IMR_TXURN |
407 AR_IMR_RXERR |
408 AR_IMR_RXORN |
409 AR_IMR_BCNMISC;
410
411 if (ahp->ah_intrMitigation)
412 ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
413 else
414 ahp->ah_maskReg |= AR_IMR_RXOK;
415
416 ahp->ah_maskReg |= AR_IMR_TXOK;
417
418 if (opmode == ATH9K_M_HOSTAP)
419 ahp->ah_maskReg |= AR_IMR_MIB;
420
421 REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
422 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
423
424 if (!AR_SREV_9100(ah)) {
425 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
426 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
427 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
428 }
429}
430
431static inline void ath9k_hw_init_qos(struct ath_hal *ah)
432{
433 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
434 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
435
436 REG_WRITE(ah, AR_QOS_NO_ACK,
437 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
438 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
439 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
440
441 REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
442 REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
443 REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
444 REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
445 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
446}
447
448static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
449 u32 reg,
450 u32 mask,
451 u32 shift,
452 u32 val)
453{
454 u32 regVal;
455
456 regVal = REG_READ(ah, reg) & ~mask;
457 regVal |= (val << shift) & mask;
458
459 REG_WRITE(ah, reg, regVal);
460
461 if (ah->ah_config.analog_shiftreg)
462 udelay(100);
463
464 return;
465}
466
467static u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
468 enum ieee80211_band freq_band)
469{
470 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
471 struct modal_eep_header *pModal =
472 &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]);
473 struct base_eep_header *pBase = &eep->baseEepHeader;
474 u8 num_ant_config;
475
476 num_ant_config = 1;
477
478 if (pBase->version >= 0x0E0D)
479 if (pModal->useAnt1)
480 num_ant_config += 1;
481
482 return num_ant_config;
483}
484
485static int
486ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
487 struct ath9k_channel *chan,
488 u8 index,
489 u16 *config)
490{
491 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
492 struct modal_eep_header *pModal =
493 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
494 struct base_eep_header *pBase = &eep->baseEepHeader;
495
496 switch (index) {
497 case 0:
498 *config = pModal->antCtrlCommon & 0xFFFF;
499 return 0;
500 case 1:
501 if (pBase->version >= 0x0E0D) {
502 if (pModal->useAnt1) {
503 *config =
504 ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
505 return 0;
506 }
507 }
508 break;
509 default:
510 break;
511 }
512
513 return -EINVAL;
514}
515
516static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
517 u32 off,
518 u16 *data)
519{
520 if (ath9k_hw_use_flash(ah))
521 return ath9k_hw_flash_read(ah, off, data);
522 else
523 return ath9k_hw_eeprom_read(ah, off, data);
524}
525
526static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
527{
528 struct ath_hal_5416 *ahp = AH5416(ah);
529 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
530 u16 *eep_data;
531 int addr, ar5416_eep_start_loc = 0;
532
533 if (!ath9k_hw_use_flash(ah)) {
534 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
535 "%s: Reading from EEPROM, not flash\n", __func__);
536 ar5416_eep_start_loc = 256;
537 }
538 if (AR_SREV_9100(ah))
539 ar5416_eep_start_loc = 256;
540
541 eep_data = (u16 *) eep;
542 for (addr = 0;
543 addr < sizeof(struct ar5416_eeprom) / sizeof(u16);
544 addr++) {
545 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
546 eep_data)) {
547 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
548 "%s: Unable to read eeprom region \n",
549 __func__);
550 return false;
551 }
552 eep_data++;
553 }
554 return true;
555}
556
557/* XXX: Clean me up, make me more legible */
558static bool
559ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
560 struct ath9k_channel *chan)
561{
562 struct modal_eep_header *pModal;
563 int i, regChainOffset;
564 struct ath_hal_5416 *ahp = AH5416(ah);
565 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
566 u8 txRxAttenLocal;
567 u16 ant_config;
568
569 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
570
571 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
572
573 ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
574 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
575
576 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
577 if (AR_SREV_9280(ah)) {
578 if (i >= 2)
579 break;
580 }
581
582 if (AR_SREV_5416_V20_OR_LATER(ah) &&
583 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
584 && (i != 0))
585 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
586 else
587 regChainOffset = i * 0x1000;
588
589 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
590 pModal->antCtrlChain[i]);
591
592 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
593 (REG_READ(ah,
594 AR_PHY_TIMING_CTRL4(0) +
595 regChainOffset) &
596 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
597 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
598 SM(pModal->iqCalICh[i],
599 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
600 SM(pModal->iqCalQCh[i],
601 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
602
603 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
604 if ((eep->baseEepHeader.version &
605 AR5416_EEP_VER_MINOR_MASK) >=
606 AR5416_EEP_MINOR_VER_3) {
607 txRxAttenLocal = pModal->txRxAttenCh[i];
608 if (AR_SREV_9280_10_OR_LATER(ah)) {
609 REG_RMW_FIELD(ah,
610 AR_PHY_GAIN_2GHZ +
611 regChainOffset,
612 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
613 pModal->
614 bswMargin[i]);
615 REG_RMW_FIELD(ah,
616 AR_PHY_GAIN_2GHZ +
617 regChainOffset,
618 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
619 pModal->
620 bswAtten[i]);
621 REG_RMW_FIELD(ah,
622 AR_PHY_GAIN_2GHZ +
623 regChainOffset,
624 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
625 pModal->
626 xatten2Margin[i]);
627 REG_RMW_FIELD(ah,
628 AR_PHY_GAIN_2GHZ +
629 regChainOffset,
630 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
631 pModal->
632 xatten2Db[i]);
633 } else {
634 REG_WRITE(ah,
635 AR_PHY_GAIN_2GHZ +
636 regChainOffset,
637 (REG_READ(ah,
638 AR_PHY_GAIN_2GHZ +
639 regChainOffset) &
640 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
641 | SM(pModal->
642 bswMargin[i],
643 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
644 REG_WRITE(ah,
645 AR_PHY_GAIN_2GHZ +
646 regChainOffset,
647 (REG_READ(ah,
648 AR_PHY_GAIN_2GHZ +
649 regChainOffset) &
650 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
651 | SM(pModal->bswAtten[i],
652 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
653 }
654 }
655 if (AR_SREV_9280_10_OR_LATER(ah)) {
656 REG_RMW_FIELD(ah,
657 AR_PHY_RXGAIN +
658 regChainOffset,
659 AR9280_PHY_RXGAIN_TXRX_ATTEN,
660 txRxAttenLocal);
661 REG_RMW_FIELD(ah,
662 AR_PHY_RXGAIN +
663 regChainOffset,
664 AR9280_PHY_RXGAIN_TXRX_MARGIN,
665 pModal->rxTxMarginCh[i]);
666 } else {
667 REG_WRITE(ah,
668 AR_PHY_RXGAIN + regChainOffset,
669 (REG_READ(ah,
670 AR_PHY_RXGAIN +
671 regChainOffset) &
672 ~AR_PHY_RXGAIN_TXRX_ATTEN) |
673 SM(txRxAttenLocal,
674 AR_PHY_RXGAIN_TXRX_ATTEN));
675 REG_WRITE(ah,
676 AR_PHY_GAIN_2GHZ +
677 regChainOffset,
678 (REG_READ(ah,
679 AR_PHY_GAIN_2GHZ +
680 regChainOffset) &
681 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
682 SM(pModal->rxTxMarginCh[i],
683 AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
684 }
685 }
686 }
687
688 if (AR_SREV_9280_10_OR_LATER(ah)) {
689 if (IS_CHAN_2GHZ(chan)) {
690 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
691 AR_AN_RF2G1_CH0_OB,
692 AR_AN_RF2G1_CH0_OB_S,
693 pModal->ob);
694 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
695 AR_AN_RF2G1_CH0_DB,
696 AR_AN_RF2G1_CH0_DB_S,
697 pModal->db);
698 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
699 AR_AN_RF2G1_CH1_OB,
700 AR_AN_RF2G1_CH1_OB_S,
701 pModal->ob_ch1);
702 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
703 AR_AN_RF2G1_CH1_DB,
704 AR_AN_RF2G1_CH1_DB_S,
705 pModal->db_ch1);
706 } else {
707 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
708 AR_AN_RF5G1_CH0_OB5,
709 AR_AN_RF5G1_CH0_OB5_S,
710 pModal->ob);
711 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
712 AR_AN_RF5G1_CH0_DB5,
713 AR_AN_RF5G1_CH0_DB5_S,
714 pModal->db);
715 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
716 AR_AN_RF5G1_CH1_OB5,
717 AR_AN_RF5G1_CH1_OB5_S,
718 pModal->ob_ch1);
719 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
720 AR_AN_RF5G1_CH1_DB5,
721 AR_AN_RF5G1_CH1_DB5_S,
722 pModal->db_ch1);
723 }
724 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
725 AR_AN_TOP2_XPABIAS_LVL,
726 AR_AN_TOP2_XPABIAS_LVL_S,
727 pModal->xpaBiasLvl);
728 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
729 AR_AN_TOP2_LOCALBIAS,
730 AR_AN_TOP2_LOCALBIAS_S,
731 pModal->local_bias);
732 DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n",
733 pModal->force_xpaon);
734 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
735 pModal->force_xpaon);
736 }
737
738 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
739 pModal->switchSettling);
740 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
741 pModal->adcDesiredSize);
742
743 if (!AR_SREV_9280_10_OR_LATER(ah))
744 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
745 AR_PHY_DESIRED_SZ_PGA,
746 pModal->pgaDesiredSize);
747
748 REG_WRITE(ah, AR_PHY_RF_CTL4,
749 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
750 | SM(pModal->txEndToXpaOff,
751 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
752 | SM(pModal->txFrameToXpaOn,
753 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
754 | SM(pModal->txFrameToXpaOn,
755 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
756
757 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
758 pModal->txEndToRxOn);
759 if (AR_SREV_9280_10_OR_LATER(ah)) {
760 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
761 pModal->thresh62);
762 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
763 AR_PHY_EXT_CCA0_THRESH62,
764 pModal->thresh62);
765 } else {
766 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
767 pModal->thresh62);
768 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
769 AR_PHY_EXT_CCA_THRESH62,
770 pModal->thresh62);
771 }
772
773 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
774 AR5416_EEP_MINOR_VER_2) {
775 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
776 AR_PHY_TX_END_DATA_START,
777 pModal->txFrameToDataStart);
778 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
779 pModal->txFrameToPaOn);
780 }
781
782 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
783 AR5416_EEP_MINOR_VER_3) {
784 if (IS_CHAN_HT40(chan))
785 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
786 AR_PHY_SETTLING_SWITCH,
787 pModal->swSettleHt40);
788 }
789
790 return true;
791}
792
793static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
794{
795 u32 sum = 0, el;
796 u16 *eepdata;
797 int i;
798 struct ath_hal_5416 *ahp = AH5416(ah);
799 bool need_swap = false;
800 struct ar5416_eeprom *eep =
801 (struct ar5416_eeprom *) &ahp->ah_eeprom;
802
803 if (!ath9k_hw_use_flash(ah)) {
804 u16 magic, magic2;
805 int addr;
806
807 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
808 &magic)) {
809 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
810 "%s: Reading Magic # failed\n", __func__);
811 return false;
812 }
813 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
814 __func__, magic);
815
816 if (magic != AR5416_EEPROM_MAGIC) {
817 magic2 = swab16(magic);
818
819 if (magic2 == AR5416_EEPROM_MAGIC) {
820 need_swap = true;
821 eepdata = (u16 *) (&ahp->ah_eeprom);
822
823 for (addr = 0;
824 addr <
825 sizeof(struct ar5416_eeprom) /
826 sizeof(u16); addr++) {
827 u16 temp;
828
829 temp = swab16(*eepdata);
830 *eepdata = temp;
831 eepdata++;
832
833 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
834 "0x%04X ", *eepdata);
835 if (((addr + 1) % 6) == 0)
836 DPRINTF(ah->ah_sc,
837 ATH_DBG_EEPROM,
838 "\n");
839 }
840 } else {
841 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
842 "Invalid EEPROM Magic. "
843 "endianness missmatch.\n");
844 return -EINVAL;
845 }
846 }
847 }
848 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
849 need_swap ? "True" : "False");
850
851 if (need_swap)
852 el = swab16(ahp->ah_eeprom.baseEepHeader.length);
853 else
854 el = ahp->ah_eeprom.baseEepHeader.length;
855
856 if (el > sizeof(struct ar5416_eeprom))
857 el = sizeof(struct ar5416_eeprom) / sizeof(u16);
858 else
859 el = el / sizeof(u16);
860
861 eepdata = (u16 *) (&ahp->ah_eeprom);
862
863 for (i = 0; i < el; i++)
864 sum ^= *eepdata++;
865
866 if (need_swap) {
867 u32 integer, j;
868 u16 word;
869
870 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
871 "EEPROM Endianness is not native.. Changing \n");
872
873 word = swab16(eep->baseEepHeader.length);
874 eep->baseEepHeader.length = word;
875
876 word = swab16(eep->baseEepHeader.checksum);
877 eep->baseEepHeader.checksum = word;
878
879 word = swab16(eep->baseEepHeader.version);
880 eep->baseEepHeader.version = word;
881
882 word = swab16(eep->baseEepHeader.regDmn[0]);
883 eep->baseEepHeader.regDmn[0] = word;
884
885 word = swab16(eep->baseEepHeader.regDmn[1]);
886 eep->baseEepHeader.regDmn[1] = word;
887
888 word = swab16(eep->baseEepHeader.rfSilent);
889 eep->baseEepHeader.rfSilent = word;
890
891 word = swab16(eep->baseEepHeader.blueToothOptions);
892 eep->baseEepHeader.blueToothOptions = word;
893
894 word = swab16(eep->baseEepHeader.deviceCap);
895 eep->baseEepHeader.deviceCap = word;
896
897 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
898 struct modal_eep_header *pModal =
899 &eep->modalHeader[j];
900 integer = swab32(pModal->antCtrlCommon);
901 pModal->antCtrlCommon = integer;
902
903 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
904 integer = swab32(pModal->antCtrlChain[i]);
905 pModal->antCtrlChain[i] = integer;
906 }
907
908 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
909 word = swab16(pModal->spurChans[i].spurChan);
910 pModal->spurChans[i].spurChan = word;
911 }
912 }
913 }
914
915 if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
916 ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
917 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
918 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
919 sum, ar5416_get_eep_ver(ahp));
920 return -EINVAL;
921 }
922
923 return 0;
924}
925
926static bool ath9k_hw_chip_test(struct ath_hal *ah)
927{
928 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
929 u32 regHold[2];
930 u32 patternData[4] = { 0x55555555,
931 0xaaaaaaaa,
932 0x66666666,
933 0x99999999 };
934 int i, j;
935
936 for (i = 0; i < 2; i++) {
937 u32 addr = regAddr[i];
938 u32 wrData, rdData;
939
940 regHold[i] = REG_READ(ah, addr);
941 for (j = 0; j < 0x100; j++) {
942 wrData = (j << 16) | j;
943 REG_WRITE(ah, addr, wrData);
944 rdData = REG_READ(ah, addr);
945 if (rdData != wrData) {
946 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
947 "%s: address test failed "
948 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
949 __func__, addr, wrData, rdData);
950 return false;
951 }
952 }
953 for (j = 0; j < 4; j++) {
954 wrData = patternData[j];
955 REG_WRITE(ah, addr, wrData);
956 rdData = REG_READ(ah, addr);
957 if (wrData != rdData) {
958 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
959 "%s: address test failed "
960 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
961 __func__, addr, wrData, rdData);
962 return false;
963 }
964 }
965 REG_WRITE(ah, regAddr[i], regHold[i]);
966 }
967 udelay(100);
968 return true;
969}
970
971u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
972{
973 u32 bits = REG_READ(ah, AR_RX_FILTER);
974 u32 phybits = REG_READ(ah, AR_PHY_ERR);
975
976 if (phybits & AR_PHY_ERR_RADAR)
977 bits |= ATH9K_RX_FILTER_PHYRADAR;
978 if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
979 bits |= ATH9K_RX_FILTER_PHYERR;
980 return bits;
981}
982
983void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
984{
985 u32 phybits;
986
987 REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
988 phybits = 0;
989 if (bits & ATH9K_RX_FILTER_PHYRADAR)
990 phybits |= AR_PHY_ERR_RADAR;
991 if (bits & ATH9K_RX_FILTER_PHYERR)
992 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
993 REG_WRITE(ah, AR_PHY_ERR, phybits);
994
995 if (phybits)
996 REG_WRITE(ah, AR_RXCFG,
997 REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
998 else
999 REG_WRITE(ah, AR_RXCFG,
1000 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
1001}
1002
1003bool ath9k_hw_setcapability(struct ath_hal *ah,
1004 enum ath9k_capability_type type,
1005 u32 capability,
1006 u32 setting,
1007 int *status)
1008{
1009 struct ath_hal_5416 *ahp = AH5416(ah);
1010 u32 v;
1011
1012 switch (type) {
1013 case ATH9K_CAP_TKIP_MIC:
1014 if (setting)
1015 ahp->ah_staId1Defaults |=
1016 AR_STA_ID1_CRPT_MIC_ENABLE;
1017 else
1018 ahp->ah_staId1Defaults &=
1019 ~AR_STA_ID1_CRPT_MIC_ENABLE;
1020 return true;
1021 case ATH9K_CAP_DIVERSITY:
1022 v = REG_READ(ah, AR_PHY_CCK_DETECT);
1023 if (setting)
1024 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1025 else
1026 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1027 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
1028 return true;
1029 case ATH9K_CAP_MCAST_KEYSRCH:
1030 if (setting)
1031 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1032 else
1033 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1034 return true;
1035 case ATH9K_CAP_TSF_ADJUST:
1036 if (setting)
1037 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
1038 else
1039 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
1040 return true;
1041 default:
1042 return false;
1043 }
1044}
1045
1046void ath9k_hw_dmaRegDump(struct ath_hal *ah)
1047{
1048 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
1049 int qcuOffset = 0, dcuOffset = 0;
1050 u32 *qcuBase = &val[0], *dcuBase = &val[4];
1051 int i;
1052
1053 REG_WRITE(ah, AR_MACMISC,
1054 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1055 (AR_MACMISC_MISC_OBS_BUS_1 <<
1056 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1057
1058 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
1059 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
1060 if (i % 4 == 0)
1061 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1062
1063 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
1064 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
1065 }
1066
1067 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
1068 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1069 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1070
1071 for (i = 0; i < ATH9K_NUM_QUEUES;
1072 i++, qcuOffset += 4, dcuOffset += 5) {
1073 if (i == 8) {
1074 qcuOffset = 0;
1075 qcuBase++;
1076 }
1077
1078 if (i == 6) {
1079 dcuOffset = 0;
1080 dcuBase++;
1081 }
1082
1083 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1084 "%2d %2x %1x %2x %2x\n",
1085 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1086 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset +
1087 3),
1088 val[2] & (0x7 << (i * 3)) >> (i * 3),
1089 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1090 }
1091
1092 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1093 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1094 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
1095 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
1096 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1097 "qcu_complete state: %2x dcu_complete state: %2x\n",
1098 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
1099 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1100 "dcu_arb state: %2x dcu_fp state: %2x\n",
1101 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
1102 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1103 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
1104 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
1105 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1106 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
1107 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
1108 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1109 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
1110 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
1111
1112 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
1113 REG_READ(ah, AR_OBS_BUS_1));
1114 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1115 "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
1116}
1117
1118u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
1119 u32 *rxc_pcnt,
1120 u32 *rxf_pcnt,
1121 u32 *txf_pcnt)
1122{
1123 static u32 cycles, rx_clear, rx_frame, tx_frame;
1124 u32 good = 1;
1125
1126 u32 rc = REG_READ(ah, AR_RCCNT);
1127 u32 rf = REG_READ(ah, AR_RFCNT);
1128 u32 tf = REG_READ(ah, AR_TFCNT);
1129 u32 cc = REG_READ(ah, AR_CCCNT);
1130
1131 if (cycles == 0 || cycles > cc) {
1132 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1133 "%s: cycle counter wrap. ExtBusy = 0\n",
1134 __func__);
1135 good = 0;
1136 } else {
1137 u32 cc_d = cc - cycles;
1138 u32 rc_d = rc - rx_clear;
1139 u32 rf_d = rf - rx_frame;
1140 u32 tf_d = tf - tx_frame;
1141
1142 if (cc_d != 0) {
1143 *rxc_pcnt = rc_d * 100 / cc_d;
1144 *rxf_pcnt = rf_d * 100 / cc_d;
1145 *txf_pcnt = tf_d * 100 / cc_d;
1146 } else {
1147 good = 0;
1148 }
1149 }
1150
1151 cycles = cc;
1152 rx_frame = rf;
1153 rx_clear = rc;
1154 tx_frame = tf;
1155
1156 return good;
1157}
1158
1159void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
1160{
1161 u32 macmode;
1162
1163 if (mode == ATH9K_HT_MACMODE_2040 &&
1164 !ah->ah_config.cwm_ignore_extcca)
1165 macmode = AR_2040_JOINED_RX_CLEAR;
1166 else
1167 macmode = 0;
1168
1169 REG_WRITE(ah, AR_2040_MODE, macmode);
1170}
1171
1172static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
1173{
1174 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1175}
1176
1177
1178static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
1179 struct ath_softc *sc,
1180 void __iomem *mem,
1181 int *status)
1182{
1183 static const u8 defbssidmask[ETH_ALEN] =
1184 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1185 struct ath_hal_5416 *ahp;
1186 struct ath_hal *ah;
1187
1188 ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
1189 if (ahp == NULL) {
1190 DPRINTF(sc, ATH_DBG_FATAL,
1191 "%s: cannot allocate memory for state block\n",
1192 __func__);
1193 *status = -ENOMEM;
1194 return NULL;
1195 }
1196
1197 ah = &ahp->ah;
1198
1199 memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
1200
1201 ah->ah_sc = sc;
1202 ah->ah_sh = mem;
1203
1204 ah->ah_devid = devid;
1205 ah->ah_subvendorid = 0;
1206
1207 ah->ah_flags = 0;
1208 if ((devid == AR5416_AR9100_DEVID))
1209 ah->ah_macVersion = AR_SREV_VERSION_9100;
1210 if (!AR_SREV_9100(ah))
1211 ah->ah_flags = AH_USE_EEPROM;
1212
1213 ah->ah_powerLimit = MAX_RATE_POWER;
1214 ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
1215
1216 ahp->ah_atimWindow = 0;
1217 ahp->ah_diversityControl = ah->ah_config.diversity_control;
1218 ahp->ah_antennaSwitchSwap =
1219 ah->ah_config.antenna_switch_swap;
1220
1221 ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
1222 ahp->ah_beaconInterval = 100;
1223 ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
1224 ahp->ah_slottime = (u32) -1;
1225 ahp->ah_acktimeout = (u32) -1;
1226 ahp->ah_ctstimeout = (u32) -1;
1227 ahp->ah_globaltxtimeout = (u32) -1;
1228 memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
1229
1230 ahp->ah_gBeaconRate = 0;
1231
1232 return ahp;
1233}
1234
1235static int ath9k_hw_eeprom_attach(struct ath_hal *ah)
1236{
1237 int status;
1238
1239 if (ath9k_hw_use_flash(ah))
1240 ath9k_hw_flash_map(ah);
1241
1242 if (!ath9k_hw_fill_eeprom(ah))
1243 return -EIO;
1244
1245 status = ath9k_hw_check_eeprom(ah);
1246
1247 return status;
1248}
1249
1250u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
1251 enum eeprom_param param)
1252{
1253 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
1254 struct modal_eep_header *pModal = eep->modalHeader;
1255 struct base_eep_header *pBase = &eep->baseEepHeader;
1256
1257 switch (param) {
1258 case EEP_NFTHRESH_5:
1259 return -pModal[0].noiseFloorThreshCh[0];
1260 case EEP_NFTHRESH_2:
1261 return -pModal[1].noiseFloorThreshCh[0];
1262 case AR_EEPROM_MAC(0):
1263 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1264 case AR_EEPROM_MAC(1):
1265 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1266 case AR_EEPROM_MAC(2):
1267 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1268 case EEP_REG_0:
1269 return pBase->regDmn[0];
1270 case EEP_REG_1:
1271 return pBase->regDmn[1];
1272 case EEP_OP_CAP:
1273 return pBase->deviceCap;
1274 case EEP_OP_MODE:
1275 return pBase->opCapFlags;
1276 case EEP_RF_SILENT:
1277 return pBase->rfSilent;
1278 case EEP_OB_5:
1279 return pModal[0].ob;
1280 case EEP_DB_5:
1281 return pModal[0].db;
1282 case EEP_OB_2:
1283 return pModal[1].ob;
1284 case EEP_DB_2:
1285 return pModal[1].db;
1286 case EEP_MINOR_REV:
1287 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
1288 case EEP_TX_MASK:
1289 return pBase->txMask;
1290 case EEP_RX_MASK:
1291 return pBase->rxMask;
1292 default:
1293 return 0;
1294 }
1295}
1296
1297static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
1298{
1299 u32 val;
1300 int i;
1301
1302 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
1303 for (i = 0; i < 8; i++)
1304 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
1305 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
1306 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
1307 return ath9k_hw_reverse_bits(val, 8);
1308}
1309
1310static inline int ath9k_hw_init_macaddr(struct ath_hal *ah)
1311{
1312 u32 sum;
1313 int i;
1314 u16 eeval;
1315 struct ath_hal_5416 *ahp = AH5416(ah);
1316 DECLARE_MAC_BUF(mac);
1317
1318 sum = 0;
1319 for (i = 0; i < 3; i++) {
1320 eeval = ath9k_hw_get_eeprom(ahp, AR_EEPROM_MAC(i));
1321 sum += eeval;
1322 ahp->ah_macaddr[2 * i] = eeval >> 8;
1323 ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
1324 }
1325 if (sum == 0 || sum == 0xffff * 3) {
1326 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1327 "%s: mac address read failed: %s\n", __func__,
1328 print_mac(mac, ahp->ah_macaddr));
1329 return -EADDRNOTAVAIL;
1330 }
1331
1332 return 0;
1333}
1334
1335static inline int16_t ath9k_hw_interpolate(u16 target,
1336 u16 srcLeft,
1337 u16 srcRight,
1338 int16_t targetLeft,
1339 int16_t targetRight)
1340{
1341 int16_t rv;
1342
1343 if (srcRight == srcLeft) {
1344 rv = targetLeft;
1345 } else {
1346 rv = (int16_t) (((target - srcLeft) * targetRight +
1347 (srcRight - target) * targetLeft) /
1348 (srcRight - srcLeft));
1349 }
1350 return rv;
1351}
1352
1353static inline u16 ath9k_hw_fbin2freq(u8 fbin,
1354 bool is2GHz)
1355{
1356
1357 if (fbin == AR5416_BCHAN_UNUSED)
1358 return fbin;
1359
1360 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
1361}
1362
1363static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
1364 u16 i,
1365 bool is2GHz)
1366{
1367 struct ath_hal_5416 *ahp = AH5416(ah);
1368 struct ar5416_eeprom *eep =
1369 (struct ar5416_eeprom *) &ahp->ah_eeprom;
1370 u16 spur_val = AR_NO_SPUR;
1371
1372 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1373 "Getting spur idx %d is2Ghz. %d val %x\n",
1374 i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
1375
1376 switch (ah->ah_config.spurmode) {
1377 case SPUR_DISABLE:
1378 break;
1379 case SPUR_ENABLE_IOCTL:
1380 spur_val = ah->ah_config.spurchans[i][is2GHz];
1381 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1382 "Getting spur val from new loc. %d\n", spur_val);
1383 break;
1384 case SPUR_ENABLE_EEPROM:
1385 spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
1386 break;
1387
1388 }
1389 return spur_val;
1390}
1391
1392static inline int ath9k_hw_rfattach(struct ath_hal *ah)
1393{
1394 bool rfStatus = false;
1395 int ecode = 0;
1396
1397 rfStatus = ath9k_hw_init_rf(ah, &ecode);
1398 if (!rfStatus) {
1399 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1400 "%s: RF setup failed, status %u\n", __func__,
1401 ecode);
1402 return ecode;
1403 }
1404
1405 return 0;
1406}
1407
1408static int ath9k_hw_rf_claim(struct ath_hal *ah)
1409{
1410 u32 val;
1411
1412 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1413
1414 val = ath9k_hw_get_radiorev(ah);
1415 switch (val & AR_RADIO_SREV_MAJOR) {
1416 case 0:
1417 val = AR_RAD5133_SREV_MAJOR;
1418 break;
1419 case AR_RAD5133_SREV_MAJOR:
1420 case AR_RAD5122_SREV_MAJOR:
1421 case AR_RAD2133_SREV_MAJOR:
1422 case AR_RAD2122_SREV_MAJOR:
1423 break;
1424 default:
1425 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1426 "%s: 5G Radio Chip Rev 0x%02X is not "
1427 "supported by this driver\n",
1428 __func__, ah->ah_analog5GhzRev);
1429 return -EOPNOTSUPP;
1430 }
1431
1432 ah->ah_analog5GhzRev = val;
1433
1434 return 0;
1435}
1436
1437static inline void ath9k_hw_init_pll(struct ath_hal *ah,
1438 struct ath9k_channel *chan)
1439{
1440 u32 pll;
1441
1442 if (AR_SREV_9100(ah)) {
1443 if (chan && IS_CHAN_5GHZ(chan))
1444 pll = 0x1450;
1445 else
1446 pll = 0x1458;
1447 } else {
1448 if (AR_SREV_9280_10_OR_LATER(ah)) {
1449 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1450
1451 if (chan && IS_CHAN_HALF_RATE(chan))
1452 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1453 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1454 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1455
1456 if (chan && IS_CHAN_5GHZ(chan)) {
1457 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
1458
1459
1460 if (AR_SREV_9280_20(ah)) {
1461 if (((chan->channel % 20) == 0)
1462 || ((chan->channel % 10) == 0))
1463 pll = 0x2850;
1464 else
1465 pll = 0x142c;
1466 }
1467 } else {
1468 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
1469 }
1470
1471 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1472
1473 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1474
1475 if (chan && IS_CHAN_HALF_RATE(chan))
1476 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1477 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1478 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1479
1480 if (chan && IS_CHAN_5GHZ(chan))
1481 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1482 else
1483 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1484 } else {
1485 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1486
1487 if (chan && IS_CHAN_HALF_RATE(chan))
1488 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1489 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1490 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1491
1492 if (chan && IS_CHAN_5GHZ(chan))
1493 pll |= SM(0xa, AR_RTC_PLL_DIV);
1494 else
1495 pll |= SM(0xb, AR_RTC_PLL_DIV);
1496 }
1497 }
1498 REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
1499
1500 udelay(RTC_PLL_SETTLE_DELAY);
1501
1502 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1503}
1504
1505static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1506 enum ath9k_ht_macmode macmode)
1507{
1508 u32 phymode;
1509 struct ath_hal_5416 *ahp = AH5416(ah);
1510
1511 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
1512 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
1513
1514 if (IS_CHAN_HT40(chan)) {
1515 phymode |= AR_PHY_FC_DYN2040_EN;
1516
1517 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
1518 (chan->chanmode == CHANNEL_G_HT40PLUS))
1519 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1520
1521 if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
1522 phymode |= AR_PHY_FC_DYN2040_EXT_CH;
1523 }
1524 REG_WRITE(ah, AR_PHY_TURBO, phymode);
1525
1526 ath9k_hw_set11nmac2040(ah, macmode);
1527
1528 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
1529 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1530}
1531
1532static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1533{
1534 u32 val;
1535
1536 val = REG_READ(ah, AR_STA_ID1);
1537 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1538 switch (opmode) {
1539 case ATH9K_M_HOSTAP:
1540 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
1541 | AR_STA_ID1_KSRCH_MODE);
1542 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1543 break;
1544 case ATH9K_M_IBSS:
1545 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
1546 | AR_STA_ID1_KSRCH_MODE);
1547 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1548 break;
1549 case ATH9K_M_STA:
1550 case ATH9K_M_MONITOR:
1551 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1552 break;
1553 }
1554}
1555
1556static inline void
1557ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1558{
1559 u32 rfMode = 0;
1560
1561 if (chan == NULL)
1562 return;
1563
1564 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
1565 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1566
1567 if (!AR_SREV_9280_10_OR_LATER(ah))
1568 rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ :
1569 AR_PHY_MODE_RF2GHZ;
1570
1571 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
1572 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1573
1574 REG_WRITE(ah, AR_PHY_MODE, rfMode);
1575}
1576
1577static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1578{
1579 u32 rst_flags;
1580 u32 tmpReg;
1581
1582 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1583 AR_RTC_FORCE_WAKE_ON_INT);
1584
1585 if (AR_SREV_9100(ah)) {
1586 rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
1587 AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
1588 } else {
1589 tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1590 if (tmpReg &
1591 (AR_INTR_SYNC_LOCAL_TIMEOUT |
1592 AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1593 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1594 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
1595 } else {
1596 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1597 }
1598
1599 rst_flags = AR_RTC_RC_MAC_WARM;
1600 if (type == ATH9K_RESET_COLD)
1601 rst_flags |= AR_RTC_RC_MAC_COLD;
1602 }
1603
1604 REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
1605 udelay(50);
1606
1607 REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
1608 if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
1609 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1610 "%s: RTC stuck in MAC reset\n",
1611 __func__);
1612 return false;
1613 }
1614
1615 if (!AR_SREV_9100(ah))
1616 REG_WRITE(ah, AR_RC, 0);
1617
1618 ath9k_hw_init_pll(ah, NULL);
1619
1620 if (AR_SREV_9100(ah))
1621 udelay(50);
1622
1623 return true;
1624}
1625
1626static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1627{
1628 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1629 AR_RTC_FORCE_WAKE_ON_INT);
1630
1631 REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
1632 REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
1633
1634 if (!ath9k_hw_wait(ah,
1635 AR_RTC_STATUS,
1636 AR_RTC_STATUS_M,
1637 AR_RTC_STATUS_ON)) {
1638 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
1639 __func__);
1640 return false;
1641 }
1642
1643 ath9k_hw_read_revisions(ah);
1644
1645 return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
1646}
1647
1648static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
1649 u32 type)
1650{
1651 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1652 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1653
1654 switch (type) {
1655 case ATH9K_RESET_POWER_ON:
1656 return ath9k_hw_set_reset_power_on(ah);
1657 break;
1658 case ATH9K_RESET_WARM:
1659 case ATH9K_RESET_COLD:
1660 return ath9k_hw_set_reset(ah, type);
1661 break;
1662 default:
1663 return false;
1664 }
1665}
1666
1667static inline
1668struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
1669 struct ath9k_channel *chan)
1670{
1671 if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
1672 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1673 "%s: invalid channel %u/0x%x; not marked as "
1674 "2GHz or 5GHz\n", __func__, chan->channel,
1675 chan->channelFlags);
1676 return NULL;
1677 }
1678
1679 if (!IS_CHAN_OFDM(chan) &&
1680 !IS_CHAN_CCK(chan) &&
1681 !IS_CHAN_HT20(chan) &&
1682 !IS_CHAN_HT40(chan)) {
1683 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1684 "%s: invalid channel %u/0x%x; not marked as "
1685 "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
1686 __func__, chan->channel, chan->channelFlags);
1687 return NULL;
1688 }
1689
1690 return ath9k_regd_check_channel(ah, chan);
1691}
1692
1693static inline bool
1694ath9k_hw_get_lower_upper_index(u8 target,
1695 u8 *pList,
1696 u16 listSize,
1697 u16 *indexL,
1698 u16 *indexR)
1699{
1700 u16 i;
1701
1702 if (target <= pList[0]) {
1703 *indexL = *indexR = 0;
1704 return true;
1705 }
1706 if (target >= pList[listSize - 1]) {
1707 *indexL = *indexR = (u16) (listSize - 1);
1708 return true;
1709 }
1710
1711 for (i = 0; i < listSize - 1; i++) {
1712 if (pList[i] == target) {
1713 *indexL = *indexR = i;
1714 return true;
1715 }
1716 if (target < pList[i + 1]) {
1717 *indexL = i;
1718 *indexR = (u16) (i + 1);
1719 return false;
1720 }
1721 }
1722 return false;
1723}
1724
1725static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
1726{
1727 int16_t nfval;
1728 int16_t sort[ATH9K_NF_CAL_HIST_MAX];
1729 int i, j;
1730
1731 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
1732 sort[i] = nfCalBuffer[i];
1733
1734 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
1735 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
1736 if (sort[j] > sort[j - 1]) {
1737 nfval = sort[j];
1738 sort[j] = sort[j - 1];
1739 sort[j - 1] = nfval;
1740 }
1741 }
1742 }
1743 nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
1744
1745 return nfval;
1746}
1747
1748static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
1749 int16_t *nfarray)
1750{
1751 int i;
1752
1753 for (i = 0; i < NUM_NF_READINGS; i++) {
1754 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
1755
1756 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
1757 h[i].currIndex = 0;
1758
1759 if (h[i].invalidNFcount > 0) {
1760 if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE
1761 || nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
1762 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
1763 } else {
1764 h[i].invalidNFcount--;
1765 h[i].privNF = nfarray[i];
1766 }
1767 } else {
1768 h[i].privNF =
1769 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
1770 }
1771 }
1772 return;
1773}
1774
1775static void ar5416GetNoiseFloor(struct ath_hal *ah,
1776 int16_t nfarray[NUM_NF_READINGS])
1777{
1778 int16_t nf;
1779
1780 if (AR_SREV_9280_10_OR_LATER(ah))
1781 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
1782 else
1783 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1784
1785 if (nf & 0x100)
1786 nf = 0 - ((nf ^ 0x1ff) + 1);
1787 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1788 "NF calibrated [ctl] [chain 0] is %d\n", nf);
1789 nfarray[0] = nf;
1790
1791 if (AR_SREV_9280_10_OR_LATER(ah))
1792 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1793 AR9280_PHY_CH1_MINCCA_PWR);
1794 else
1795 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1796 AR_PHY_CH1_MINCCA_PWR);
1797
1798 if (nf & 0x100)
1799 nf = 0 - ((nf ^ 0x1ff) + 1);
1800 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1801 "NF calibrated [ctl] [chain 1] is %d\n", nf);
1802 nfarray[1] = nf;
1803
1804 if (!AR_SREV_9280(ah)) {
1805 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
1806 AR_PHY_CH2_MINCCA_PWR);
1807 if (nf & 0x100)
1808 nf = 0 - ((nf ^ 0x1ff) + 1);
1809 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1810 "NF calibrated [ctl] [chain 2] is %d\n", nf);
1811 nfarray[2] = nf;
1812 }
1813
1814 if (AR_SREV_9280_10_OR_LATER(ah))
1815 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1816 AR9280_PHY_EXT_MINCCA_PWR);
1817 else
1818 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1819 AR_PHY_EXT_MINCCA_PWR);
1820
1821 if (nf & 0x100)
1822 nf = 0 - ((nf ^ 0x1ff) + 1);
1823 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1824 "NF calibrated [ext] [chain 0] is %d\n", nf);
1825 nfarray[3] = nf;
1826
1827 if (AR_SREV_9280_10_OR_LATER(ah))
1828 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1829 AR9280_PHY_CH1_EXT_MINCCA_PWR);
1830 else
1831 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1832 AR_PHY_CH1_EXT_MINCCA_PWR);
1833
1834 if (nf & 0x100)
1835 nf = 0 - ((nf ^ 0x1ff) + 1);
1836 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1837 "NF calibrated [ext] [chain 1] is %d\n", nf);
1838 nfarray[4] = nf;
1839
1840 if (!AR_SREV_9280(ah)) {
1841 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
1842 AR_PHY_CH2_EXT_MINCCA_PWR);
1843 if (nf & 0x100)
1844 nf = 0 - ((nf ^ 0x1ff) + 1);
1845 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1846 "NF calibrated [ext] [chain 2] is %d\n", nf);
1847 nfarray[5] = nf;
1848 }
1849}
1850
1851static bool
1852getNoiseFloorThresh(struct ath_hal *ah,
1853 const struct ath9k_channel *chan,
1854 int16_t *nft)
1855{
1856 struct ath_hal_5416 *ahp = AH5416(ah);
1857
1858 switch (chan->chanmode) {
1859 case CHANNEL_A:
1860 case CHANNEL_A_HT20:
1861 case CHANNEL_A_HT40PLUS:
1862 case CHANNEL_A_HT40MINUS:
1863 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_5);
1864 break;
1865 case CHANNEL_B:
1866 case CHANNEL_G:
1867 case CHANNEL_G_HT20:
1868 case CHANNEL_G_HT40PLUS:
1869 case CHANNEL_G_HT40MINUS:
1870 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_2);
1871 break;
1872 default:
1873 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1874 "%s: invalid channel flags 0x%x\n", __func__,
1875 chan->channelFlags);
1876 return false;
1877 }
1878 return true;
1879}
1880
1881static void ath9k_hw_start_nfcal(struct ath_hal *ah)
1882{
1883 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1884 AR_PHY_AGC_CONTROL_ENABLE_NF);
1885 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1886 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1887 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1888}
1889
1890static void
1891ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
1892{
1893 struct ath9k_nfcal_hist *h;
1894 int i, j;
1895 int32_t val;
1896 const u32 ar5416_cca_regs[6] = {
1897 AR_PHY_CCA,
1898 AR_PHY_CH1_CCA,
1899 AR_PHY_CH2_CCA,
1900 AR_PHY_EXT_CCA,
1901 AR_PHY_CH1_EXT_CCA,
1902 AR_PHY_CH2_EXT_CCA
1903 };
1904 u8 chainmask;
1905
1906 if (AR_SREV_9280(ah))
1907 chainmask = 0x1B;
1908 else
1909 chainmask = 0x3F;
1910
1911#ifdef ATH_NF_PER_CHAN
1912 h = chan->nfCalHist;
1913#else
1914 h = ah->nfCalHist;
1915#endif
1916
1917 for (i = 0; i < NUM_NF_READINGS; i++) {
1918 if (chainmask & (1 << i)) {
1919 val = REG_READ(ah, ar5416_cca_regs[i]);
1920 val &= 0xFFFFFE00;
1921 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1922 REG_WRITE(ah, ar5416_cca_regs[i], val);
1923 }
1924 }
1925
1926 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1927 AR_PHY_AGC_CONTROL_ENABLE_NF);
1928 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1929 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1930 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1931
1932 for (j = 0; j < 1000; j++) {
1933 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1934 AR_PHY_AGC_CONTROL_NF) == 0)
1935 break;
1936 udelay(10);
1937 }
1938
1939 for (i = 0; i < NUM_NF_READINGS; i++) {
1940 if (chainmask & (1 << i)) {
1941 val = REG_READ(ah, ar5416_cca_regs[i]);
1942 val &= 0xFFFFFE00;
1943 val |= (((u32) (-50) << 1) & 0x1ff);
1944 REG_WRITE(ah, ar5416_cca_regs[i], val);
1945 }
1946 }
1947}
1948
1949static int16_t ath9k_hw_getnf(struct ath_hal *ah,
1950 struct ath9k_channel *chan)
1951{
1952 int16_t nf, nfThresh;
1953 int16_t nfarray[NUM_NF_READINGS] = { 0 };
1954 struct ath9k_nfcal_hist *h;
1955 u8 chainmask;
1956
1957 if (AR_SREV_9280(ah))
1958 chainmask = 0x1B;
1959 else
1960 chainmask = 0x3F;
1961
1962 chan->channelFlags &= (~CHANNEL_CW_INT);
1963 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1964 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1965 "%s: NF did not complete in calibration window\n",
1966 __func__);
1967 nf = 0;
1968 chan->rawNoiseFloor = nf;
1969 return chan->rawNoiseFloor;
1970 } else {
1971 ar5416GetNoiseFloor(ah, nfarray);
1972 nf = nfarray[0];
1973 if (getNoiseFloorThresh(ah, chan, &nfThresh)
1974 && nf > nfThresh) {
1975 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1976 "%s: noise floor failed detected; "
1977 "detected %d, threshold %d\n", __func__,
1978 nf, nfThresh);
1979 chan->channelFlags |= CHANNEL_CW_INT;
1980 }
1981 }
1982
1983#ifdef ATH_NF_PER_CHAN
1984 h = chan->nfCalHist;
1985#else
1986 h = ah->nfCalHist;
1987#endif
1988
1989 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
1990 chan->rawNoiseFloor = h[0].privNF;
1991
1992 return chan->rawNoiseFloor;
1993}
1994
1995static void ath9k_hw_update_mibstats(struct ath_hal *ah,
1996 struct ath9k_mib_stats *stats)
1997{
1998 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
1999 stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
2000 stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
2001 stats->rts_good += REG_READ(ah, AR_RTS_OK);
2002 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
2003}
2004
2005static void ath9k_enable_mib_counters(struct ath_hal *ah)
2006{
2007 struct ath_hal_5416 *ahp = AH5416(ah);
2008
2009 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable mib counters\n");
2010
2011 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2012
2013 REG_WRITE(ah, AR_FILT_OFDM, 0);
2014 REG_WRITE(ah, AR_FILT_CCK, 0);
2015 REG_WRITE(ah, AR_MIBC,
2016 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
2017 & 0x0f);
2018 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2019 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2020}
2021
2022static void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
2023{
2024 struct ath_hal_5416 *ahp = AH5416(ah);
2025
2026 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling MIB counters\n");
2027
2028 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
2029
2030 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2031
2032 REG_WRITE(ah, AR_FILT_OFDM, 0);
2033 REG_WRITE(ah, AR_FILT_CCK, 0);
2034}
2035
2036static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
2037 struct ath9k_channel *chan)
2038{
2039 struct ath_hal_5416 *ahp = AH5416(ah);
2040 int i;
2041
2042 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2043 if (ahp->ah_ani[i].c.channel == chan->channel)
2044 return i;
2045 if (ahp->ah_ani[i].c.channel == 0) {
2046 ahp->ah_ani[i].c.channel = chan->channel;
2047 ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
2048 return i;
2049 }
2050 }
2051
2052 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2053 "No more channel states left. Using channel 0\n");
2054 return 0;
2055}
2056
2057static void ath9k_hw_ani_attach(struct ath_hal *ah)
2058{
2059 struct ath_hal_5416 *ahp = AH5416(ah);
2060 int i;
2061
2062 ahp->ah_hasHwPhyCounters = 1;
2063
2064 memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
2065 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2066 ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
2067 ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
2068 ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
2069 ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
2070 ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
2071 ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
2072 ahp->ah_ani[i].ofdmWeakSigDetectOff =
2073 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
2074 ahp->ah_ani[i].cckWeakSigThreshold =
2075 ATH9K_ANI_CCK_WEAK_SIG_THR;
2076 ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
2077 ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
2078 if (ahp->ah_hasHwPhyCounters) {
2079 ahp->ah_ani[i].ofdmPhyErrBase =
2080 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
2081 ahp->ah_ani[i].cckPhyErrBase =
2082 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
2083 }
2084 }
2085 if (ahp->ah_hasHwPhyCounters) {
2086 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2087 "Setting OfdmErrBase = 0x%08x\n",
2088 ahp->ah_ani[0].ofdmPhyErrBase);
2089 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
2090 ahp->ah_ani[0].cckPhyErrBase);
2091
2092 REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
2093 REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
2094 ath9k_enable_mib_counters(ah);
2095 }
2096 ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
2097 if (ah->ah_config.enable_ani)
2098 ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
2099}
2100
2101static inline void ath9k_hw_ani_setup(struct ath_hal *ah)
2102{
2103 struct ath_hal_5416 *ahp = AH5416(ah);
2104 int i;
2105
2106 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
2107 const int coarseHigh[] = { -14, -14, -14, -14, -12 };
2108 const int coarseLow[] = { -64, -64, -64, -64, -70 };
2109 const int firpwr[] = { -78, -78, -78, -78, -80 };
2110
2111 for (i = 0; i < 5; i++) {
2112 ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
2113 ahp->ah_coarseHigh[i] = coarseHigh[i];
2114 ahp->ah_coarseLow[i] = coarseLow[i];
2115 ahp->ah_firpwr[i] = firpwr[i];
2116 }
2117}
2118
2119static void ath9k_hw_ani_detach(struct ath_hal *ah)
2120{
2121 struct ath_hal_5416 *ahp = AH5416(ah);
2122
2123 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detaching Ani\n");
2124 if (ahp->ah_hasHwPhyCounters) {
2125 ath9k_hw_disable_mib_counters(ah);
2126 REG_WRITE(ah, AR_PHY_ERR_1, 0);
2127 REG_WRITE(ah, AR_PHY_ERR_2, 0);
2128 }
2129}
2130
2131
2132static bool ath9k_hw_ani_control(struct ath_hal *ah,
2133 enum ath9k_ani_cmd cmd, int param)
2134{
2135 struct ath_hal_5416 *ahp = AH5416(ah);
2136 struct ar5416AniState *aniState = ahp->ah_curani;
2137
2138 switch (cmd & ahp->ah_ani_function) {
2139 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
2140 u32 level = param;
2141
2142 if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
2143 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2144 "%s: level out of range (%u > %u)\n",
2145 __func__, level,
2146 (unsigned) ARRAY_SIZE(ahp->
2147 ah_totalSizeDesired));
2148 return false;
2149 }
2150
2151 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
2152 AR_PHY_DESIRED_SZ_TOT_DES,
2153 ahp->ah_totalSizeDesired[level]);
2154 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2155 AR_PHY_AGC_CTL1_COARSE_LOW,
2156 ahp->ah_coarseLow[level]);
2157 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2158 AR_PHY_AGC_CTL1_COARSE_HIGH,
2159 ahp->ah_coarseHigh[level]);
2160 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2161 AR_PHY_FIND_SIG_FIRPWR,
2162 ahp->ah_firpwr[level]);
2163
2164 if (level > aniState->noiseImmunityLevel)
2165 ahp->ah_stats.ast_ani_niup++;
2166 else if (level < aniState->noiseImmunityLevel)
2167 ahp->ah_stats.ast_ani_nidown++;
2168 aniState->noiseImmunityLevel = level;
2169 break;
2170 }
2171 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
2172 const int m1ThreshLow[] = { 127, 50 };
2173 const int m2ThreshLow[] = { 127, 40 };
2174 const int m1Thresh[] = { 127, 0x4d };
2175 const int m2Thresh[] = { 127, 0x40 };
2176 const int m2CountThr[] = { 31, 16 };
2177 const int m2CountThrLow[] = { 63, 48 };
2178 u32 on = param ? 1 : 0;
2179
2180 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2181 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
2182 m1ThreshLow[on]);
2183 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2184 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
2185 m2ThreshLow[on]);
2186 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2187 AR_PHY_SFCORR_M1_THRESH,
2188 m1Thresh[on]);
2189 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2190 AR_PHY_SFCORR_M2_THRESH,
2191 m2Thresh[on]);
2192 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2193 AR_PHY_SFCORR_M2COUNT_THR,
2194 m2CountThr[on]);
2195 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2196 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
2197 m2CountThrLow[on]);
2198
2199 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2200 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
2201 m1ThreshLow[on]);
2202 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2203 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
2204 m2ThreshLow[on]);
2205 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2206 AR_PHY_SFCORR_EXT_M1_THRESH,
2207 m1Thresh[on]);
2208 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2209 AR_PHY_SFCORR_EXT_M2_THRESH,
2210 m2Thresh[on]);
2211
2212 if (on)
2213 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
2214 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2215 else
2216 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
2217 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2218
2219 if (!on != aniState->ofdmWeakSigDetectOff) {
2220 if (on)
2221 ahp->ah_stats.ast_ani_ofdmon++;
2222 else
2223 ahp->ah_stats.ast_ani_ofdmoff++;
2224 aniState->ofdmWeakSigDetectOff = !on;
2225 }
2226 break;
2227 }
2228 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
2229 const int weakSigThrCck[] = { 8, 6 };
2230 u32 high = param ? 1 : 0;
2231
2232 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
2233 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
2234 weakSigThrCck[high]);
2235 if (high != aniState->cckWeakSigThreshold) {
2236 if (high)
2237 ahp->ah_stats.ast_ani_cckhigh++;
2238 else
2239 ahp->ah_stats.ast_ani_ccklow++;
2240 aniState->cckWeakSigThreshold = high;
2241 }
2242 break;
2243 }
2244 case ATH9K_ANI_FIRSTEP_LEVEL:{
2245 const int firstep[] = { 0, 4, 8 };
2246 u32 level = param;
2247
2248 if (level >= ARRAY_SIZE(firstep)) {
2249 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2250 "%s: level out of range (%u > %u)\n",
2251 __func__, level,
2252 (unsigned) ARRAY_SIZE(firstep));
2253 return false;
2254 }
2255 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2256 AR_PHY_FIND_SIG_FIRSTEP,
2257 firstep[level]);
2258 if (level > aniState->firstepLevel)
2259 ahp->ah_stats.ast_ani_stepup++;
2260 else if (level < aniState->firstepLevel)
2261 ahp->ah_stats.ast_ani_stepdown++;
2262 aniState->firstepLevel = level;
2263 break;
2264 }
2265 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
2266 const int cycpwrThr1[] =
2267 { 2, 4, 6, 8, 10, 12, 14, 16 };
2268 u32 level = param;
2269
2270 if (level >= ARRAY_SIZE(cycpwrThr1)) {
2271 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2272 "%s: level out of range (%u > %u)\n",
2273 __func__, level,
2274 (unsigned)
2275 ARRAY_SIZE(cycpwrThr1));
2276 return false;
2277 }
2278 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
2279 AR_PHY_TIMING5_CYCPWR_THR1,
2280 cycpwrThr1[level]);
2281 if (level > aniState->spurImmunityLevel)
2282 ahp->ah_stats.ast_ani_spurup++;
2283 else if (level < aniState->spurImmunityLevel)
2284 ahp->ah_stats.ast_ani_spurdown++;
2285 aniState->spurImmunityLevel = level;
2286 break;
2287 }
2288 case ATH9K_ANI_PRESENT:
2289 break;
2290 default:
2291 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2292 "%s: invalid cmd %u\n", __func__, cmd);
2293 return false;
2294 }
2295
2296 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
2297 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2298 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
2299 "ofdmWeakSigDetectOff=%d\n",
2300 aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
2301 !aniState->ofdmWeakSigDetectOff);
2302 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2303 "cckWeakSigThreshold=%d, "
2304 "firstepLevel=%d, listenTime=%d\n",
2305 aniState->cckWeakSigThreshold, aniState->firstepLevel,
2306 aniState->listenTime);
2307 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2308 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
2309 aniState->cycleCount, aniState->ofdmPhyErrCount,
2310 aniState->cckPhyErrCount);
2311 return true;
2312}
2313
2314static void ath9k_ani_restart(struct ath_hal *ah)
2315{
2316 struct ath_hal_5416 *ahp = AH5416(ah);
2317 struct ar5416AniState *aniState;
2318
2319 if (!DO_ANI(ah))
2320 return;
2321
2322 aniState = ahp->ah_curani;
2323
2324 aniState->listenTime = 0;
2325 if (ahp->ah_hasHwPhyCounters) {
2326 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
2327 aniState->ofdmPhyErrBase = 0;
2328 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2329 "OFDM Trigger is too high for hw counters\n");
2330 } else {
2331 aniState->ofdmPhyErrBase =
2332 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
2333 }
2334 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
2335 aniState->cckPhyErrBase = 0;
2336 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2337 "CCK Trigger is too high for hw counters\n");
2338 } else {
2339 aniState->cckPhyErrBase =
2340 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
2341 }
2342 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2343 "%s: Writing ofdmbase=%u cckbase=%u\n",
2344 __func__, aniState->ofdmPhyErrBase,
2345 aniState->cckPhyErrBase);
2346 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
2347 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
2348 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2349 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2350
2351 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2352 }
2353 aniState->ofdmPhyErrCount = 0;
2354 aniState->cckPhyErrCount = 0;
2355}
2356
2357static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
2358{
2359 struct ath_hal_5416 *ahp = AH5416(ah);
2360 struct ath9k_channel *chan = ah->ah_curchan;
2361 struct ar5416AniState *aniState;
2362 enum wireless_mode mode;
2363 int32_t rssi;
2364
2365 if (!DO_ANI(ah))
2366 return;
2367
2368 aniState = ahp->ah_curani;
2369
2370 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2371 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2372 aniState->noiseImmunityLevel + 1)) {
2373 return;
2374 }
2375 }
2376
2377 if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
2378 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2379 aniState->spurImmunityLevel + 1)) {
2380 return;
2381 }
2382 }
2383
2384 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2385 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2386 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2387 aniState->firstepLevel + 1);
2388 }
2389 return;
2390 }
2391 rssi = BEACON_RSSI(ahp);
2392 if (rssi > aniState->rssiThrHigh) {
2393 if (!aniState->ofdmWeakSigDetectOff) {
2394 if (ath9k_hw_ani_control(ah,
2395 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2396 false)) {
2397 ath9k_hw_ani_control(ah,
2398 ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2399 0);
2400 return;
2401 }
2402 }
2403 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2404 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2405 aniState->firstepLevel + 1);
2406 return;
2407 }
2408 } else if (rssi > aniState->rssiThrLow) {
2409 if (aniState->ofdmWeakSigDetectOff)
2410 ath9k_hw_ani_control(ah,
2411 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2412 true);
2413 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2414 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2415 aniState->firstepLevel + 1);
2416 return;
2417 } else {
2418 mode = ath9k_hw_chan2wmode(ah, chan);
2419 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
2420 if (!aniState->ofdmWeakSigDetectOff)
2421 ath9k_hw_ani_control(ah,
2422 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2423 false);
2424 if (aniState->firstepLevel > 0)
2425 ath9k_hw_ani_control(ah,
2426 ATH9K_ANI_FIRSTEP_LEVEL,
2427 0);
2428 return;
2429 }
2430 }
2431}
2432
2433static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
2434{
2435 struct ath_hal_5416 *ahp = AH5416(ah);
2436 struct ath9k_channel *chan = ah->ah_curchan;
2437 struct ar5416AniState *aniState;
2438 enum wireless_mode mode;
2439 int32_t rssi;
2440
2441 if (!DO_ANI(ah))
2442 return;
2443
2444 aniState = ahp->ah_curani;
2445 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2446 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2447 aniState->noiseImmunityLevel + 1)) {
2448 return;
2449 }
2450 }
2451 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2452 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2453 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2454 aniState->firstepLevel + 1);
2455 }
2456 return;
2457 }
2458 rssi = BEACON_RSSI(ahp);
2459 if (rssi > aniState->rssiThrLow) {
2460 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2461 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2462 aniState->firstepLevel + 1);
2463 } else {
2464 mode = ath9k_hw_chan2wmode(ah, chan);
2465 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
2466 if (aniState->firstepLevel > 0)
2467 ath9k_hw_ani_control(ah,
2468 ATH9K_ANI_FIRSTEP_LEVEL,
2469 0);
2470 }
2471 }
2472}
2473
2474static void ath9k_ani_reset(struct ath_hal *ah)
2475{
2476 struct ath_hal_5416 *ahp = AH5416(ah);
2477 struct ar5416AniState *aniState;
2478 struct ath9k_channel *chan = ah->ah_curchan;
2479 int index;
2480
2481 if (!DO_ANI(ah))
2482 return;
2483
2484 index = ath9k_hw_get_ani_channel_idx(ah, chan);
2485 aniState = &ahp->ah_ani[index];
2486 ahp->ah_curani = aniState;
2487
2488 if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
2489 && ah->ah_opmode != ATH9K_M_IBSS) {
2490 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2491 "%s: Reset ANI state opmode %u\n", __func__,
2492 ah->ah_opmode);
2493 ahp->ah_stats.ast_ani_reset++;
2494 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
2495 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
2496 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
2497 ath9k_hw_ani_control(ah,
2498 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2499 !ATH9K_ANI_USE_OFDM_WEAK_SIG);
2500 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2501 ATH9K_ANI_CCK_WEAK_SIG_THR);
2502 ath9k_hw_setrxfilter(ah,
2503 ath9k_hw_getrxfilter(ah) |
2504 ATH9K_RX_FILTER_PHYERR);
2505 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2506 ahp->ah_curani->ofdmTrigHigh =
2507 ah->ah_config.ofdm_trig_high;
2508 ahp->ah_curani->ofdmTrigLow =
2509 ah->ah_config.ofdm_trig_low;
2510 ahp->ah_curani->cckTrigHigh =
2511 ah->ah_config.cck_trig_high;
2512 ahp->ah_curani->cckTrigLow =
2513 ah->ah_config.cck_trig_low;
2514 }
2515 ath9k_ani_restart(ah);
2516 return;
2517 }
2518
2519 if (aniState->noiseImmunityLevel != 0)
2520 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2521 aniState->noiseImmunityLevel);
2522 if (aniState->spurImmunityLevel != 0)
2523 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2524 aniState->spurImmunityLevel);
2525 if (aniState->ofdmWeakSigDetectOff)
2526 ath9k_hw_ani_control(ah,
2527 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2528 !aniState->ofdmWeakSigDetectOff);
2529 if (aniState->cckWeakSigThreshold)
2530 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2531 aniState->cckWeakSigThreshold);
2532 if (aniState->firstepLevel != 0)
2533 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2534 aniState->firstepLevel);
2535 if (ahp->ah_hasHwPhyCounters) {
2536 ath9k_hw_setrxfilter(ah,
2537 ath9k_hw_getrxfilter(ah) &
2538 ~ATH9K_RX_FILTER_PHYERR);
2539 ath9k_ani_restart(ah);
2540 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2541 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2542
2543 } else {
2544 ath9k_ani_restart(ah);
2545 ath9k_hw_setrxfilter(ah,
2546 ath9k_hw_getrxfilter(ah) |
2547 ATH9K_RX_FILTER_PHYERR);
2548 }
2549}
2550
2551void ath9k_hw_procmibevent(struct ath_hal *ah,
2552 const struct ath9k_node_stats *stats)
2553{
2554 struct ath_hal_5416 *ahp = AH5416(ah);
2555 u32 phyCnt1, phyCnt2;
2556
2557 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n");
2558
2559 REG_WRITE(ah, AR_FILT_OFDM, 0);
2560 REG_WRITE(ah, AR_FILT_CCK, 0);
2561 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
2562 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
2563
2564 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2565 ahp->ah_stats.ast_nodestats = *stats;
2566
2567 if (!DO_ANI(ah))
2568 return;
2569
2570 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2571 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2572 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
2573 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
2574 struct ar5416AniState *aniState = ahp->ah_curani;
2575 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2576
2577 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2578 ahp->ah_stats.ast_ani_ofdmerrs +=
2579 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2580 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2581
2582 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2583 ahp->ah_stats.ast_ani_cckerrs +=
2584 cckPhyErrCnt - aniState->cckPhyErrCount;
2585 aniState->cckPhyErrCount = cckPhyErrCnt;
2586
2587 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
2588 ath9k_hw_ani_ofdm_err_trigger(ah);
2589 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
2590 ath9k_hw_ani_cck_err_trigger(ah);
2591
2592 ath9k_ani_restart(ah);
2593 }
2594}
2595
2596static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
2597{
2598 struct ath_hal_5416 *ahp = AH5416(ah);
2599 struct ar5416AniState *aniState;
2600 int32_t rssi;
2601
2602 aniState = ahp->ah_curani;
2603
2604 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2605 if (aniState->firstepLevel > 0) {
2606 if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2607 aniState->firstepLevel - 1)) {
2608 return;
2609 }
2610 }
2611 } else {
2612 rssi = BEACON_RSSI(ahp);
2613 if (rssi > aniState->rssiThrHigh) {
2614 /* XXX: Handle me */
2615 } else if (rssi > aniState->rssiThrLow) {
2616 if (aniState->ofdmWeakSigDetectOff) {
2617 if (ath9k_hw_ani_control(ah,
2618 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2619 true) ==
2620 true) {
2621 return;
2622 }
2623 }
2624 if (aniState->firstepLevel > 0) {
2625 if (ath9k_hw_ani_control
2626 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2627 aniState->firstepLevel - 1) ==
2628 true) {
2629 return;
2630 }
2631 }
2632 } else {
2633 if (aniState->firstepLevel > 0) {
2634 if (ath9k_hw_ani_control
2635 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2636 aniState->firstepLevel - 1) ==
2637 true) {
2638 return;
2639 }
2640 }
2641 }
2642 }
2643
2644 if (aniState->spurImmunityLevel > 0) {
2645 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2646 aniState->spurImmunityLevel - 1)) {
2647 return;
2648 }
2649 }
2650
2651 if (aniState->noiseImmunityLevel > 0) {
2652 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2653 aniState->noiseImmunityLevel - 1);
2654 return;
2655 }
2656}
2657
2658static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
2659{
2660 struct ath_hal_5416 *ahp = AH5416(ah);
2661 struct ar5416AniState *aniState;
2662 u32 txFrameCount, rxFrameCount, cycleCount;
2663 int32_t listenTime;
2664
2665 txFrameCount = REG_READ(ah, AR_TFCNT);
2666 rxFrameCount = REG_READ(ah, AR_RFCNT);
2667 cycleCount = REG_READ(ah, AR_CCCNT);
2668
2669 aniState = ahp->ah_curani;
2670 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
2671
2672 listenTime = 0;
2673 ahp->ah_stats.ast_ani_lzero++;
2674 } else {
2675 int32_t ccdelta = cycleCount - aniState->cycleCount;
2676 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
2677 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
2678 listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
2679 }
2680 aniState->cycleCount = cycleCount;
2681 aniState->txFrameCount = txFrameCount;
2682 aniState->rxFrameCount = rxFrameCount;
2683
2684 return listenTime;
2685}
2686
2687void ath9k_hw_ani_monitor(struct ath_hal *ah,
2688 const struct ath9k_node_stats *stats,
2689 struct ath9k_channel *chan)
2690{
2691 struct ath_hal_5416 *ahp = AH5416(ah);
2692 struct ar5416AniState *aniState;
2693 int32_t listenTime;
2694
2695 aniState = ahp->ah_curani;
2696 ahp->ah_stats.ast_nodestats = *stats;
2697
2698 listenTime = ath9k_hw_ani_get_listen_time(ah);
2699 if (listenTime < 0) {
2700 ahp->ah_stats.ast_ani_lneg++;
2701 ath9k_ani_restart(ah);
2702 return;
2703 }
2704
2705 aniState->listenTime += listenTime;
2706
2707 if (ahp->ah_hasHwPhyCounters) {
2708 u32 phyCnt1, phyCnt2;
2709 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2710
2711 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2712
2713 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2714 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2715
2716 if (phyCnt1 < aniState->ofdmPhyErrBase ||
2717 phyCnt2 < aniState->cckPhyErrBase) {
2718 if (phyCnt1 < aniState->ofdmPhyErrBase) {
2719 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2720 "%s: phyCnt1 0x%x, resetting "
2721 "counter value to 0x%x\n",
2722 __func__, phyCnt1,
2723 aniState->ofdmPhyErrBase);
2724 REG_WRITE(ah, AR_PHY_ERR_1,
2725 aniState->ofdmPhyErrBase);
2726 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
2727 AR_PHY_ERR_OFDM_TIMING);
2728 }
2729 if (phyCnt2 < aniState->cckPhyErrBase) {
2730 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2731 "%s: phyCnt2 0x%x, resetting "
2732 "counter value to 0x%x\n",
2733 __func__, phyCnt2,
2734 aniState->cckPhyErrBase);
2735 REG_WRITE(ah, AR_PHY_ERR_2,
2736 aniState->cckPhyErrBase);
2737 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
2738 AR_PHY_ERR_CCK_TIMING);
2739 }
2740 return;
2741 }
2742
2743 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2744 ahp->ah_stats.ast_ani_ofdmerrs +=
2745 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2746 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2747
2748 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2749 ahp->ah_stats.ast_ani_cckerrs +=
2750 cckPhyErrCnt - aniState->cckPhyErrCount;
2751 aniState->cckPhyErrCount = cckPhyErrCnt;
2752 }
2753
2754 if (!DO_ANI(ah))
2755 return;
2756
2757 if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
2758 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
2759 aniState->ofdmTrigLow / 1000 &&
2760 aniState->cckPhyErrCount <= aniState->listenTime *
2761 aniState->cckTrigLow / 1000)
2762 ath9k_hw_ani_lower_immunity(ah);
2763 ath9k_ani_restart(ah);
2764 } else if (aniState->listenTime > ahp->ah_aniPeriod) {
2765 if (aniState->ofdmPhyErrCount > aniState->listenTime *
2766 aniState->ofdmTrigHigh / 1000) {
2767 ath9k_hw_ani_ofdm_err_trigger(ah);
2768 ath9k_ani_restart(ah);
2769 } else if (aniState->cckPhyErrCount >
2770 aniState->listenTime * aniState->cckTrigHigh /
2771 1000) {
2772 ath9k_hw_ani_cck_err_trigger(ah);
2773 ath9k_ani_restart(ah);
2774 }
2775 }
2776}
2777
2778#ifndef ATH_NF_PER_CHAN
2779static void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
2780{
2781 int i, j;
2782
2783 for (i = 0; i < NUM_NF_READINGS; i++) {
2784 ah->nfCalHist[i].currIndex = 0;
2785 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
2786 ah->nfCalHist[i].invalidNFcount =
2787 AR_PHY_CCA_FILTERWINDOW_LENGTH;
2788 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
2789 ah->nfCalHist[i].nfCalBuffer[j] =
2790 AR_PHY_CCA_MAX_GOOD_VALUE;
2791 }
2792 }
2793 return;
2794}
2795#endif
2796
2797static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
2798 u32 gpio, u32 type)
2799{
2800 int addr;
2801 u32 gpio_shift, tmp;
2802
2803 if (gpio > 11)
2804 addr = AR_GPIO_OUTPUT_MUX3;
2805 else if (gpio > 5)
2806 addr = AR_GPIO_OUTPUT_MUX2;
2807 else
2808 addr = AR_GPIO_OUTPUT_MUX1;
2809
2810 gpio_shift = (gpio % 6) * 5;
2811
2812 if (AR_SREV_9280_20_OR_LATER(ah)
2813 || (addr != AR_GPIO_OUTPUT_MUX1)) {
2814 REG_RMW(ah, addr, (type << gpio_shift),
2815 (0x1f << gpio_shift));
2816 } else {
2817 tmp = REG_READ(ah, addr);
2818 tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
2819 tmp &= ~(0x1f << gpio_shift);
2820 tmp |= (type << gpio_shift);
2821 REG_WRITE(ah, addr, tmp);
2822 }
2823}
2824
2825static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2826 enum ath9k_gpio_output_mux_type
2827 halSignalType)
2828{
2829 u32 ah_signal_type;
2830 u32 gpio_shift;
2831
2832 static u32 MuxSignalConversionTable[] = {
2833
2834 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
2835
2836 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
2837
2838 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
2839
2840 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
2841
2842 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
2843 };
2844
2845 if ((halSignalType >= 0)
2846 && (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
2847 ah_signal_type = MuxSignalConversionTable[halSignalType];
2848 else
2849 return false;
2850
2851 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
2852
2853 gpio_shift = 2 * gpio;
2854
2855 REG_RMW(ah,
2856 AR_GPIO_OE_OUT,
2857 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
2858 (AR_GPIO_OE_OUT_DRV << gpio_shift));
2859
2860 return true;
2861}
2862
2863static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio,
2864 u32 val)
2865{
2866 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
2867 AR_GPIO_BIT(gpio));
2868 return true;
2869}
2870
2871static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
2872{
2873 if (gpio >= ah->ah_caps.num_gpio_pins)
2874 return 0xffffffff;
2875
2876 if (AR_SREV_9280_10_OR_LATER(ah)) {
2877 return (MS
2878 (REG_READ(ah, AR_GPIO_IN_OUT),
2879 AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
2880 } else {
2881 return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
2882 AR_GPIO_BIT(gpio)) != 0;
2883 }
2884}
2885
2886static inline int ath9k_hw_post_attach(struct ath_hal *ah)
2887{
2888 int ecode;
2889
2890 if (!ath9k_hw_chip_test(ah)) {
2891 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2892 "%s: hardware self-test failed\n", __func__);
2893 return -ENODEV;
2894 }
2895
2896 ecode = ath9k_hw_rf_claim(ah);
2897 if (ecode != 0)
2898 return ecode;
2899
2900 ecode = ath9k_hw_eeprom_attach(ah);
2901 if (ecode != 0)
2902 return ecode;
2903 ecode = ath9k_hw_rfattach(ah);
2904 if (ecode != 0)
2905 return ecode;
2906
2907 if (!AR_SREV_9100(ah)) {
2908 ath9k_hw_ani_setup(ah);
2909 ath9k_hw_ani_attach(ah);
2910 }
2911 return 0;
2912}
2913
2914static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
2915 struct ar5416_eeprom *pEepData,
2916 u32 reg, u32 value)
2917{
2918 struct base_eep_header *pBase = &(pEepData->baseEepHeader);
2919
2920 switch (ah->ah_devid) {
2921 case AR9280_DEVID_PCI:
2922 if (reg == 0x7894) {
2923 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2924 "ini VAL: %x EEPROM: %x\n", value,
2925 (pBase->version & 0xff));
2926
2927 if ((pBase->version & 0xff) > 0x0a) {
2928 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2929 "PWDCLKIND: %d\n",
2930 pBase->pwdclkind);
2931 value &= ~AR_AN_TOP2_PWDCLKIND;
2932 value |= AR_AN_TOP2_PWDCLKIND & (pBase->
2933 pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
2934 } else {
2935 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2936 "PWDCLKIND Earlier Rev\n");
2937 }
2938
2939 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2940 "final ini VAL: %x\n", value);
2941 }
2942 break;
2943 }
2944 return value;
2945}
2946
2947static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
2948{
2949 struct ath_hal_5416 *ahp = AH5416(ah);
2950 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
2951 u16 capField = 0, eeval;
2952
2953 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_0);
2954
2955 ah->ah_currentRD = eeval;
2956
2957 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_1);
2958 ah->ah_currentRDExt = eeval;
2959
2960 capField = ath9k_hw_get_eeprom(ahp, EEP_OP_CAP);
2961
2962 if (ah->ah_opmode != ATH9K_M_HOSTAP &&
2963 ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2964 if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
2965 ah->ah_currentRD += 5;
2966 else if (ah->ah_currentRD == 0x41)
2967 ah->ah_currentRD = 0x43;
2968 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
2969 "%s: regdomain mapped to 0x%x\n", __func__,
2970 ah->ah_currentRD);
2971 }
2972
2973 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2974 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
2975
2976 if (eeval & AR5416_OPFLAGS_11A) {
2977 set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
2978 if (ah->ah_config.ht_enable) {
2979 if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
2980 set_bit(ATH9K_MODE_11NA_HT20,
2981 pCap->wireless_modes);
2982 if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
2983 set_bit(ATH9K_MODE_11NA_HT40PLUS,
2984 pCap->wireless_modes);
2985 set_bit(ATH9K_MODE_11NA_HT40MINUS,
2986 pCap->wireless_modes);
2987 }
2988 }
2989 }
2990
2991 if (eeval & AR5416_OPFLAGS_11G) {
2992 set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
2993 set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
2994 if (ah->ah_config.ht_enable) {
2995 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
2996 set_bit(ATH9K_MODE_11NG_HT20,
2997 pCap->wireless_modes);
2998 if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
2999 set_bit(ATH9K_MODE_11NG_HT40PLUS,
3000 pCap->wireless_modes);
3001 set_bit(ATH9K_MODE_11NG_HT40MINUS,
3002 pCap->wireless_modes);
3003 }
3004 }
3005 }
3006
3007 pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
3008 if ((ah->ah_isPciExpress)
3009 || (eeval & AR5416_OPFLAGS_11A)) {
3010 pCap->rx_chainmask =
3011 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3012 } else {
3013 pCap->rx_chainmask =
3014 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3015 }
3016
3017 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3018 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3019
3020 pCap->low_2ghz_chan = 2312;
3021 pCap->high_2ghz_chan = 2732;
3022
3023 pCap->low_5ghz_chan = 4920;
3024 pCap->high_5ghz_chan = 6100;
3025
3026 pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
3027 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
3028 pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
3029
3030 pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
3031 pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
3032 pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
3033
3034 pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
3035
3036 if (ah->ah_config.ht_enable)
3037 pCap->hw_caps |= ATH9K_HW_CAP_HT;
3038 else
3039 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
3040
3041 pCap->hw_caps |= ATH9K_HW_CAP_GTT;
3042 pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
3043 pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
3044 pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
3045
3046 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
3047 pCap->total_queues =
3048 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3049 else
3050 pCap->total_queues = ATH9K_NUM_TX_QUEUES;
3051
3052 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
3053 pCap->keycache_size =
3054 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3055 else
3056 pCap->keycache_size = AR_KEYTABLE_SIZE;
3057
3058 pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
3059 pCap->num_mr_retries = 4;
3060 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3061
3062 if (AR_SREV_9280_10_OR_LATER(ah))
3063 pCap->num_gpio_pins = AR928X_NUM_GPIO;
3064 else
3065 pCap->num_gpio_pins = AR_NUM_GPIO;
3066
3067 if (AR_SREV_9280_10_OR_LATER(ah)) {
3068 pCap->hw_caps |= ATH9K_HW_CAP_WOW;
3069 pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3070 } else {
3071 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
3072 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3073 }
3074
3075 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
3076 pCap->hw_caps |= ATH9K_HW_CAP_CST;
3077 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
3078 } else {
3079 pCap->rts_aggr_limit = (8 * 1024);
3080 }
3081
3082 pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
3083
3084 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3085 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3086 ahp->ah_gpioSelect =
3087 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3088 ahp->ah_polarity =
3089 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3090
3091 ath9k_hw_setcapability(ah, ATH9K_CAP_RFSILENT, 1, true,
3092 NULL);
3093 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
3094 }
3095
3096 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3097 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3098 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3099 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3100 (ah->ah_macVersion == AR_SREV_VERSION_9280))
3101 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3102 else
3103 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
3104
3105 if (AR_SREV_9280(ah))
3106 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
3107 else
3108 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
3109
3110 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
3111 pCap->reg_cap =
3112 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3113 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3114 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3115 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3116 } else {
3117 pCap->reg_cap =
3118 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3119 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3120 }
3121
3122 pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3123
3124 pCap->num_antcfg_5ghz =
3125 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_5GHZ);
3126 pCap->num_antcfg_2ghz =
3127 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_2GHZ);
3128
3129 return true;
3130}
3131
3132static void ar5416DisablePciePhy(struct ath_hal *ah)
3133{
3134 if (!AR_SREV_9100(ah))
3135 return;
3136
3137 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3138 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3139 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3140 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3141 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3142 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3143 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3144 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3145 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3146
3147 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3148}
3149
3150static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3151{
3152 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3153 if (setChip) {
3154 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3155 AR_RTC_FORCE_WAKE_EN);
3156 if (!AR_SREV_9100(ah))
3157 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3158
3159 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3160 AR_RTC_RESET_EN);
3161 }
3162}
3163
3164static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3165{
3166 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3167 if (setChip) {
3168 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3169
3170 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
3171 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3172 AR_RTC_FORCE_WAKE_ON_INT);
3173 } else {
3174 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3175 AR_RTC_FORCE_WAKE_EN);
3176 }
3177 }
3178}
3179
3180static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3181 int setChip)
3182{
3183 u32 val;
3184 int i;
3185
3186 if (setChip) {
3187 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3188 AR_RTC_STATUS_SHUTDOWN) {
3189 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3190 != true) {
3191 return false;
3192 }
3193 }
3194 if (AR_SREV_9100(ah))
3195 REG_SET_BIT(ah, AR_RTC_RESET,
3196 AR_RTC_RESET_EN);
3197
3198 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3199 AR_RTC_FORCE_WAKE_EN);
3200 udelay(50);
3201
3202 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3203 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3204 if (val == AR_RTC_STATUS_ON)
3205 break;
3206 udelay(50);
3207 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3208 AR_RTC_FORCE_WAKE_EN);
3209 }
3210 if (i == 0) {
3211 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3212 "%s: Failed to wakeup in %uus\n",
3213 __func__, POWER_UP_TIME / 20);
3214 return false;
3215 }
3216 }
3217
3218 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3219 return true;
3220}
3221
3222bool ath9k_hw_setpower(struct ath_hal *ah,
3223 enum ath9k_power_mode mode)
3224{
3225 struct ath_hal_5416 *ahp = AH5416(ah);
3226 static const char *modes[] = {
3227 "AWAKE",
3228 "FULL-SLEEP",
3229 "NETWORK SLEEP",
3230 "UNDEFINED"
3231 };
3232 int status = true, setChip = true;
3233
3234 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3235 modes[ahp->ah_powerMode], modes[mode],
3236 setChip ? "set chip " : "");
3237
3238 switch (mode) {
3239 case ATH9K_PM_AWAKE:
3240 status = ath9k_hw_set_power_awake(ah, setChip);
3241 break;
3242 case ATH9K_PM_FULL_SLEEP:
3243 ath9k_set_power_sleep(ah, setChip);
3244 ahp->ah_chipFullSleep = true;
3245 break;
3246 case ATH9K_PM_NETWORK_SLEEP:
3247 ath9k_set_power_network_sleep(ah, setChip);
3248 break;
3249 default:
3250 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3251 "%s: unknown power mode %u\n", __func__, mode);
3252 return false;
3253 }
3254 ahp->ah_powerMode = mode;
3255 return status;
3256}
3257
3258static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3259 struct ath_softc *sc,
3260 void __iomem *mem,
3261 int *status)
3262{
3263 struct ath_hal_5416 *ahp;
3264 struct ath_hal *ah;
3265 int ecode;
3266#ifndef CONFIG_SLOW_ANT_DIV
3267 u32 i;
3268 u32 j;
3269#endif
3270
3271 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3272 if (ahp == NULL)
3273 return NULL;
3274
3275 ah = &ahp->ah;
3276
3277 ath9k_hw_set_defaults(ah);
3278
3279 if (ah->ah_config.intr_mitigation != 0)
3280 ahp->ah_intrMitigation = true;
3281
3282 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3283 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3284 __func__);
3285 ecode = -EIO;
3286 goto bad;
3287 }
3288
3289 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3290 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3291 __func__);
3292 ecode = -EIO;
3293 goto bad;
3294 }
3295
3296 if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
3297 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
3298 ah->ah_config.serialize_regmode =
3299 SER_REG_MODE_ON;
3300 } else {
3301 ah->ah_config.serialize_regmode =
3302 SER_REG_MODE_OFF;
3303 }
3304 }
3305 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3306 "%s: serialize_regmode is %d\n",
3307 __func__, ah->ah_config.serialize_regmode);
3308
3309 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3310 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3311 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3312 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3313 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3314 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3315 "this driver\n", __func__,
3316 ah->ah_macVersion, ah->ah_macRev);
3317 ecode = -EOPNOTSUPP;
3318 goto bad;
3319 }
3320
3321 if (AR_SREV_9100(ah)) {
3322 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3323 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3324 ah->ah_isPciExpress = false;
3325 }
3326 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3327
3328 if (AR_SREV_9160_10_OR_LATER(ah)) {
3329 if (AR_SREV_9280_10_OR_LATER(ah)) {
3330 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3331 ahp->ah_adcGainCalData.calData =
3332 &adc_gain_cal_single_sample;
3333 ahp->ah_adcDcCalData.calData =
3334 &adc_dc_cal_single_sample;
3335 ahp->ah_adcDcCalInitData.calData =
3336 &adc_init_dc_cal;
3337 } else {
3338 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3339 ahp->ah_adcGainCalData.calData =
3340 &adc_gain_cal_multi_sample;
3341 ahp->ah_adcDcCalData.calData =
3342 &adc_dc_cal_multi_sample;
3343 ahp->ah_adcDcCalInitData.calData =
3344 &adc_init_dc_cal;
3345 }
3346 ahp->ah_suppCals =
3347 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3348 }
3349
3350 if (AR_SREV_9160(ah)) {
3351 ah->ah_config.enable_ani = 1;
3352 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3353 ATH9K_ANI_FIRSTEP_LEVEL);
3354 } else {
3355 ahp->ah_ani_function = ATH9K_ANI_ALL;
3356 if (AR_SREV_9280_10_OR_LATER(ah)) {
3357 ahp->ah_ani_function &=
3358 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3359 }
3360 }
3361
3362 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3363 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3364 ah->ah_macVersion, ah->ah_macRev);
3365
3366 if (AR_SREV_9280_20_OR_LATER(ah)) {
3367 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3368 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3369 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3370 ARRAY_SIZE(ar9280Common_9280_2), 2);
3371
3372 if (ah->ah_config.pcie_clock_req) {
3373 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3374 ar9280PciePhy_clkreq_off_L1_9280,
3375 ARRAY_SIZE
3376 (ar9280PciePhy_clkreq_off_L1_9280),
3377 2);
3378 } else {
3379 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3380 ar9280PciePhy_clkreq_always_on_L1_9280,
3381 ARRAY_SIZE
3382 (ar9280PciePhy_clkreq_always_on_L1_9280),
3383 2);
3384 }
3385 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3386 ar9280Modes_fast_clock_9280_2,
3387 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3388 3);
3389 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3390 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3391 ARRAY_SIZE(ar9280Modes_9280), 6);
3392 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3393 ARRAY_SIZE(ar9280Common_9280), 2);
3394 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3395 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3396 ARRAY_SIZE(ar5416Modes_9160), 6);
3397 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3398 ARRAY_SIZE(ar5416Common_9160), 2);
3399 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3400 ARRAY_SIZE(ar5416Bank0_9160), 2);
3401 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3402 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3403 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3404 ARRAY_SIZE(ar5416Bank1_9160), 2);
3405 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3406 ARRAY_SIZE(ar5416Bank2_9160), 2);
3407 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3408 ARRAY_SIZE(ar5416Bank3_9160), 3);
3409 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3410 ARRAY_SIZE(ar5416Bank6_9160), 3);
3411 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3412 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3413 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3414 ARRAY_SIZE(ar5416Bank7_9160), 2);
3415 if (AR_SREV_9160_11(ah)) {
3416 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3417 ar5416Addac_91601_1,
3418 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3419 } else {
3420 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3421 ARRAY_SIZE(ar5416Addac_9160), 2);
3422 }
3423 } else if (AR_SREV_9100_OR_LATER(ah)) {
3424 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3425 ARRAY_SIZE(ar5416Modes_9100), 6);
3426 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3427 ARRAY_SIZE(ar5416Common_9100), 2);
3428 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3429 ARRAY_SIZE(ar5416Bank0_9100), 2);
3430 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3431 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3432 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3433 ARRAY_SIZE(ar5416Bank1_9100), 2);
3434 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3435 ARRAY_SIZE(ar5416Bank2_9100), 2);
3436 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3437 ARRAY_SIZE(ar5416Bank3_9100), 3);
3438 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3439 ARRAY_SIZE(ar5416Bank6_9100), 3);
3440 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3441 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3442 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3443 ARRAY_SIZE(ar5416Bank7_9100), 2);
3444 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3445 ARRAY_SIZE(ar5416Addac_9100), 2);
3446 } else {
3447 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3448 ARRAY_SIZE(ar5416Modes), 6);
3449 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3450 ARRAY_SIZE(ar5416Common), 2);
3451 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3452 ARRAY_SIZE(ar5416Bank0), 2);
3453 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3454 ARRAY_SIZE(ar5416BB_RfGain), 3);
3455 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3456 ARRAY_SIZE(ar5416Bank1), 2);
3457 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3458 ARRAY_SIZE(ar5416Bank2), 2);
3459 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3460 ARRAY_SIZE(ar5416Bank3), 3);
3461 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3462 ARRAY_SIZE(ar5416Bank6), 3);
3463 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3464 ARRAY_SIZE(ar5416Bank6TPC), 3);
3465 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3466 ARRAY_SIZE(ar5416Bank7), 2);
3467 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3468 ARRAY_SIZE(ar5416Addac), 2);
3469 }
3470
3471 if (ah->ah_isPciExpress)
3472 ath9k_hw_configpcipowersave(ah, 0);
3473 else
3474 ar5416DisablePciePhy(ah);
3475
3476 ecode = ath9k_hw_post_attach(ah);
3477 if (ecode != 0)
3478 goto bad;
3479
3480#ifndef CONFIG_SLOW_ANT_DIV
3481 if (ah->ah_devid == AR9280_DEVID_PCI) {
3482 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3483 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3484
3485 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3486 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3487
3488 INI_RA(&ahp->ah_iniModes, i, j) =
3489 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3490 reg, val);
3491 }
3492 }
3493 }
3494#endif
3495
3496 if (!ath9k_hw_fill_cap_info(ah)) {
3497 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3498 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3499 ecode = -EINVAL;
3500 goto bad;
3501 }
3502
3503 ecode = ath9k_hw_init_macaddr(ah);
3504 if (ecode != 0) {
3505 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3506 "%s: failed initializing mac address\n",
3507 __func__);
3508 goto bad;
3509 }
3510
3511 if (AR_SREV_9285(ah))
3512 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3513 else
3514 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3515
3516#ifndef ATH_NF_PER_CHAN
3517
3518 ath9k_init_nfcal_hist_buffer(ah);
3519#endif
3520
3521 return ah;
3522
3523bad:
3524 if (ahp)
3525 ath9k_hw_detach((struct ath_hal *) ahp);
3526 if (status)
3527 *status = ecode;
3528 return NULL;
3529}
3530
3531void ath9k_hw_detach(struct ath_hal *ah)
3532{
3533 if (!AR_SREV_9100(ah))
3534 ath9k_hw_ani_detach(ah);
3535 ath9k_hw_rfdetach(ah);
3536
3537 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3538 kfree(ah);
3539}
3540
3541bool ath9k_get_channel_edges(struct ath_hal *ah,
3542 u16 flags, u16 *low,
3543 u16 *high)
3544{
3545 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3546
3547 if (flags & CHANNEL_5GHZ) {
3548 *low = pCap->low_5ghz_chan;
3549 *high = pCap->high_5ghz_chan;
3550 return true;
3551 }
3552 if ((flags & CHANNEL_2GHZ)) {
3553 *low = pCap->low_2ghz_chan;
3554 *high = pCap->high_2ghz_chan;
3555
3556 return true;
3557 }
3558 return false;
3559}
3560
3561static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3562 u8 pwrMax,
3563 u8 *pPwrList,
3564 u8 *pVpdList,
3565 u16
3566 numIntercepts,
3567 u8 *pRetVpdList)
3568{
3569 u16 i, k;
3570 u8 currPwr = pwrMin;
3571 u16 idxL = 0, idxR = 0;
3572
3573 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3574 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3575 numIntercepts, &(idxL),
3576 &(idxR));
3577 if (idxR < 1)
3578 idxR = 1;
3579 if (idxL == numIntercepts - 1)
3580 idxL = (u16) (numIntercepts - 2);
3581 if (pPwrList[idxL] == pPwrList[idxR])
3582 k = pVpdList[idxL];
3583 else
3584 k = (u16) (((currPwr -
3585 pPwrList[idxL]) *
3586 pVpdList[idxR] +
3587 (pPwrList[idxR] -
3588 currPwr) * pVpdList[idxL]) /
3589 (pPwrList[idxR] -
3590 pPwrList[idxL]));
3591 pRetVpdList[i] = (u8) k;
3592 currPwr += 2;
3593 }
3594
3595 return true;
3596}
3597
3598static inline void
3599ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3600 struct ath9k_channel *chan,
3601 struct cal_data_per_freq *pRawDataSet,
3602 u8 *bChans,
3603 u16 availPiers,
3604 u16 tPdGainOverlap,
3605 int16_t *pMinCalPower,
3606 u16 *pPdGainBoundaries,
3607 u8 *pPDADCValues,
3608 u16 numXpdGains)
3609{
3610 int i, j, k;
3611 int16_t ss;
3612 u16 idxL = 0, idxR = 0, numPiers;
3613 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3614 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3615 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3616 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3617 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3618 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3619
3620 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3621 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3622 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3623 int16_t vpdStep;
3624 int16_t tmpVal;
3625 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3626 bool match;
3627 int16_t minDelta = 0;
3628 struct chan_centers centers;
3629
3630 ath9k_hw_get_channel_centers(ah, chan, &centers);
3631
3632 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3633 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3634 break;
3635 }
3636
3637 match = ath9k_hw_get_lower_upper_index((u8)
3638 FREQ2FBIN(centers.
3639 synth_center,
3640 IS_CHAN_2GHZ
3641 (chan)), bChans,
3642 numPiers, &idxL, &idxR);
3643
3644 if (match) {
3645 for (i = 0; i < numXpdGains; i++) {
3646 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3647 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3648 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3649 pRawDataSet[idxL].
3650 pwrPdg[i],
3651 pRawDataSet[idxL].
3652 vpdPdg[i],
3653 AR5416_PD_GAIN_ICEPTS,
3654 vpdTableI[i]);
3655 }
3656 } else {
3657 for (i = 0; i < numXpdGains; i++) {
3658 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3659 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3660 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3661 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3662
3663 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3664
3665 maxPwrT4[i] =
3666 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3667 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3668
3669
3670 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3671 pPwrL, pVpdL,
3672 AR5416_PD_GAIN_ICEPTS,
3673 vpdTableL[i]);
3674 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3675 pPwrR, pVpdR,
3676 AR5416_PD_GAIN_ICEPTS,
3677 vpdTableR[i]);
3678
3679 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3680 vpdTableI[i][j] =
3681 (u8) (ath9k_hw_interpolate
3682 ((u16)
3683 FREQ2FBIN(centers.
3684 synth_center,
3685 IS_CHAN_2GHZ
3686 (chan)),
3687 bChans[idxL],
3688 bChans[idxR], vpdTableL[i]
3689 [j], vpdTableR[i]
3690 [j]));
3691 }
3692 }
3693 }
3694
3695 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3696
3697 k = 0;
3698 for (i = 0; i < numXpdGains; i++) {
3699 if (i == (numXpdGains - 1))
3700 pPdGainBoundaries[i] =
3701 (u16) (maxPwrT4[i] / 2);
3702 else
3703 pPdGainBoundaries[i] =
3704 (u16) ((maxPwrT4[i] +
3705 minPwrT4[i + 1]) / 4);
3706
3707 pPdGainBoundaries[i] =
3708 min((u16) AR5416_MAX_RATE_POWER,
3709 pPdGainBoundaries[i]);
3710
3711 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3712 minDelta = pPdGainBoundaries[0] - 23;
3713 pPdGainBoundaries[0] = 23;
3714 } else {
3715 minDelta = 0;
3716 }
3717
3718 if (i == 0) {
3719 if (AR_SREV_9280_10_OR_LATER(ah))
3720 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3721 else
3722 ss = 0;
3723 } else {
3724 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3725 (minPwrT4[i] / 2)) -
3726 tPdGainOverlap + 1 + minDelta);
3727 }
3728 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3729 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3730
3731 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3732 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3733 pPDADCValues[k++] =
3734 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3735 ss++;
3736 }
3737
3738 sizeCurrVpdTable =
3739 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3740 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3741 (minPwrT4[i] / 2));
3742 maxIndex = (tgtIndex <
3743 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3744
3745 while ((ss < maxIndex)
3746 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3747 pPDADCValues[k++] = vpdTableI[i][ss++];
3748 }
3749
3750 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3751 vpdTableI[i][sizeCurrVpdTable - 2]);
3752 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3753
3754 if (tgtIndex > maxIndex) {
3755 while ((ss <= tgtIndex)
3756 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3757 tmpVal = (int16_t) ((vpdTableI[i]
3758 [sizeCurrVpdTable -
3759 1] + (ss - maxIndex +
3760 1) * vpdStep));
3761 pPDADCValues[k++] = (u8) ((tmpVal >
3762 255) ? 255 : tmpVal);
3763 ss++;
3764 }
3765 }
3766 }
3767
3768 while (i < AR5416_PD_GAINS_IN_MASK) {
3769 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3770 i++;
3771 }
3772
3773 while (k < AR5416_NUM_PDADC_VALUES) {
3774 pPDADCValues[k] = pPDADCValues[k - 1];
3775 k++;
3776 }
3777 return;
3778}
3779
3780static inline bool
3781ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3782 struct ar5416_eeprom *pEepData,
3783 struct ath9k_channel *chan,
3784 int16_t *pTxPowerIndexOffset)
3785{
3786 struct cal_data_per_freq *pRawDataset;
3787 u8 *pCalBChans = NULL;
3788 u16 pdGainOverlap_t2;
3789 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3790 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3791 u16 numPiers, i, j;
3792 int16_t tMinCalPower;
3793 u16 numXpdGain, xpdMask;
3794 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3795 u32 reg32, regOffset, regChainOffset;
3796 int16_t modalIdx;
3797 struct ath_hal_5416 *ahp = AH5416(ah);
3798
3799 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3800 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3801
3802 if ((pEepData->baseEepHeader.
3803 version & AR5416_EEP_VER_MINOR_MASK) >=
3804 AR5416_EEP_MINOR_VER_2) {
3805 pdGainOverlap_t2 =
3806 pEepData->modalHeader[modalIdx].pdGainOverlap;
3807 } else {
3808 pdGainOverlap_t2 =
3809 (u16) (MS
3810 (REG_READ(ah, AR_PHY_TPCRG5),
3811 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3812 }
3813
3814 if (IS_CHAN_2GHZ(chan)) {
3815 pCalBChans = pEepData->calFreqPier2G;
3816 numPiers = AR5416_NUM_2G_CAL_PIERS;
3817 } else {
3818 pCalBChans = pEepData->calFreqPier5G;
3819 numPiers = AR5416_NUM_5G_CAL_PIERS;
3820 }
3821
3822 numXpdGain = 0;
3823
3824 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3825 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3826 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3827 break;
3828 xpdGainValues[numXpdGain] =
3829 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3830 numXpdGain++;
3831 }
3832 }
3833
3834 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3835 (numXpdGain - 1) & 0x3);
3836 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3837 xpdGainValues[0]);
3838 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3839 xpdGainValues[1]);
3840 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3841 xpdGainValues[2]);
3842
3843 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3844 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3845 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3846 && (i != 0)) {
3847 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3848 } else
3849 regChainOffset = i * 0x1000;
3850 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3851 if (IS_CHAN_2GHZ(chan))
3852 pRawDataset = pEepData->calPierData2G[i];
3853 else
3854 pRawDataset = pEepData->calPierData5G[i];
3855
3856 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3857 pRawDataset,
3858 pCalBChans,
3859 numPiers,
3860 pdGainOverlap_t2,
3861 &tMinCalPower,
3862 gainBoundaries,
3863 pdadcValues,
3864 numXpdGain);
3865
3866 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3867
3868 REG_WRITE(ah,
3869 AR_PHY_TPCRG5 + regChainOffset,
3870 SM(pdGainOverlap_t2,
3871 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3872 | SM(gainBoundaries[0],
3873 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3874 | SM(gainBoundaries[1],
3875 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3876 | SM(gainBoundaries[2],
3877 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3878 | SM(gainBoundaries[3],
3879 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3880 }
3881
3882 regOffset =
3883 AR_PHY_BASE + (672 << 2) + regChainOffset;
3884 for (j = 0; j < 32; j++) {
3885 reg32 =
3886 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3887 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3888 8) | ((pdadcValues[4 * j + 2] &
3889 0xFF) << 16) |
3890 ((pdadcValues[4 * j + 3] & 0xFF) <<
3891 24);
3892 REG_WRITE(ah, regOffset, reg32);
3893
3894 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3895 "PDADC (%d,%4x): %4.4x %8.8x\n",
3896 i, regChainOffset, regOffset,
3897 reg32);
3898 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3899 "PDADC: Chain %d | PDADC %3d Value %3d | "
3900 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3901 "PDADC %3d Value %3d |\n",
3902 i, 4 * j, pdadcValues[4 * j],
3903 4 * j + 1, pdadcValues[4 * j + 1],
3904 4 * j + 2, pdadcValues[4 * j + 2],
3905 4 * j + 3,
3906 pdadcValues[4 * j + 3]);
3907
3908 regOffset += 4;
3909 }
3910 }
3911 }
3912 *pTxPowerIndexOffset = 0;
3913
3914 return true;
3915}
3916
3917void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3918{
3919 struct ath_hal_5416 *ahp = AH5416(ah);
3920 u8 i;
3921
3922 if (ah->ah_isPciExpress != true)
3923 return;
3924
3925 if (ah->ah_config.pcie_powersave_enable == 2)
3926 return;
3927
3928 if (restore)
3929 return;
3930
3931 if (AR_SREV_9280_20_OR_LATER(ah)) {
3932 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3933 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3934 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3935 }
3936 udelay(1000);
3937 } else if (AR_SREV_9280(ah)
3938 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3939 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3940 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3941
3942 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3943 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3944 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3945
3946 if (ah->ah_config.pcie_clock_req)
3947 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3948 else
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3950
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3953 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3954
3955 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3956
3957 udelay(1000);
3958 } else {
3959 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3960 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3961 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3962 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3963 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3964 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3965 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3966 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3967 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3968 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3969 }
3970
3971 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3972
3973 if (ah->ah_config.pcie_waen) {
3974 REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
3975 } else {
3976 if (AR_SREV_9280(ah))
3977 REG_WRITE(ah, AR_WA, 0x0040073f);
3978 else
3979 REG_WRITE(ah, AR_WA, 0x0000073f);
3980 }
3981}
3982
3983static inline void
3984ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3985 struct ath9k_channel *chan,
3986 struct cal_target_power_leg *powInfo,
3987 u16 numChannels,
3988 struct cal_target_power_leg *pNewPower,
3989 u16 numRates,
3990 bool isExtTarget)
3991{
3992 u16 clo, chi;
3993 int i;
3994 int matchIndex = -1, lowIndex = -1;
3995 u16 freq;
3996 struct chan_centers centers;
3997
3998 ath9k_hw_get_channel_centers(ah, chan, &centers);
3999 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
4000
4001 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
4002 IS_CHAN_2GHZ(chan))) {
4003 matchIndex = 0;
4004 } else {
4005 for (i = 0; (i < numChannels)
4006 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4007 if (freq ==
4008 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4009 IS_CHAN_2GHZ(chan))) {
4010 matchIndex = i;
4011 break;
4012 } else if ((freq <
4013 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4014 IS_CHAN_2GHZ(chan)))
4015 && (freq >
4016 ath9k_hw_fbin2freq(powInfo[i - 1].
4017 bChannel,
4018 IS_CHAN_2GHZ
4019 (chan)))) {
4020 lowIndex = i - 1;
4021 break;
4022 }
4023 }
4024 if ((matchIndex == -1) && (lowIndex == -1))
4025 matchIndex = i - 1;
4026 }
4027
4028 if (matchIndex != -1) {
4029 *pNewPower = powInfo[matchIndex];
4030 } else {
4031 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4032 IS_CHAN_2GHZ(chan));
4033 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4034 IS_CHAN_2GHZ(chan));
4035
4036 for (i = 0; i < numRates; i++) {
4037 pNewPower->tPow2x[i] =
4038 (u8) ath9k_hw_interpolate(freq, clo, chi,
4039 powInfo
4040 [lowIndex].
4041 tPow2x[i],
4042 powInfo
4043 [lowIndex +
4044 1].tPow2x[i]);
4045 }
4046 }
4047}
4048
4049static inline void
4050ath9k_hw_get_target_powers(struct ath_hal *ah,
4051 struct ath9k_channel *chan,
4052 struct cal_target_power_ht *powInfo,
4053 u16 numChannels,
4054 struct cal_target_power_ht *pNewPower,
4055 u16 numRates,
4056 bool isHt40Target)
4057{
4058 u16 clo, chi;
4059 int i;
4060 int matchIndex = -1, lowIndex = -1;
4061 u16 freq;
4062 struct chan_centers centers;
4063
4064 ath9k_hw_get_channel_centers(ah, chan, &centers);
4065 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4066
4067 if (freq <=
4068 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4069 matchIndex = 0;
4070 } else {
4071 for (i = 0; (i < numChannels)
4072 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4073 if (freq ==
4074 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4075 IS_CHAN_2GHZ(chan))) {
4076 matchIndex = i;
4077 break;
4078 } else
4079 if ((freq <
4080 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4081 IS_CHAN_2GHZ(chan)))
4082 && (freq >
4083 ath9k_hw_fbin2freq(powInfo[i - 1].
4084 bChannel,
4085 IS_CHAN_2GHZ
4086 (chan)))) {
4087 lowIndex = i - 1;
4088 break;
4089 }
4090 }
4091 if ((matchIndex == -1) && (lowIndex == -1))
4092 matchIndex = i - 1;
4093 }
4094
4095 if (matchIndex != -1) {
4096 *pNewPower = powInfo[matchIndex];
4097 } else {
4098 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4099 IS_CHAN_2GHZ(chan));
4100 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4101 IS_CHAN_2GHZ(chan));
4102
4103 for (i = 0; i < numRates; i++) {
4104 pNewPower->tPow2x[i] =
4105 (u8) ath9k_hw_interpolate(freq, clo, chi,
4106 powInfo
4107 [lowIndex].
4108 tPow2x[i],
4109 powInfo
4110 [lowIndex +
4111 1].tPow2x[i]);
4112 }
4113 }
4114}
4115
4116static inline u16
4117ath9k_hw_get_max_edge_power(u16 freq,
4118 struct cal_ctl_edges *pRdEdgesPower,
4119 bool is2GHz)
4120{
4121 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4122 int i;
4123
4124 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4125 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4126 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4127 is2GHz)) {
4128 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4129 break;
4130 } else if ((i > 0)
4131 && (freq <
4132 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4133 bChannel, is2GHz))) {
4134 if (ath9k_hw_fbin2freq
4135 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4136 && pRdEdgesPower[i - 1].flag) {
4137 twiceMaxEdgePower =
4138 pRdEdgesPower[i - 1].tPower;
4139 }
4140 break;
4141 }
4142 }
4143 return twiceMaxEdgePower;
4144}
4145
4146static inline bool
4147ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4148 struct ar5416_eeprom *pEepData,
4149 struct ath9k_channel *chan,
4150 int16_t *ratesArray,
4151 u16 cfgCtl,
4152 u8 AntennaReduction,
4153 u8 twiceMaxRegulatoryPower,
4154 u8 powerLimit)
4155{
4156 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4157 static const u16 tpScaleReductionTable[5] =
4158 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4159
4160 int i;
4161 int8_t twiceLargestAntenna;
4162 struct cal_ctl_data *rep;
4163 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4164 0, { 0, 0, 0, 0}
4165 };
4166 struct cal_target_power_leg targetPowerOfdmExt = {
4167 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4168 0, { 0, 0, 0, 0 }
4169 };
4170 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4171 0, {0, 0, 0, 0}
4172 };
4173 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4174 u16 ctlModesFor11a[] =
4175 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4176 u16 ctlModesFor11g[] =
4177 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4178 CTL_2GHT40
4179 };
4180 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4181 struct chan_centers centers;
4182 int tx_chainmask;
4183 u8 twiceMinEdgePower;
4184 struct ath_hal_5416 *ahp = AH5416(ah);
4185
4186 tx_chainmask = ahp->ah_txchainmask;
4187
4188 ath9k_hw_get_channel_centers(ah, chan, &centers);
4189
4190 twiceLargestAntenna = max(
4191 pEepData->modalHeader
4192 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4193 pEepData->modalHeader
4194 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4195
4196 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4197 pEepData->modalHeader
4198 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4199
4200 twiceLargestAntenna =
4201 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4202
4203 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4204
4205 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4206 maxRegAllowedPower -=
4207 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4208 }
4209
4210 scaledPower = min(powerLimit, maxRegAllowedPower);
4211
4212 switch (ar5416_get_ntxchains(tx_chainmask)) {
4213 case 1:
4214 break;
4215 case 2:
4216 scaledPower -=
4217 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4218 pwrDecreaseFor2Chain;
4219 break;
4220 case 3:
4221 scaledPower -=
4222 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4223 pwrDecreaseFor3Chain;
4224 break;
4225 }
4226
4227 scaledPower = max(0, (int32_t) scaledPower);
4228
4229 if (IS_CHAN_2GHZ(chan)) {
4230 numCtlModes =
4231 ARRAY_SIZE(ctlModesFor11g) -
4232 SUB_NUM_CTL_MODES_AT_2G_40;
4233 pCtlMode = ctlModesFor11g;
4234
4235 ath9k_hw_get_legacy_target_powers(ah, chan,
4236 pEepData->
4237 calTargetPowerCck,
4238 AR5416_NUM_2G_CCK_TARGET_POWERS,
4239 &targetPowerCck, 4,
4240 false);
4241 ath9k_hw_get_legacy_target_powers(ah, chan,
4242 pEepData->
4243 calTargetPower2G,
4244 AR5416_NUM_2G_20_TARGET_POWERS,
4245 &targetPowerOfdm, 4,
4246 false);
4247 ath9k_hw_get_target_powers(ah, chan,
4248 pEepData->calTargetPower2GHT20,
4249 AR5416_NUM_2G_20_TARGET_POWERS,
4250 &targetPowerHt20, 8, false);
4251
4252 if (IS_CHAN_HT40(chan)) {
4253 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4254 ath9k_hw_get_target_powers(ah, chan,
4255 pEepData->
4256 calTargetPower2GHT40,
4257 AR5416_NUM_2G_40_TARGET_POWERS,
4258 &targetPowerHt40, 8,
4259 true);
4260 ath9k_hw_get_legacy_target_powers(ah, chan,
4261 pEepData->
4262 calTargetPowerCck,
4263 AR5416_NUM_2G_CCK_TARGET_POWERS,
4264 &targetPowerCckExt,
4265 4, true);
4266 ath9k_hw_get_legacy_target_powers(ah, chan,
4267 pEepData->
4268 calTargetPower2G,
4269 AR5416_NUM_2G_20_TARGET_POWERS,
4270 &targetPowerOfdmExt,
4271 4, true);
4272 }
4273 } else {
4274
4275 numCtlModes =
4276 ARRAY_SIZE(ctlModesFor11a) -
4277 SUB_NUM_CTL_MODES_AT_5G_40;
4278 pCtlMode = ctlModesFor11a;
4279
4280 ath9k_hw_get_legacy_target_powers(ah, chan,
4281 pEepData->
4282 calTargetPower5G,
4283 AR5416_NUM_5G_20_TARGET_POWERS,
4284 &targetPowerOfdm, 4,
4285 false);
4286 ath9k_hw_get_target_powers(ah, chan,
4287 pEepData->calTargetPower5GHT20,
4288 AR5416_NUM_5G_20_TARGET_POWERS,
4289 &targetPowerHt20, 8, false);
4290
4291 if (IS_CHAN_HT40(chan)) {
4292 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4293 ath9k_hw_get_target_powers(ah, chan,
4294 pEepData->
4295 calTargetPower5GHT40,
4296 AR5416_NUM_5G_40_TARGET_POWERS,
4297 &targetPowerHt40, 8,
4298 true);
4299 ath9k_hw_get_legacy_target_powers(ah, chan,
4300 pEepData->
4301 calTargetPower5G,
4302 AR5416_NUM_5G_20_TARGET_POWERS,
4303 &targetPowerOfdmExt,
4304 4, true);
4305 }
4306 }
4307
4308 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4309 bool isHt40CtlMode =
4310 (pCtlMode[ctlMode] == CTL_5GHT40)
4311 || (pCtlMode[ctlMode] == CTL_2GHT40);
4312 if (isHt40CtlMode)
4313 freq = centers.synth_center;
4314 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4315 freq = centers.ext_center;
4316 else
4317 freq = centers.ctl_center;
4318
4319 if (ar5416_get_eep_ver(ahp) == 14
4320 && ar5416_get_eep_rev(ahp) <= 2)
4321 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4322
4323 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4324 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4325 "EXT_ADDITIVE %d\n",
4326 ctlMode, numCtlModes, isHt40CtlMode,
4327 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4328
4329 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4330 i++) {
4331 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4332 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4333 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4334 "chan %d\n",
4335 i, cfgCtl, pCtlMode[ctlMode],
4336 pEepData->ctlIndex[i], chan->channel);
4337
4338 if ((((cfgCtl & ~CTL_MODE_M) |
4339 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4340 pEepData->ctlIndex[i])
4341 ||
4342 (((cfgCtl & ~CTL_MODE_M) |
4343 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4344 ((pEepData->
4345 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4346 rep = &(pEepData->ctlData[i]);
4347
4348 twiceMinEdgePower =
4349 ath9k_hw_get_max_edge_power(freq,
4350 rep->
4351 ctlEdges
4352 [ar5416_get_ntxchains
4353 (tx_chainmask)
4354 - 1],
4355 IS_CHAN_2GHZ
4356 (chan));
4357
4358 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4359 " MATCH-EE_IDX %d: ch %d is2 %d "
4360 "2xMinEdge %d chainmask %d chains %d\n",
4361 i, freq, IS_CHAN_2GHZ(chan),
4362 twiceMinEdgePower, tx_chainmask,
4363 ar5416_get_ntxchains
4364 (tx_chainmask));
4365 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4366 twiceMaxEdgePower =
4367 min(twiceMaxEdgePower,
4368 twiceMinEdgePower);
4369 } else {
4370 twiceMaxEdgePower =
4371 twiceMinEdgePower;
4372 break;
4373 }
4374 }
4375 }
4376
4377 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4378
4379 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4380 " SEL-Min ctlMode %d pCtlMode %d "
4381 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4382 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4383 scaledPower, minCtlPower);
4384
4385 switch (pCtlMode[ctlMode]) {
4386 case CTL_11B:
4387 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4388 i++) {
4389 targetPowerCck.tPow2x[i] =
4390 min(targetPowerCck.tPow2x[i],
4391 minCtlPower);
4392 }
4393 break;
4394 case CTL_11A:
4395 case CTL_11G:
4396 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4397 i++) {
4398 targetPowerOfdm.tPow2x[i] =
4399 min(targetPowerOfdm.tPow2x[i],
4400 minCtlPower);
4401 }
4402 break;
4403 case CTL_5GHT20:
4404 case CTL_2GHT20:
4405 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4406 i++) {
4407 targetPowerHt20.tPow2x[i] =
4408 min(targetPowerHt20.tPow2x[i],
4409 minCtlPower);
4410 }
4411 break;
4412 case CTL_11B_EXT:
4413 targetPowerCckExt.tPow2x[0] =
4414 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4415 break;
4416 case CTL_11A_EXT:
4417 case CTL_11G_EXT:
4418 targetPowerOfdmExt.tPow2x[0] =
4419 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4420 break;
4421 case CTL_5GHT40:
4422 case CTL_2GHT40:
4423 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4424 i++) {
4425 targetPowerHt40.tPow2x[i] =
4426 min(targetPowerHt40.tPow2x[i],
4427 minCtlPower);
4428 }
4429 break;
4430 default:
4431 break;
4432 }
4433 }
4434
4435 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4436 ratesArray[rate18mb] = ratesArray[rate24mb] =
4437 targetPowerOfdm.tPow2x[0];
4438 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4439 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4440 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4441 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4442
4443 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4444 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4445
4446 if (IS_CHAN_2GHZ(chan)) {
4447 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4448 ratesArray[rate2s] = ratesArray[rate2l] =
4449 targetPowerCck.tPow2x[1];
4450 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4451 targetPowerCck.tPow2x[2];
4452 ;
4453 ratesArray[rate11s] = ratesArray[rate11l] =
4454 targetPowerCck.tPow2x[3];
4455 ;
4456 }
4457 if (IS_CHAN_HT40(chan)) {
4458 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4459 ratesArray[rateHt40_0 + i] =
4460 targetPowerHt40.tPow2x[i];
4461 }
4462 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4463 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4464 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4465 if (IS_CHAN_2GHZ(chan)) {
4466 ratesArray[rateExtCck] =
4467 targetPowerCckExt.tPow2x[0];
4468 }
4469 }
4470 return true;
4471}
4472
4473static int
4474ath9k_hw_set_txpower(struct ath_hal *ah,
4475 struct ar5416_eeprom *pEepData,
4476 struct ath9k_channel *chan,
4477 u16 cfgCtl,
4478 u8 twiceAntennaReduction,
4479 u8 twiceMaxRegulatoryPower,
4480 u8 powerLimit)
4481{
4482 struct modal_eep_header *pModal =
4483 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4484 int16_t ratesArray[Ar5416RateSize];
4485 int16_t txPowerIndexOffset = 0;
4486 u8 ht40PowerIncForPdadc = 2;
4487 int i;
4488
4489 memset(ratesArray, 0, sizeof(ratesArray));
4490
4491 if ((pEepData->baseEepHeader.
4492 version & AR5416_EEP_VER_MINOR_MASK) >=
4493 AR5416_EEP_MINOR_VER_2) {
4494 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4495 }
4496
4497 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4498 &ratesArray[0], cfgCtl,
4499 twiceAntennaReduction,
4500 twiceMaxRegulatoryPower,
4501 powerLimit)) {
4502 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4503 "ath9k_hw_set_txpower: unable to set "
4504 "tx power per rate table\n");
4505 return -EIO;
4506 }
4507
4508 if (!ath9k_hw_set_power_cal_table
4509 (ah, pEepData, chan, &txPowerIndexOffset)) {
4510 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4511 "ath9k_hw_set_txpower: unable to set power table\n");
4512 return -EIO;
4513 }
4514
4515 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4516 ratesArray[i] =
4517 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4518 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4519 ratesArray[i] = AR5416_MAX_RATE_POWER;
4520 }
4521
4522 if (AR_SREV_9280_10_OR_LATER(ah)) {
4523 for (i = 0; i < Ar5416RateSize; i++)
4524 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4525 }
4526
4527 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4528 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4529 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4530 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4531 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4532 );
4533 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4534 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4535 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4536 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4537 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4538 );
4539
4540 if (IS_CHAN_2GHZ(chan)) {
4541 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4542 ATH9K_POW_SM(ratesArray[rate2s], 24)
4543 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4544 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4545 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4546 );
4547 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4548 ATH9K_POW_SM(ratesArray[rate11s], 24)
4549 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4550 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4551 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4552 );
4553 }
4554
4555 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4556 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4557 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4558 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4559 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4560 );
4561 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4562 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4563 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4564 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4565 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4566 );
4567
4568 if (IS_CHAN_HT40(chan)) {
4569 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4570 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4571 ht40PowerIncForPdadc, 24)
4572 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4573 ht40PowerIncForPdadc, 16)
4574 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4575 ht40PowerIncForPdadc, 8)
4576 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4577 ht40PowerIncForPdadc, 0)
4578 );
4579 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4580 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4581 ht40PowerIncForPdadc, 24)
4582 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4583 ht40PowerIncForPdadc, 16)
4584 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4585 ht40PowerIncForPdadc, 8)
4586 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4587 ht40PowerIncForPdadc, 0)
4588 );
4589
4590 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4591 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4592 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4593 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4594 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4595 );
4596 }
4597
4598 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4599 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4600 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4601 );
4602
4603 i = rate6mb;
4604 if (IS_CHAN_HT40(chan))
4605 i = rateHt40_0;
4606 else if (IS_CHAN_HT20(chan))
4607 i = rateHt20_0;
4608
4609 if (AR_SREV_9280_10_OR_LATER(ah))
4610 ah->ah_maxPowerLevel =
4611 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4612 else
4613 ah->ah_maxPowerLevel = ratesArray[i];
4614
4615 return 0;
4616}
4617
4618static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4619 u32 coef_scaled,
4620 u32 *coef_mantissa,
4621 u32 *coef_exponent)
4622{
4623 u32 coef_exp, coef_man;
4624
4625 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4626 if ((coef_scaled >> coef_exp) & 0x1)
4627 break;
4628
4629 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4630
4631 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4632
4633 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4634 *coef_exponent = coef_exp - 16;
4635}
4636
4637static void
4638ath9k_hw_set_delta_slope(struct ath_hal *ah,
4639 struct ath9k_channel *chan)
4640{
4641 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4642 u32 clockMhzScaled = 0x64000000;
4643 struct chan_centers centers;
4644
4645 if (IS_CHAN_HALF_RATE(chan))
4646 clockMhzScaled = clockMhzScaled >> 1;
4647 else if (IS_CHAN_QUARTER_RATE(chan))
4648 clockMhzScaled = clockMhzScaled >> 2;
4649
4650 ath9k_hw_get_channel_centers(ah, chan, &centers);
4651 coef_scaled = clockMhzScaled / centers.synth_center;
4652
4653 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4654 &ds_coef_exp);
4655
4656 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4657 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4658 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4659 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4660
4661 coef_scaled = (9 * coef_scaled) / 10;
4662
4663 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4664 &ds_coef_exp);
4665
4666 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4667 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4668 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4669 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4670}
4671
4672static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4673 struct ath9k_channel *chan)
4674{
4675 int bb_spur = AR_NO_SPUR;
4676 int freq;
4677 int bin, cur_bin;
4678 int bb_spur_off, spur_subchannel_sd;
4679 int spur_freq_sd;
4680 int spur_delta_phase;
4681 int denominator;
4682 int upper, lower, cur_vit_mask;
4683 int tmp, newVal;
4684 int i;
4685 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4686 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4687 };
4688 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4689 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4690 };
4691 int inc[4] = { 0, 100, 0, 0 };
4692 struct chan_centers centers;
4693
4694 int8_t mask_m[123];
4695 int8_t mask_p[123];
4696 int8_t mask_amt;
4697 int tmp_mask;
4698 int cur_bb_spur;
4699 bool is2GHz = IS_CHAN_2GHZ(chan);
4700
4701 memset(&mask_m, 0, sizeof(int8_t) * 123);
4702 memset(&mask_p, 0, sizeof(int8_t) * 123);
4703
4704 ath9k_hw_get_channel_centers(ah, chan, &centers);
4705 freq = centers.synth_center;
4706
4707 ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
4708 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4709 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4710
4711 if (is2GHz)
4712 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4713 else
4714 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4715
4716 if (AR_NO_SPUR == cur_bb_spur)
4717 break;
4718 cur_bb_spur = cur_bb_spur - freq;
4719
4720 if (IS_CHAN_HT40(chan)) {
4721 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4722 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4723 bb_spur = cur_bb_spur;
4724 break;
4725 }
4726 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4727 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4728 bb_spur = cur_bb_spur;
4729 break;
4730 }
4731 }
4732
4733 if (AR_NO_SPUR == bb_spur) {
4734 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4735 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4736 return;
4737 } else {
4738 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4739 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4740 }
4741
4742 bin = bb_spur * 320;
4743
4744 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4745
4746 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4747 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4748 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4749 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4750 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4751
4752 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4753 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4754 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4755 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4756 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4757 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4758
4759 if (IS_CHAN_HT40(chan)) {
4760 if (bb_spur < 0) {
4761 spur_subchannel_sd = 1;
4762 bb_spur_off = bb_spur + 10;
4763 } else {
4764 spur_subchannel_sd = 0;
4765 bb_spur_off = bb_spur - 10;
4766 }
4767 } else {
4768 spur_subchannel_sd = 0;
4769 bb_spur_off = bb_spur;
4770 }
4771
4772 if (IS_CHAN_HT40(chan))
4773 spur_delta_phase =
4774 ((bb_spur * 262144) /
4775 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4776 else
4777 spur_delta_phase =
4778 ((bb_spur * 524288) /
4779 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4780
4781 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4782 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4783
4784 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4785 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4786 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4787 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4788
4789 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4790 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4791
4792 cur_bin = -6000;
4793 upper = bin + 100;
4794 lower = bin - 100;
4795
4796 for (i = 0; i < 4; i++) {
4797 int pilot_mask = 0;
4798 int chan_mask = 0;
4799 int bp = 0;
4800 for (bp = 0; bp < 30; bp++) {
4801 if ((cur_bin > lower) && (cur_bin < upper)) {
4802 pilot_mask = pilot_mask | 0x1 << bp;
4803 chan_mask = chan_mask | 0x1 << bp;
4804 }
4805 cur_bin += 100;
4806 }
4807 cur_bin += inc[i];
4808 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4809 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4810 }
4811
4812 cur_vit_mask = 6100;
4813 upper = bin + 120;
4814 lower = bin - 120;
4815
4816 for (i = 0; i < 123; i++) {
4817 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
4818
4819 /* workaround for gcc bug #37014 */
4820 volatile int tmp = abs(cur_vit_mask - bin);
4821
4822 if (tmp < 75)
4823 mask_amt = 1;
4824 else
4825 mask_amt = 0;
4826 if (cur_vit_mask < 0)
4827 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4828 else
4829 mask_p[cur_vit_mask / 100] = mask_amt;
4830 }
4831 cur_vit_mask -= 100;
4832 }
4833
4834 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4835 | (mask_m[48] << 26) | (mask_m[49] << 24)
4836 | (mask_m[50] << 22) | (mask_m[51] << 20)
4837 | (mask_m[52] << 18) | (mask_m[53] << 16)
4838 | (mask_m[54] << 14) | (mask_m[55] << 12)
4839 | (mask_m[56] << 10) | (mask_m[57] << 8)
4840 | (mask_m[58] << 6) | (mask_m[59] << 4)
4841 | (mask_m[60] << 2) | (mask_m[61] << 0);
4842 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4843 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4844
4845 tmp_mask = (mask_m[31] << 28)
4846 | (mask_m[32] << 26) | (mask_m[33] << 24)
4847 | (mask_m[34] << 22) | (mask_m[35] << 20)
4848 | (mask_m[36] << 18) | (mask_m[37] << 16)
4849 | (mask_m[48] << 14) | (mask_m[39] << 12)
4850 | (mask_m[40] << 10) | (mask_m[41] << 8)
4851 | (mask_m[42] << 6) | (mask_m[43] << 4)
4852 | (mask_m[44] << 2) | (mask_m[45] << 0);
4853 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4854 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4855
4856 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4857 | (mask_m[18] << 26) | (mask_m[18] << 24)
4858 | (mask_m[20] << 22) | (mask_m[20] << 20)
4859 | (mask_m[22] << 18) | (mask_m[22] << 16)
4860 | (mask_m[24] << 14) | (mask_m[24] << 12)
4861 | (mask_m[25] << 10) | (mask_m[26] << 8)
4862 | (mask_m[27] << 6) | (mask_m[28] << 4)
4863 | (mask_m[29] << 2) | (mask_m[30] << 0);
4864 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4865 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4866
4867 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4868 | (mask_m[2] << 26) | (mask_m[3] << 24)
4869 | (mask_m[4] << 22) | (mask_m[5] << 20)
4870 | (mask_m[6] << 18) | (mask_m[7] << 16)
4871 | (mask_m[8] << 14) | (mask_m[9] << 12)
4872 | (mask_m[10] << 10) | (mask_m[11] << 8)
4873 | (mask_m[12] << 6) | (mask_m[13] << 4)
4874 | (mask_m[14] << 2) | (mask_m[15] << 0);
4875 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4876 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4877
4878 tmp_mask = (mask_p[15] << 28)
4879 | (mask_p[14] << 26) | (mask_p[13] << 24)
4880 | (mask_p[12] << 22) | (mask_p[11] << 20)
4881 | (mask_p[10] << 18) | (mask_p[9] << 16)
4882 | (mask_p[8] << 14) | (mask_p[7] << 12)
4883 | (mask_p[6] << 10) | (mask_p[5] << 8)
4884 | (mask_p[4] << 6) | (mask_p[3] << 4)
4885 | (mask_p[2] << 2) | (mask_p[1] << 0);
4886 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4887 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4888
4889 tmp_mask = (mask_p[30] << 28)
4890 | (mask_p[29] << 26) | (mask_p[28] << 24)
4891 | (mask_p[27] << 22) | (mask_p[26] << 20)
4892 | (mask_p[25] << 18) | (mask_p[24] << 16)
4893 | (mask_p[23] << 14) | (mask_p[22] << 12)
4894 | (mask_p[21] << 10) | (mask_p[20] << 8)
4895 | (mask_p[19] << 6) | (mask_p[18] << 4)
4896 | (mask_p[17] << 2) | (mask_p[16] << 0);
4897 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4898 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4899
4900 tmp_mask = (mask_p[45] << 28)
4901 | (mask_p[44] << 26) | (mask_p[43] << 24)
4902 | (mask_p[42] << 22) | (mask_p[41] << 20)
4903 | (mask_p[40] << 18) | (mask_p[39] << 16)
4904 | (mask_p[38] << 14) | (mask_p[37] << 12)
4905 | (mask_p[36] << 10) | (mask_p[35] << 8)
4906 | (mask_p[34] << 6) | (mask_p[33] << 4)
4907 | (mask_p[32] << 2) | (mask_p[31] << 0);
4908 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4909 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4910
4911 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4912 | (mask_p[59] << 26) | (mask_p[58] << 24)
4913 | (mask_p[57] << 22) | (mask_p[56] << 20)
4914 | (mask_p[55] << 18) | (mask_p[54] << 16)
4915 | (mask_p[53] << 14) | (mask_p[52] << 12)
4916 | (mask_p[51] << 10) | (mask_p[50] << 8)
4917 | (mask_p[49] << 6) | (mask_p[48] << 4)
4918 | (mask_p[47] << 2) | (mask_p[46] << 0);
4919 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4920 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4921}
4922
4923static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4924 struct ath9k_channel *chan)
4925{
4926 int bb_spur = AR_NO_SPUR;
4927 int bin, cur_bin;
4928 int spur_freq_sd;
4929 int spur_delta_phase;
4930 int denominator;
4931 int upper, lower, cur_vit_mask;
4932 int tmp, new;
4933 int i;
4934 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4935 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4936 };
4937 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4938 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4939 };
4940 int inc[4] = { 0, 100, 0, 0 };
4941
4942 int8_t mask_m[123];
4943 int8_t mask_p[123];
4944 int8_t mask_amt;
4945 int tmp_mask;
4946 int cur_bb_spur;
4947 bool is2GHz = IS_CHAN_2GHZ(chan);
4948
4949 memset(&mask_m, 0, sizeof(int8_t) * 123);
4950 memset(&mask_p, 0, sizeof(int8_t) * 123);
4951
4952 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4953 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4954 if (AR_NO_SPUR == cur_bb_spur)
4955 break;
4956 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4957 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4958 bb_spur = cur_bb_spur;
4959 break;
4960 }
4961 }
4962
4963 if (AR_NO_SPUR == bb_spur)
4964 return;
4965
4966 bin = bb_spur * 32;
4967
4968 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4969 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4970 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4971 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4972 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4973
4974 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4975
4976 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4977 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4978 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4979 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4980 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4981 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4982
4983 spur_delta_phase = ((bb_spur * 524288) / 100) &
4984 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4985
4986 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4987 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4988
4989 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4990 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4991 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4992 REG_WRITE(ah, AR_PHY_TIMING11, new);
4993
4994 cur_bin = -6000;
4995 upper = bin + 100;
4996 lower = bin - 100;
4997
4998 for (i = 0; i < 4; i++) {
4999 int pilot_mask = 0;
5000 int chan_mask = 0;
5001 int bp = 0;
5002 for (bp = 0; bp < 30; bp++) {
5003 if ((cur_bin > lower) && (cur_bin < upper)) {
5004 pilot_mask = pilot_mask | 0x1 << bp;
5005 chan_mask = chan_mask | 0x1 << bp;
5006 }
5007 cur_bin += 100;
5008 }
5009 cur_bin += inc[i];
5010 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
5011 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
5012 }
5013
5014 cur_vit_mask = 6100;
5015 upper = bin + 120;
5016 lower = bin - 120;
5017
5018 for (i = 0; i < 123; i++) {
5019 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5020
5021 /* workaround for gcc bug #37014 */
5022 volatile int tmp = abs(cur_vit_mask - bin);
5023
5024 if (tmp < 75)
5025 mask_amt = 1;
5026 else
5027 mask_amt = 0;
5028 if (cur_vit_mask < 0)
5029 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5030 else
5031 mask_p[cur_vit_mask / 100] = mask_amt;
5032 }
5033 cur_vit_mask -= 100;
5034 }
5035
5036 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5037 | (mask_m[48] << 26) | (mask_m[49] << 24)
5038 | (mask_m[50] << 22) | (mask_m[51] << 20)
5039 | (mask_m[52] << 18) | (mask_m[53] << 16)
5040 | (mask_m[54] << 14) | (mask_m[55] << 12)
5041 | (mask_m[56] << 10) | (mask_m[57] << 8)
5042 | (mask_m[58] << 6) | (mask_m[59] << 4)
5043 | (mask_m[60] << 2) | (mask_m[61] << 0);
5044 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5045 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5046
5047 tmp_mask = (mask_m[31] << 28)
5048 | (mask_m[32] << 26) | (mask_m[33] << 24)
5049 | (mask_m[34] << 22) | (mask_m[35] << 20)
5050 | (mask_m[36] << 18) | (mask_m[37] << 16)
5051 | (mask_m[48] << 14) | (mask_m[39] << 12)
5052 | (mask_m[40] << 10) | (mask_m[41] << 8)
5053 | (mask_m[42] << 6) | (mask_m[43] << 4)
5054 | (mask_m[44] << 2) | (mask_m[45] << 0);
5055 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5056 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5057
5058 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5059 | (mask_m[18] << 26) | (mask_m[18] << 24)
5060 | (mask_m[20] << 22) | (mask_m[20] << 20)
5061 | (mask_m[22] << 18) | (mask_m[22] << 16)
5062 | (mask_m[24] << 14) | (mask_m[24] << 12)
5063 | (mask_m[25] << 10) | (mask_m[26] << 8)
5064 | (mask_m[27] << 6) | (mask_m[28] << 4)
5065 | (mask_m[29] << 2) | (mask_m[30] << 0);
5066 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5067 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5068
5069 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5070 | (mask_m[2] << 26) | (mask_m[3] << 24)
5071 | (mask_m[4] << 22) | (mask_m[5] << 20)
5072 | (mask_m[6] << 18) | (mask_m[7] << 16)
5073 | (mask_m[8] << 14) | (mask_m[9] << 12)
5074 | (mask_m[10] << 10) | (mask_m[11] << 8)
5075 | (mask_m[12] << 6) | (mask_m[13] << 4)
5076 | (mask_m[14] << 2) | (mask_m[15] << 0);
5077 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5078 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5079
5080 tmp_mask = (mask_p[15] << 28)
5081 | (mask_p[14] << 26) | (mask_p[13] << 24)
5082 | (mask_p[12] << 22) | (mask_p[11] << 20)
5083 | (mask_p[10] << 18) | (mask_p[9] << 16)
5084 | (mask_p[8] << 14) | (mask_p[7] << 12)
5085 | (mask_p[6] << 10) | (mask_p[5] << 8)
5086 | (mask_p[4] << 6) | (mask_p[3] << 4)
5087 | (mask_p[2] << 2) | (mask_p[1] << 0);
5088 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5089 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5090
5091 tmp_mask = (mask_p[30] << 28)
5092 | (mask_p[29] << 26) | (mask_p[28] << 24)
5093 | (mask_p[27] << 22) | (mask_p[26] << 20)
5094 | (mask_p[25] << 18) | (mask_p[24] << 16)
5095 | (mask_p[23] << 14) | (mask_p[22] << 12)
5096 | (mask_p[21] << 10) | (mask_p[20] << 8)
5097 | (mask_p[19] << 6) | (mask_p[18] << 4)
5098 | (mask_p[17] << 2) | (mask_p[16] << 0);
5099 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5100 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5101
5102 tmp_mask = (mask_p[45] << 28)
5103 | (mask_p[44] << 26) | (mask_p[43] << 24)
5104 | (mask_p[42] << 22) | (mask_p[41] << 20)
5105 | (mask_p[40] << 18) | (mask_p[39] << 16)
5106 | (mask_p[38] << 14) | (mask_p[37] << 12)
5107 | (mask_p[36] << 10) | (mask_p[35] << 8)
5108 | (mask_p[34] << 6) | (mask_p[33] << 4)
5109 | (mask_p[32] << 2) | (mask_p[31] << 0);
5110 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5111 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5112
5113 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5114 | (mask_p[59] << 26) | (mask_p[58] << 24)
5115 | (mask_p[57] << 22) | (mask_p[56] << 20)
5116 | (mask_p[55] << 18) | (mask_p[54] << 16)
5117 | (mask_p[53] << 14) | (mask_p[52] << 12)
5118 | (mask_p[51] << 10) | (mask_p[50] << 8)
5119 | (mask_p[49] << 6) | (mask_p[48] << 4)
5120 | (mask_p[47] << 2) | (mask_p[46] << 0);
5121 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5122 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5123}
5124
5125static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5126{
5127 struct ath_hal_5416 *ahp = AH5416(ah);
5128 int rx_chainmask, tx_chainmask;
5129
5130 rx_chainmask = ahp->ah_rxchainmask;
5131 tx_chainmask = ahp->ah_txchainmask;
5132
5133 switch (rx_chainmask) {
5134 case 0x5:
5135 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5136 AR_PHY_SWAP_ALT_CHAIN);
5137 case 0x3:
5138 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5139 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5140 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5141 break;
5142 }
5143 case 0x1:
5144 case 0x2:
5145 if (!AR_SREV_9280(ah))
5146 break;
5147 case 0x7:
5148 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5149 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5150 break;
5151 default:
5152 break;
5153 }
5154
5155 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5156 if (tx_chainmask == 0x5) {
5157 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5158 AR_PHY_SWAP_ALT_CHAIN);
5159 }
5160 if (AR_SREV_9100(ah))
5161 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5162 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5163}
5164
5165static void ath9k_hw_set_addac(struct ath_hal *ah,
5166 struct ath9k_channel *chan)
5167{
5168 struct modal_eep_header *pModal;
5169 struct ath_hal_5416 *ahp = AH5416(ah);
5170 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5171 u8 biaslevel;
5172
5173 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5174 return;
5175
5176 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5177 return;
5178
5179 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5180
5181 if (pModal->xpaBiasLvl != 0xff) {
5182 biaslevel = pModal->xpaBiasLvl;
5183 } else {
5184
5185 u16 resetFreqBin, freqBin, freqCount = 0;
5186 struct chan_centers centers;
5187
5188 ath9k_hw_get_channel_centers(ah, chan, &centers);
5189
5190 resetFreqBin =
5191 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5192 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5193 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5194
5195 freqCount++;
5196
5197 while (freqCount < 3) {
5198 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5199 break;
5200
5201 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5202 if (resetFreqBin >= freqBin) {
5203 biaslevel =
5204 (u8) (pModal->
5205 xpaBiasLvlFreq[freqCount]
5206 >> 14);
5207 } else {
5208 break;
5209 }
5210 freqCount++;
5211 }
5212 }
5213
5214 if (IS_CHAN_2GHZ(chan)) {
5215 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5216 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5217 << 3;
5218 } else {
5219 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5220 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5221 << 6;
5222 }
5223}
5224
5225static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5226{
5227 if (ah->ah_curchan != NULL)
5228 return clks /
5229 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5230 else
5231 return clks / CLOCK_RATE[ATH9K_MODE_11B];
5232}
5233
5234static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5235{
5236 struct ath9k_channel *chan = ah->ah_curchan;
5237
5238 if (chan && IS_CHAN_HT40(chan))
5239 return ath9k_hw_mac_usec(ah, clks) / 2;
5240 else
5241 return ath9k_hw_mac_usec(ah, clks);
5242}
5243
5244static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5245{
5246 if (ah->ah_curchan != NULL)
5247 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5248 ah->ah_curchan)];
5249 else
5250 return usecs * CLOCK_RATE[ATH9K_MODE_11B];
5251}
5252
5253static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5254{
5255 struct ath9k_channel *chan = ah->ah_curchan;
5256
5257 if (chan && IS_CHAN_HT40(chan))
5258 return ath9k_hw_mac_clks(ah, usecs) * 2;
5259 else
5260 return ath9k_hw_mac_clks(ah, usecs);
5261}
5262
5263static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5264{
5265 struct ath_hal_5416 *ahp = AH5416(ah);
5266
5267 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5268 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5269 __func__, us);
5270 ahp->ah_acktimeout = (u32) -1;
5271 return false;
5272 } else {
5273 REG_RMW_FIELD(ah, AR_TIME_OUT,
5274 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5275 ahp->ah_acktimeout = us;
5276 return true;
5277 }
5278}
5279
5280static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5281{
5282 struct ath_hal_5416 *ahp = AH5416(ah);
5283
5284 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5285 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5286 __func__, us);
5287 ahp->ah_ctstimeout = (u32) -1;
5288 return false;
5289 } else {
5290 REG_RMW_FIELD(ah, AR_TIME_OUT,
5291 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5292 ahp->ah_ctstimeout = us;
5293 return true;
5294 }
5295}
5296static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5297 u32 tu)
5298{
5299 struct ath_hal_5416 *ahp = AH5416(ah);
5300
5301 if (tu > 0xFFFF) {
5302 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5303 "%s: bad global tx timeout %u\n", __func__, tu);
5304 ahp->ah_globaltxtimeout = (u32) -1;
5305 return false;
5306 } else {
5307 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5308 ahp->ah_globaltxtimeout = tu;
5309 return true;
5310 }
5311}
5312
5313bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5314{
5315 struct ath_hal_5416 *ahp = AH5416(ah);
5316
5317 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5318 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5319 __func__, us);
5320 ahp->ah_slottime = (u32) -1;
5321 return false;
5322 } else {
5323 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5324 ahp->ah_slottime = us;
5325 return true;
5326 }
5327}
5328
5329static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5330{
5331 struct ath_hal_5416 *ahp = AH5416(ah);
5332
5333 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5334 __func__, ahp->ah_miscMode);
5335 if (ahp->ah_miscMode != 0)
5336 REG_WRITE(ah, AR_PCU_MISC,
5337 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5338 if (ahp->ah_slottime != (u32) -1)
5339 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5340 if (ahp->ah_acktimeout != (u32) -1)
5341 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5342 if (ahp->ah_ctstimeout != (u32) -1)
5343 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5344 if (ahp->ah_globaltxtimeout != (u32) -1)
5345 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5346}
5347
5348static inline int
5349ath9k_hw_process_ini(struct ath_hal *ah,
5350 struct ath9k_channel *chan,
5351 enum ath9k_ht_macmode macmode)
5352{
5353 int i, regWrites = 0;
5354 struct ath_hal_5416 *ahp = AH5416(ah);
5355 u32 modesIndex, freqIndex;
5356 int status;
5357
5358 switch (chan->chanmode) {
5359 case CHANNEL_A:
5360 case CHANNEL_A_HT20:
5361 modesIndex = 1;
5362 freqIndex = 1;
5363 break;
5364 case CHANNEL_A_HT40PLUS:
5365 case CHANNEL_A_HT40MINUS:
5366 modesIndex = 2;
5367 freqIndex = 1;
5368 break;
5369 case CHANNEL_G:
5370 case CHANNEL_G_HT20:
5371 case CHANNEL_B:
5372 modesIndex = 4;
5373 freqIndex = 2;
5374 break;
5375 case CHANNEL_G_HT40PLUS:
5376 case CHANNEL_G_HT40MINUS:
5377 modesIndex = 3;
5378 freqIndex = 2;
5379 break;
5380
5381 default:
5382 return -EINVAL;
5383 }
5384
5385 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5386
5387 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5388
5389 ath9k_hw_set_addac(ah, chan);
5390
5391 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5392 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5393 } else {
5394 struct ar5416IniArray temp;
5395 u32 addacSize =
5396 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5397 ahp->ah_iniAddac.ia_columns;
5398
5399 memcpy(ahp->ah_addac5416_21,
5400 ahp->ah_iniAddac.ia_array, addacSize);
5401
5402 (ahp->ah_addac5416_21)[31 *
5403 ahp->ah_iniAddac.ia_columns + 1] = 0;
5404
5405 temp.ia_array = ahp->ah_addac5416_21;
5406 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5407 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5408 REG_WRITE_ARRAY(&temp, 1, regWrites);
5409 }
5410 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5411
5412 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5413 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5414 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5415
5416#ifdef CONFIG_SLOW_ANT_DIV
5417 if (ah->ah_devid == AR9280_DEVID_PCI)
5418 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5419 val);
5420#endif
5421
5422 REG_WRITE(ah, reg, val);
5423
5424 if (reg >= 0x7800 && reg < 0x78a0
5425 && ah->ah_config.analog_shiftreg) {
5426 udelay(100);
5427 }
5428
5429 DO_DELAY(regWrites);
5430 }
5431
5432 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5433 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5434 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5435
5436 REG_WRITE(ah, reg, val);
5437
5438 if (reg >= 0x7800 && reg < 0x78a0
5439 && ah->ah_config.analog_shiftreg) {
5440 udelay(100);
5441 }
5442
5443 DO_DELAY(regWrites);
5444 }
5445
5446 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5447
5448 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5449 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5450 regWrites);
5451 }
5452
5453 ath9k_hw_override_ini(ah, chan);
5454 ath9k_hw_set_regs(ah, chan, macmode);
5455 ath9k_hw_init_chain_masks(ah);
5456
5457 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5458 ath9k_regd_get_ctl(ah, chan),
5459 ath9k_regd_get_antenna_allowed(ah,
5460 chan),
5461 chan->maxRegTxPower * 2,
5462 min((u32) MAX_RATE_POWER,
5463 (u32) ah->ah_powerLimit));
5464 if (status != 0) {
5465 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5466 "%s: error init'ing transmit power\n", __func__);
5467 return -EIO;
5468 }
5469
5470 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5471 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5472 "%s: ar5416SetRfRegs failed\n", __func__);
5473 return -EIO;
5474 }
5475
5476 return 0;
5477}
5478
5479static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5480 struct hal_cal_list *currCal)
5481{
5482 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5483 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5484 currCal->calData->calCountMax);
5485
5486 switch (currCal->calData->calType) {
5487 case IQ_MISMATCH_CAL:
5488 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5489 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5490 "%s: starting IQ Mismatch Calibration\n",
5491 __func__);
5492 break;
5493 case ADC_GAIN_CAL:
5494 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5495 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5496 "%s: starting ADC Gain Calibration\n", __func__);
5497 break;
5498 case ADC_DC_CAL:
5499 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5500 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5501 "%s: starting ADC DC Calibration\n", __func__);
5502 break;
5503 case ADC_DC_INIT_CAL:
5504 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5505 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5506 "%s: starting Init ADC DC Calibration\n",
5507 __func__);
5508 break;
5509 }
5510
5511 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5512 AR_PHY_TIMING_CTRL4_DO_CAL);
5513}
5514
5515static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5516 struct hal_cal_list *currCal)
5517{
5518 struct ath_hal_5416 *ahp = AH5416(ah);
5519 int i;
5520
5521 ath9k_hw_setup_calibration(ah, currCal);
5522
5523 currCal->calState = CAL_RUNNING;
5524
5525 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5526 ahp->ah_Meas0.sign[i] = 0;
5527 ahp->ah_Meas1.sign[i] = 0;
5528 ahp->ah_Meas2.sign[i] = 0;
5529 ahp->ah_Meas3.sign[i] = 0;
5530 }
5531
5532 ahp->ah_CalSamples = 0;
5533}
5534
5535static inline void
5536ath9k_hw_per_calibration(struct ath_hal *ah,
5537 struct ath9k_channel *ichan,
5538 u8 rxchainmask,
5539 struct hal_cal_list *currCal,
5540 bool *isCalDone)
5541{
5542 struct ath_hal_5416 *ahp = AH5416(ah);
5543
5544 *isCalDone = false;
5545
5546 if (currCal->calState == CAL_RUNNING) {
5547 if (!(REG_READ(ah,
5548 AR_PHY_TIMING_CTRL4(0)) &
5549 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5550
5551 currCal->calData->calCollect(ah);
5552
5553 ahp->ah_CalSamples++;
5554
5555 if (ahp->ah_CalSamples >=
5556 currCal->calData->calNumSamples) {
5557 int i, numChains = 0;
5558 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5559 if (rxchainmask & (1 << i))
5560 numChains++;
5561 }
5562
5563 currCal->calData->calPostProc(ah,
5564 numChains);
5565
5566 ichan->CalValid |=
5567 currCal->calData->calType;
5568 currCal->calState = CAL_DONE;
5569 *isCalDone = true;
5570 } else {
5571 ath9k_hw_setup_calibration(ah, currCal);
5572 }
5573 }
5574 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5575 ath9k_hw_reset_calibration(ah, currCal);
5576 }
5577}
5578
5579static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5580 int init_cal_count)
5581{
5582 struct ath_hal_5416 *ahp = AH5416(ah);
5583 struct ath9k_channel ichan;
5584 bool isCalDone;
5585 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5586 const struct hal_percal_data *calData = currCal->calData;
5587 int i;
5588
5589 if (currCal == NULL)
5590 return false;
5591
5592 ichan.CalValid = 0;
5593
5594 for (i = 0; i < init_cal_count; i++) {
5595 ath9k_hw_reset_calibration(ah, currCal);
5596
5597 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5598 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5599 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5600 "%s: Cal %d failed to complete in 100ms.\n",
5601 __func__, calData->calType);
5602
5603 ahp->ah_cal_list = ahp->ah_cal_list_last =
5604 ahp->ah_cal_list_curr = NULL;
5605 return false;
5606 }
5607
5608 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5609 currCal, &isCalDone);
5610 if (!isCalDone) {
5611 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5612 "%s: Not able to run Init Cal %d.\n",
5613 __func__, calData->calType);
5614 }
5615 if (currCal->calNext) {
5616 currCal = currCal->calNext;
5617 calData = currCal->calData;
5618 }
5619 }
5620
5621 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5622 return true;
5623}
5624
5625static inline bool
5626ath9k_hw_channel_change(struct ath_hal *ah,
5627 struct ath9k_channel *chan,
5628 enum ath9k_ht_macmode macmode)
5629{
5630 u32 synthDelay, qnum;
5631 struct ath_hal_5416 *ahp = AH5416(ah);
5632
5633 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5634 if (ath9k_hw_numtxpending(ah, qnum)) {
5635 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5636 "%s: Transmit frames pending on queue %d\n",
5637 __func__, qnum);
5638 return false;
5639 }
5640 }
5641
5642 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5643 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5644 AR_PHY_RFBUS_GRANT_EN)) {
5645 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5646 "%s: Could not kill baseband RX\n", __func__);
5647 return false;
5648 }
5649
5650 ath9k_hw_set_regs(ah, chan, macmode);
5651
5652 if (AR_SREV_9280_10_OR_LATER(ah)) {
5653 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5654 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5655 "%s: failed to set channel\n", __func__);
5656 return false;
5657 }
5658 } else {
5659 if (!(ath9k_hw_set_channel(ah, chan))) {
5660 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5661 "%s: failed to set channel\n", __func__);
5662 return false;
5663 }
5664 }
5665
5666 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5667 ath9k_regd_get_ctl(ah, chan),
5668 ath9k_regd_get_antenna_allowed(ah, chan),
5669 chan->maxRegTxPower * 2,
5670 min((u32) MAX_RATE_POWER,
5671 (u32) ah->ah_powerLimit)) != 0) {
5672 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5673 "%s: error init'ing transmit power\n", __func__);
5674 return false;
5675 }
5676
5677 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5678 if (IS_CHAN_CCK(chan))
5679 synthDelay = (4 * synthDelay) / 22;
5680 else
5681 synthDelay /= 10;
5682
5683 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5684
5685 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5686
5687 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5688 ath9k_hw_set_delta_slope(ah, chan);
5689
5690 if (AR_SREV_9280_10_OR_LATER(ah))
5691 ath9k_hw_9280_spur_mitigate(ah, chan);
5692 else
5693 ath9k_hw_spur_mitigate(ah, chan);
5694
5695 if (!chan->oneTimeCalsDone)
5696 chan->oneTimeCalsDone = true;
5697
5698 return true;
5699}
5700
5701static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5702 struct ath9k_channel *chan)
5703{
5704 struct ath_hal_5416 *ahp = AH5416(ah);
5705
5706 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5707 return false;
5708
5709 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5710 return false;
5711
5712 ahp->ah_chipFullSleep = false;
5713
5714 ath9k_hw_init_pll(ah, chan);
5715
5716 ath9k_hw_set_rfmode(ah, chan);
5717
5718 return true;
5719}
5720
5721static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5722{
5723 u32 regval;
5724
5725 regval = REG_READ(ah, AR_AHB_MODE);
5726 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5727
5728 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5729 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5730
5731 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5732
5733 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5734 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5735
5736 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5737
5738 if (AR_SREV_9285(ah)) {
5739 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5740 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5741 } else {
5742 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5743 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5744 }
5745}
5746
5747bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5748{
5749 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5750 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5751 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5752 "%s: dma failed to stop in 10ms\n"
5753 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5754 __func__,
5755 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5756 return false;
5757 } else {
5758 return true;
5759 }
5760}
5761
5762void ath9k_hw_startpcureceive(struct ath_hal *ah)
5763{
5764 REG_CLR_BIT(ah, AR_DIAG_SW,
5765 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5766
5767 ath9k_enable_mib_counters(ah);
5768
5769 ath9k_ani_reset(ah);
5770}
5771
5772void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5773{
5774 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5775
5776 ath9k_hw_disable_mib_counters(ah);
5777}
5778
5779static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5780 struct ath9k_channel *chan,
5781 enum hal_cal_types calType)
5782{
5783 struct ath_hal_5416 *ahp = AH5416(ah);
5784 bool retval = false;
5785
5786 switch (calType & ahp->ah_suppCals) {
5787 case IQ_MISMATCH_CAL:
5788 if (!IS_CHAN_B(chan))
5789 retval = true;
5790 break;
5791 case ADC_GAIN_CAL:
5792 case ADC_DC_CAL:
5793 if (!IS_CHAN_B(chan)
5794 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5795 retval = true;
5796 break;
5797 }
5798
5799 return retval;
5800}
5801
5802static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5803 struct ath9k_channel *chan)
5804{
5805 struct ath_hal_5416 *ahp = AH5416(ah);
5806 struct ath9k_channel *ichan =
5807 ath9k_regd_check_channel(ah, chan);
5808
5809 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5810 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5811 AR_PHY_AGC_CONTROL_CAL);
5812
5813 if (!ath9k_hw_wait
5814 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5815 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5816 "%s: offset calibration failed to complete in 1ms; "
5817 "noisy environment?\n", __func__);
5818 return false;
5819 }
5820
5821 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5822 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5823 AR_PHY_AGC_CONTROL_NF);
5824
5825 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5826 NULL;
5827
5828 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5829 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5830 INIT_CAL(&ahp->ah_adcGainCalData);
5831 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5832 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5833 "%s: enabling ADC Gain Calibration.\n",
5834 __func__);
5835 }
5836 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5837 INIT_CAL(&ahp->ah_adcDcCalData);
5838 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5839 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5840 "%s: enabling ADC DC Calibration.\n",
5841 __func__);
5842 }
5843 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5844 INIT_CAL(&ahp->ah_iqCalData);
5845 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5846 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5847 "%s: enabling IQ Calibration.\n",
5848 __func__);
5849 }
5850
5851 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5852
5853 if (ahp->ah_cal_list_curr)
5854 ath9k_hw_reset_calibration(ah,
5855 ahp->ah_cal_list_curr);
5856 }
5857
5858 ichan->CalValid = 0;
5859
5860 return true;
5861}
5862
5863
5864bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5865 struct ath9k_channel *chan,
5866 enum ath9k_ht_macmode macmode,
5867 u8 txchainmask, u8 rxchainmask,
5868 enum ath9k_ht_extprotspacing extprotspacing,
5869 bool bChannelChange,
5870 int *status)
5871{
5872#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5873 u32 saveLedState;
5874 struct ath_hal_5416 *ahp = AH5416(ah);
5875 struct ath9k_channel *curchan = ah->ah_curchan;
5876 u32 saveDefAntenna;
5877 u32 macStaId1;
5878 int ecode;
5879 int i, rx_chainmask;
5880
5881 ahp->ah_extprotspacing = extprotspacing;
5882 ahp->ah_txchainmask = txchainmask;
5883 ahp->ah_rxchainmask = rxchainmask;
5884
5885 if (AR_SREV_9280(ah)) {
5886 ahp->ah_txchainmask &= 0x3;
5887 ahp->ah_rxchainmask &= 0x3;
5888 }
5889
5890 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5891 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5892 "%s: invalid channel %u/0x%x; no mapping\n",
5893 __func__, chan->channel, chan->channelFlags);
5894 FAIL(-EINVAL);
5895 }
5896
5897 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5898 return false;
5899
5900 if (curchan)
5901 ath9k_hw_getnf(ah, curchan);
5902
5903 if (bChannelChange &&
5904 (ahp->ah_chipFullSleep != true) &&
5905 (ah->ah_curchan != NULL) &&
5906 (chan->channel != ah->ah_curchan->channel) &&
5907 ((chan->channelFlags & CHANNEL_ALL) ==
5908 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5909 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5910 !IS_CHAN_A_5MHZ_SPACED(ah->
5911 ah_curchan)))) {
5912
5913 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5914 ath9k_hw_loadnf(ah, ah->ah_curchan);
5915 ath9k_hw_start_nfcal(ah);
5916 return true;
5917 }
5918 }
5919
5920 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5921 if (saveDefAntenna == 0)
5922 saveDefAntenna = 1;
5923
5924 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5925
5926 saveLedState = REG_READ(ah, AR_CFG_LED) &
5927 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5928 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5929
5930 ath9k_hw_mark_phy_inactive(ah);
5931
5932 if (!ath9k_hw_chip_reset(ah, chan)) {
5933 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5934 __func__);
5935 FAIL(-EIO);
5936 }
5937
5938 if (AR_SREV_9280(ah)) {
5939 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5940 AR_GPIO_JTAG_DISABLE);
5941
5942 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
5943 if (IS_CHAN_5GHZ(chan))
5944 ath9k_hw_set_gpio(ah, 9, 0);
5945 else
5946 ath9k_hw_set_gpio(ah, 9, 1);
5947 }
5948 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5949 }
5950
5951 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5952 if (ecode != 0)
5953 goto bad;
5954
5955 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5956 ath9k_hw_set_delta_slope(ah, chan);
5957
5958 if (AR_SREV_9280_10_OR_LATER(ah))
5959 ath9k_hw_9280_spur_mitigate(ah, chan);
5960 else
5961 ath9k_hw_spur_mitigate(ah, chan);
5962
5963 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5964 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5965 "%s: error setting board options\n", __func__);
5966 FAIL(-EIO);
5967 }
5968
5969 ath9k_hw_decrease_chain_power(ah, chan);
5970
5971 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5972 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5973 | macStaId1
5974 | AR_STA_ID1_RTS_USE_DEF
5975 | (ah->ah_config.
5976 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
5977 | ahp->ah_staId1Defaults);
5978 ath9k_hw_set_operating_mode(ah, opmode);
5979
5980 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5981 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5982
5983 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5984
5985 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5986 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5987 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5988
5989 REG_WRITE(ah, AR_ISR, ~0);
5990
5991 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5992
5993 if (AR_SREV_9280_10_OR_LATER(ah)) {
5994 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5995 FAIL(-EIO);
5996 } else {
5997 if (!(ath9k_hw_set_channel(ah, chan)))
5998 FAIL(-EIO);
5999 }
6000
6001 for (i = 0; i < AR_NUM_DCU; i++)
6002 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
6003
6004 ahp->ah_intrTxqs = 0;
6005 for (i = 0; i < ah->ah_caps.total_queues; i++)
6006 ath9k_hw_resettxqueue(ah, i);
6007
6008 ath9k_hw_init_interrupt_masks(ah, opmode);
6009 ath9k_hw_init_qos(ah);
6010
6011 ath9k_hw_init_user_settings(ah);
6012
6013 ah->ah_opmode = opmode;
6014
6015 REG_WRITE(ah, AR_STA_ID1,
6016 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6017
6018 ath9k_hw_set_dma(ah);
6019
6020 REG_WRITE(ah, AR_OBS, 8);
6021
6022 if (ahp->ah_intrMitigation) {
6023
6024 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6025 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6026 }
6027
6028 ath9k_hw_init_bb(ah, chan);
6029
6030 if (!ath9k_hw_init_cal(ah, chan))
6031 FAIL(-ENODEV);
6032
6033 rx_chainmask = ahp->ah_rxchainmask;
6034 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6035 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6036 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6037 }
6038
6039 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6040
6041 if (AR_SREV_9100(ah)) {
6042 u32 mask;
6043 mask = REG_READ(ah, AR_CFG);
6044 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6045 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6046 "%s CFG Byte Swap Set 0x%x\n", __func__,
6047 mask);
6048 } else {
6049 mask =
6050 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6051 REG_WRITE(ah, AR_CFG, mask);
6052 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6053 "%s Setting CFG 0x%x\n", __func__,
6054 REG_READ(ah, AR_CFG));
6055 }
6056 } else {
6057#ifdef __BIG_ENDIAN
6058 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6059#endif
6060 }
6061
6062 return true;
6063bad:
6064 if (status)
6065 *status = ecode;
6066 return false;
6067#undef FAIL
6068}
6069
6070bool ath9k_hw_phy_disable(struct ath_hal *ah)
6071{
6072 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6073}
6074
6075bool ath9k_hw_disable(struct ath_hal *ah)
6076{
6077 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6078 return false;
6079
6080 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6081}
6082
6083bool
6084ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6085 u8 rxchainmask, bool longcal,
6086 bool *isCalDone)
6087{
6088 struct ath_hal_5416 *ahp = AH5416(ah);
6089 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6090 struct ath9k_channel *ichan =
6091 ath9k_regd_check_channel(ah, chan);
6092
6093 *isCalDone = true;
6094
6095 if (ichan == NULL) {
6096 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6097 "%s: invalid channel %u/0x%x; no mapping\n",
6098 __func__, chan->channel, chan->channelFlags);
6099 return false;
6100 }
6101
6102 if (currCal &&
6103 (currCal->calState == CAL_RUNNING ||
6104 currCal->calState == CAL_WAITING)) {
6105 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6106 isCalDone);
6107 if (*isCalDone) {
6108 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6109
6110 if (currCal->calState == CAL_WAITING) {
6111 *isCalDone = false;
6112 ath9k_hw_reset_calibration(ah, currCal);
6113 }
6114 }
6115 }
6116
6117 if (longcal) {
6118 ath9k_hw_getnf(ah, ichan);
6119 ath9k_hw_loadnf(ah, ah->ah_curchan);
6120 ath9k_hw_start_nfcal(ah);
6121
6122 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6123
6124 chan->channelFlags |= CHANNEL_CW_INT;
6125 ichan->channelFlags &= ~CHANNEL_CW_INT;
6126 }
6127 }
6128
6129 return true;
6130}
6131
6132static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6133{
6134 struct ath_hal_5416 *ahp = AH5416(ah);
6135 int i;
6136
6137 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6138 ahp->ah_totalPowerMeasI[i] +=
6139 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6140 ahp->ah_totalPowerMeasQ[i] +=
6141 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6142 ahp->ah_totalIqCorrMeas[i] +=
6143 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6144 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6145 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6146 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6147 ahp->ah_totalPowerMeasQ[i],
6148 ahp->ah_totalIqCorrMeas[i]);
6149 }
6150}
6151
6152static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6153{
6154 struct ath_hal_5416 *ahp = AH5416(ah);
6155 int i;
6156
6157 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6158 ahp->ah_totalAdcIOddPhase[i] +=
6159 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6160 ahp->ah_totalAdcIEvenPhase[i] +=
6161 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6162 ahp->ah_totalAdcQOddPhase[i] +=
6163 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6164 ahp->ah_totalAdcQEvenPhase[i] +=
6165 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6166
6167 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6168 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6169 "oddq=0x%08x; evenq=0x%08x;\n",
6170 ahp->ah_CalSamples, i,
6171 ahp->ah_totalAdcIOddPhase[i],
6172 ahp->ah_totalAdcIEvenPhase[i],
6173 ahp->ah_totalAdcQOddPhase[i],
6174 ahp->ah_totalAdcQEvenPhase[i]);
6175 }
6176}
6177
6178static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6179{
6180 struct ath_hal_5416 *ahp = AH5416(ah);
6181 int i;
6182
6183 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6184 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6185 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6186 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6187 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6188 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6189 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6190 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6191 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6192
6193 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6194 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6195 "oddq=0x%08x; evenq=0x%08x;\n",
6196 ahp->ah_CalSamples, i,
6197 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6198 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6199 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6200 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6201 }
6202}
6203
6204static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6205{
6206 struct ath_hal_5416 *ahp = AH5416(ah);
6207 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6208 u32 qCoffDenom, iCoffDenom;
6209 int32_t qCoff, iCoff;
6210 int iqCorrNeg, i;
6211
6212 for (i = 0; i < numChains; i++) {
6213 powerMeasI = ahp->ah_totalPowerMeasI[i];
6214 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6215 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6216
6217 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6218 "Starting IQ Cal and Correction for Chain %d\n",
6219 i);
6220
6221 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6222 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6223 i, ahp->ah_totalIqCorrMeas[i]);
6224
6225 iqCorrNeg = 0;
6226
6227
6228 if (iqCorrMeas > 0x80000000) {
6229 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6230 iqCorrNeg = 1;
6231 }
6232
6233 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6234 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6235 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6236 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6237 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6238 iqCorrNeg);
6239
6240 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6241 qCoffDenom = powerMeasQ / 64;
6242
6243 if (powerMeasQ != 0) {
6244
6245 iCoff = iqCorrMeas / iCoffDenom;
6246 qCoff = powerMeasI / qCoffDenom - 64;
6247 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6248 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6249 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6250 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6251
6252
6253 iCoff = iCoff & 0x3f;
6254 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6255 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6256 if (iqCorrNeg == 0x0)
6257 iCoff = 0x40 - iCoff;
6258
6259 if (qCoff > 15)
6260 qCoff = 15;
6261 else if (qCoff <= -16)
6262 qCoff = 16;
6263
6264 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6265 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6266 i, iCoff, qCoff);
6267
6268 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6269 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6270 iCoff);
6271 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6272 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6273 qCoff);
6274 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6275 "IQ Cal and Correction done for Chain %d\n",
6276 i);
6277 }
6278 }
6279
6280 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6281 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6282}
6283
6284static void
6285ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6286{
6287 struct ath_hal_5416 *ahp = AH5416(ah);
6288 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6289 qEvenMeasOffset;
6290 u32 qGainMismatch, iGainMismatch, val, i;
6291
6292 for (i = 0; i < numChains; i++) {
6293 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6294 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6295 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6296 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6297
6298 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6299 "Starting ADC Gain Cal for Chain %d\n", i);
6300
6301 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6302 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6303 iOddMeasOffset);
6304 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6305 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6306 iEvenMeasOffset);
6307 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6308 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6309 qOddMeasOffset);
6310 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6311 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6312 qEvenMeasOffset);
6313
6314 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6315 iGainMismatch =
6316 ((iEvenMeasOffset * 32) /
6317 iOddMeasOffset) & 0x3f;
6318 qGainMismatch =
6319 ((qOddMeasOffset * 32) /
6320 qEvenMeasOffset) & 0x3f;
6321
6322 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6323 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6324 iGainMismatch);
6325 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6326 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6327 qGainMismatch);
6328
6329 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6330 val &= 0xfffff000;
6331 val |= (qGainMismatch) | (iGainMismatch << 6);
6332 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6333
6334 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6335 "ADC Gain Cal done for Chain %d\n", i);
6336 }
6337 }
6338
6339 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6340 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6341 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6342}
6343
6344static void
6345ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6346{
6347 struct ath_hal_5416 *ahp = AH5416(ah);
6348 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6349 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6350 const struct hal_percal_data *calData =
6351 ahp->ah_cal_list_curr->calData;
6352 u32 numSamples =
6353 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6354
6355 for (i = 0; i < numChains; i++) {
6356 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6357 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6358 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6359 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6360
6361 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6362 "Starting ADC DC Offset Cal for Chain %d\n", i);
6363
6364 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6365 "Chn %d pwr_meas_odd_i = %d\n", i,
6366 iOddMeasOffset);
6367 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6368 "Chn %d pwr_meas_even_i = %d\n", i,
6369 iEvenMeasOffset);
6370 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6371 "Chn %d pwr_meas_odd_q = %d\n", i,
6372 qOddMeasOffset);
6373 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6374 "Chn %d pwr_meas_even_q = %d\n", i,
6375 qEvenMeasOffset);
6376
6377 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6378 numSamples) & 0x1ff;
6379 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6380 numSamples) & 0x1ff;
6381
6382 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6383 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6384 iDcMismatch);
6385 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6386 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6387 qDcMismatch);
6388
6389 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6390 val &= 0xc0000fff;
6391 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6392 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6393
6394 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6395 "ADC DC Offset Cal done for Chain %d\n", i);
6396 }
6397
6398 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6399 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6400 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6401}
6402
6403bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6404{
6405 struct ath_hal_5416 *ahp = AH5416(ah);
6406 struct ath9k_channel *chan = ah->ah_curchan;
6407
6408 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6409
6410 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6411 ath9k_regd_get_ctl(ah, chan),
6412 ath9k_regd_get_antenna_allowed(ah,
6413 chan),
6414 chan->maxRegTxPower * 2,
6415 min((u32) MAX_RATE_POWER,
6416 (u32) ah->ah_powerLimit)) != 0)
6417 return false;
6418
6419 return true;
6420}
6421
6422void
6423ath9k_hw_get_channel_centers(struct ath_hal *ah,
6424 struct ath9k_channel *chan,
6425 struct chan_centers *centers)
6426{
6427 int8_t extoff;
6428 struct ath_hal_5416 *ahp = AH5416(ah);
6429
6430 if (!IS_CHAN_HT40(chan)) {
6431 centers->ctl_center = centers->ext_center =
6432 centers->synth_center = chan->channel;
6433 return;
6434 }
6435
6436 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6437 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6438 centers->synth_center =
6439 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6440 extoff = 1;
6441 } else {
6442 centers->synth_center =
6443 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6444 extoff = -1;
6445 }
6446
6447 centers->ctl_center = centers->synth_center - (extoff *
6448 HT40_CHANNEL_CENTER_SHIFT);
6449 centers->ext_center = centers->synth_center + (extoff *
6450 ((ahp->
6451 ah_extprotspacing
6452 ==
6453 ATH9K_HT_EXTPROTSPACING_20)
6454 ?
6455 HT40_CHANNEL_CENTER_SHIFT
6456 : 15));
6457
6458}
6459
6460void
6461ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6462 bool *isCalDone)
6463{
6464 struct ath_hal_5416 *ahp = AH5416(ah);
6465 struct ath9k_channel *ichan =
6466 ath9k_regd_check_channel(ah, chan);
6467 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6468
6469 *isCalDone = true;
6470
6471 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6472 return;
6473
6474 if (currCal == NULL)
6475 return;
6476
6477 if (ichan == NULL) {
6478 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6479 "%s: invalid channel %u/0x%x; no mapping\n",
6480 __func__, chan->channel, chan->channelFlags);
6481 return;
6482 }
6483
6484
6485 if (currCal->calState != CAL_DONE) {
6486 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6487 "%s: Calibration state incorrect, %d\n",
6488 __func__, currCal->calState);
6489 return;
6490 }
6491
6492
6493 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6494 return;
6495
6496 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6497 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6498 __func__, currCal->calData->calType, chan->channel,
6499 chan->channelFlags);
6500
6501 ichan->CalValid &= ~currCal->calData->calType;
6502 currCal->calState = CAL_WAITING;
6503
6504 *isCalDone = false;
6505}
6506
6507void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6508{
6509 struct ath_hal_5416 *ahp = AH5416(ah);
6510
6511 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6512}
6513
6514bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6515{
6516 struct ath_hal_5416 *ahp = AH5416(ah);
6517
6518 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6519 return true;
6520}
6521
6522void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6523{
6524 struct ath_hal_5416 *ahp = AH5416(ah);
6525
6526 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6527}
6528
6529bool
6530ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6531{
6532 struct ath_hal_5416 *ahp = AH5416(ah);
6533
6534 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6535
6536 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6537 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6538
6539 return true;
6540}
6541
6542#ifdef CONFIG_ATH9K_RFKILL
6543static void ath9k_enable_rfkill(struct ath_hal *ah)
6544{
6545 struct ath_hal_5416 *ahp = AH5416(ah);
6546
6547 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6548 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6549
6550 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6551 AR_GPIO_INPUT_MUX2_RFSILENT);
6552
6553 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6554 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6555
6556 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6557
6558 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6559 !ahp->ah_gpioBit);
6560 } else {
6561 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6562 ahp->ah_gpioBit);
6563 }
6564}
6565#endif
6566
6567void
6568ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6569 u16 assocId)
6570{
6571 struct ath_hal_5416 *ahp = AH5416(ah);
6572
6573 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6574 ahp->ah_assocId = assocId;
6575
6576 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6577 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6578 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6579}
6580
6581u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6582{
6583 u64 tsf;
6584
6585 tsf = REG_READ(ah, AR_TSF_U32);
6586 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6587 return tsf;
6588}
6589
6590void ath9k_hw_reset_tsf(struct ath_hal *ah)
6591{
6592 int count;
6593
6594 count = 0;
6595 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6596 count++;
6597 if (count > 10) {
6598 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6599 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6600 __func__);
6601 break;
6602 }
6603 udelay(10);
6604 }
6605 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6606}
6607
6608u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6609{
6610 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6611}
6612
6613void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6614{
6615 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6616}
6617
6618bool
6619ath9k_hw_setantennaswitch(struct ath_hal *ah,
6620 enum ath9k_ant_setting settings,
6621 struct ath9k_channel *chan,
6622 u8 *tx_chainmask,
6623 u8 *rx_chainmask,
6624 u8 *antenna_cfgd)
6625{
6626 struct ath_hal_5416 *ahp = AH5416(ah);
6627 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6628
6629 if (AR_SREV_9280(ah)) {
6630 if (!tx_chainmask_cfg) {
6631
6632 tx_chainmask_cfg = *tx_chainmask;
6633 rx_chainmask_cfg = *rx_chainmask;
6634 }
6635
6636 switch (settings) {
6637 case ATH9K_ANT_FIXED_A:
6638 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6639 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6640 *antenna_cfgd = true;
6641 break;
6642 case ATH9K_ANT_FIXED_B:
6643 if (ah->ah_caps.tx_chainmask >
6644 ATH9K_ANTENNA1_CHAINMASK) {
6645 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6646 }
6647 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6648 *antenna_cfgd = true;
6649 break;
6650 case ATH9K_ANT_VARIABLE:
6651 *tx_chainmask = tx_chainmask_cfg;
6652 *rx_chainmask = rx_chainmask_cfg;
6653 *antenna_cfgd = true;
6654 break;
6655 default:
6656 break;
6657 }
6658 } else {
6659 ahp->ah_diversityControl = settings;
6660 }
6661
6662 return true;
6663}
6664
6665void ath9k_hw_setopmode(struct ath_hal *ah)
6666{
6667 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6668}
6669
6670bool
6671ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
6672 u32 capability, u32 *result)
6673{
6674 struct ath_hal_5416 *ahp = AH5416(ah);
6675 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6676
6677 switch (type) {
6678 case ATH9K_CAP_CIPHER:
6679 switch (capability) {
6680 case ATH9K_CIPHER_AES_CCM:
6681 case ATH9K_CIPHER_AES_OCB:
6682 case ATH9K_CIPHER_TKIP:
6683 case ATH9K_CIPHER_WEP:
6684 case ATH9K_CIPHER_MIC:
6685 case ATH9K_CIPHER_CLR:
6686 return true;
6687 default:
6688 return false;
6689 }
6690 case ATH9K_CAP_TKIP_MIC:
6691 switch (capability) {
6692 case 0:
6693 return true;
6694 case 1:
6695 return (ahp->ah_staId1Defaults &
6696 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6697 false;
6698 }
6699 case ATH9K_CAP_TKIP_SPLIT:
6700 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6701 false : true;
6702 case ATH9K_CAP_WME_TKIPMIC:
6703 return 0;
6704 case ATH9K_CAP_PHYCOUNTERS:
6705 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6706 case ATH9K_CAP_DIVERSITY:
6707 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6708 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6709 true : false;
6710 case ATH9K_CAP_PHYDIAG:
6711 return true;
6712 case ATH9K_CAP_MCAST_KEYSRCH:
6713 switch (capability) {
6714 case 0:
6715 return true;
6716 case 1:
6717 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6718 return false;
6719 } else {
6720 return (ahp->ah_staId1Defaults &
6721 AR_STA_ID1_MCAST_KSRCH) ? true :
6722 false;
6723 }
6724 }
6725 return false;
6726 case ATH9K_CAP_TSF_ADJUST:
6727 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6728 true : false;
6729 case ATH9K_CAP_RFSILENT:
6730 if (capability == 3)
6731 return false;
6732 case ATH9K_CAP_ANT_CFG_2GHZ:
6733 *result = pCap->num_antcfg_2ghz;
6734 return true;
6735 case ATH9K_CAP_ANT_CFG_5GHZ:
6736 *result = pCap->num_antcfg_5ghz;
6737 return true;
6738 case ATH9K_CAP_TXPOW:
6739 switch (capability) {
6740 case 0:
6741 return 0;
6742 case 1:
6743 *result = ah->ah_powerLimit;
6744 return 0;
6745 case 2:
6746 *result = ah->ah_maxPowerLevel;
6747 return 0;
6748 case 3:
6749 *result = ah->ah_tpScale;
6750 return 0;
6751 }
6752 return false;
6753 default:
6754 return false;
6755 }
6756}
6757
6758int
6759ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6760{
6761 struct ath_hal_5416 *ahp = AH5416(ah);
6762 struct ath9k_channel *chan = ah->ah_curchan;
6763 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6764 u16 ant_config;
6765 u32 halNumAntConfig;
6766
6767 halNumAntConfig =
6768 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6769 num_antcfg_5ghz;
6770
6771 if (cfg < halNumAntConfig) {
6772 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6773 cfg, &ant_config)) {
6774 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6775 return 0;
6776 }
6777 }
6778
6779 return -EINVAL;
6780}
6781
6782bool ath9k_hw_intrpend(struct ath_hal *ah)
6783{
6784 u32 host_isr;
6785
6786 if (AR_SREV_9100(ah))
6787 return true;
6788
6789 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6790 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6791 return true;
6792
6793 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6794 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6795 && (host_isr != AR_INTR_SPURIOUS))
6796 return true;
6797
6798 return false;
6799}
6800
6801bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6802{
6803 u32 isr = 0;
6804 u32 mask2 = 0;
6805 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6806 u32 sync_cause = 0;
6807 bool fatal_int = false;
6808
6809 if (!AR_SREV_9100(ah)) {
6810 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6811 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6812 == AR_RTC_STATUS_ON) {
6813 isr = REG_READ(ah, AR_ISR);
6814 }
6815 }
6816
6817 sync_cause =
6818 REG_READ(ah,
6819 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6820
6821 *masked = 0;
6822
6823 if (!isr && !sync_cause)
6824 return false;
6825 } else {
6826 *masked = 0;
6827 isr = REG_READ(ah, AR_ISR);
6828 }
6829
6830 if (isr) {
6831 struct ath_hal_5416 *ahp = AH5416(ah);
6832
6833 if (isr & AR_ISR_BCNMISC) {
6834 u32 isr2;
6835 isr2 = REG_READ(ah, AR_ISR_S2);
6836 if (isr2 & AR_ISR_S2_TIM)
6837 mask2 |= ATH9K_INT_TIM;
6838 if (isr2 & AR_ISR_S2_DTIM)
6839 mask2 |= ATH9K_INT_DTIM;
6840 if (isr2 & AR_ISR_S2_DTIMSYNC)
6841 mask2 |= ATH9K_INT_DTIMSYNC;
6842 if (isr2 & (AR_ISR_S2_CABEND))
6843 mask2 |= ATH9K_INT_CABEND;
6844 if (isr2 & AR_ISR_S2_GTT)
6845 mask2 |= ATH9K_INT_GTT;
6846 if (isr2 & AR_ISR_S2_CST)
6847 mask2 |= ATH9K_INT_CST;
6848 }
6849
6850 isr = REG_READ(ah, AR_ISR_RAC);
6851 if (isr == 0xffffffff) {
6852 *masked = 0;
6853 return false;
6854 }
6855
6856 *masked = isr & ATH9K_INT_COMMON;
6857
6858 if (ahp->ah_intrMitigation) {
6859
6860 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6861 *masked |= ATH9K_INT_RX;
6862 }
6863
6864 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6865 *masked |= ATH9K_INT_RX;
6866 if (isr &
6867 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6868 AR_ISR_TXEOL)) {
6869 u32 s0_s, s1_s;
6870
6871 *masked |= ATH9K_INT_TX;
6872
6873 s0_s = REG_READ(ah, AR_ISR_S0_S);
6874 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6875 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6876
6877 s1_s = REG_READ(ah, AR_ISR_S1_S);
6878 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6879 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6880 }
6881
6882 if (isr & AR_ISR_RXORN) {
6883 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6884 "%s: receive FIFO overrun interrupt\n",
6885 __func__);
6886 }
6887
6888 if (!AR_SREV_9100(ah)) {
6889 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
6890 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6891 if (isr5 & AR_ISR_S5_TIM_TIMER)
6892 *masked |= ATH9K_INT_TIM_TIMER;
6893 }
6894 }
6895
6896 *masked |= mask2;
6897 }
6898 if (AR_SREV_9100(ah))
6899 return true;
6900 if (sync_cause) {
6901 fatal_int =
6902 (sync_cause &
6903 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6904 ? true : false;
6905
6906 if (fatal_int) {
6907 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6908 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6909 "%s: received PCI FATAL interrupt\n",
6910 __func__);
6911 }
6912 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6913 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6914 "%s: received PCI PERR interrupt\n",
6915 __func__);
6916 }
6917 }
6918 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6919 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6920 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6921 __func__);
6922 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6923 REG_WRITE(ah, AR_RC, 0);
6924 *masked |= ATH9K_INT_FATAL;
6925 }
6926 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6927 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6928 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6929 __func__);
6930 }
6931
6932 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6933 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6934 }
6935 return true;
6936}
6937
6938enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6939{
6940 return AH5416(ah)->ah_maskReg;
6941}
6942
6943enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6944{
6945 struct ath_hal_5416 *ahp = AH5416(ah);
6946 u32 omask = ahp->ah_maskReg;
6947 u32 mask, mask2;
6948 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6949
6950 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6951 omask, ints);
6952
6953 if (omask & ATH9K_INT_GLOBAL) {
6954 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6955 __func__);
6956 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6957 (void) REG_READ(ah, AR_IER);
6958 if (!AR_SREV_9100(ah)) {
6959 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6960 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6961
6962 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6963 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6964 }
6965 }
6966
6967 mask = ints & ATH9K_INT_COMMON;
6968 mask2 = 0;
6969
6970 if (ints & ATH9K_INT_TX) {
6971 if (ahp->ah_txOkInterruptMask)
6972 mask |= AR_IMR_TXOK;
6973 if (ahp->ah_txDescInterruptMask)
6974 mask |= AR_IMR_TXDESC;
6975 if (ahp->ah_txErrInterruptMask)
6976 mask |= AR_IMR_TXERR;
6977 if (ahp->ah_txEolInterruptMask)
6978 mask |= AR_IMR_TXEOL;
6979 }
6980 if (ints & ATH9K_INT_RX) {
6981 mask |= AR_IMR_RXERR;
6982 if (ahp->ah_intrMitigation)
6983 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6984 else
6985 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6986 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
6987 mask |= AR_IMR_GENTMR;
6988 }
6989
6990 if (ints & (ATH9K_INT_BMISC)) {
6991 mask |= AR_IMR_BCNMISC;
6992 if (ints & ATH9K_INT_TIM)
6993 mask2 |= AR_IMR_S2_TIM;
6994 if (ints & ATH9K_INT_DTIM)
6995 mask2 |= AR_IMR_S2_DTIM;
6996 if (ints & ATH9K_INT_DTIMSYNC)
6997 mask2 |= AR_IMR_S2_DTIMSYNC;
6998 if (ints & ATH9K_INT_CABEND)
6999 mask2 |= (AR_IMR_S2_CABEND);
7000 }
7001
7002 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
7003 mask |= AR_IMR_BCNMISC;
7004 if (ints & ATH9K_INT_GTT)
7005 mask2 |= AR_IMR_S2_GTT;
7006 if (ints & ATH9K_INT_CST)
7007 mask2 |= AR_IMR_S2_CST;
7008 }
7009
7010 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
7011 mask);
7012 REG_WRITE(ah, AR_IMR, mask);
7013 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
7014 AR_IMR_S2_DTIM |
7015 AR_IMR_S2_DTIMSYNC |
7016 AR_IMR_S2_CABEND |
7017 AR_IMR_S2_CABTO |
7018 AR_IMR_S2_TSFOOR |
7019 AR_IMR_S2_GTT | AR_IMR_S2_CST);
7020 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7021 ahp->ah_maskReg = ints;
7022
7023 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
7024 if (ints & ATH9K_INT_TIM_TIMER)
7025 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7026 else
7027 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7028 }
7029
7030 if (ints & ATH9K_INT_GLOBAL) {
7031 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7032 __func__);
7033 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7034 if (!AR_SREV_9100(ah)) {
7035 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7036 AR_INTR_MAC_IRQ);
7037 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7038
7039
7040 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7041 AR_INTR_SYNC_DEFAULT);
7042 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7043 AR_INTR_SYNC_DEFAULT);
7044 }
7045 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7046 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7047 }
7048
7049 return omask;
7050}
7051
7052void
7053ath9k_hw_beaconinit(struct ath_hal *ah,
7054 u32 next_beacon, u32 beacon_period)
7055{
7056 struct ath_hal_5416 *ahp = AH5416(ah);
7057 int flags = 0;
7058
7059 ahp->ah_beaconInterval = beacon_period;
7060
7061 switch (ah->ah_opmode) {
7062 case ATH9K_M_STA:
7063 case ATH9K_M_MONITOR:
7064 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7065 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7066 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7067 flags |= AR_TBTT_TIMER_EN;
7068 break;
7069 case ATH9K_M_IBSS:
7070 REG_SET_BIT(ah, AR_TXCFG,
7071 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7072 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7073 TU_TO_USEC(next_beacon +
7074 (ahp->ah_atimWindow ? ahp->
7075 ah_atimWindow : 1)));
7076 flags |= AR_NDP_TIMER_EN;
7077 case ATH9K_M_HOSTAP:
7078 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7079 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7080 TU_TO_USEC(next_beacon -
7081 ah->ah_config.
7082 dma_beacon_response_time));
7083 REG_WRITE(ah, AR_NEXT_SWBA,
7084 TU_TO_USEC(next_beacon -
7085 ah->ah_config.
7086 sw_beacon_response_time));
7087 flags |=
7088 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7089 break;
7090 }
7091
7092 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7093 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7094 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7095 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7096
7097 beacon_period &= ~ATH9K_BEACON_ENA;
7098 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7099 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7100 ath9k_hw_reset_tsf(ah);
7101 }
7102
7103 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7104}
7105
7106void
7107ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7108 const struct ath9k_beacon_state *bs)
7109{
7110 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7111 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7112
7113 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7114
7115 REG_WRITE(ah, AR_BEACON_PERIOD,
7116 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7117 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7118 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7119
7120 REG_RMW_FIELD(ah, AR_RSSI_THR,
7121 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7122
7123 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7124
7125 if (bs->bs_sleepduration > beaconintval)
7126 beaconintval = bs->bs_sleepduration;
7127
7128 dtimperiod = bs->bs_dtimperiod;
7129 if (bs->bs_sleepduration > dtimperiod)
7130 dtimperiod = bs->bs_sleepduration;
7131
7132 if (beaconintval == dtimperiod)
7133 nextTbtt = bs->bs_nextdtim;
7134 else
7135 nextTbtt = bs->bs_nexttbtt;
7136
7137 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7138 bs->bs_nextdtim);
7139 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7140 nextTbtt);
7141 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7142 beaconintval);
7143 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7144 dtimperiod);
7145
7146 REG_WRITE(ah, AR_NEXT_DTIM,
7147 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7148 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7149
7150 REG_WRITE(ah, AR_SLEEP1,
7151 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7152 | AR_SLEEP1_ASSUME_DTIM);
7153
7154 if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
7155 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7156 else
7157 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7158
7159 REG_WRITE(ah, AR_SLEEP2,
7160 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7161
7162 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7163 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7164
7165 REG_SET_BIT(ah, AR_TIMER_MODE,
7166 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7167 AR_DTIM_TIMER_EN);
7168
7169}
7170
7171bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7172{
7173 if (entry < ah->ah_caps.keycache_size) {
7174 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7175 if (val & AR_KEYTABLE_VALID)
7176 return true;
7177 }
7178 return false;
7179}
7180
7181bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7182{
7183 u32 keyType;
7184
7185 if (entry >= ah->ah_caps.keycache_size) {
7186 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7187 "%s: entry %u out of range\n", __func__, entry);
7188 return false;
7189 }
7190 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7191
7192 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7193 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7194 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7195 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7196 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7197 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7198 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7199 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7200
7201 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7202 u16 micentry = entry + 64;
7203
7204 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7205 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7206 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7207 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7208
7209 }
7210
7211 if (ah->ah_curchan == NULL)
7212 return true;
7213
7214 return true;
7215}
7216
7217bool
7218ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7219 const u8 *mac)
7220{
7221 u32 macHi, macLo;
7222
7223 if (entry >= ah->ah_caps.keycache_size) {
7224 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7225 "%s: entry %u out of range\n", __func__, entry);
7226 return false;
7227 }
7228
7229 if (mac != NULL) {
7230 macHi = (mac[5] << 8) | mac[4];
7231 macLo = (mac[3] << 24) | (mac[2] << 16)
7232 | (mac[1] << 8) | mac[0];
7233 macLo >>= 1;
7234 macLo |= (macHi & 1) << 31;
7235 macHi >>= 1;
7236 } else {
7237 macLo = macHi = 0;
7238 }
7239 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7240 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7241
7242 return true;
7243}
7244
7245bool
7246ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7247 const struct ath9k_keyval *k,
7248 const u8 *mac, int xorKey)
7249{
7250 const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7251 u32 key0, key1, key2, key3, key4;
7252 u32 keyType;
7253 u32 xorMask = xorKey ?
7254 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7255 | ATH9K_KEY_XOR) : 0;
7256 struct ath_hal_5416 *ahp = AH5416(ah);
7257
7258 if (entry >= pCap->keycache_size) {
7259 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7260 "%s: entry %u out of range\n", __func__, entry);
7261 return false;
7262 }
7263 switch (k->kv_type) {
7264 case ATH9K_CIPHER_AES_OCB:
7265 keyType = AR_KEYTABLE_TYPE_AES;
7266 break;
7267 case ATH9K_CIPHER_AES_CCM:
7268 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
7269 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7270 "%s: AES-CCM not supported by "
7271 "mac rev 0x%x\n", __func__,
7272 ah->ah_macRev);
7273 return false;
7274 }
7275 keyType = AR_KEYTABLE_TYPE_CCM;
7276 break;
7277 case ATH9K_CIPHER_TKIP:
7278 keyType = AR_KEYTABLE_TYPE_TKIP;
7279 if (ATH9K_IS_MIC_ENABLED(ah)
7280 && entry + 64 >= pCap->keycache_size) {
7281 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7282 "%s: entry %u inappropriate for TKIP\n",
7283 __func__, entry);
7284 return false;
7285 }
7286 break;
7287 case ATH9K_CIPHER_WEP:
7288 if (k->kv_len < 40 / NBBY) {
7289 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7290 "%s: WEP key length %u too small\n",
7291 __func__, k->kv_len);
7292 return false;
7293 }
7294 if (k->kv_len <= 40 / NBBY)
7295 keyType = AR_KEYTABLE_TYPE_40;
7296 else if (k->kv_len <= 104 / NBBY)
7297 keyType = AR_KEYTABLE_TYPE_104;
7298 else
7299 keyType = AR_KEYTABLE_TYPE_128;
7300 break;
7301 case ATH9K_CIPHER_CLR:
7302 keyType = AR_KEYTABLE_TYPE_CLR;
7303 break;
7304 default:
7305 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7306 "%s: cipher %u not supported\n", __func__,
7307 k->kv_type);
7308 return false;
7309 }
7310
7311 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7312 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7313 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7314 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7315 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7316 if (k->kv_len <= 104 / NBBY)
7317 key4 &= 0xff;
7318
7319 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7320 u16 micentry = entry + 64;
7321
7322 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7323 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7324 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7325 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7326 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7327 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7328 (void) ath9k_hw_keysetmac(ah, entry, mac);
7329
7330 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7331 u32 mic0, mic1, mic2, mic3, mic4;
7332
7333 mic0 = get_unaligned_le32(k->kv_mic + 0);
7334 mic2 = get_unaligned_le32(k->kv_mic + 4);
7335 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7336 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7337 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7338 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7341 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7342 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7343 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7344 AR_KEYTABLE_TYPE_CLR);
7345
7346 } else {
7347 u32 mic0, mic2;
7348
7349 mic0 = get_unaligned_le32(k->kv_mic + 0);
7350 mic2 = get_unaligned_le32(k->kv_mic + 4);
7351 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7352 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7353 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7354 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7355 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7356 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7357 AR_KEYTABLE_TYPE_CLR);
7358 }
7359 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7360 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7361 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7362 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7363 } else {
7364 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7365 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7366 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7367 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7368 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7369 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7370
7371 (void) ath9k_hw_keysetmac(ah, entry, mac);
7372 }
7373
7374 if (ah->ah_curchan == NULL)
7375 return true;
7376
7377 return true;
7378}
7379
7380bool
7381ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7382{
7383 struct ath_hal_5416 *ahp = AH5416(ah);
7384 u32 txcfg, curLevel, newLevel;
7385 enum ath9k_int omask;
7386
7387 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7388 return false;
7389
7390 omask = ath9k_hw_set_interrupts(ah,
7391 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7392
7393 txcfg = REG_READ(ah, AR_TXCFG);
7394 curLevel = MS(txcfg, AR_FTRIG);
7395 newLevel = curLevel;
7396 if (bIncTrigLevel) {
7397 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7398 newLevel++;
7399 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7400 newLevel--;
7401 if (newLevel != curLevel)
7402 REG_WRITE(ah, AR_TXCFG,
7403 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7404
7405 ath9k_hw_set_interrupts(ah, omask);
7406
7407 ah->ah_txTrigLevel = newLevel;
7408
7409 return newLevel != curLevel;
7410}
7411
7412bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7413 const struct ath9k_tx_queue_info *qinfo)
7414{
7415 u32 cw;
7416 struct ath_hal_5416 *ahp = AH5416(ah);
7417 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7418 struct ath9k_tx_queue_info *qi;
7419
7420 if (q >= pCap->total_queues) {
7421 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7422 __func__, q);
7423 return false;
7424 }
7425
7426 qi = &ahp->ah_txq[q];
7427 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7428 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7429 __func__);
7430 return false;
7431 }
7432
7433 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7434
7435 qi->tqi_ver = qinfo->tqi_ver;
7436 qi->tqi_subtype = qinfo->tqi_subtype;
7437 qi->tqi_qflags = qinfo->tqi_qflags;
7438 qi->tqi_priority = qinfo->tqi_priority;
7439 if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7440 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
7441 else
7442 qi->tqi_aifs = INIT_AIFS;
7443 if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7444 cw = min(qinfo->tqi_cwmin, 1024U);
7445 qi->tqi_cwmin = 1;
7446 while (qi->tqi_cwmin < cw)
7447 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7448 } else
7449 qi->tqi_cwmin = qinfo->tqi_cwmin;
7450 if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7451 cw = min(qinfo->tqi_cwmax, 1024U);
7452 qi->tqi_cwmax = 1;
7453 while (qi->tqi_cwmax < cw)
7454 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7455 } else
7456 qi->tqi_cwmax = INIT_CWMAX;
7457
7458 if (qinfo->tqi_shretry != 0)
7459 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
7460 else
7461 qi->tqi_shretry = INIT_SH_RETRY;
7462 if (qinfo->tqi_lgretry != 0)
7463 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
7464 else
7465 qi->tqi_lgretry = INIT_LG_RETRY;
7466 qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7467 qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7468 qi->tqi_burstTime = qinfo->tqi_burstTime;
7469 qi->tqi_readyTime = qinfo->tqi_readyTime;
7470
7471 switch (qinfo->tqi_subtype) {
7472 case ATH9K_WME_UPSD:
7473 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7474 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7475 break;
7476 default:
7477 break;
7478 }
7479 return true;
7480}
7481
7482bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7483 struct ath9k_tx_queue_info *qinfo)
7484{
7485 struct ath_hal_5416 *ahp = AH5416(ah);
7486 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7487 struct ath9k_tx_queue_info *qi;
7488
7489 if (q >= pCap->total_queues) {
7490 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7491 __func__, q);
7492 return false;
7493 }
7494
7495 qi = &ahp->ah_txq[q];
7496 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7497 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7498 __func__);
7499 return false;
7500 }
7501
7502 qinfo->tqi_qflags = qi->tqi_qflags;
7503 qinfo->tqi_ver = qi->tqi_ver;
7504 qinfo->tqi_subtype = qi->tqi_subtype;
7505 qinfo->tqi_qflags = qi->tqi_qflags;
7506 qinfo->tqi_priority = qi->tqi_priority;
7507 qinfo->tqi_aifs = qi->tqi_aifs;
7508 qinfo->tqi_cwmin = qi->tqi_cwmin;
7509 qinfo->tqi_cwmax = qi->tqi_cwmax;
7510 qinfo->tqi_shretry = qi->tqi_shretry;
7511 qinfo->tqi_lgretry = qi->tqi_lgretry;
7512 qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7513 qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7514 qinfo->tqi_burstTime = qi->tqi_burstTime;
7515 qinfo->tqi_readyTime = qi->tqi_readyTime;
7516
7517 return true;
7518}
7519
7520int
7521ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7522 const struct ath9k_tx_queue_info *qinfo)
7523{
7524 struct ath_hal_5416 *ahp = AH5416(ah);
7525 struct ath9k_tx_queue_info *qi;
7526 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7527 int q;
7528
7529 switch (type) {
7530 case ATH9K_TX_QUEUE_BEACON:
7531 q = pCap->total_queues - 1;
7532 break;
7533 case ATH9K_TX_QUEUE_CAB:
7534 q = pCap->total_queues - 2;
7535 break;
7536 case ATH9K_TX_QUEUE_PSPOLL:
7537 q = 1;
7538 break;
7539 case ATH9K_TX_QUEUE_UAPSD:
7540 q = pCap->total_queues - 3;
7541 break;
7542 case ATH9K_TX_QUEUE_DATA:
7543 for (q = 0; q < pCap->total_queues; q++)
7544 if (ahp->ah_txq[q].tqi_type ==
7545 ATH9K_TX_QUEUE_INACTIVE)
7546 break;
7547 if (q == pCap->total_queues) {
7548 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7549 "%s: no available tx queue\n", __func__);
7550 return -1;
7551 }
7552 break;
7553 default:
7554 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7555 __func__, type);
7556 return -1;
7557 }
7558
7559 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7560
7561 qi = &ahp->ah_txq[q];
7562 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7563 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7564 "%s: tx queue %u already active\n", __func__, q);
7565 return -1;
7566 }
7567 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7568 qi->tqi_type = type;
7569 if (qinfo == NULL) {
7570 qi->tqi_qflags =
7571 TXQ_FLAG_TXOKINT_ENABLE
7572 | TXQ_FLAG_TXERRINT_ENABLE
7573 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7574 qi->tqi_aifs = INIT_AIFS;
7575 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7576 qi->tqi_cwmax = INIT_CWMAX;
7577 qi->tqi_shretry = INIT_SH_RETRY;
7578 qi->tqi_lgretry = INIT_LG_RETRY;
7579 qi->tqi_physCompBuf = 0;
7580 } else {
7581 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7582 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
7583 }
7584
7585 return q;
7586}
7587
7588static void
7589ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7590 struct ath9k_tx_queue_info *qi)
7591{
7592 struct ath_hal_5416 *ahp = AH5416(ah);
7593
7594 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7595 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7596 __func__, ahp->ah_txOkInterruptMask,
7597 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7598 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7599
7600 REG_WRITE(ah, AR_IMR_S0,
7601 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7602 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7603 REG_WRITE(ah, AR_IMR_S1,
7604 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7605 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7606 REG_RMW_FIELD(ah, AR_IMR_S2,
7607 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7608}
7609
7610bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7611{
7612 struct ath_hal_5416 *ahp = AH5416(ah);
7613 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7614 struct ath9k_tx_queue_info *qi;
7615
7616 if (q >= pCap->total_queues) {
7617 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7618 __func__, q);
7619 return false;
7620 }
7621 qi = &ahp->ah_txq[q];
7622 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7623 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7624 __func__, q);
7625 return false;
7626 }
7627
7628 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7629 __func__, q);
7630
7631 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7632 ahp->ah_txOkInterruptMask &= ~(1 << q);
7633 ahp->ah_txErrInterruptMask &= ~(1 << q);
7634 ahp->ah_txDescInterruptMask &= ~(1 << q);
7635 ahp->ah_txEolInterruptMask &= ~(1 << q);
7636 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7637 ath9k_hw_set_txq_interrupts(ah, qi);
7638
7639 return true;
7640}
7641
7642bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7643{
7644 struct ath_hal_5416 *ahp = AH5416(ah);
7645 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7646 struct ath9k_channel *chan = ah->ah_curchan;
7647 struct ath9k_tx_queue_info *qi;
7648 u32 cwMin, chanCwMin, value;
7649
7650 if (q >= pCap->total_queues) {
7651 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7652 __func__, q);
7653 return false;
7654 }
7655 qi = &ahp->ah_txq[q];
7656 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7657 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7658 __func__, q);
7659 return true;
7660 }
7661
7662 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7663
7664 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7665 if (chan && IS_CHAN_B(chan))
7666 chanCwMin = INIT_CWMIN_11B;
7667 else
7668 chanCwMin = INIT_CWMIN;
7669
7670 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7671 } else
7672 cwMin = qi->tqi_cwmin;
7673
7674 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7675 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7676 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7677
7678 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7679 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7680 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7681 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7682 );
7683
7684 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7685 REG_WRITE(ah, AR_DMISC(q),
7686 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7687
7688 if (qi->tqi_cbrPeriod) {
7689 REG_WRITE(ah, AR_QCBRCFG(q),
7690 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7691 | SM(qi->tqi_cbrOverflowLimit,
7692 AR_Q_CBRCFG_OVF_THRESH));
7693 REG_WRITE(ah, AR_QMISC(q),
7694 REG_READ(ah,
7695 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7696 tqi_cbrOverflowLimit
7697 ?
7698 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7699 :
7700 0));
7701 }
7702 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7703 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7704 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7705 AR_Q_RDYTIMECFG_EN);
7706 }
7707
7708 REG_WRITE(ah, AR_DCHNTIME(q),
7709 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7710 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7711
7712 if (qi->tqi_burstTime
7713 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7714 REG_WRITE(ah, AR_QMISC(q),
7715 REG_READ(ah,
7716 AR_QMISC(q)) |
7717 AR_Q_MISC_RDYTIME_EXP_POLICY);
7718
7719 }
7720
7721 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7722 REG_WRITE(ah, AR_DMISC(q),
7723 REG_READ(ah, AR_DMISC(q)) |
7724 AR_D_MISC_POST_FR_BKOFF_DIS);
7725 }
7726 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7727 REG_WRITE(ah, AR_DMISC(q),
7728 REG_READ(ah, AR_DMISC(q)) |
7729 AR_D_MISC_FRAG_BKOFF_EN);
7730 }
7731 switch (qi->tqi_type) {
7732 case ATH9K_TX_QUEUE_BEACON:
7733 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7734 | AR_Q_MISC_FSP_DBA_GATED
7735 | AR_Q_MISC_BEACON_USE
7736 | AR_Q_MISC_CBR_INCR_DIS1);
7737
7738 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7739 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7740 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7741 | AR_D_MISC_BEACON_USE
7742 | AR_D_MISC_POST_FR_BKOFF_DIS);
7743 break;
7744 case ATH9K_TX_QUEUE_CAB:
7745 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7746 | AR_Q_MISC_FSP_DBA_GATED
7747 | AR_Q_MISC_CBR_INCR_DIS1
7748 | AR_Q_MISC_CBR_INCR_DIS0);
7749 value = (qi->tqi_readyTime
7750 - (ah->ah_config.sw_beacon_response_time -
7751 ah->ah_config.dma_beacon_response_time)
7752 -
7753 ah->ah_config.additional_swba_backoff) *
7754 1024;
7755 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7756 value | AR_Q_RDYTIMECFG_EN);
7757 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7758 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7759 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7760 break;
7761 case ATH9K_TX_QUEUE_PSPOLL:
7762 REG_WRITE(ah, AR_QMISC(q),
7763 REG_READ(ah,
7764 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7765 break;
7766 case ATH9K_TX_QUEUE_UAPSD:
7767 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7768 | AR_D_MISC_POST_FR_BKOFF_DIS);
7769 break;
7770 default:
7771 break;
7772 }
7773
7774 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7775 REG_WRITE(ah, AR_DMISC(q),
7776 REG_READ(ah, AR_DMISC(q)) |
7777 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7778 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7779 AR_D_MISC_POST_FR_BKOFF_DIS);
7780 }
7781
7782 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7783 ahp->ah_txOkInterruptMask |= 1 << q;
7784 else
7785 ahp->ah_txOkInterruptMask &= ~(1 << q);
7786 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7787 ahp->ah_txErrInterruptMask |= 1 << q;
7788 else
7789 ahp->ah_txErrInterruptMask &= ~(1 << q);
7790 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7791 ahp->ah_txDescInterruptMask |= 1 << q;
7792 else
7793 ahp->ah_txDescInterruptMask &= ~(1 << q);
7794 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7795 ahp->ah_txEolInterruptMask |= 1 << q;
7796 else
7797 ahp->ah_txEolInterruptMask &= ~(1 << q);
7798 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7799 ahp->ah_txUrnInterruptMask |= 1 << q;
7800 else
7801 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7802 ath9k_hw_set_txq_interrupts(ah, qi);
7803
7804 return true;
7805}
7806
7807void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7808{
7809 struct ath_hal_5416 *ahp = AH5416(ah);
7810 *txqs &= ahp->ah_intrTxqs;
7811 ahp->ah_intrTxqs &= ~(*txqs);
7812}
7813
7814bool
7815ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7816 u32 segLen, bool firstSeg,
7817 bool lastSeg, const struct ath_desc *ds0)
7818{
7819 struct ar5416_desc *ads = AR5416DESC(ds);
7820
7821 if (firstSeg) {
7822 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7823 } else if (lastSeg) {
7824 ads->ds_ctl0 = 0;
7825 ads->ds_ctl1 = segLen;
7826 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7827 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7828 } else {
7829 ads->ds_ctl0 = 0;
7830 ads->ds_ctl1 = segLen | AR_TxMore;
7831 ads->ds_ctl2 = 0;
7832 ads->ds_ctl3 = 0;
7833 }
7834 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7835 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7836 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7837 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7838 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7839 return true;
7840}
7841
7842void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7843{
7844 struct ar5416_desc *ads = AR5416DESC(ds);
7845
7846 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7847 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7848 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7849 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7850 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7851}
7852
7853int
7854ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7855{
7856 struct ar5416_desc *ads = AR5416DESC(ds);
7857
7858 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7859 return -EINPROGRESS;
7860
7861 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7862 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7863 ds->ds_txstat.ts_status = 0;
7864 ds->ds_txstat.ts_flags = 0;
7865
7866 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7867 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7868 if (ads->ds_txstatus1 & AR_Filtered)
7869 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7870 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7871 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7872 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7873 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7874 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7875 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7876
7877 if (ads->ds_txstatus1 & AR_DescCfgErr)
7878 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7879 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7880 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7881 ath9k_hw_updatetxtriglevel(ah, true);
7882 }
7883 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7884 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7885 ath9k_hw_updatetxtriglevel(ah, true);
7886 }
7887 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7888 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7889 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7890 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7891 }
7892
7893 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7894 switch (ds->ds_txstat.ts_rateindex) {
7895 case 0:
7896 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7897 break;
7898 case 1:
7899 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7900 break;
7901 case 2:
7902 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7903 break;
7904 case 3:
7905 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7906 break;
7907 }
7908
7909 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7910 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7911 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7912 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7913 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7914 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7915 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7916 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7917 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7918 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7919 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7920 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7921 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7922 ds->ds_txstat.ts_antenna = 1;
7923
7924 return 0;
7925}
7926
7927void
7928ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7929 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7930 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7931{
7932 struct ar5416_desc *ads = AR5416DESC(ds);
7933 struct ath_hal_5416 *ahp = AH5416(ah);
7934
7935 txPower += ahp->ah_txPowerIndexOffset;
7936 if (txPower > 63)
7937 txPower = 63;
7938
7939 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7940 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7941 | SM(txPower, AR_XmitPower)
7942 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7943 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7944 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7945 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7946
7947 ads->ds_ctl1 =
7948 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7949 | SM(type, AR_FrameType)
7950 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7951 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7952 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7953
7954 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7955
7956 if (AR_SREV_9285(ah)) {
7957
7958 ads->ds_ctl8 = 0;
7959 ads->ds_ctl9 = 0;
7960 ads->ds_ctl10 = 0;
7961 ads->ds_ctl11 = 0;
7962 }
7963}
7964
7965void
7966ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7967 struct ath_desc *lastds,
7968 u32 durUpdateEn, u32 rtsctsRate,
7969 u32 rtsctsDuration,
7970 struct ath9k_11n_rate_series series[],
7971 u32 nseries, u32 flags)
7972{
7973 struct ar5416_desc *ads = AR5416DESC(ds);
7974 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7975 u32 ds_ctl0;
7976
7977 (void) nseries;
7978 (void) rtsctsDuration;
7979
7980 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7981 ds_ctl0 = ads->ds_ctl0;
7982
7983 if (flags & ATH9K_TXDESC_RTSENA) {
7984 ds_ctl0 &= ~AR_CTSEnable;
7985 ds_ctl0 |= AR_RTSEnable;
7986 } else {
7987 ds_ctl0 &= ~AR_RTSEnable;
7988 ds_ctl0 |= AR_CTSEnable;
7989 }
7990
7991 ads->ds_ctl0 = ds_ctl0;
7992 } else {
7993 ads->ds_ctl0 =
7994 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7995 }
7996
7997 ads->ds_ctl2 = set11nTries(series, 0)
7998 | set11nTries(series, 1)
7999 | set11nTries(series, 2)
8000 | set11nTries(series, 3)
8001 | (durUpdateEn ? AR_DurUpdateEna : 0)
8002 | SM(0, AR_BurstDur);
8003
8004 ads->ds_ctl3 = set11nRate(series, 0)
8005 | set11nRate(series, 1)
8006 | set11nRate(series, 2)
8007 | set11nRate(series, 3);
8008
8009 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
8010 | set11nPktDurRTSCTS(series, 1);
8011
8012 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8013 | set11nPktDurRTSCTS(series, 3);
8014
8015 ads->ds_ctl7 = set11nRateFlags(series, 0)
8016 | set11nRateFlags(series, 1)
8017 | set11nRateFlags(series, 2)
8018 | set11nRateFlags(series, 3)
8019 | SM(rtsctsRate, AR_RTSCTSRate);
8020 last_ads->ds_ctl2 = ads->ds_ctl2;
8021 last_ads->ds_ctl3 = ads->ds_ctl3;
8022}
8023
8024void
8025ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8026 u32 aggrLen)
8027{
8028 struct ar5416_desc *ads = AR5416DESC(ds);
8029
8030 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8031
8032 ads->ds_ctl6 &= ~AR_AggrLen;
8033 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8034}
8035
8036void
8037ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8038 u32 numDelims)
8039{
8040 struct ar5416_desc *ads = AR5416DESC(ds);
8041 unsigned int ctl6;
8042
8043 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8044
8045 ctl6 = ads->ds_ctl6;
8046 ctl6 &= ~AR_PadDelim;
8047 ctl6 |= SM(numDelims, AR_PadDelim);
8048 ads->ds_ctl6 = ctl6;
8049}
8050
8051void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8052{
8053 struct ar5416_desc *ads = AR5416DESC(ds);
8054
8055 ads->ds_ctl1 |= AR_IsAggr;
8056 ads->ds_ctl1 &= ~AR_MoreAggr;
8057 ads->ds_ctl6 &= ~AR_PadDelim;
8058}
8059
8060void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8061{
8062 struct ar5416_desc *ads = AR5416DESC(ds);
8063
8064 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8065}
8066
8067void
8068ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8069 u32 burstDuration)
8070{
8071 struct ar5416_desc *ads = AR5416DESC(ds);
8072
8073 ads->ds_ctl2 &= ~AR_BurstDur;
8074 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8075}
8076
8077void
8078ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8079 u32 vmf)
8080{
8081 struct ar5416_desc *ads = AR5416DESC(ds);
8082
8083 if (vmf)
8084 ads->ds_ctl0 |= AR_VirtMoreFrag;
8085 else
8086 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8087}
8088
8089void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8090{
8091 REG_WRITE(ah, AR_RXDP, rxdp);
8092}
8093
8094void ath9k_hw_rxena(struct ath_hal *ah)
8095{
8096 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8097}
8098
8099bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8100{
8101 if (set) {
8102
8103 REG_SET_BIT(ah, AR_DIAG_SW,
8104 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8105
8106 if (!ath9k_hw_wait
8107 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8108 u32 reg;
8109
8110 REG_CLR_BIT(ah, AR_DIAG_SW,
8111 (AR_DIAG_RX_DIS |
8112 AR_DIAG_RX_ABORT));
8113
8114 reg = REG_READ(ah, AR_OBS_BUS_1);
8115 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8116 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8117 __func__, reg);
8118
8119 return false;
8120 }
8121 } else {
8122 REG_CLR_BIT(ah, AR_DIAG_SW,
8123 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8124 }
8125
8126 return true;
8127}
8128
8129void
8130ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8131 u32 filter1)
8132{
8133 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8134 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8135}
8136
8137bool
8138ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8139 u32 size, u32 flags)
8140{
8141 struct ar5416_desc *ads = AR5416DESC(ds);
8142 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
8143
8144 ads->ds_ctl1 = size & AR_BufLen;
8145 if (flags & ATH9K_RXDESC_INTREQ)
8146 ads->ds_ctl1 |= AR_RxIntrReq;
8147
8148 ads->ds_rxstatus8 &= ~AR_RxDone;
8149 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
8150 memset(&(ads->u), 0, sizeof(ads->u));
8151 return true;
8152}
8153
8154int
8155ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8156 u32 pa, struct ath_desc *nds, u64 tsf)
8157{
8158 struct ar5416_desc ads;
8159 struct ar5416_desc *adsp = AR5416DESC(ds);
8160
8161 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8162 return -EINPROGRESS;
8163
8164 ads.u.rx = adsp->u.rx;
8165
8166 ds->ds_rxstat.rs_status = 0;
8167 ds->ds_rxstat.rs_flags = 0;
8168
8169 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8170 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8171
8172 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8173 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8174 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8175 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8176 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8177 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8178 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8179 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8180 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8181 else
8182 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8183
8184 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8185 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8186
8187 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8188 ds->ds_rxstat.rs_moreaggr =
8189 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8190 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8191 ds->ds_rxstat.rs_flags =
8192 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8193 ds->ds_rxstat.rs_flags |=
8194 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8195
8196 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8197 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8198 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8199 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8200 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8201 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8202
8203 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8204
8205 if (ads.ds_rxstatus8 & AR_CRCErr)
8206 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8207 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8208 u32 phyerr;
8209
8210 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8211 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8212 ds->ds_rxstat.rs_phyerr = phyerr;
8213 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8214 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8215 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8216 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8217 }
8218
8219 return 0;
8220}
8221
8222static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8223 struct ath9k_rate_table *rt)
8224{
8225 int i;
8226
8227 if (rt->rateCodeToIndex[0] != 0)
8228 return;
8229 for (i = 0; i < 256; i++)
8230 rt->rateCodeToIndex[i] = (u8) -1;
8231 for (i = 0; i < rt->rateCount; i++) {
8232 u8 code = rt->info[i].rateCode;
8233 u8 cix = rt->info[i].controlRate;
8234
8235 rt->rateCodeToIndex[code] = i;
8236 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8237
8238 rt->info[i].lpAckDuration =
8239 ath9k_hw_computetxtime(ah, rt,
8240 WLAN_CTRL_FRAME_SIZE,
8241 cix,
8242 false);
8243 rt->info[i].spAckDuration =
8244 ath9k_hw_computetxtime(ah, rt,
8245 WLAN_CTRL_FRAME_SIZE,
8246 cix,
8247 true);
8248 }
8249}
8250
8251const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8252 u32 mode)
8253{
8254 struct ath9k_rate_table *rt;
8255 switch (mode) {
8256 case ATH9K_MODE_11A:
8257 rt = &ar5416_11a_table;
8258 break;
8259 case ATH9K_MODE_11B:
8260 rt = &ar5416_11b_table;
8261 break;
8262 case ATH9K_MODE_11G:
8263 rt = &ar5416_11g_table;
8264 break;
8265 case ATH9K_MODE_11NG_HT20:
8266 case ATH9K_MODE_11NG_HT40PLUS:
8267 case ATH9K_MODE_11NG_HT40MINUS:
8268 rt = &ar5416_11ng_table;
8269 break;
8270 case ATH9K_MODE_11NA_HT20:
8271 case ATH9K_MODE_11NA_HT40PLUS:
8272 case ATH9K_MODE_11NA_HT40MINUS:
8273 rt = &ar5416_11na_table;
8274 break;
8275 default:
8276 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8277 __func__, mode);
8278 return NULL;
8279 }
8280 ath9k_hw_setup_rate_table(ah, rt);
8281 return rt;
8282}
8283
8284static const char *ath9k_hw_devname(u16 devid)
8285{
8286 switch (devid) {
8287 case AR5416_DEVID_PCI:
8288 case AR5416_DEVID_PCIE:
8289 return "Atheros 5416";
8290 case AR9160_DEVID_PCI:
8291 return "Atheros 9160";
8292 case AR9280_DEVID_PCI:
8293 case AR9280_DEVID_PCIE:
8294 return "Atheros 9280";
8295 }
8296 return NULL;
8297}
8298
8299const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8300{
8301 return vendorid == ATHEROS_VENDOR_ID ?
8302 ath9k_hw_devname(devid) : NULL;
8303}
8304
8305struct ath_hal *ath9k_hw_attach(u16 devid,
8306 struct ath_softc *sc,
8307 void __iomem *mem,
8308 int *error)
8309{
8310 struct ath_hal *ah = NULL;
8311
8312 switch (devid) {
8313 case AR5416_DEVID_PCI:
8314 case AR5416_DEVID_PCIE:
8315 case AR9160_DEVID_PCI:
8316 case AR9280_DEVID_PCI:
8317 case AR9280_DEVID_PCIE:
8318 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8319 break;
8320 default:
8321 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8322 "devid=0x%x not supported.\n", devid);
8323 ah = NULL;
8324 *error = -ENXIO;
8325 break;
8326 }
8327 if (ah != NULL) {
8328 ah->ah_devid = ah->ah_devid;
8329 ah->ah_subvendorid = ah->ah_subvendorid;
8330 ah->ah_macVersion = ah->ah_macVersion;
8331 ah->ah_macRev = ah->ah_macRev;
8332 ah->ah_phyRev = ah->ah_phyRev;
8333 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8334 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8335 }
8336 return ah;
8337}
8338
8339u16
8340ath9k_hw_computetxtime(struct ath_hal *ah,
8341 const struct ath9k_rate_table *rates,
8342 u32 frameLen, u16 rateix,
8343 bool shortPreamble)
8344{
8345 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8346 u32 kbps;
8347
8348 kbps = rates->info[rateix].rateKbps;
8349
8350 if (kbps == 0)
8351 return 0;
8352 switch (rates->info[rateix].phy) {
8353
8354 case PHY_CCK:
8355 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8356 if (shortPreamble && rates->info[rateix].shortPreamble)
8357 phyTime >>= 1;
8358 numBits = frameLen << 3;
8359 txTime = CCK_SIFS_TIME + phyTime
8360 + ((numBits * 1000) / kbps);
8361 break;
8362 case PHY_OFDM:
8363 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8364 bitsPerSymbol =
8365 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8366
8367 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8368 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8369 txTime = OFDM_SIFS_TIME_QUARTER
8370 + OFDM_PREAMBLE_TIME_QUARTER
8371 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8372 } else if (ah->ah_curchan &&
8373 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8374 bitsPerSymbol =
8375 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8376
8377 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8378 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8379 txTime = OFDM_SIFS_TIME_HALF +
8380 OFDM_PREAMBLE_TIME_HALF
8381 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8382 } else {
8383 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8384
8385 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8386 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8387 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8388 + (numSymbols * OFDM_SYMBOL_TIME);
8389 }
8390 break;
8391
8392 default:
8393 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8394 "%s: unknown phy %u (rate ix %u)\n", __func__,
8395 rates->info[rateix].phy, rateix);
8396 txTime = 0;
8397 break;
8398 }
8399 return txTime;
8400}
8401
8402u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8403{
8404 if (flags & CHANNEL_2GHZ) {
8405 if (freq == 2484)
8406 return 14;
8407 if (freq < 2484)
8408 return (freq - 2407) / 5;
8409 else
8410 return 15 + ((freq - 2512) / 20);
8411 } else if (flags & CHANNEL_5GHZ) {
8412 if (ath9k_regd_is_public_safety_sku(ah) &&
8413 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8414 return ((freq * 10) +
8415 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8416 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8417 return (freq - 4000) / 5;
8418 } else {
8419 return (freq - 5000) / 5;
8420 }
8421 } else {
8422 if (freq == 2484)
8423 return 14;
8424 if (freq < 2484)
8425 return (freq - 2407) / 5;
8426 if (freq < 5000) {
8427 if (ath9k_regd_is_public_safety_sku(ah)
8428 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8429 return ((freq * 10) +
8430 (((freq % 5) ==
8431 2) ? 5 : 0) - 49400) / 5;
8432 } else if (freq > 4900) {
8433 return (freq - 4000) / 5;
8434 } else {
8435 return 15 + ((freq - 2512) / 20);
8436 }
8437 }
8438 return (freq - 5000) / 5;
8439 }
8440}
8441
8442int16_t
8443ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8444{
8445 struct ath9k_channel *ichan;
8446
8447 ichan = ath9k_regd_check_channel(ah, chan);
8448 if (ichan == NULL) {
8449 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8450 "%s: invalid channel %u/0x%x; no mapping\n",
8451 __func__, chan->channel, chan->channelFlags);
8452 return 0;
8453 }
8454 if (ichan->rawNoiseFloor == 0) {
8455 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8456 return NOISE_FLOOR[mode];
8457 } else
8458 return ichan->rawNoiseFloor;
8459}
8460
8461bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8462{
8463 struct ath_hal_5416 *ahp = AH5416(ah);
8464
8465 if (setting)
8466 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8467 else
8468 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8469 return true;
8470}
8471
8472bool ath9k_hw_phycounters(struct ath_hal *ah)
8473{
8474 struct ath_hal_5416 *ahp = AH5416(ah);
8475
8476 return ahp->ah_hasHwPhyCounters ? true : false;
8477}
8478
8479u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8480{
8481 return REG_READ(ah, AR_QTXDP(q));
8482}
8483
8484bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8485 u32 txdp)
8486{
8487 REG_WRITE(ah, AR_QTXDP(q), txdp);
8488
8489 return true;
8490}
8491
8492bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8493{
8494 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8495
8496 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8497
8498 return true;
8499}
8500
8501u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8502{
8503 u32 npend;
8504
8505 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8506 if (npend == 0) {
8507
8508 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8509 npend = 1;
8510 }
8511 return npend;
8512}
8513
8514bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8515{
8516 u32 wait;
8517
8518 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8519
8520 for (wait = 1000; wait != 0; wait--) {
8521 if (ath9k_hw_numtxpending(ah, q) == 0)
8522 break;
8523 udelay(100);
8524 }
8525
8526 if (ath9k_hw_numtxpending(ah, q)) {
8527 u32 tsfLow, j;
8528
8529 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8530 "%s: Num of pending TX Frames %d on Q %d\n",
8531 __func__, ath9k_hw_numtxpending(ah, q), q);
8532
8533 for (j = 0; j < 2; j++) {
8534 tsfLow = REG_READ(ah, AR_TSF_L32);
8535 REG_WRITE(ah, AR_QUIET2,
8536 SM(10, AR_QUIET2_QUIET_DUR));
8537 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8538 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8539 REG_SET_BIT(ah, AR_TIMER_MODE,
8540 AR_QUIET_TIMER_EN);
8541
8542 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8543 (tsfLow >> 10)) {
8544 break;
8545 }
8546 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8547 "%s: TSF have moved while trying to set "
8548 "quiet time TSF: 0x%08x\n",
8549 __func__, tsfLow);
8550 }
8551
8552 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8553
8554 udelay(200);
8555 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8556
8557 wait = 1000;
8558
8559 while (ath9k_hw_numtxpending(ah, q)) {
8560 if ((--wait) == 0) {
8561 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8562 "%s: Failed to stop Tx DMA in 100 "
8563 "msec after killing last frame\n",
8564 __func__);
8565 break;
8566 }
8567 udelay(100);
8568 }
8569
8570 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8571 }
8572
8573 REG_WRITE(ah, AR_Q_TXD, 0);
8574 return wait != 0;
8575}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
new file mode 100644
index 000000000000..ae680f21ba7e
--- /dev/null
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -0,0 +1,969 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HW_H
18#define HW_H
19
20#include <linux/if_ether.h>
21#include <linux/delay.h>
22
23struct ar5416_desc {
24 u32 ds_link;
25 u32 ds_data;
26 u32 ds_ctl0;
27 u32 ds_ctl1;
28 union {
29 struct {
30 u32 ctl2;
31 u32 ctl3;
32 u32 ctl4;
33 u32 ctl5;
34 u32 ctl6;
35 u32 ctl7;
36 u32 ctl8;
37 u32 ctl9;
38 u32 ctl10;
39 u32 ctl11;
40 u32 status0;
41 u32 status1;
42 u32 status2;
43 u32 status3;
44 u32 status4;
45 u32 status5;
46 u32 status6;
47 u32 status7;
48 u32 status8;
49 u32 status9;
50 } tx;
51 struct {
52 u32 status0;
53 u32 status1;
54 u32 status2;
55 u32 status3;
56 u32 status4;
57 u32 status5;
58 u32 status6;
59 u32 status7;
60 u32 status8;
61 } rx;
62 } u;
63} __packed;
64
65#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
66#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
67
68#define ds_ctl2 u.tx.ctl2
69#define ds_ctl3 u.tx.ctl3
70#define ds_ctl4 u.tx.ctl4
71#define ds_ctl5 u.tx.ctl5
72#define ds_ctl6 u.tx.ctl6
73#define ds_ctl7 u.tx.ctl7
74#define ds_ctl8 u.tx.ctl8
75#define ds_ctl9 u.tx.ctl9
76#define ds_ctl10 u.tx.ctl10
77#define ds_ctl11 u.tx.ctl11
78
79#define ds_txstatus0 u.tx.status0
80#define ds_txstatus1 u.tx.status1
81#define ds_txstatus2 u.tx.status2
82#define ds_txstatus3 u.tx.status3
83#define ds_txstatus4 u.tx.status4
84#define ds_txstatus5 u.tx.status5
85#define ds_txstatus6 u.tx.status6
86#define ds_txstatus7 u.tx.status7
87#define ds_txstatus8 u.tx.status8
88#define ds_txstatus9 u.tx.status9
89
90#define ds_rxstatus0 u.rx.status0
91#define ds_rxstatus1 u.rx.status1
92#define ds_rxstatus2 u.rx.status2
93#define ds_rxstatus3 u.rx.status3
94#define ds_rxstatus4 u.rx.status4
95#define ds_rxstatus5 u.rx.status5
96#define ds_rxstatus6 u.rx.status6
97#define ds_rxstatus7 u.rx.status7
98#define ds_rxstatus8 u.rx.status8
99
100#define AR_FrameLen 0x00000fff
101#define AR_VirtMoreFrag 0x00001000
102#define AR_TxCtlRsvd00 0x0000e000
103#define AR_XmitPower 0x003f0000
104#define AR_XmitPower_S 16
105#define AR_RTSEnable 0x00400000
106#define AR_VEOL 0x00800000
107#define AR_ClrDestMask 0x01000000
108#define AR_TxCtlRsvd01 0x1e000000
109#define AR_TxIntrReq 0x20000000
110#define AR_DestIdxValid 0x40000000
111#define AR_CTSEnable 0x80000000
112
113#define AR_BufLen 0x00000fff
114#define AR_TxMore 0x00001000
115#define AR_DestIdx 0x000fe000
116#define AR_DestIdx_S 13
117#define AR_FrameType 0x00f00000
118#define AR_FrameType_S 20
119#define AR_NoAck 0x01000000
120#define AR_InsertTS 0x02000000
121#define AR_CorruptFCS 0x04000000
122#define AR_ExtOnly 0x08000000
123#define AR_ExtAndCtl 0x10000000
124#define AR_MoreAggr 0x20000000
125#define AR_IsAggr 0x40000000
126
127#define AR_BurstDur 0x00007fff
128#define AR_BurstDur_S 0
129#define AR_DurUpdateEna 0x00008000
130#define AR_XmitDataTries0 0x000f0000
131#define AR_XmitDataTries0_S 16
132#define AR_XmitDataTries1 0x00f00000
133#define AR_XmitDataTries1_S 20
134#define AR_XmitDataTries2 0x0f000000
135#define AR_XmitDataTries2_S 24
136#define AR_XmitDataTries3 0xf0000000
137#define AR_XmitDataTries3_S 28
138
139#define AR_XmitRate0 0x000000ff
140#define AR_XmitRate0_S 0
141#define AR_XmitRate1 0x0000ff00
142#define AR_XmitRate1_S 8
143#define AR_XmitRate2 0x00ff0000
144#define AR_XmitRate2_S 16
145#define AR_XmitRate3 0xff000000
146#define AR_XmitRate3_S 24
147
148#define AR_PacketDur0 0x00007fff
149#define AR_PacketDur0_S 0
150#define AR_RTSCTSQual0 0x00008000
151#define AR_PacketDur1 0x7fff0000
152#define AR_PacketDur1_S 16
153#define AR_RTSCTSQual1 0x80000000
154
155#define AR_PacketDur2 0x00007fff
156#define AR_PacketDur2_S 0
157#define AR_RTSCTSQual2 0x00008000
158#define AR_PacketDur3 0x7fff0000
159#define AR_PacketDur3_S 16
160#define AR_RTSCTSQual3 0x80000000
161
162#define AR_AggrLen 0x0000ffff
163#define AR_AggrLen_S 0
164#define AR_TxCtlRsvd60 0x00030000
165#define AR_PadDelim 0x03fc0000
166#define AR_PadDelim_S 18
167#define AR_EncrType 0x0c000000
168#define AR_EncrType_S 26
169#define AR_TxCtlRsvd61 0xf0000000
170
171#define AR_2040_0 0x00000001
172#define AR_GI0 0x00000002
173#define AR_ChainSel0 0x0000001c
174#define AR_ChainSel0_S 2
175#define AR_2040_1 0x00000020
176#define AR_GI1 0x00000040
177#define AR_ChainSel1 0x00000380
178#define AR_ChainSel1_S 7
179#define AR_2040_2 0x00000400
180#define AR_GI2 0x00000800
181#define AR_ChainSel2 0x00007000
182#define AR_ChainSel2_S 12
183#define AR_2040_3 0x00008000
184#define AR_GI3 0x00010000
185#define AR_ChainSel3 0x000e0000
186#define AR_ChainSel3_S 17
187#define AR_RTSCTSRate 0x0ff00000
188#define AR_RTSCTSRate_S 20
189#define AR_TxCtlRsvd70 0xf0000000
190
191#define AR_TxRSSIAnt00 0x000000ff
192#define AR_TxRSSIAnt00_S 0
193#define AR_TxRSSIAnt01 0x0000ff00
194#define AR_TxRSSIAnt01_S 8
195#define AR_TxRSSIAnt02 0x00ff0000
196#define AR_TxRSSIAnt02_S 16
197#define AR_TxStatusRsvd00 0x3f000000
198#define AR_TxBaStatus 0x40000000
199#define AR_TxStatusRsvd01 0x80000000
200
201#define AR_FrmXmitOK 0x00000001
202#define AR_ExcessiveRetries 0x00000002
203#define AR_FIFOUnderrun 0x00000004
204#define AR_Filtered 0x00000008
205#define AR_RTSFailCnt 0x000000f0
206#define AR_RTSFailCnt_S 4
207#define AR_DataFailCnt 0x00000f00
208#define AR_DataFailCnt_S 8
209#define AR_VirtRetryCnt 0x0000f000
210#define AR_VirtRetryCnt_S 12
211#define AR_TxDelimUnderrun 0x00010000
212#define AR_TxDataUnderrun 0x00020000
213#define AR_DescCfgErr 0x00040000
214#define AR_TxTimerExpired 0x00080000
215#define AR_TxStatusRsvd10 0xfff00000
216
217#define AR_SendTimestamp ds_txstatus2
218#define AR_BaBitmapLow ds_txstatus3
219#define AR_BaBitmapHigh ds_txstatus4
220
221#define AR_TxRSSIAnt10 0x000000ff
222#define AR_TxRSSIAnt10_S 0
223#define AR_TxRSSIAnt11 0x0000ff00
224#define AR_TxRSSIAnt11_S 8
225#define AR_TxRSSIAnt12 0x00ff0000
226#define AR_TxRSSIAnt12_S 16
227#define AR_TxRSSICombined 0xff000000
228#define AR_TxRSSICombined_S 24
229
230#define AR_TxEVM0 ds_txstatus5
231#define AR_TxEVM1 ds_txstatus6
232#define AR_TxEVM2 ds_txstatus7
233
234#define AR_TxDone 0x00000001
235#define AR_SeqNum 0x00001ffe
236#define AR_SeqNum_S 1
237#define AR_TxStatusRsvd80 0x0001e000
238#define AR_TxOpExceeded 0x00020000
239#define AR_TxStatusRsvd81 0x001c0000
240#define AR_FinalTxIdx 0x00600000
241#define AR_FinalTxIdx_S 21
242#define AR_TxStatusRsvd82 0x01800000
243#define AR_PowerMgmt 0x02000000
244#define AR_TxStatusRsvd83 0xfc000000
245
246#define AR_RxCTLRsvd00 0xffffffff
247
248#define AR_BufLen 0x00000fff
249#define AR_RxCtlRsvd00 0x00001000
250#define AR_RxIntrReq 0x00002000
251#define AR_RxCtlRsvd01 0xffffc000
252
253#define AR_RxRSSIAnt00 0x000000ff
254#define AR_RxRSSIAnt00_S 0
255#define AR_RxRSSIAnt01 0x0000ff00
256#define AR_RxRSSIAnt01_S 8
257#define AR_RxRSSIAnt02 0x00ff0000
258#define AR_RxRSSIAnt02_S 16
259#define AR_RxRate 0xff000000
260#define AR_RxRate_S 24
261#define AR_RxStatusRsvd00 0xff000000
262
263#define AR_DataLen 0x00000fff
264#define AR_RxMore 0x00001000
265#define AR_NumDelim 0x003fc000
266#define AR_NumDelim_S 14
267#define AR_RxStatusRsvd10 0xff800000
268
269#define AR_RcvTimestamp ds_rxstatus2
270
271#define AR_GI 0x00000001
272#define AR_2040 0x00000002
273#define AR_Parallel40 0x00000004
274#define AR_Parallel40_S 2
275#define AR_RxStatusRsvd30 0x000000f8
276#define AR_RxAntenna 0xffffff00
277#define AR_RxAntenna_S 8
278
279#define AR_RxRSSIAnt10 0x000000ff
280#define AR_RxRSSIAnt10_S 0
281#define AR_RxRSSIAnt11 0x0000ff00
282#define AR_RxRSSIAnt11_S 8
283#define AR_RxRSSIAnt12 0x00ff0000
284#define AR_RxRSSIAnt12_S 16
285#define AR_RxRSSICombined 0xff000000
286#define AR_RxRSSICombined_S 24
287
288#define AR_RxEVM0 ds_rxstatus4
289#define AR_RxEVM1 ds_rxstatus5
290#define AR_RxEVM2 ds_rxstatus6
291
292#define AR_RxDone 0x00000001
293#define AR_RxFrameOK 0x00000002
294#define AR_CRCErr 0x00000004
295#define AR_DecryptCRCErr 0x00000008
296#define AR_PHYErr 0x00000010
297#define AR_MichaelErr 0x00000020
298#define AR_PreDelimCRCErr 0x00000040
299#define AR_RxStatusRsvd70 0x00000080
300#define AR_RxKeyIdxValid 0x00000100
301#define AR_KeyIdx 0x0000fe00
302#define AR_KeyIdx_S 9
303#define AR_PHYErrCode 0x0000ff00
304#define AR_PHYErrCode_S 8
305#define AR_RxMoreAggr 0x00010000
306#define AR_RxAggr 0x00020000
307#define AR_PostDelimCRCErr 0x00040000
308#define AR_RxStatusRsvd71 0x3ff80000
309#define AR_DecryptBusyErr 0x40000000
310#define AR_KeyMiss 0x80000000
311
312#define AR5416_MAGIC 0x19641014
313
314#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
315 MS(ads->ds_rxstatus0, AR_RxRate) : \
316 (ads->ds_rxstatus3 >> 2) & 0xFF)
317#define RXSTATUS_DUPLICATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
318 MS(ads->ds_rxstatus3, AR_Parallel40) : \
319 (ads->ds_rxstatus3 >> 10) & 0x1)
320
321#define set11nTries(_series, _index) \
322 (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
323
324#define set11nRate(_series, _index) \
325 (SM((_series)[_index].Rate, AR_XmitRate##_index))
326
327#define set11nPktDurRTSCTS(_series, _index) \
328 (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
329 ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
330 AR_RTSCTSQual##_index : 0))
331
332#define set11nRateFlags(_series, _index) \
333 (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
334 AR_2040_##_index : 0) \
335 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
336 AR_GI##_index : 0) \
337 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
338
339#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
340
341#define INIT_CONFIG_STATUS 0x00000000
342#define INIT_RSSI_THR 0x00000700
343#define INIT_BCON_CNTRL_REG 0x00000000
344
345#define MIN_TX_FIFO_THRESHOLD 0x1
346#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
347#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
348
349#define NUM_CORNER_FIX_BITS_2133 7
350#define CCK_OFDM_GAIN_DELTA 15
351
352struct ar5416AniState {
353 struct ath9k_channel c;
354 u8 noiseImmunityLevel;
355 u8 spurImmunityLevel;
356 u8 firstepLevel;
357 u8 ofdmWeakSigDetectOff;
358 u8 cckWeakSigThreshold;
359 u32 listenTime;
360 u32 ofdmTrigHigh;
361 u32 ofdmTrigLow;
362 int32_t cckTrigHigh;
363 int32_t cckTrigLow;
364 int32_t rssiThrLow;
365 int32_t rssiThrHigh;
366 u32 noiseFloor;
367 u32 txFrameCount;
368 u32 rxFrameCount;
369 u32 cycleCount;
370 u32 ofdmPhyErrCount;
371 u32 cckPhyErrCount;
372 u32 ofdmPhyErrBase;
373 u32 cckPhyErrBase;
374 int16_t pktRssi[2];
375 int16_t ofdmErrRssi[2];
376 int16_t cckErrRssi[2];
377};
378
379#define HAL_PROCESS_ANI 0x00000001
380#define HAL_RADAR_EN 0x80000000
381#define HAL_AR_EN 0x40000000
382
383#define DO_ANI(ah) \
384 ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
385
386struct ar5416Stats {
387 u32 ast_ani_niup;
388 u32 ast_ani_nidown;
389 u32 ast_ani_spurup;
390 u32 ast_ani_spurdown;
391 u32 ast_ani_ofdmon;
392 u32 ast_ani_ofdmoff;
393 u32 ast_ani_cckhigh;
394 u32 ast_ani_ccklow;
395 u32 ast_ani_stepup;
396 u32 ast_ani_stepdown;
397 u32 ast_ani_ofdmerrs;
398 u32 ast_ani_cckerrs;
399 u32 ast_ani_reset;
400 u32 ast_ani_lzero;
401 u32 ast_ani_lneg;
402 struct ath9k_mib_stats ast_mibstats;
403 struct ath9k_node_stats ast_nodestats;
404};
405
406#define AR5416_OPFLAGS_11A 0x01
407#define AR5416_OPFLAGS_11G 0x02
408#define AR5416_OPFLAGS_N_5G_HT40 0x04
409#define AR5416_OPFLAGS_N_2G_HT40 0x08
410#define AR5416_OPFLAGS_N_5G_HT20 0x10
411#define AR5416_OPFLAGS_N_2G_HT20 0x20
412
413#define EEP_RFSILENT_ENABLED 0x0001
414#define EEP_RFSILENT_ENABLED_S 0
415#define EEP_RFSILENT_POLARITY 0x0002
416#define EEP_RFSILENT_POLARITY_S 1
417#define EEP_RFSILENT_GPIO_SEL 0x001c
418#define EEP_RFSILENT_GPIO_SEL_S 2
419
420#define AR5416_EEP_NO_BACK_VER 0x1
421#define AR5416_EEP_VER 0xE
422#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
423#define AR5416_EEP_MINOR_VER_2 0x2
424#define AR5416_EEP_MINOR_VER_3 0x3
425#define AR5416_EEP_MINOR_VER_7 0x7
426#define AR5416_EEP_MINOR_VER_9 0x9
427
428#define AR5416_EEP_START_LOC 256
429#define AR5416_NUM_5G_CAL_PIERS 8
430#define AR5416_NUM_2G_CAL_PIERS 4
431#define AR5416_NUM_5G_20_TARGET_POWERS 8
432#define AR5416_NUM_5G_40_TARGET_POWERS 8
433#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
434#define AR5416_NUM_2G_20_TARGET_POWERS 4
435#define AR5416_NUM_2G_40_TARGET_POWERS 4
436#define AR5416_NUM_CTLS 24
437#define AR5416_NUM_BAND_EDGES 8
438#define AR5416_NUM_PD_GAINS 4
439#define AR5416_PD_GAINS_IN_MASK 4
440#define AR5416_PD_GAIN_ICEPTS 5
441#define AR5416_EEPROM_MODAL_SPURS 5
442#define AR5416_MAX_RATE_POWER 63
443#define AR5416_NUM_PDADC_VALUES 128
444#define AR5416_NUM_RATES 16
445#define AR5416_BCHAN_UNUSED 0xFF
446#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
447#define AR5416_EEPMISC_BIG_ENDIAN 0x01
448#define AR5416_MAX_CHAINS 3
449#define AR5416_ANT_16S 25
450
451#define AR5416_NUM_ANT_CHAIN_FIELDS 7
452#define AR5416_NUM_ANT_COMMON_FIELDS 4
453#define AR5416_SIZE_ANT_CHAIN_FIELD 3
454#define AR5416_SIZE_ANT_COMMON_FIELD 4
455#define AR5416_ANT_CHAIN_MASK 0x7
456#define AR5416_ANT_COMMON_MASK 0xf
457#define AR5416_CHAIN_0_IDX 0
458#define AR5416_CHAIN_1_IDX 1
459#define AR5416_CHAIN_2_IDX 2
460
461#define AR5416_PWR_TABLE_OFFSET -5
462#define AR5416_LEGACY_CHAINMASK 1
463
464enum eeprom_param {
465 EEP_NFTHRESH_5,
466 EEP_NFTHRESH_2,
467 EEP_MAC_MSW,
468 EEP_MAC_MID,
469 EEP_MAC_LSW,
470 EEP_REG_0,
471 EEP_REG_1,
472 EEP_OP_CAP,
473 EEP_OP_MODE,
474 EEP_RF_SILENT,
475 EEP_OB_5,
476 EEP_DB_5,
477 EEP_OB_2,
478 EEP_DB_2,
479 EEP_MINOR_REV,
480 EEP_TX_MASK,
481 EEP_RX_MASK,
482};
483
484enum ar5416_rates {
485 rate6mb, rate9mb, rate12mb, rate18mb,
486 rate24mb, rate36mb, rate48mb, rate54mb,
487 rate1l, rate2l, rate2s, rate5_5l,
488 rate5_5s, rate11l, rate11s, rateXr,
489 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
490 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
491 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
492 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
493 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
494 Ar5416RateSize
495};
496
497struct base_eep_header {
498 u16 length;
499 u16 checksum;
500 u16 version;
501 u8 opCapFlags;
502 u8 eepMisc;
503 u16 regDmn[2];
504 u8 macAddr[6];
505 u8 rxMask;
506 u8 txMask;
507 u16 rfSilent;
508 u16 blueToothOptions;
509 u16 deviceCap;
510 u32 binBuildNumber;
511 u8 deviceType;
512 u8 pwdclkind;
513 u8 futureBase[32];
514} __packed;
515
516struct spur_chan {
517 u16 spurChan;
518 u8 spurRangeLow;
519 u8 spurRangeHigh;
520} __packed;
521
522struct modal_eep_header {
523 u32 antCtrlChain[AR5416_MAX_CHAINS];
524 u32 antCtrlCommon;
525 u8 antennaGainCh[AR5416_MAX_CHAINS];
526 u8 switchSettling;
527 u8 txRxAttenCh[AR5416_MAX_CHAINS];
528 u8 rxTxMarginCh[AR5416_MAX_CHAINS];
529 u8 adcDesiredSize;
530 u8 pgaDesiredSize;
531 u8 xlnaGainCh[AR5416_MAX_CHAINS];
532 u8 txEndToXpaOff;
533 u8 txEndToRxOn;
534 u8 txFrameToXpaOn;
535 u8 thresh62;
536 u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
537 u8 xpdGain;
538 u8 xpd;
539 u8 iqCalICh[AR5416_MAX_CHAINS];
540 u8 iqCalQCh[AR5416_MAX_CHAINS];
541 u8 pdGainOverlap;
542 u8 ob;
543 u8 db;
544 u8 xpaBiasLvl;
545 u8 pwrDecreaseFor2Chain;
546 u8 pwrDecreaseFor3Chain;
547 u8 txFrameToDataStart;
548 u8 txFrameToPaOn;
549 u8 ht40PowerIncForPdadc;
550 u8 bswAtten[AR5416_MAX_CHAINS];
551 u8 bswMargin[AR5416_MAX_CHAINS];
552 u8 swSettleHt40;
553 u8 xatten2Db[AR5416_MAX_CHAINS];
554 u8 xatten2Margin[AR5416_MAX_CHAINS];
555 u8 ob_ch1;
556 u8 db_ch1;
557 u8 useAnt1:1,
558 force_xpaon:1,
559 local_bias:1,
560 femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
561 u8 futureModalar9280;
562 u16 xpaBiasLvlFreq[3];
563 u8 futureModal[6];
564
565 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
566} __packed;
567
568struct cal_data_per_freq {
569 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
570 u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
571} __packed;
572
573struct cal_target_power_leg {
574 u8 bChannel;
575 u8 tPow2x[4];
576} __packed;
577
578struct cal_target_power_ht {
579 u8 bChannel;
580 u8 tPow2x[8];
581} __packed;
582
583#ifdef __BIG_ENDIAN_BITFIELD
584struct cal_ctl_edges {
585 u8 bChannel;
586 u8 flag:2, tPower:6;
587} __packed;
588#else
589struct cal_ctl_edges {
590 u8 bChannel;
591 u8 tPower:6, flag:2;
592} __packed;
593#endif
594
595struct cal_ctl_data {
596 struct cal_ctl_edges
597 ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
598} __packed;
599
600struct ar5416_eeprom {
601 struct base_eep_header baseEepHeader;
602 u8 custData[64];
603 struct modal_eep_header modalHeader[2];
604 u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
605 u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
606 struct cal_data_per_freq
607 calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
608 struct cal_data_per_freq
609 calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
610 struct cal_target_power_leg
611 calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
612 struct cal_target_power_ht
613 calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
614 struct cal_target_power_ht
615 calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
616 struct cal_target_power_leg
617 calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
618 struct cal_target_power_leg
619 calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
620 struct cal_target_power_ht
621 calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
622 struct cal_target_power_ht
623 calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
624 u8 ctlIndex[AR5416_NUM_CTLS];
625 struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
626 u8 padding;
627} __packed;
628
629struct ar5416IniArray {
630 u32 *ia_array;
631 u32 ia_rows;
632 u32 ia_columns;
633};
634
635#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
636 (iniarray)->ia_array = (u32 *)(array); \
637 (iniarray)->ia_rows = (rows); \
638 (iniarray)->ia_columns = (columns); \
639 } while (0)
640
641#define INI_RA(iniarray, row, column) \
642 (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
643
644#define INIT_CAL(_perCal) do { \
645 (_perCal)->calState = CAL_WAITING; \
646 (_perCal)->calNext = NULL; \
647 } while (0)
648
649#define INSERT_CAL(_ahp, _perCal) \
650 do { \
651 if ((_ahp)->ah_cal_list_last == NULL) { \
652 (_ahp)->ah_cal_list = \
653 (_ahp)->ah_cal_list_last = (_perCal); \
654 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
655 } else { \
656 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
657 (_ahp)->ah_cal_list_last = (_perCal); \
658 (_perCal)->calNext = (_ahp)->ah_cal_list; \
659 } \
660 } while (0)
661
662enum hal_cal_types {
663 ADC_DC_INIT_CAL = 0x1,
664 ADC_GAIN_CAL = 0x2,
665 ADC_DC_CAL = 0x4,
666 IQ_MISMATCH_CAL = 0x8
667};
668
669enum hal_cal_state {
670 CAL_INACTIVE,
671 CAL_WAITING,
672 CAL_RUNNING,
673 CAL_DONE
674};
675
676#define MIN_CAL_SAMPLES 1
677#define MAX_CAL_SAMPLES 64
678#define INIT_LOG_COUNT 5
679#define PER_MIN_LOG_COUNT 2
680#define PER_MAX_LOG_COUNT 10
681
682struct hal_percal_data {
683 enum hal_cal_types calType;
684 u32 calNumSamples;
685 u32 calCountMax;
686 void (*calCollect) (struct ath_hal *);
687 void (*calPostProc) (struct ath_hal *, u8);
688};
689
690struct hal_cal_list {
691 const struct hal_percal_data *calData;
692 enum hal_cal_state calState;
693 struct hal_cal_list *calNext;
694};
695
696struct ath_hal_5416 {
697 struct ath_hal ah;
698 struct ar5416_eeprom ah_eeprom;
699 u8 ah_macaddr[ETH_ALEN];
700 u8 ah_bssid[ETH_ALEN];
701 u8 ah_bssidmask[ETH_ALEN];
702 u16 ah_assocId;
703 int16_t ah_curchanRadIndex;
704 u32 ah_maskReg;
705 struct ar5416Stats ah_stats;
706 u32 ah_txDescMask;
707 u32 ah_txOkInterruptMask;
708 u32 ah_txErrInterruptMask;
709 u32 ah_txDescInterruptMask;
710 u32 ah_txEolInterruptMask;
711 u32 ah_txUrnInterruptMask;
712 struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
713 enum ath9k_power_mode ah_powerMode;
714 bool ah_chipFullSleep;
715 u32 ah_atimWindow;
716 enum ath9k_ant_setting ah_diversityControl;
717 u16 ah_antennaSwitchSwap;
718 enum hal_cal_types ah_suppCals;
719 struct hal_cal_list ah_iqCalData;
720 struct hal_cal_list ah_adcGainCalData;
721 struct hal_cal_list ah_adcDcCalInitData;
722 struct hal_cal_list ah_adcDcCalData;
723 struct hal_cal_list *ah_cal_list;
724 struct hal_cal_list *ah_cal_list_last;
725 struct hal_cal_list *ah_cal_list_curr;
726#define ah_totalPowerMeasI ah_Meas0.unsign
727#define ah_totalPowerMeasQ ah_Meas1.unsign
728#define ah_totalIqCorrMeas ah_Meas2.sign
729#define ah_totalAdcIOddPhase ah_Meas0.unsign
730#define ah_totalAdcIEvenPhase ah_Meas1.unsign
731#define ah_totalAdcQOddPhase ah_Meas2.unsign
732#define ah_totalAdcQEvenPhase ah_Meas3.unsign
733#define ah_totalAdcDcOffsetIOddPhase ah_Meas0.sign
734#define ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign
735#define ah_totalAdcDcOffsetQOddPhase ah_Meas2.sign
736#define ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign
737 union {
738 u32 unsign[AR5416_MAX_CHAINS];
739 int32_t sign[AR5416_MAX_CHAINS];
740 } ah_Meas0;
741 union {
742 u32 unsign[AR5416_MAX_CHAINS];
743 int32_t sign[AR5416_MAX_CHAINS];
744 } ah_Meas1;
745 union {
746 u32 unsign[AR5416_MAX_CHAINS];
747 int32_t sign[AR5416_MAX_CHAINS];
748 } ah_Meas2;
749 union {
750 u32 unsign[AR5416_MAX_CHAINS];
751 int32_t sign[AR5416_MAX_CHAINS];
752 } ah_Meas3;
753 u16 ah_CalSamples;
754 u32 ah_tx6PowerInHalfDbm;
755 u32 ah_staId1Defaults;
756 u32 ah_miscMode;
757 bool ah_tpcEnabled;
758 u32 ah_beaconInterval;
759 enum {
760 AUTO_32KHZ,
761 USE_32KHZ,
762 DONT_USE_32KHZ,
763 } ah_enable32kHzClock;
764 u32 *ah_analogBank0Data;
765 u32 *ah_analogBank1Data;
766 u32 *ah_analogBank2Data;
767 u32 *ah_analogBank3Data;
768 u32 *ah_analogBank6Data;
769 u32 *ah_analogBank6TPCData;
770 u32 *ah_analogBank7Data;
771 u32 *ah_addac5416_21;
772 u32 *ah_bank6Temp;
773 u32 ah_ofdmTxPower;
774 int16_t ah_txPowerIndexOffset;
775 u32 ah_slottime;
776 u32 ah_acktimeout;
777 u32 ah_ctstimeout;
778 u32 ah_globaltxtimeout;
779 u8 ah_gBeaconRate;
780 u32 ah_gpioSelect;
781 u32 ah_polarity;
782 u32 ah_gpioBit;
783 bool ah_eepEnabled;
784 u32 ah_procPhyErr;
785 bool ah_hasHwPhyCounters;
786 u32 ah_aniPeriod;
787 struct ar5416AniState *ah_curani;
788 struct ar5416AniState ah_ani[255];
789 int ah_totalSizeDesired[5];
790 int ah_coarseHigh[5];
791 int ah_coarseLow[5];
792 int ah_firpwr[5];
793 u16 ah_ratesArray[16];
794 u32 ah_intrTxqs;
795 bool ah_intrMitigation;
796 u32 ah_cycleCount;
797 u32 ah_ctlBusy;
798 u32 ah_extBusy;
799 enum ath9k_ht_extprotspacing ah_extprotspacing;
800 u8 ah_txchainmask;
801 u8 ah_rxchainmask;
802 int ah_hwp;
803 void __iomem *ah_cal_mem;
804 enum ath9k_ani_cmd ah_ani_function;
805 struct ar5416IniArray ah_iniModes;
806 struct ar5416IniArray ah_iniCommon;
807 struct ar5416IniArray ah_iniBank0;
808 struct ar5416IniArray ah_iniBB_RfGain;
809 struct ar5416IniArray ah_iniBank1;
810 struct ar5416IniArray ah_iniBank2;
811 struct ar5416IniArray ah_iniBank3;
812 struct ar5416IniArray ah_iniBank6;
813 struct ar5416IniArray ah_iniBank6TPC;
814 struct ar5416IniArray ah_iniBank7;
815 struct ar5416IniArray ah_iniAddac;
816 struct ar5416IniArray ah_iniPcieSerdes;
817 struct ar5416IniArray ah_iniModesAdditional;
818};
819#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
820
821#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
822
823#define IS_5416_EMU(ah) \
824 ((ah->ah_devid == AR5416_DEVID_EMU) || \
825 (ah->ah_devid == AR5416_DEVID_EMU_PCIE))
826
827#define ar5416RfDetach(ah) do { \
828 if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
829 AH5416(ah)->ah_rfHal.rfDetach(ah); \
830 } while (0)
831
832#define ath9k_hw_use_flash(_ah) \
833 (!(_ah->ah_flags & AH_USE_EEPROM))
834
835
836#define DO_DELAY(x) do { \
837 if ((++(x) % 64) == 0) \
838 udelay(1); \
839 } while (0)
840
841#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
842 int r; \
843 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
844 REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
845 INI_RA((iniarray), r, (column))); \
846 DO_DELAY(regWr); \
847 } \
848 } while (0)
849
850#define BASE_ACTIVATE_DELAY 100
851#define RTC_PLL_SETTLE_DELAY 1000
852#define COEF_SCALE_S 24
853#define HT40_CHANNEL_CENTER_SHIFT 10
854
855#define ar5416CheckOpMode(_opmode) \
856 ((_opmode == ATH9K_M_STA) || (_opmode == ATH9K_M_IBSS) || \
857 (_opmode == ATH9K_M_HOSTAP) || (_opmode == ATH9K_M_MONITOR))
858
859#define AR5416_EEPROM_MAGIC_OFFSET 0x0
860
861#define AR5416_EEPROM_S 2
862#define AR5416_EEPROM_OFFSET 0x2000
863#define AR5416_EEPROM_START_ADDR \
864 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
865#define AR5416_EEPROM_MAX 0xae0
866#define ar5416_get_eep_ver(_ahp) \
867 (((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF)
868#define ar5416_get_eep_rev(_ahp) \
869 (((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF)
870#define ar5416_get_ntxchains(_txchainmask) \
871 (((_txchainmask >> 2) & 1) + \
872 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
873
874#define IS_EEP_MINOR_V3(_ahp) \
875 (ath9k_hw_get_eeprom((_ahp), EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_3)
876
877#define FIXED_CCA_THRESHOLD 15
878
879#ifdef __BIG_ENDIAN
880#define AR5416_EEPROM_MAGIC 0x5aa5
881#else
882#define AR5416_EEPROM_MAGIC 0xa55a
883#endif
884
885#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
886
887#define ATH9K_ANTENNA0_CHAINMASK 0x1
888#define ATH9K_ANTENNA1_CHAINMASK 0x2
889
890#define ATH9K_NUM_DMA_DEBUG_REGS 8
891#define ATH9K_NUM_QUEUES 10
892
893#define HAL_NOISE_IMMUNE_MAX 4
894#define HAL_SPUR_IMMUNE_MAX 7
895#define HAL_FIRST_STEP_MAX 2
896
897#define ATH9K_ANI_OFDM_TRIG_HIGH 500
898#define ATH9K_ANI_OFDM_TRIG_LOW 200
899#define ATH9K_ANI_CCK_TRIG_HIGH 200
900#define ATH9K_ANI_CCK_TRIG_LOW 100
901#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
902#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
903#define ATH9K_ANI_CCK_WEAK_SIG_THR false
904#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
905#define ATH9K_ANI_FIRSTEP_LVL 0
906#define ATH9K_ANI_RSSI_THR_HIGH 40
907#define ATH9K_ANI_RSSI_THR_LOW 7
908#define ATH9K_ANI_PERIOD 100
909
910#define AR_GPIOD_MASK 0x00001FFF
911#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
912
913#define MAX_ANALOG_START 319
914
915#define HAL_EP_RND(x, mul) \
916 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
917#define BEACON_RSSI(ahp) \
918 HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
919 ATH9K_RSSI_EP_MULTIPLIER)
920
921#define ah_mibStats ah_stats.ast_mibstats
922
923#define AH_TIMEOUT 100000
924#define AH_TIME_QUANTUM 10
925
926#define IS(_c, _f) (((_c)->channelFlags & _f) || 0)
927
928#define AR_KEYTABLE_SIZE 128
929#define POWER_UP_TIME 200000
930
931#define EXT_ADDITIVE (0x8000)
932#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
933#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
934#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
935
936#define SUB_NUM_CTL_MODES_AT_5G_40 2
937#define SUB_NUM_CTL_MODES_AT_2G_40 3
938#define SPUR_RSSI_THRESH 40
939
940#define TU_TO_USEC(_tu) ((_tu) << 10)
941
942#define CAB_TIMEOUT_VAL 10
943#define BEACON_TIMEOUT_VAL 10
944#define MIN_BEACON_TIMEOUT_VAL 1
945#define SLEEP_SLOP 3
946
947#define CCK_SIFS_TIME 10
948#define CCK_PREAMBLE_BITS 144
949#define CCK_PLCP_BITS 48
950
951#define OFDM_SIFS_TIME 16
952#define OFDM_PREAMBLE_TIME 20
953#define OFDM_PLCP_BITS 22
954#define OFDM_SYMBOL_TIME 4
955
956#define OFDM_SIFS_TIME_HALF 32
957#define OFDM_PREAMBLE_TIME_HALF 40
958#define OFDM_PLCP_BITS_HALF 22
959#define OFDM_SYMBOL_TIME_HALF 8
960
961#define OFDM_SIFS_TIME_QUARTER 64
962#define OFDM_PREAMBLE_TIME_QUARTER 80
963#define OFDM_PLCP_BITS_QUARTER 22
964#define OFDM_SYMBOL_TIME_QUARTER 16
965
966u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
967 enum eeprom_param param);
968
969#endif
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
new file mode 100644
index 000000000000..3dd3815940a4
--- /dev/null
+++ b/drivers/net/wireless/ath9k/initvals.h
@@ -0,0 +1,3146 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17static const u32 ar5416Modes_9100[][6] = {
18 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
19 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
20 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
21 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
22 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
23 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
24 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
25 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
26 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
27 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
28 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
29 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
30 { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
31 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
32 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
33 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
34 { 0x00009850, 0x6de8b4e0, 0x6de8b4e0, 0x6de8b0de, 0x6de8b0de, 0x6de8b0de },
35 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
36 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
37 { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
38 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
39 { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
40 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
41 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
42 { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
43 { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
44 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
45 { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
46 { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
47 { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
48 { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
49 { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
50 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
51 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
52 { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
53 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
54 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
55 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
56 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
57 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
58 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
59 { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
60 { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
61 { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
62 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
63 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
64 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
65 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
66 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
67 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
68 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
69 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
70 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
71 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
72 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
73 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
74 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
75 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
76 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
77 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
78 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
79};
80
81static const u32 ar5416Common_9100[][2] = {
82 { 0x0000000c, 0x00000000 },
83 { 0x00000030, 0x00020015 },
84 { 0x00000034, 0x00000005 },
85 { 0x00000040, 0x00000000 },
86 { 0x00000044, 0x00000008 },
87 { 0x00000048, 0x00000008 },
88 { 0x0000004c, 0x00000010 },
89 { 0x00000050, 0x00000000 },
90 { 0x00000054, 0x0000001f },
91 { 0x00000800, 0x00000000 },
92 { 0x00000804, 0x00000000 },
93 { 0x00000808, 0x00000000 },
94 { 0x0000080c, 0x00000000 },
95 { 0x00000810, 0x00000000 },
96 { 0x00000814, 0x00000000 },
97 { 0x00000818, 0x00000000 },
98 { 0x0000081c, 0x00000000 },
99 { 0x00000820, 0x00000000 },
100 { 0x00000824, 0x00000000 },
101 { 0x00001040, 0x002ffc0f },
102 { 0x00001044, 0x002ffc0f },
103 { 0x00001048, 0x002ffc0f },
104 { 0x0000104c, 0x002ffc0f },
105 { 0x00001050, 0x002ffc0f },
106 { 0x00001054, 0x002ffc0f },
107 { 0x00001058, 0x002ffc0f },
108 { 0x0000105c, 0x002ffc0f },
109 { 0x00001060, 0x002ffc0f },
110 { 0x00001064, 0x002ffc0f },
111 { 0x00001230, 0x00000000 },
112 { 0x00001270, 0x00000000 },
113 { 0x00001038, 0x00000000 },
114 { 0x00001078, 0x00000000 },
115 { 0x000010b8, 0x00000000 },
116 { 0x000010f8, 0x00000000 },
117 { 0x00001138, 0x00000000 },
118 { 0x00001178, 0x00000000 },
119 { 0x000011b8, 0x00000000 },
120 { 0x000011f8, 0x00000000 },
121 { 0x00001238, 0x00000000 },
122 { 0x00001278, 0x00000000 },
123 { 0x000012b8, 0x00000000 },
124 { 0x000012f8, 0x00000000 },
125 { 0x00001338, 0x00000000 },
126 { 0x00001378, 0x00000000 },
127 { 0x000013b8, 0x00000000 },
128 { 0x000013f8, 0x00000000 },
129 { 0x00001438, 0x00000000 },
130 { 0x00001478, 0x00000000 },
131 { 0x000014b8, 0x00000000 },
132 { 0x000014f8, 0x00000000 },
133 { 0x00001538, 0x00000000 },
134 { 0x00001578, 0x00000000 },
135 { 0x000015b8, 0x00000000 },
136 { 0x000015f8, 0x00000000 },
137 { 0x00001638, 0x00000000 },
138 { 0x00001678, 0x00000000 },
139 { 0x000016b8, 0x00000000 },
140 { 0x000016f8, 0x00000000 },
141 { 0x00001738, 0x00000000 },
142 { 0x00001778, 0x00000000 },
143 { 0x000017b8, 0x00000000 },
144 { 0x000017f8, 0x00000000 },
145 { 0x0000103c, 0x00000000 },
146 { 0x0000107c, 0x00000000 },
147 { 0x000010bc, 0x00000000 },
148 { 0x000010fc, 0x00000000 },
149 { 0x0000113c, 0x00000000 },
150 { 0x0000117c, 0x00000000 },
151 { 0x000011bc, 0x00000000 },
152 { 0x000011fc, 0x00000000 },
153 { 0x0000123c, 0x00000000 },
154 { 0x0000127c, 0x00000000 },
155 { 0x000012bc, 0x00000000 },
156 { 0x000012fc, 0x00000000 },
157 { 0x0000133c, 0x00000000 },
158 { 0x0000137c, 0x00000000 },
159 { 0x000013bc, 0x00000000 },
160 { 0x000013fc, 0x00000000 },
161 { 0x0000143c, 0x00000000 },
162 { 0x0000147c, 0x00000000 },
163 { 0x00004030, 0x00000002 },
164 { 0x0000403c, 0x00000002 },
165 { 0x00007010, 0x00000000 },
166 { 0x00007038, 0x000004c2 },
167 { 0x00008004, 0x00000000 },
168 { 0x00008008, 0x00000000 },
169 { 0x0000800c, 0x00000000 },
170 { 0x00008018, 0x00000700 },
171 { 0x00008020, 0x00000000 },
172 { 0x00008038, 0x00000000 },
173 { 0x0000803c, 0x00000000 },
174 { 0x00008048, 0x40000000 },
175 { 0x00008054, 0x00000000 },
176 { 0x00008058, 0x00000000 },
177 { 0x0000805c, 0x000fc78f },
178 { 0x00008060, 0x0000000f },
179 { 0x00008064, 0x00000000 },
180 { 0x000080c0, 0x2a82301a },
181 { 0x000080c4, 0x05dc01e0 },
182 { 0x000080c8, 0x1f402710 },
183 { 0x000080cc, 0x01f40000 },
184 { 0x000080d0, 0x00001e00 },
185 { 0x000080d4, 0x00000000 },
186 { 0x000080d8, 0x00400000 },
187 { 0x000080e0, 0xffffffff },
188 { 0x000080e4, 0x0000ffff },
189 { 0x000080e8, 0x003f3f3f },
190 { 0x000080ec, 0x00000000 },
191 { 0x000080f0, 0x00000000 },
192 { 0x000080f4, 0x00000000 },
193 { 0x000080f8, 0x00000000 },
194 { 0x000080fc, 0x00020000 },
195 { 0x00008100, 0x00020000 },
196 { 0x00008104, 0x00000001 },
197 { 0x00008108, 0x00000052 },
198 { 0x0000810c, 0x00000000 },
199 { 0x00008110, 0x00000168 },
200 { 0x00008118, 0x000100aa },
201 { 0x0000811c, 0x00003210 },
202 { 0x00008120, 0x08f04800 },
203 { 0x00008124, 0x00000000 },
204 { 0x00008128, 0x00000000 },
205 { 0x0000812c, 0x00000000 },
206 { 0x00008130, 0x00000000 },
207 { 0x00008134, 0x00000000 },
208 { 0x00008138, 0x00000000 },
209 { 0x0000813c, 0x00000000 },
210 { 0x00008144, 0x00000000 },
211 { 0x00008168, 0x00000000 },
212 { 0x0000816c, 0x00000000 },
213 { 0x00008170, 0x32143320 },
214 { 0x00008174, 0xfaa4fa50 },
215 { 0x00008178, 0x00000100 },
216 { 0x0000817c, 0x00000000 },
217 { 0x000081c4, 0x00000000 },
218 { 0x000081d0, 0x00003210 },
219 { 0x000081ec, 0x00000000 },
220 { 0x000081f0, 0x00000000 },
221 { 0x000081f4, 0x00000000 },
222 { 0x000081f8, 0x00000000 },
223 { 0x000081fc, 0x00000000 },
224 { 0x00008200, 0x00000000 },
225 { 0x00008204, 0x00000000 },
226 { 0x00008208, 0x00000000 },
227 { 0x0000820c, 0x00000000 },
228 { 0x00008210, 0x00000000 },
229 { 0x00008214, 0x00000000 },
230 { 0x00008218, 0x00000000 },
231 { 0x0000821c, 0x00000000 },
232 { 0x00008220, 0x00000000 },
233 { 0x00008224, 0x00000000 },
234 { 0x00008228, 0x00000000 },
235 { 0x0000822c, 0x00000000 },
236 { 0x00008230, 0x00000000 },
237 { 0x00008234, 0x00000000 },
238 { 0x00008238, 0x00000000 },
239 { 0x0000823c, 0x00000000 },
240 { 0x00008240, 0x00100000 },
241 { 0x00008244, 0x0010f400 },
242 { 0x00008248, 0x00000100 },
243 { 0x0000824c, 0x0001e800 },
244 { 0x00008250, 0x00000000 },
245 { 0x00008254, 0x00000000 },
246 { 0x00008258, 0x00000000 },
247 { 0x0000825c, 0x400000ff },
248 { 0x00008260, 0x00080922 },
249 { 0x00008270, 0x00000000 },
250 { 0x00008274, 0x40000000 },
251 { 0x00008278, 0x003e4180 },
252 { 0x0000827c, 0x00000000 },
253 { 0x00008284, 0x0000002c },
254 { 0x00008288, 0x0000002c },
255 { 0x0000828c, 0x00000000 },
256 { 0x00008294, 0x00000000 },
257 { 0x00008298, 0x00000000 },
258 { 0x00008300, 0x00000000 },
259 { 0x00008304, 0x00000000 },
260 { 0x00008308, 0x00000000 },
261 { 0x0000830c, 0x00000000 },
262 { 0x00008310, 0x00000000 },
263 { 0x00008314, 0x00000000 },
264 { 0x00008318, 0x00000000 },
265 { 0x00008328, 0x00000000 },
266 { 0x0000832c, 0x00000007 },
267 { 0x00008330, 0x00000302 },
268 { 0x00008334, 0x00000e00 },
269 { 0x00008338, 0x00000000 },
270 { 0x0000833c, 0x00000000 },
271 { 0x00008340, 0x000107ff },
272 { 0x00009808, 0x00000000 },
273 { 0x0000980c, 0xad848e19 },
274 { 0x00009810, 0x7d14e000 },
275 { 0x00009814, 0x9c0a9f6b },
276 { 0x0000981c, 0x00000000 },
277 { 0x0000982c, 0x0000a000 },
278 { 0x00009830, 0x00000000 },
279 { 0x0000983c, 0x00200400 },
280 { 0x00009840, 0x206a002e },
281 { 0x0000984c, 0x1284233c },
282 { 0x00009854, 0x00000859 },
283 { 0x00009900, 0x00000000 },
284 { 0x00009904, 0x00000000 },
285 { 0x00009908, 0x00000000 },
286 { 0x0000990c, 0x00000000 },
287 { 0x0000991c, 0x10000fff },
288 { 0x00009920, 0x05100000 },
289 { 0x0000a920, 0x05100000 },
290 { 0x0000b920, 0x05100000 },
291 { 0x00009928, 0x00000001 },
292 { 0x0000992c, 0x00000004 },
293 { 0x00009934, 0x1e1f2022 },
294 { 0x00009938, 0x0a0b0c0d },
295 { 0x0000993c, 0x00000000 },
296 { 0x00009948, 0x9280b212 },
297 { 0x0000994c, 0x00020028 },
298 { 0x00009954, 0x5d50e188 },
299 { 0x00009958, 0x00081fff },
300 { 0x0000c95c, 0x004b6a8e },
301 { 0x0000c968, 0x000003ce },
302 { 0x00009970, 0x190fb515 },
303 { 0x00009974, 0x00000000 },
304 { 0x00009978, 0x00000001 },
305 { 0x0000997c, 0x00000000 },
306 { 0x00009980, 0x00000000 },
307 { 0x00009984, 0x00000000 },
308 { 0x00009988, 0x00000000 },
309 { 0x0000998c, 0x00000000 },
310 { 0x00009990, 0x00000000 },
311 { 0x00009994, 0x00000000 },
312 { 0x00009998, 0x00000000 },
313 { 0x0000999c, 0x00000000 },
314 { 0x000099a0, 0x00000000 },
315 { 0x000099a4, 0x00000001 },
316 { 0x000099a8, 0x001fff00 },
317 { 0x000099ac, 0x00000000 },
318 { 0x000099b0, 0x03051000 },
319 { 0x000099dc, 0x00000000 },
320 { 0x000099e0, 0x00000200 },
321 { 0x000099e4, 0xaaaaaaaa },
322 { 0x000099e8, 0x3c466478 },
323 { 0x000099ec, 0x000000aa },
324 { 0x000099fc, 0x00001042 },
325 { 0x00009b00, 0x00000000 },
326 { 0x00009b04, 0x00000001 },
327 { 0x00009b08, 0x00000002 },
328 { 0x00009b0c, 0x00000003 },
329 { 0x00009b10, 0x00000004 },
330 { 0x00009b14, 0x00000005 },
331 { 0x00009b18, 0x00000008 },
332 { 0x00009b1c, 0x00000009 },
333 { 0x00009b20, 0x0000000a },
334 { 0x00009b24, 0x0000000b },
335 { 0x00009b28, 0x0000000c },
336 { 0x00009b2c, 0x0000000d },
337 { 0x00009b30, 0x00000010 },
338 { 0x00009b34, 0x00000011 },
339 { 0x00009b38, 0x00000012 },
340 { 0x00009b3c, 0x00000013 },
341 { 0x00009b40, 0x00000014 },
342 { 0x00009b44, 0x00000015 },
343 { 0x00009b48, 0x00000018 },
344 { 0x00009b4c, 0x00000019 },
345 { 0x00009b50, 0x0000001a },
346 { 0x00009b54, 0x0000001b },
347 { 0x00009b58, 0x0000001c },
348 { 0x00009b5c, 0x0000001d },
349 { 0x00009b60, 0x00000020 },
350 { 0x00009b64, 0x00000021 },
351 { 0x00009b68, 0x00000022 },
352 { 0x00009b6c, 0x00000023 },
353 { 0x00009b70, 0x00000024 },
354 { 0x00009b74, 0x00000025 },
355 { 0x00009b78, 0x00000028 },
356 { 0x00009b7c, 0x00000029 },
357 { 0x00009b80, 0x0000002a },
358 { 0x00009b84, 0x0000002b },
359 { 0x00009b88, 0x0000002c },
360 { 0x00009b8c, 0x0000002d },
361 { 0x00009b90, 0x00000030 },
362 { 0x00009b94, 0x00000031 },
363 { 0x00009b98, 0x00000032 },
364 { 0x00009b9c, 0x00000033 },
365 { 0x00009ba0, 0x00000034 },
366 { 0x00009ba4, 0x00000035 },
367 { 0x00009ba8, 0x00000035 },
368 { 0x00009bac, 0x00000035 },
369 { 0x00009bb0, 0x00000035 },
370 { 0x00009bb4, 0x00000035 },
371 { 0x00009bb8, 0x00000035 },
372 { 0x00009bbc, 0x00000035 },
373 { 0x00009bc0, 0x00000035 },
374 { 0x00009bc4, 0x00000035 },
375 { 0x00009bc8, 0x00000035 },
376 { 0x00009bcc, 0x00000035 },
377 { 0x00009bd0, 0x00000035 },
378 { 0x00009bd4, 0x00000035 },
379 { 0x00009bd8, 0x00000035 },
380 { 0x00009bdc, 0x00000035 },
381 { 0x00009be0, 0x00000035 },
382 { 0x00009be4, 0x00000035 },
383 { 0x00009be8, 0x00000035 },
384 { 0x00009bec, 0x00000035 },
385 { 0x00009bf0, 0x00000035 },
386 { 0x00009bf4, 0x00000035 },
387 { 0x00009bf8, 0x00000010 },
388 { 0x00009bfc, 0x0000001a },
389 { 0x0000a210, 0x40806333 },
390 { 0x0000a214, 0x00106c10 },
391 { 0x0000a218, 0x009c4060 },
392 { 0x0000a220, 0x018830c6 },
393 { 0x0000a224, 0x00000400 },
394 { 0x0000a228, 0x00000bb5 },
395 { 0x0000a22c, 0x00000011 },
396 { 0x0000a234, 0x20202020 },
397 { 0x0000a238, 0x20202020 },
398 { 0x0000a23c, 0x13c889af },
399 { 0x0000a240, 0x38490a20 },
400 { 0x0000a244, 0x00007bb6 },
401 { 0x0000a248, 0x0fff3ffc },
402 { 0x0000a24c, 0x00000001 },
403 { 0x0000a250, 0x0000a000 },
404 { 0x0000a254, 0x00000000 },
405 { 0x0000a258, 0x0cc75380 },
406 { 0x0000a25c, 0x0f0f0f01 },
407 { 0x0000a260, 0xdfa91f01 },
408 { 0x0000a268, 0x00000000 },
409 { 0x0000a26c, 0x0ebae9c6 },
410 { 0x0000b26c, 0x0ebae9c6 },
411 { 0x0000c26c, 0x0ebae9c6 },
412 { 0x0000d270, 0x00820820 },
413 { 0x0000a278, 0x1ce739ce },
414 { 0x0000a27c, 0x051701ce },
415 { 0x0000a338, 0x00000000 },
416 { 0x0000a33c, 0x00000000 },
417 { 0x0000a340, 0x00000000 },
418 { 0x0000a344, 0x00000000 },
419 { 0x0000a348, 0x3fffffff },
420 { 0x0000a34c, 0x3fffffff },
421 { 0x0000a350, 0x3fffffff },
422 { 0x0000a354, 0x0003ffff },
423 { 0x0000a358, 0x79a8aa1f },
424 { 0x0000d35c, 0x07ffffef },
425 { 0x0000d360, 0x0fffffe7 },
426 { 0x0000d364, 0x17ffffe5 },
427 { 0x0000d368, 0x1fffffe4 },
428 { 0x0000d36c, 0x37ffffe3 },
429 { 0x0000d370, 0x3fffffe3 },
430 { 0x0000d374, 0x57ffffe3 },
431 { 0x0000d378, 0x5fffffe2 },
432 { 0x0000d37c, 0x7fffffe2 },
433 { 0x0000d380, 0x7f3c7bba },
434 { 0x0000d384, 0xf3307ff0 },
435 { 0x0000a388, 0x08000000 },
436 { 0x0000a38c, 0x20202020 },
437 { 0x0000a390, 0x20202020 },
438 { 0x0000a394, 0x1ce739ce },
439 { 0x0000a398, 0x000001ce },
440 { 0x0000a39c, 0x00000001 },
441 { 0x0000a3a0, 0x00000000 },
442 { 0x0000a3a4, 0x00000000 },
443 { 0x0000a3a8, 0x00000000 },
444 { 0x0000a3ac, 0x00000000 },
445 { 0x0000a3b0, 0x00000000 },
446 { 0x0000a3b4, 0x00000000 },
447 { 0x0000a3b8, 0x00000000 },
448 { 0x0000a3bc, 0x00000000 },
449 { 0x0000a3c0, 0x00000000 },
450 { 0x0000a3c4, 0x00000000 },
451 { 0x0000a3c8, 0x00000246 },
452 { 0x0000a3cc, 0x20202020 },
453 { 0x0000a3d0, 0x20202020 },
454 { 0x0000a3d4, 0x20202020 },
455 { 0x0000a3dc, 0x1ce739ce },
456 { 0x0000a3e0, 0x000001ce },
457};
458
459static const u32 ar5416Bank0_9100[][2] = {
460 { 0x000098b0, 0x1e5795e5 },
461 { 0x000098e0, 0x02008020 },
462};
463
464static const u32 ar5416BB_RfGain_9100[][3] = {
465 { 0x00009a00, 0x00000000, 0x00000000 },
466 { 0x00009a04, 0x00000040, 0x00000040 },
467 { 0x00009a08, 0x00000080, 0x00000080 },
468 { 0x00009a0c, 0x000001a1, 0x00000141 },
469 { 0x00009a10, 0x000001e1, 0x00000181 },
470 { 0x00009a14, 0x00000021, 0x000001c1 },
471 { 0x00009a18, 0x00000061, 0x00000001 },
472 { 0x00009a1c, 0x00000168, 0x00000041 },
473 { 0x00009a20, 0x000001a8, 0x000001a8 },
474 { 0x00009a24, 0x000001e8, 0x000001e8 },
475 { 0x00009a28, 0x00000028, 0x00000028 },
476 { 0x00009a2c, 0x00000068, 0x00000068 },
477 { 0x00009a30, 0x00000189, 0x000000a8 },
478 { 0x00009a34, 0x000001c9, 0x00000169 },
479 { 0x00009a38, 0x00000009, 0x000001a9 },
480 { 0x00009a3c, 0x00000049, 0x000001e9 },
481 { 0x00009a40, 0x00000089, 0x00000029 },
482 { 0x00009a44, 0x00000170, 0x00000069 },
483 { 0x00009a48, 0x000001b0, 0x00000190 },
484 { 0x00009a4c, 0x000001f0, 0x000001d0 },
485 { 0x00009a50, 0x00000030, 0x00000010 },
486 { 0x00009a54, 0x00000070, 0x00000050 },
487 { 0x00009a58, 0x00000191, 0x00000090 },
488 { 0x00009a5c, 0x000001d1, 0x00000151 },
489 { 0x00009a60, 0x00000011, 0x00000191 },
490 { 0x00009a64, 0x00000051, 0x000001d1 },
491 { 0x00009a68, 0x00000091, 0x00000011 },
492 { 0x00009a6c, 0x000001b8, 0x00000051 },
493 { 0x00009a70, 0x000001f8, 0x00000198 },
494 { 0x00009a74, 0x00000038, 0x000001d8 },
495 { 0x00009a78, 0x00000078, 0x00000018 },
496 { 0x00009a7c, 0x00000199, 0x00000058 },
497 { 0x00009a80, 0x000001d9, 0x00000098 },
498 { 0x00009a84, 0x00000019, 0x00000159 },
499 { 0x00009a88, 0x00000059, 0x00000199 },
500 { 0x00009a8c, 0x00000099, 0x000001d9 },
501 { 0x00009a90, 0x000000d9, 0x00000019 },
502 { 0x00009a94, 0x000000f9, 0x00000059 },
503 { 0x00009a98, 0x000000f9, 0x00000099 },
504 { 0x00009a9c, 0x000000f9, 0x000000d9 },
505 { 0x00009aa0, 0x000000f9, 0x000000f9 },
506 { 0x00009aa4, 0x000000f9, 0x000000f9 },
507 { 0x00009aa8, 0x000000f9, 0x000000f9 },
508 { 0x00009aac, 0x000000f9, 0x000000f9 },
509 { 0x00009ab0, 0x000000f9, 0x000000f9 },
510 { 0x00009ab4, 0x000000f9, 0x000000f9 },
511 { 0x00009ab8, 0x000000f9, 0x000000f9 },
512 { 0x00009abc, 0x000000f9, 0x000000f9 },
513 { 0x00009ac0, 0x000000f9, 0x000000f9 },
514 { 0x00009ac4, 0x000000f9, 0x000000f9 },
515 { 0x00009ac8, 0x000000f9, 0x000000f9 },
516 { 0x00009acc, 0x000000f9, 0x000000f9 },
517 { 0x00009ad0, 0x000000f9, 0x000000f9 },
518 { 0x00009ad4, 0x000000f9, 0x000000f9 },
519 { 0x00009ad8, 0x000000f9, 0x000000f9 },
520 { 0x00009adc, 0x000000f9, 0x000000f9 },
521 { 0x00009ae0, 0x000000f9, 0x000000f9 },
522 { 0x00009ae4, 0x000000f9, 0x000000f9 },
523 { 0x00009ae8, 0x000000f9, 0x000000f9 },
524 { 0x00009aec, 0x000000f9, 0x000000f9 },
525 { 0x00009af0, 0x000000f9, 0x000000f9 },
526 { 0x00009af4, 0x000000f9, 0x000000f9 },
527 { 0x00009af8, 0x000000f9, 0x000000f9 },
528 { 0x00009afc, 0x000000f9, 0x000000f9 },
529};
530
531static const u32 ar5416Bank1_9100[][2] = {
532 { 0x000098b0, 0x02108421 },
533 { 0x000098ec, 0x00000008 },
534};
535
536static const u32 ar5416Bank2_9100[][2] = {
537 { 0x000098b0, 0x0e73ff17 },
538 { 0x000098e0, 0x00000420 },
539};
540
541static const u32 ar5416Bank3_9100[][3] = {
542 { 0x000098f0, 0x01400018, 0x01c00018 },
543};
544
545static const u32 ar5416Bank6_9100[][3] = {
546
547 { 0x0000989c, 0x00000000, 0x00000000 },
548 { 0x0000989c, 0x00000000, 0x00000000 },
549 { 0x0000989c, 0x00000000, 0x00000000 },
550 { 0x0000989c, 0x00e00000, 0x00e00000 },
551 { 0x0000989c, 0x005e0000, 0x005e0000 },
552 { 0x0000989c, 0x00120000, 0x00120000 },
553 { 0x0000989c, 0x00620000, 0x00620000 },
554 { 0x0000989c, 0x00020000, 0x00020000 },
555 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
556 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
557 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
558 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
559 { 0x0000989c, 0x005f0000, 0x005f0000 },
560 { 0x0000989c, 0x00870000, 0x00870000 },
561 { 0x0000989c, 0x00f90000, 0x00f90000 },
562 { 0x0000989c, 0x007b0000, 0x007b0000 },
563 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
564 { 0x0000989c, 0x00f50000, 0x00f50000 },
565 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
566 { 0x0000989c, 0x00110000, 0x00110000 },
567 { 0x0000989c, 0x006100a8, 0x006100a8 },
568 { 0x0000989c, 0x004210a2, 0x004210a2 },
569 { 0x0000989c, 0x0014008f, 0x0014008f },
570 { 0x0000989c, 0x00c40003, 0x00c40003 },
571 { 0x0000989c, 0x003000f2, 0x003000f2 },
572 { 0x0000989c, 0x00440016, 0x00440016 },
573 { 0x0000989c, 0x00410040, 0x00410040 },
574 { 0x0000989c, 0x0001805e, 0x0001805e },
575 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
576 { 0x0000989c, 0x000000f1, 0x000000f1 },
577 { 0x0000989c, 0x00002081, 0x00002081 },
578 { 0x0000989c, 0x000000d4, 0x000000d4 },
579 { 0x000098d0, 0x0000000f, 0x0010000f },
580};
581
582static const u32 ar5416Bank6TPC_9100[][3] = {
583 { 0x0000989c, 0x00000000, 0x00000000 },
584 { 0x0000989c, 0x00000000, 0x00000000 },
585 { 0x0000989c, 0x00000000, 0x00000000 },
586 { 0x0000989c, 0x00e00000, 0x00e00000 },
587 { 0x0000989c, 0x005e0000, 0x005e0000 },
588 { 0x0000989c, 0x00120000, 0x00120000 },
589 { 0x0000989c, 0x00620000, 0x00620000 },
590 { 0x0000989c, 0x00020000, 0x00020000 },
591 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
592 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
593 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
594 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
595 { 0x0000989c, 0x005f0000, 0x005f0000 },
596 { 0x0000989c, 0x00870000, 0x00870000 },
597 { 0x0000989c, 0x00f90000, 0x00f90000 },
598 { 0x0000989c, 0x007b0000, 0x007b0000 },
599 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
600 { 0x0000989c, 0x00f50000, 0x00f50000 },
601 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
602 { 0x0000989c, 0x00110000, 0x00110000 },
603 { 0x0000989c, 0x006100a8, 0x006100a8 },
604 { 0x0000989c, 0x00423022, 0x00423022 },
605 { 0x0000989c, 0x201400df, 0x201400df },
606 { 0x0000989c, 0x00c40002, 0x00c40002 },
607 { 0x0000989c, 0x003000f2, 0x003000f2 },
608 { 0x0000989c, 0x00440016, 0x00440016 },
609 { 0x0000989c, 0x00410040, 0x00410040 },
610 { 0x0000989c, 0x0001805e, 0x0001805e },
611 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
612 { 0x0000989c, 0x000000e1, 0x000000e1 },
613 { 0x0000989c, 0x00007081, 0x00007081 },
614 { 0x0000989c, 0x000000d4, 0x000000d4 },
615 { 0x000098d0, 0x0000000f, 0x0010000f },
616};
617
618static const u32 ar5416Bank7_9100[][2] = {
619 { 0x0000989c, 0x00000500 },
620 { 0x0000989c, 0x00000800 },
621 { 0x000098cc, 0x0000000e },
622};
623
624static const u32 ar5416Addac_9100[][2] = {
625 {0x0000989c, 0x00000000 },
626 {0x0000989c, 0x00000003 },
627 {0x0000989c, 0x00000000 },
628 {0x0000989c, 0x0000000c },
629 {0x0000989c, 0x00000000 },
630 {0x0000989c, 0x00000030 },
631 {0x0000989c, 0x00000000 },
632 {0x0000989c, 0x00000000 },
633 {0x0000989c, 0x00000000 },
634 {0x0000989c, 0x00000000 },
635 {0x0000989c, 0x00000000 },
636 {0x0000989c, 0x00000000 },
637 {0x0000989c, 0x00000000 },
638 {0x0000989c, 0x00000000 },
639 {0x0000989c, 0x00000000 },
640 {0x0000989c, 0x00000000 },
641 {0x0000989c, 0x00000000 },
642 {0x0000989c, 0x00000000 },
643 {0x0000989c, 0x00000060 },
644 {0x0000989c, 0x00000000 },
645 {0x0000989c, 0x00000000 },
646 {0x0000989c, 0x00000000 },
647 {0x0000989c, 0x00000000 },
648 {0x0000989c, 0x00000000 },
649 {0x0000989c, 0x00000000 },
650 {0x0000989c, 0x00000000 },
651 {0x0000989c, 0x00000000 },
652 {0x0000989c, 0x00000000 },
653 {0x0000989c, 0x00000000 },
654 {0x0000989c, 0x00000000 },
655 {0x0000989c, 0x00000000 },
656 {0x0000989c, 0x00000058 },
657 {0x0000989c, 0x00000000 },
658 {0x0000989c, 0x00000000 },
659 {0x0000989c, 0x00000000 },
660 {0x0000989c, 0x00000000 },
661 {0x000098c4, 0x00000000 },
662};
663
664static const u32 ar5416Modes[][6] = {
665 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
666 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
667 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
668 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
669 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
670 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
671 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
672 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
673 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
674 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
675 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
676 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
677 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
678 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
679 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
680 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
681 { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
682 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
683 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
684 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
685 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
686 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
687 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
688 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
689 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
690 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
691 { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
692 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
693 { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
694 { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
695#ifdef TB243
696 { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
697 { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
698 { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
699 { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
700#else
701 { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
702 { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
703 { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
704 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
705#endif
706 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
707 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
708 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
709 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
710 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
711 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
712 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
713 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
714 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
715 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
716 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
717 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
718 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
719 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
720 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
721 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
722 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
723 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
724 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
725 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
726 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
727 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
728 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
729 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
730 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
731 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
732 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
733 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
734 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
735 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
736};
737
738static const u32 ar5416Common[][2] = {
739 { 0x0000000c, 0x00000000 },
740 { 0x00000030, 0x00020015 },
741 { 0x00000034, 0x00000005 },
742 { 0x00000040, 0x00000000 },
743 { 0x00000044, 0x00000008 },
744 { 0x00000048, 0x00000008 },
745 { 0x0000004c, 0x00000010 },
746 { 0x00000050, 0x00000000 },
747 { 0x00000054, 0x0000001f },
748 { 0x00000800, 0x00000000 },
749 { 0x00000804, 0x00000000 },
750 { 0x00000808, 0x00000000 },
751 { 0x0000080c, 0x00000000 },
752 { 0x00000810, 0x00000000 },
753 { 0x00000814, 0x00000000 },
754 { 0x00000818, 0x00000000 },
755 { 0x0000081c, 0x00000000 },
756 { 0x00000820, 0x00000000 },
757 { 0x00000824, 0x00000000 },
758 { 0x00001040, 0x002ffc0f },
759 { 0x00001044, 0x002ffc0f },
760 { 0x00001048, 0x002ffc0f },
761 { 0x0000104c, 0x002ffc0f },
762 { 0x00001050, 0x002ffc0f },
763 { 0x00001054, 0x002ffc0f },
764 { 0x00001058, 0x002ffc0f },
765 { 0x0000105c, 0x002ffc0f },
766 { 0x00001060, 0x002ffc0f },
767 { 0x00001064, 0x002ffc0f },
768 { 0x00001230, 0x00000000 },
769 { 0x00001270, 0x00000000 },
770 { 0x00001038, 0x00000000 },
771 { 0x00001078, 0x00000000 },
772 { 0x000010b8, 0x00000000 },
773 { 0x000010f8, 0x00000000 },
774 { 0x00001138, 0x00000000 },
775 { 0x00001178, 0x00000000 },
776 { 0x000011b8, 0x00000000 },
777 { 0x000011f8, 0x00000000 },
778 { 0x00001238, 0x00000000 },
779 { 0x00001278, 0x00000000 },
780 { 0x000012b8, 0x00000000 },
781 { 0x000012f8, 0x00000000 },
782 { 0x00001338, 0x00000000 },
783 { 0x00001378, 0x00000000 },
784 { 0x000013b8, 0x00000000 },
785 { 0x000013f8, 0x00000000 },
786 { 0x00001438, 0x00000000 },
787 { 0x00001478, 0x00000000 },
788 { 0x000014b8, 0x00000000 },
789 { 0x000014f8, 0x00000000 },
790 { 0x00001538, 0x00000000 },
791 { 0x00001578, 0x00000000 },
792 { 0x000015b8, 0x00000000 },
793 { 0x000015f8, 0x00000000 },
794 { 0x00001638, 0x00000000 },
795 { 0x00001678, 0x00000000 },
796 { 0x000016b8, 0x00000000 },
797 { 0x000016f8, 0x00000000 },
798 { 0x00001738, 0x00000000 },
799 { 0x00001778, 0x00000000 },
800 { 0x000017b8, 0x00000000 },
801 { 0x000017f8, 0x00000000 },
802 { 0x0000103c, 0x00000000 },
803 { 0x0000107c, 0x00000000 },
804 { 0x000010bc, 0x00000000 },
805 { 0x000010fc, 0x00000000 },
806 { 0x0000113c, 0x00000000 },
807 { 0x0000117c, 0x00000000 },
808 { 0x000011bc, 0x00000000 },
809 { 0x000011fc, 0x00000000 },
810 { 0x0000123c, 0x00000000 },
811 { 0x0000127c, 0x00000000 },
812 { 0x000012bc, 0x00000000 },
813 { 0x000012fc, 0x00000000 },
814 { 0x0000133c, 0x00000000 },
815 { 0x0000137c, 0x00000000 },
816 { 0x000013bc, 0x00000000 },
817 { 0x000013fc, 0x00000000 },
818 { 0x0000143c, 0x00000000 },
819 { 0x0000147c, 0x00000000 },
820 { 0x00020010, 0x00000003 },
821 { 0x00020038, 0x000004c2 },
822 { 0x00008004, 0x00000000 },
823 { 0x00008008, 0x00000000 },
824 { 0x0000800c, 0x00000000 },
825 { 0x00008018, 0x00000700 },
826 { 0x00008020, 0x00000000 },
827 { 0x00008038, 0x00000000 },
828 { 0x0000803c, 0x00000000 },
829 { 0x00008048, 0x40000000 },
830 { 0x00008054, 0x00004000 },
831 { 0x00008058, 0x00000000 },
832 { 0x0000805c, 0x000fc78f },
833 { 0x00008060, 0x0000000f },
834 { 0x00008064, 0x00000000 },
835 { 0x000080c0, 0x2a82301a },
836 { 0x000080c4, 0x05dc01e0 },
837 { 0x000080c8, 0x1f402710 },
838 { 0x000080cc, 0x01f40000 },
839 { 0x000080d0, 0x00001e00 },
840 { 0x000080d4, 0x00000000 },
841 { 0x000080d8, 0x00400000 },
842 { 0x000080e0, 0xffffffff },
843 { 0x000080e4, 0x0000ffff },
844 { 0x000080e8, 0x003f3f3f },
845 { 0x000080ec, 0x00000000 },
846 { 0x000080f0, 0x00000000 },
847 { 0x000080f4, 0x00000000 },
848 { 0x000080f8, 0x00000000 },
849 { 0x000080fc, 0x00020000 },
850 { 0x00008100, 0x00020000 },
851 { 0x00008104, 0x00000001 },
852 { 0x00008108, 0x00000052 },
853 { 0x0000810c, 0x00000000 },
854 { 0x00008110, 0x00000168 },
855 { 0x00008118, 0x000100aa },
856 { 0x0000811c, 0x00003210 },
857 { 0x00008120, 0x08f04800 },
858 { 0x00008124, 0x00000000 },
859 { 0x00008128, 0x00000000 },
860 { 0x0000812c, 0x00000000 },
861 { 0x00008130, 0x00000000 },
862 { 0x00008134, 0x00000000 },
863 { 0x00008138, 0x00000000 },
864 { 0x0000813c, 0x00000000 },
865 { 0x00008144, 0x00000000 },
866 { 0x00008168, 0x00000000 },
867 { 0x0000816c, 0x00000000 },
868 { 0x00008170, 0x32143320 },
869 { 0x00008174, 0xfaa4fa50 },
870 { 0x00008178, 0x00000100 },
871 { 0x0000817c, 0x00000000 },
872 { 0x000081c4, 0x00000000 },
873 { 0x000081d0, 0x00003210 },
874 { 0x000081ec, 0x00000000 },
875 { 0x000081f0, 0x00000000 },
876 { 0x000081f4, 0x00000000 },
877 { 0x000081f8, 0x00000000 },
878 { 0x000081fc, 0x00000000 },
879 { 0x00008200, 0x00000000 },
880 { 0x00008204, 0x00000000 },
881 { 0x00008208, 0x00000000 },
882 { 0x0000820c, 0x00000000 },
883 { 0x00008210, 0x00000000 },
884 { 0x00008214, 0x00000000 },
885 { 0x00008218, 0x00000000 },
886 { 0x0000821c, 0x00000000 },
887 { 0x00008220, 0x00000000 },
888 { 0x00008224, 0x00000000 },
889 { 0x00008228, 0x00000000 },
890 { 0x0000822c, 0x00000000 },
891 { 0x00008230, 0x00000000 },
892 { 0x00008234, 0x00000000 },
893 { 0x00008238, 0x00000000 },
894 { 0x0000823c, 0x00000000 },
895 { 0x00008240, 0x00100000 },
896 { 0x00008244, 0x0010f400 },
897 { 0x00008248, 0x00000100 },
898 { 0x0000824c, 0x0001e800 },
899 { 0x00008250, 0x00000000 },
900 { 0x00008254, 0x00000000 },
901 { 0x00008258, 0x00000000 },
902 { 0x0000825c, 0x400000ff },
903 { 0x00008260, 0x00080922 },
904 { 0x00008270, 0x00000000 },
905 { 0x00008274, 0x40000000 },
906 { 0x00008278, 0x003e4180 },
907 { 0x0000827c, 0x00000000 },
908 { 0x00008284, 0x0000002c },
909 { 0x00008288, 0x0000002c },
910 { 0x0000828c, 0x00000000 },
911 { 0x00008294, 0x00000000 },
912 { 0x00008298, 0x00000000 },
913 { 0x00008300, 0x00000000 },
914 { 0x00008304, 0x00000000 },
915 { 0x00008308, 0x00000000 },
916 { 0x0000830c, 0x00000000 },
917 { 0x00008310, 0x00000000 },
918 { 0x00008314, 0x00000000 },
919 { 0x00008318, 0x00000000 },
920 { 0x00008328, 0x00000000 },
921 { 0x0000832c, 0x00000007 },
922 { 0x00008330, 0x00000302 },
923 { 0x00008334, 0x00000e00 },
924 { 0x00008338, 0x00000000 },
925 { 0x0000833c, 0x00000000 },
926 { 0x00008340, 0x000107ff },
927 { 0x00009808, 0x00000000 },
928 { 0x0000980c, 0xad848e19 },
929 { 0x00009810, 0x7d14e000 },
930 { 0x00009814, 0x9c0a9f6b },
931 { 0x0000981c, 0x00000000 },
932 { 0x0000982c, 0x0000a000 },
933 { 0x00009830, 0x00000000 },
934 { 0x0000983c, 0x00200400 },
935 { 0x00009840, 0x206a01ae },
936 { 0x0000984c, 0x1284233c },
937 { 0x00009854, 0x00000859 },
938 { 0x00009900, 0x00000000 },
939 { 0x00009904, 0x00000000 },
940 { 0x00009908, 0x00000000 },
941 { 0x0000990c, 0x00000000 },
942 { 0x0000991c, 0x10000fff },
943 { 0x00009920, 0x05100000 },
944 { 0x0000a920, 0x05100000 },
945 { 0x0000b920, 0x05100000 },
946 { 0x00009928, 0x00000001 },
947 { 0x0000992c, 0x00000004 },
948 { 0x00009934, 0x1e1f2022 },
949 { 0x00009938, 0x0a0b0c0d },
950 { 0x0000993c, 0x00000000 },
951 { 0x00009948, 0x9280b212 },
952 { 0x0000994c, 0x00020028 },
953 { 0x0000c95c, 0x004b6a8e },
954 { 0x0000c968, 0x000003ce },
955 { 0x00009970, 0x190fb514 },
956 { 0x00009974, 0x00000000 },
957 { 0x00009978, 0x00000001 },
958 { 0x0000997c, 0x00000000 },
959 { 0x00009980, 0x00000000 },
960 { 0x00009984, 0x00000000 },
961 { 0x00009988, 0x00000000 },
962 { 0x0000998c, 0x00000000 },
963 { 0x00009990, 0x00000000 },
964 { 0x00009994, 0x00000000 },
965 { 0x00009998, 0x00000000 },
966 { 0x0000999c, 0x00000000 },
967 { 0x000099a0, 0x00000000 },
968 { 0x000099a4, 0x00000001 },
969 { 0x000099a8, 0x201fff00 },
970 { 0x000099ac, 0x006f0000 },
971 { 0x000099b0, 0x03051000 },
972 { 0x000099dc, 0x00000000 },
973 { 0x000099e0, 0x00000200 },
974 { 0x000099e4, 0xaaaaaaaa },
975 { 0x000099e8, 0x3c466478 },
976 { 0x000099ec, 0x0cc80caa },
977 { 0x000099fc, 0x00001042 },
978 { 0x00009b00, 0x00000000 },
979 { 0x00009b04, 0x00000001 },
980 { 0x00009b08, 0x00000002 },
981 { 0x00009b0c, 0x00000003 },
982 { 0x00009b10, 0x00000004 },
983 { 0x00009b14, 0x00000005 },
984 { 0x00009b18, 0x00000008 },
985 { 0x00009b1c, 0x00000009 },
986 { 0x00009b20, 0x0000000a },
987 { 0x00009b24, 0x0000000b },
988 { 0x00009b28, 0x0000000c },
989 { 0x00009b2c, 0x0000000d },
990 { 0x00009b30, 0x00000010 },
991 { 0x00009b34, 0x00000011 },
992 { 0x00009b38, 0x00000012 },
993 { 0x00009b3c, 0x00000013 },
994 { 0x00009b40, 0x00000014 },
995 { 0x00009b44, 0x00000015 },
996 { 0x00009b48, 0x00000018 },
997 { 0x00009b4c, 0x00000019 },
998 { 0x00009b50, 0x0000001a },
999 { 0x00009b54, 0x0000001b },
1000 { 0x00009b58, 0x0000001c },
1001 { 0x00009b5c, 0x0000001d },
1002 { 0x00009b60, 0x00000020 },
1003 { 0x00009b64, 0x00000021 },
1004 { 0x00009b68, 0x00000022 },
1005 { 0x00009b6c, 0x00000023 },
1006 { 0x00009b70, 0x00000024 },
1007 { 0x00009b74, 0x00000025 },
1008 { 0x00009b78, 0x00000028 },
1009 { 0x00009b7c, 0x00000029 },
1010 { 0x00009b80, 0x0000002a },
1011 { 0x00009b84, 0x0000002b },
1012 { 0x00009b88, 0x0000002c },
1013 { 0x00009b8c, 0x0000002d },
1014 { 0x00009b90, 0x00000030 },
1015 { 0x00009b94, 0x00000031 },
1016 { 0x00009b98, 0x00000032 },
1017 { 0x00009b9c, 0x00000033 },
1018 { 0x00009ba0, 0x00000034 },
1019 { 0x00009ba4, 0x00000035 },
1020 { 0x00009ba8, 0x00000035 },
1021 { 0x00009bac, 0x00000035 },
1022 { 0x00009bb0, 0x00000035 },
1023 { 0x00009bb4, 0x00000035 },
1024 { 0x00009bb8, 0x00000035 },
1025 { 0x00009bbc, 0x00000035 },
1026 { 0x00009bc0, 0x00000035 },
1027 { 0x00009bc4, 0x00000035 },
1028 { 0x00009bc8, 0x00000035 },
1029 { 0x00009bcc, 0x00000035 },
1030 { 0x00009bd0, 0x00000035 },
1031 { 0x00009bd4, 0x00000035 },
1032 { 0x00009bd8, 0x00000035 },
1033 { 0x00009bdc, 0x00000035 },
1034 { 0x00009be0, 0x00000035 },
1035 { 0x00009be4, 0x00000035 },
1036 { 0x00009be8, 0x00000035 },
1037 { 0x00009bec, 0x00000035 },
1038 { 0x00009bf0, 0x00000035 },
1039 { 0x00009bf4, 0x00000035 },
1040 { 0x00009bf8, 0x00000010 },
1041 { 0x00009bfc, 0x0000001a },
1042 { 0x0000a210, 0x40806333 },
1043 { 0x0000a214, 0x00106c10 },
1044 { 0x0000a218, 0x009c4060 },
1045 { 0x0000a220, 0x018830c6 },
1046 { 0x0000a224, 0x00000400 },
1047 { 0x0000a228, 0x001a0bb5 },
1048 { 0x0000a22c, 0x00000000 },
1049 { 0x0000a234, 0x20202020 },
1050 { 0x0000a238, 0x20202020 },
1051 { 0x0000a23c, 0x13c889ae },
1052 { 0x0000a240, 0x38490a20 },
1053 { 0x0000a244, 0x00007bb6 },
1054 { 0x0000a248, 0x0fff3ffc },
1055 { 0x0000a24c, 0x00000001 },
1056 { 0x0000a250, 0x0000a000 },
1057 { 0x0000a254, 0x00000000 },
1058 { 0x0000a258, 0x0cc75380 },
1059 { 0x0000a25c, 0x0f0f0f01 },
1060 { 0x0000a260, 0xdfa91f01 },
1061 { 0x0000a268, 0x00000001 },
1062 { 0x0000a26c, 0x0ebae9c6 },
1063 { 0x0000b26c, 0x0ebae9c6 },
1064 { 0x0000c26c, 0x0ebae9c6 },
1065 { 0x0000d270, 0x00820820 },
1066 { 0x0000a278, 0x1ce739ce },
1067 { 0x0000a27c, 0x050701ce },
1068 { 0x0000a338, 0x00000000 },
1069 { 0x0000a33c, 0x00000000 },
1070 { 0x0000a340, 0x00000000 },
1071 { 0x0000a344, 0x00000000 },
1072 { 0x0000a348, 0x3fffffff },
1073 { 0x0000a34c, 0x3fffffff },
1074 { 0x0000a350, 0x3fffffff },
1075 { 0x0000a354, 0x0003ffff },
1076 { 0x0000a358, 0x79a8aa33 },
1077 { 0x0000d35c, 0x07ffffef },
1078 { 0x0000d360, 0x0fffffe7 },
1079 { 0x0000d364, 0x17ffffe5 },
1080 { 0x0000d368, 0x1fffffe4 },
1081 { 0x0000d36c, 0x37ffffe3 },
1082 { 0x0000d370, 0x3fffffe3 },
1083 { 0x0000d374, 0x57ffffe3 },
1084 { 0x0000d378, 0x5fffffe2 },
1085 { 0x0000d37c, 0x7fffffe2 },
1086 { 0x0000d380, 0x7f3c7bba },
1087 { 0x0000d384, 0xf3307ff0 },
1088 { 0x0000a388, 0x0c000000 },
1089 { 0x0000a38c, 0x20202020 },
1090 { 0x0000a390, 0x20202020 },
1091 { 0x0000a394, 0x1ce739ce },
1092 { 0x0000a398, 0x000001ce },
1093 { 0x0000a39c, 0x00000001 },
1094 { 0x0000a3a0, 0x00000000 },
1095 { 0x0000a3a4, 0x00000000 },
1096 { 0x0000a3a8, 0x00000000 },
1097 { 0x0000a3ac, 0x00000000 },
1098 { 0x0000a3b0, 0x00000000 },
1099 { 0x0000a3b4, 0x00000000 },
1100 { 0x0000a3b8, 0x00000000 },
1101 { 0x0000a3bc, 0x00000000 },
1102 { 0x0000a3c0, 0x00000000 },
1103 { 0x0000a3c4, 0x00000000 },
1104 { 0x0000a3c8, 0x00000246 },
1105 { 0x0000a3cc, 0x20202020 },
1106 { 0x0000a3d0, 0x20202020 },
1107 { 0x0000a3d4, 0x20202020 },
1108 { 0x0000a3dc, 0x1ce739ce },
1109 { 0x0000a3e0, 0x000001ce },
1110};
1111
1112static const u32 ar5416Bank0[][2] = {
1113 { 0x000098b0, 0x1e5795e5 },
1114 { 0x000098e0, 0x02008020 },
1115};
1116
1117static const u32 ar5416BB_RfGain[][3] = {
1118 { 0x00009a00, 0x00000000, 0x00000000 },
1119 { 0x00009a04, 0x00000040, 0x00000040 },
1120 { 0x00009a08, 0x00000080, 0x00000080 },
1121 { 0x00009a0c, 0x000001a1, 0x00000141 },
1122 { 0x00009a10, 0x000001e1, 0x00000181 },
1123 { 0x00009a14, 0x00000021, 0x000001c1 },
1124 { 0x00009a18, 0x00000061, 0x00000001 },
1125 { 0x00009a1c, 0x00000168, 0x00000041 },
1126 { 0x00009a20, 0x000001a8, 0x000001a8 },
1127 { 0x00009a24, 0x000001e8, 0x000001e8 },
1128 { 0x00009a28, 0x00000028, 0x00000028 },
1129 { 0x00009a2c, 0x00000068, 0x00000068 },
1130 { 0x00009a30, 0x00000189, 0x000000a8 },
1131 { 0x00009a34, 0x000001c9, 0x00000169 },
1132 { 0x00009a38, 0x00000009, 0x000001a9 },
1133 { 0x00009a3c, 0x00000049, 0x000001e9 },
1134 { 0x00009a40, 0x00000089, 0x00000029 },
1135 { 0x00009a44, 0x00000170, 0x00000069 },
1136 { 0x00009a48, 0x000001b0, 0x00000190 },
1137 { 0x00009a4c, 0x000001f0, 0x000001d0 },
1138 { 0x00009a50, 0x00000030, 0x00000010 },
1139 { 0x00009a54, 0x00000070, 0x00000050 },
1140 { 0x00009a58, 0x00000191, 0x00000090 },
1141 { 0x00009a5c, 0x000001d1, 0x00000151 },
1142 { 0x00009a60, 0x00000011, 0x00000191 },
1143 { 0x00009a64, 0x00000051, 0x000001d1 },
1144 { 0x00009a68, 0x00000091, 0x00000011 },
1145 { 0x00009a6c, 0x000001b8, 0x00000051 },
1146 { 0x00009a70, 0x000001f8, 0x00000198 },
1147 { 0x00009a74, 0x00000038, 0x000001d8 },
1148 { 0x00009a78, 0x00000078, 0x00000018 },
1149 { 0x00009a7c, 0x00000199, 0x00000058 },
1150 { 0x00009a80, 0x000001d9, 0x00000098 },
1151 { 0x00009a84, 0x00000019, 0x00000159 },
1152 { 0x00009a88, 0x00000059, 0x00000199 },
1153 { 0x00009a8c, 0x00000099, 0x000001d9 },
1154 { 0x00009a90, 0x000000d9, 0x00000019 },
1155 { 0x00009a94, 0x000000f9, 0x00000059 },
1156 { 0x00009a98, 0x000000f9, 0x00000099 },
1157 { 0x00009a9c, 0x000000f9, 0x000000d9 },
1158 { 0x00009aa0, 0x000000f9, 0x000000f9 },
1159 { 0x00009aa4, 0x000000f9, 0x000000f9 },
1160 { 0x00009aa8, 0x000000f9, 0x000000f9 },
1161 { 0x00009aac, 0x000000f9, 0x000000f9 },
1162 { 0x00009ab0, 0x000000f9, 0x000000f9 },
1163 { 0x00009ab4, 0x000000f9, 0x000000f9 },
1164 { 0x00009ab8, 0x000000f9, 0x000000f9 },
1165 { 0x00009abc, 0x000000f9, 0x000000f9 },
1166 { 0x00009ac0, 0x000000f9, 0x000000f9 },
1167 { 0x00009ac4, 0x000000f9, 0x000000f9 },
1168 { 0x00009ac8, 0x000000f9, 0x000000f9 },
1169 { 0x00009acc, 0x000000f9, 0x000000f9 },
1170 { 0x00009ad0, 0x000000f9, 0x000000f9 },
1171 { 0x00009ad4, 0x000000f9, 0x000000f9 },
1172 { 0x00009ad8, 0x000000f9, 0x000000f9 },
1173 { 0x00009adc, 0x000000f9, 0x000000f9 },
1174 { 0x00009ae0, 0x000000f9, 0x000000f9 },
1175 { 0x00009ae4, 0x000000f9, 0x000000f9 },
1176 { 0x00009ae8, 0x000000f9, 0x000000f9 },
1177 { 0x00009aec, 0x000000f9, 0x000000f9 },
1178 { 0x00009af0, 0x000000f9, 0x000000f9 },
1179 { 0x00009af4, 0x000000f9, 0x000000f9 },
1180 { 0x00009af8, 0x000000f9, 0x000000f9 },
1181 { 0x00009afc, 0x000000f9, 0x000000f9 },
1182};
1183
1184static const u32 ar5416Bank1[][2] = {
1185 { 0x000098b0, 0x02108421},
1186 { 0x000098ec, 0x00000008},
1187};
1188
1189static const u32 ar5416Bank2[][2] = {
1190 { 0x000098b0, 0x0e73ff17},
1191 { 0x000098e0, 0x00000420},
1192};
1193
1194static const u32 ar5416Bank3[][3] = {
1195 { 0x000098f0, 0x01400018, 0x01c00018 },
1196};
1197
1198static const u32 ar5416Bank6[][3] = {
1199
1200 { 0x0000989c, 0x00000000, 0x00000000 },
1201 { 0x0000989c, 0x00000000, 0x00000000 },
1202 { 0x0000989c, 0x00000000, 0x00000000 },
1203 { 0x0000989c, 0x00e00000, 0x00e00000 },
1204 { 0x0000989c, 0x005e0000, 0x005e0000 },
1205 { 0x0000989c, 0x00120000, 0x00120000 },
1206 { 0x0000989c, 0x00620000, 0x00620000 },
1207 { 0x0000989c, 0x00020000, 0x00020000 },
1208 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1209 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1210 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1211 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1212 { 0x0000989c, 0x005f0000, 0x005f0000 },
1213 { 0x0000989c, 0x00870000, 0x00870000 },
1214 { 0x0000989c, 0x00f90000, 0x00f90000 },
1215 { 0x0000989c, 0x007b0000, 0x007b0000 },
1216 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1217 { 0x0000989c, 0x00f50000, 0x00f50000 },
1218 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1219 { 0x0000989c, 0x00110000, 0x00110000 },
1220 { 0x0000989c, 0x006100a8, 0x006100a8 },
1221 { 0x0000989c, 0x004210a2, 0x004210a2 },
1222 { 0x0000989c, 0x0014000f, 0x0014000f },
1223 { 0x0000989c, 0x00c40002, 0x00c40002 },
1224 { 0x0000989c, 0x003000f2, 0x003000f2 },
1225 { 0x0000989c, 0x00440016, 0x00440016 },
1226 { 0x0000989c, 0x00410040, 0x00410040 },
1227 { 0x0000989c, 0x000180d6, 0x000180d6 },
1228 { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
1229 { 0x0000989c, 0x000000b1, 0x000000b1 },
1230 { 0x0000989c, 0x00002000, 0x00002000 },
1231 { 0x0000989c, 0x000000d4, 0x000000d4 },
1232 { 0x000098d0, 0x0000000f, 0x0010000f },
1233};
1234
1235
1236static const u32 ar5416Bank6TPC[][3] = {
1237
1238 { 0x0000989c, 0x00000000, 0x00000000 },
1239 { 0x0000989c, 0x00000000, 0x00000000 },
1240 { 0x0000989c, 0x00000000, 0x00000000 },
1241 { 0x0000989c, 0x00e00000, 0x00e00000 },
1242 { 0x0000989c, 0x005e0000, 0x005e0000 },
1243 { 0x0000989c, 0x00120000, 0x00120000 },
1244 { 0x0000989c, 0x00620000, 0x00620000 },
1245 { 0x0000989c, 0x00020000, 0x00020000 },
1246 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1247 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1248 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1249 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1250 { 0x0000989c, 0x005f0000, 0x005f0000 },
1251 { 0x0000989c, 0x00870000, 0x00870000 },
1252 { 0x0000989c, 0x00f90000, 0x00f90000 },
1253 { 0x0000989c, 0x007b0000, 0x007b0000 },
1254 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1255 { 0x0000989c, 0x00f50000, 0x00f50000 },
1256 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1257 { 0x0000989c, 0x00110000, 0x00110000 },
1258 { 0x0000989c, 0x006100a8, 0x006100a8 },
1259 { 0x0000989c, 0x00423022, 0x00423022 },
1260 { 0x0000989c, 0x2014008f, 0x2014008f },
1261 { 0x0000989c, 0x00c40002, 0x00c40002 },
1262 { 0x0000989c, 0x003000f2, 0x003000f2 },
1263 { 0x0000989c, 0x00440016, 0x00440016 },
1264 { 0x0000989c, 0x00410040, 0x00410040 },
1265 { 0x0000989c, 0x0001805e, 0x0001805e },
1266 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1267 { 0x0000989c, 0x000000e1, 0x000000e1 },
1268 { 0x0000989c, 0x00007080, 0x00007080 },
1269 { 0x0000989c, 0x000000d4, 0x000000d4 },
1270 { 0x000098d0, 0x0000000f, 0x0010000f },
1271};
1272
1273static const u32 ar5416Bank7[][2] = {
1274 { 0x0000989c, 0x00000500 },
1275 { 0x0000989c, 0x00000800 },
1276 { 0x000098cc, 0x0000000e },
1277};
1278
1279static const u32 ar5416Addac[][2] = {
1280 {0x0000989c, 0x00000000 },
1281 {0x0000989c, 0x00000000 },
1282 {0x0000989c, 0x00000000 },
1283 {0x0000989c, 0x00000000 },
1284 {0x0000989c, 0x00000000 },
1285 {0x0000989c, 0x00000000 },
1286 {0x0000989c, 0x00000000 },
1287 {0x0000989c, 0x00000010 },
1288 {0x0000989c, 0x00000000 },
1289 {0x0000989c, 0x00000000 },
1290 {0x0000989c, 0x00000000 },
1291 {0x0000989c, 0x00000000 },
1292 {0x0000989c, 0x00000000 },
1293 {0x0000989c, 0x00000000 },
1294 {0x0000989c, 0x00000000 },
1295 {0x0000989c, 0x00000000 },
1296 {0x0000989c, 0x00000000 },
1297 {0x0000989c, 0x00000000 },
1298 {0x0000989c, 0x00000000 },
1299 {0x0000989c, 0x00000000 },
1300 {0x0000989c, 0x00000000 },
1301 {0x0000989c, 0x000000c0 },
1302 {0x0000989c, 0x00000015 },
1303 {0x0000989c, 0x00000000 },
1304 {0x0000989c, 0x00000000 },
1305 {0x0000989c, 0x00000000 },
1306 {0x0000989c, 0x00000000 },
1307 {0x0000989c, 0x00000000 },
1308 {0x0000989c, 0x00000000 },
1309 {0x0000989c, 0x00000000 },
1310 {0x0000989c, 0x00000000 },
1311 {0x000098cc, 0x00000000 },
1312};
1313
1314
1315static const u32 ar5416Modes_9160[][6] = {
1316 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
1317 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
1318 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
1319 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
1320 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
1321 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
1322 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
1323 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
1324 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
1325 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
1326 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
1327 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
1328 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
1329 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1330 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1331 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1332 { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
1333 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
1334 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
1335 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
1336 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
1337 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
1338 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
1339 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
1340 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
1341 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
1342 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
1343 { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1344 { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1345 { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1346 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
1347 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
1348 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
1349 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
1350 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
1351 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
1352 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
1353 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1354 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1355 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
1356 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
1357 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1358 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1359 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1360 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
1361 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
1362 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
1363 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
1364 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
1365 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
1366 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
1367 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
1368 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
1369 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
1370 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
1371 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
1372 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
1373 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
1374 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1375 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1376 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1377};
1378
1379static const u32 ar5416Common_9160[][2] = {
1380 { 0x0000000c, 0x00000000 },
1381 { 0x00000030, 0x00020015 },
1382 { 0x00000034, 0x00000005 },
1383 { 0x00000040, 0x00000000 },
1384 { 0x00000044, 0x00000008 },
1385 { 0x00000048, 0x00000008 },
1386 { 0x0000004c, 0x00000010 },
1387 { 0x00000050, 0x00000000 },
1388 { 0x00000054, 0x0000001f },
1389 { 0x00000800, 0x00000000 },
1390 { 0x00000804, 0x00000000 },
1391 { 0x00000808, 0x00000000 },
1392 { 0x0000080c, 0x00000000 },
1393 { 0x00000810, 0x00000000 },
1394 { 0x00000814, 0x00000000 },
1395 { 0x00000818, 0x00000000 },
1396 { 0x0000081c, 0x00000000 },
1397 { 0x00000820, 0x00000000 },
1398 { 0x00000824, 0x00000000 },
1399 { 0x00001040, 0x002ffc0f },
1400 { 0x00001044, 0x002ffc0f },
1401 { 0x00001048, 0x002ffc0f },
1402 { 0x0000104c, 0x002ffc0f },
1403 { 0x00001050, 0x002ffc0f },
1404 { 0x00001054, 0x002ffc0f },
1405 { 0x00001058, 0x002ffc0f },
1406 { 0x0000105c, 0x002ffc0f },
1407 { 0x00001060, 0x002ffc0f },
1408 { 0x00001064, 0x002ffc0f },
1409 { 0x00001230, 0x00000000 },
1410 { 0x00001270, 0x00000000 },
1411 { 0x00001038, 0x00000000 },
1412 { 0x00001078, 0x00000000 },
1413 { 0x000010b8, 0x00000000 },
1414 { 0x000010f8, 0x00000000 },
1415 { 0x00001138, 0x00000000 },
1416 { 0x00001178, 0x00000000 },
1417 { 0x000011b8, 0x00000000 },
1418 { 0x000011f8, 0x00000000 },
1419 { 0x00001238, 0x00000000 },
1420 { 0x00001278, 0x00000000 },
1421 { 0x000012b8, 0x00000000 },
1422 { 0x000012f8, 0x00000000 },
1423 { 0x00001338, 0x00000000 },
1424 { 0x00001378, 0x00000000 },
1425 { 0x000013b8, 0x00000000 },
1426 { 0x000013f8, 0x00000000 },
1427 { 0x00001438, 0x00000000 },
1428 { 0x00001478, 0x00000000 },
1429 { 0x000014b8, 0x00000000 },
1430 { 0x000014f8, 0x00000000 },
1431 { 0x00001538, 0x00000000 },
1432 { 0x00001578, 0x00000000 },
1433 { 0x000015b8, 0x00000000 },
1434 { 0x000015f8, 0x00000000 },
1435 { 0x00001638, 0x00000000 },
1436 { 0x00001678, 0x00000000 },
1437 { 0x000016b8, 0x00000000 },
1438 { 0x000016f8, 0x00000000 },
1439 { 0x00001738, 0x00000000 },
1440 { 0x00001778, 0x00000000 },
1441 { 0x000017b8, 0x00000000 },
1442 { 0x000017f8, 0x00000000 },
1443 { 0x0000103c, 0x00000000 },
1444 { 0x0000107c, 0x00000000 },
1445 { 0x000010bc, 0x00000000 },
1446 { 0x000010fc, 0x00000000 },
1447 { 0x0000113c, 0x00000000 },
1448 { 0x0000117c, 0x00000000 },
1449 { 0x000011bc, 0x00000000 },
1450 { 0x000011fc, 0x00000000 },
1451 { 0x0000123c, 0x00000000 },
1452 { 0x0000127c, 0x00000000 },
1453 { 0x000012bc, 0x00000000 },
1454 { 0x000012fc, 0x00000000 },
1455 { 0x0000133c, 0x00000000 },
1456 { 0x0000137c, 0x00000000 },
1457 { 0x000013bc, 0x00000000 },
1458 { 0x000013fc, 0x00000000 },
1459 { 0x0000143c, 0x00000000 },
1460 { 0x0000147c, 0x00000000 },
1461 { 0x00004030, 0x00000002 },
1462 { 0x0000403c, 0x00000002 },
1463 { 0x00007010, 0x00000020 },
1464 { 0x00007038, 0x000004c2 },
1465 { 0x00008004, 0x00000000 },
1466 { 0x00008008, 0x00000000 },
1467 { 0x0000800c, 0x00000000 },
1468 { 0x00008018, 0x00000700 },
1469 { 0x00008020, 0x00000000 },
1470 { 0x00008038, 0x00000000 },
1471 { 0x0000803c, 0x00000000 },
1472 { 0x00008048, 0x40000000 },
1473 { 0x00008054, 0x00000000 },
1474 { 0x00008058, 0x00000000 },
1475 { 0x0000805c, 0x000fc78f },
1476 { 0x00008060, 0x0000000f },
1477 { 0x00008064, 0x00000000 },
1478 { 0x000080c0, 0x2a82301a },
1479 { 0x000080c4, 0x05dc01e0 },
1480 { 0x000080c8, 0x1f402710 },
1481 { 0x000080cc, 0x01f40000 },
1482 { 0x000080d0, 0x00001e00 },
1483 { 0x000080d4, 0x00000000 },
1484 { 0x000080d8, 0x00400000 },
1485 { 0x000080e0, 0xffffffff },
1486 { 0x000080e4, 0x0000ffff },
1487 { 0x000080e8, 0x003f3f3f },
1488 { 0x000080ec, 0x00000000 },
1489 { 0x000080f0, 0x00000000 },
1490 { 0x000080f4, 0x00000000 },
1491 { 0x000080f8, 0x00000000 },
1492 { 0x000080fc, 0x00020000 },
1493 { 0x00008100, 0x00020000 },
1494 { 0x00008104, 0x00000001 },
1495 { 0x00008108, 0x00000052 },
1496 { 0x0000810c, 0x00000000 },
1497 { 0x00008110, 0x00000168 },
1498 { 0x00008118, 0x000100aa },
1499 { 0x0000811c, 0x00003210 },
1500 { 0x00008120, 0x08f04800 },
1501 { 0x00008124, 0x00000000 },
1502 { 0x00008128, 0x00000000 },
1503 { 0x0000812c, 0x00000000 },
1504 { 0x00008130, 0x00000000 },
1505 { 0x00008134, 0x00000000 },
1506 { 0x00008138, 0x00000000 },
1507 { 0x0000813c, 0x00000000 },
1508 { 0x00008144, 0x00000000 },
1509 { 0x00008168, 0x00000000 },
1510 { 0x0000816c, 0x00000000 },
1511 { 0x00008170, 0x32143320 },
1512 { 0x00008174, 0xfaa4fa50 },
1513 { 0x00008178, 0x00000100 },
1514 { 0x0000817c, 0x00000000 },
1515 { 0x000081c4, 0x00000000 },
1516 { 0x000081d0, 0x00003210 },
1517 { 0x000081ec, 0x00000000 },
1518 { 0x000081f0, 0x00000000 },
1519 { 0x000081f4, 0x00000000 },
1520 { 0x000081f8, 0x00000000 },
1521 { 0x000081fc, 0x00000000 },
1522 { 0x00008200, 0x00000000 },
1523 { 0x00008204, 0x00000000 },
1524 { 0x00008208, 0x00000000 },
1525 { 0x0000820c, 0x00000000 },
1526 { 0x00008210, 0x00000000 },
1527 { 0x00008214, 0x00000000 },
1528 { 0x00008218, 0x00000000 },
1529 { 0x0000821c, 0x00000000 },
1530 { 0x00008220, 0x00000000 },
1531 { 0x00008224, 0x00000000 },
1532 { 0x00008228, 0x00000000 },
1533 { 0x0000822c, 0x00000000 },
1534 { 0x00008230, 0x00000000 },
1535 { 0x00008234, 0x00000000 },
1536 { 0x00008238, 0x00000000 },
1537 { 0x0000823c, 0x00000000 },
1538 { 0x00008240, 0x00100000 },
1539 { 0x00008244, 0x0010f400 },
1540 { 0x00008248, 0x00000100 },
1541 { 0x0000824c, 0x0001e800 },
1542 { 0x00008250, 0x00000000 },
1543 { 0x00008254, 0x00000000 },
1544 { 0x00008258, 0x00000000 },
1545 { 0x0000825c, 0x400000ff },
1546 { 0x00008260, 0x00080922 },
1547 { 0x00008270, 0x00000000 },
1548 { 0x00008274, 0x40000000 },
1549 { 0x00008278, 0x003e4180 },
1550 { 0x0000827c, 0x00000000 },
1551 { 0x00008284, 0x0000002c },
1552 { 0x00008288, 0x0000002c },
1553 { 0x0000828c, 0x00000000 },
1554 { 0x00008294, 0x00000000 },
1555 { 0x00008298, 0x00000000 },
1556 { 0x00008300, 0x00000000 },
1557 { 0x00008304, 0x00000000 },
1558 { 0x00008308, 0x00000000 },
1559 { 0x0000830c, 0x00000000 },
1560 { 0x00008310, 0x00000000 },
1561 { 0x00008314, 0x00000000 },
1562 { 0x00008318, 0x00000000 },
1563 { 0x00008328, 0x00000000 },
1564 { 0x0000832c, 0x00000007 },
1565 { 0x00008330, 0x00000302 },
1566 { 0x00008334, 0x00000e00 },
1567 { 0x00008338, 0x00000000 },
1568 { 0x0000833c, 0x00000000 },
1569 { 0x00008340, 0x000107ff },
1570 { 0x00009808, 0x00000000 },
1571 { 0x0000980c, 0xad848e19 },
1572 { 0x00009810, 0x7d14e000 },
1573 { 0x00009814, 0x9c0a9f6b },
1574 { 0x0000981c, 0x00000000 },
1575 { 0x0000982c, 0x0000a000 },
1576 { 0x00009830, 0x00000000 },
1577 { 0x0000983c, 0x00200400 },
1578 { 0x00009840, 0x206a01ae },
1579 { 0x0000984c, 0x1284233c },
1580 { 0x00009854, 0x00000859 },
1581 { 0x00009900, 0x00000000 },
1582 { 0x00009904, 0x00000000 },
1583 { 0x00009908, 0x00000000 },
1584 { 0x0000990c, 0x00000000 },
1585 { 0x0000991c, 0x10000fff },
1586 { 0x00009920, 0x05100000 },
1587 { 0x0000a920, 0x05100000 },
1588 { 0x0000b920, 0x05100000 },
1589 { 0x00009928, 0x00000001 },
1590 { 0x0000992c, 0x00000004 },
1591 { 0x00009934, 0x1e1f2022 },
1592 { 0x00009938, 0x0a0b0c0d },
1593 { 0x0000993c, 0x00000000 },
1594 { 0x00009948, 0x9280b212 },
1595 { 0x0000994c, 0x00020028 },
1596 { 0x00009954, 0x5f3ca3de },
1597 { 0x00009958, 0x2108ecff },
1598 { 0x00009940, 0x00750604 },
1599 { 0x0000c95c, 0x004b6a8e },
1600 { 0x0000c968, 0x000003ce },
1601 { 0x00009970, 0x190fb515 },
1602 { 0x00009974, 0x00000000 },
1603 { 0x00009978, 0x00000001 },
1604 { 0x0000997c, 0x00000000 },
1605 { 0x00009980, 0x00000000 },
1606 { 0x00009984, 0x00000000 },
1607 { 0x00009988, 0x00000000 },
1608 { 0x0000998c, 0x00000000 },
1609 { 0x00009990, 0x00000000 },
1610 { 0x00009994, 0x00000000 },
1611 { 0x00009998, 0x00000000 },
1612 { 0x0000999c, 0x00000000 },
1613 { 0x000099a0, 0x00000000 },
1614 { 0x000099a4, 0x00000001 },
1615 { 0x000099a8, 0x201fff00 },
1616 { 0x000099ac, 0x006f0000 },
1617 { 0x000099b0, 0x03051000 },
1618 { 0x000099dc, 0x00000000 },
1619 { 0x000099e0, 0x00000200 },
1620 { 0x000099e4, 0xaaaaaaaa },
1621 { 0x000099e8, 0x3c466478 },
1622 { 0x000099ec, 0x0cc80caa },
1623 { 0x000099fc, 0x00001042 },
1624 { 0x00009b00, 0x00000000 },
1625 { 0x00009b04, 0x00000001 },
1626 { 0x00009b08, 0x00000002 },
1627 { 0x00009b0c, 0x00000003 },
1628 { 0x00009b10, 0x00000004 },
1629 { 0x00009b14, 0x00000005 },
1630 { 0x00009b18, 0x00000008 },
1631 { 0x00009b1c, 0x00000009 },
1632 { 0x00009b20, 0x0000000a },
1633 { 0x00009b24, 0x0000000b },
1634 { 0x00009b28, 0x0000000c },
1635 { 0x00009b2c, 0x0000000d },
1636 { 0x00009b30, 0x00000010 },
1637 { 0x00009b34, 0x00000011 },
1638 { 0x00009b38, 0x00000012 },
1639 { 0x00009b3c, 0x00000013 },
1640 { 0x00009b40, 0x00000014 },
1641 { 0x00009b44, 0x00000015 },
1642 { 0x00009b48, 0x00000018 },
1643 { 0x00009b4c, 0x00000019 },
1644 { 0x00009b50, 0x0000001a },
1645 { 0x00009b54, 0x0000001b },
1646 { 0x00009b58, 0x0000001c },
1647 { 0x00009b5c, 0x0000001d },
1648 { 0x00009b60, 0x00000020 },
1649 { 0x00009b64, 0x00000021 },
1650 { 0x00009b68, 0x00000022 },
1651 { 0x00009b6c, 0x00000023 },
1652 { 0x00009b70, 0x00000024 },
1653 { 0x00009b74, 0x00000025 },
1654 { 0x00009b78, 0x00000028 },
1655 { 0x00009b7c, 0x00000029 },
1656 { 0x00009b80, 0x0000002a },
1657 { 0x00009b84, 0x0000002b },
1658 { 0x00009b88, 0x0000002c },
1659 { 0x00009b8c, 0x0000002d },
1660 { 0x00009b90, 0x00000030 },
1661 { 0x00009b94, 0x00000031 },
1662 { 0x00009b98, 0x00000032 },
1663 { 0x00009b9c, 0x00000033 },
1664 { 0x00009ba0, 0x00000034 },
1665 { 0x00009ba4, 0x00000035 },
1666 { 0x00009ba8, 0x00000035 },
1667 { 0x00009bac, 0x00000035 },
1668 { 0x00009bb0, 0x00000035 },
1669 { 0x00009bb4, 0x00000035 },
1670 { 0x00009bb8, 0x00000035 },
1671 { 0x00009bbc, 0x00000035 },
1672 { 0x00009bc0, 0x00000035 },
1673 { 0x00009bc4, 0x00000035 },
1674 { 0x00009bc8, 0x00000035 },
1675 { 0x00009bcc, 0x00000035 },
1676 { 0x00009bd0, 0x00000035 },
1677 { 0x00009bd4, 0x00000035 },
1678 { 0x00009bd8, 0x00000035 },
1679 { 0x00009bdc, 0x00000035 },
1680 { 0x00009be0, 0x00000035 },
1681 { 0x00009be4, 0x00000035 },
1682 { 0x00009be8, 0x00000035 },
1683 { 0x00009bec, 0x00000035 },
1684 { 0x00009bf0, 0x00000035 },
1685 { 0x00009bf4, 0x00000035 },
1686 { 0x00009bf8, 0x00000010 },
1687 { 0x00009bfc, 0x0000001a },
1688 { 0x0000a210, 0x40806333 },
1689 { 0x0000a214, 0x00106c10 },
1690 { 0x0000a218, 0x009c4060 },
1691 { 0x0000a220, 0x018830c6 },
1692 { 0x0000a224, 0x00000400 },
1693 { 0x0000a228, 0x001a0bb5 },
1694 { 0x0000a22c, 0x00000000 },
1695 { 0x0000a234, 0x20202020 },
1696 { 0x0000a238, 0x20202020 },
1697 { 0x0000a23c, 0x13c889af },
1698 { 0x0000a240, 0x38490a20 },
1699 { 0x0000a244, 0x00007bb6 },
1700 { 0x0000a248, 0x0fff3ffc },
1701 { 0x0000a24c, 0x00000001 },
1702 { 0x0000a250, 0x0000a000 },
1703 { 0x0000a254, 0x00000000 },
1704 { 0x0000a258, 0x0cc75380 },
1705 { 0x0000a25c, 0x0f0f0f01 },
1706 { 0x0000a260, 0xdfa91f01 },
1707 { 0x0000a268, 0x00000001 },
1708 { 0x0000a26c, 0x0ebae9c6 },
1709 { 0x0000b26c, 0x0ebae9c6 },
1710 { 0x0000c26c, 0x0ebae9c6 },
1711 { 0x0000d270, 0x00820820 },
1712 { 0x0000a278, 0x1ce739ce },
1713 { 0x0000a27c, 0x050701ce },
1714 { 0x0000a338, 0x00000000 },
1715 { 0x0000a33c, 0x00000000 },
1716 { 0x0000a340, 0x00000000 },
1717 { 0x0000a344, 0x00000000 },
1718 { 0x0000a348, 0x3fffffff },
1719 { 0x0000a34c, 0x3fffffff },
1720 { 0x0000a350, 0x3fffffff },
1721 { 0x0000a354, 0x0003ffff },
1722 { 0x0000a358, 0x79a8aa33 },
1723 { 0x0000d35c, 0x07ffffef },
1724 { 0x0000d360, 0x0fffffe7 },
1725 { 0x0000d364, 0x17ffffe5 },
1726 { 0x0000d368, 0x1fffffe4 },
1727 { 0x0000d36c, 0x37ffffe3 },
1728 { 0x0000d370, 0x3fffffe3 },
1729 { 0x0000d374, 0x57ffffe3 },
1730 { 0x0000d378, 0x5fffffe2 },
1731 { 0x0000d37c, 0x7fffffe2 },
1732 { 0x0000d380, 0x7f3c7bba },
1733 { 0x0000d384, 0xf3307ff0 },
1734 { 0x0000a388, 0x0c000000 },
1735 { 0x0000a38c, 0x20202020 },
1736 { 0x0000a390, 0x20202020 },
1737 { 0x0000a394, 0x1ce739ce },
1738 { 0x0000a398, 0x000001ce },
1739 { 0x0000a39c, 0x00000001 },
1740 { 0x0000a3a0, 0x00000000 },
1741 { 0x0000a3a4, 0x00000000 },
1742 { 0x0000a3a8, 0x00000000 },
1743 { 0x0000a3ac, 0x00000000 },
1744 { 0x0000a3b0, 0x00000000 },
1745 { 0x0000a3b4, 0x00000000 },
1746 { 0x0000a3b8, 0x00000000 },
1747 { 0x0000a3bc, 0x00000000 },
1748 { 0x0000a3c0, 0x00000000 },
1749 { 0x0000a3c4, 0x00000000 },
1750 { 0x0000a3c8, 0x00000246 },
1751 { 0x0000a3cc, 0x20202020 },
1752 { 0x0000a3d0, 0x20202020 },
1753 { 0x0000a3d4, 0x20202020 },
1754 { 0x0000a3dc, 0x1ce739ce },
1755 { 0x0000a3e0, 0x000001ce },
1756};
1757
1758static const u32 ar5416Bank0_9160[][2] = {
1759 { 0x000098b0, 0x1e5795e5 },
1760 { 0x000098e0, 0x02008020 },
1761};
1762
1763static const u32 ar5416BB_RfGain_9160[][3] = {
1764 { 0x00009a00, 0x00000000, 0x00000000 },
1765 { 0x00009a04, 0x00000040, 0x00000040 },
1766 { 0x00009a08, 0x00000080, 0x00000080 },
1767 { 0x00009a0c, 0x000001a1, 0x00000141 },
1768 { 0x00009a10, 0x000001e1, 0x00000181 },
1769 { 0x00009a14, 0x00000021, 0x000001c1 },
1770 { 0x00009a18, 0x00000061, 0x00000001 },
1771 { 0x00009a1c, 0x00000168, 0x00000041 },
1772 { 0x00009a20, 0x000001a8, 0x000001a8 },
1773 { 0x00009a24, 0x000001e8, 0x000001e8 },
1774 { 0x00009a28, 0x00000028, 0x00000028 },
1775 { 0x00009a2c, 0x00000068, 0x00000068 },
1776 { 0x00009a30, 0x00000189, 0x000000a8 },
1777 { 0x00009a34, 0x000001c9, 0x00000169 },
1778 { 0x00009a38, 0x00000009, 0x000001a9 },
1779 { 0x00009a3c, 0x00000049, 0x000001e9 },
1780 { 0x00009a40, 0x00000089, 0x00000029 },
1781 { 0x00009a44, 0x00000170, 0x00000069 },
1782 { 0x00009a48, 0x000001b0, 0x00000190 },
1783 { 0x00009a4c, 0x000001f0, 0x000001d0 },
1784 { 0x00009a50, 0x00000030, 0x00000010 },
1785 { 0x00009a54, 0x00000070, 0x00000050 },
1786 { 0x00009a58, 0x00000191, 0x00000090 },
1787 { 0x00009a5c, 0x000001d1, 0x00000151 },
1788 { 0x00009a60, 0x00000011, 0x00000191 },
1789 { 0x00009a64, 0x00000051, 0x000001d1 },
1790 { 0x00009a68, 0x00000091, 0x00000011 },
1791 { 0x00009a6c, 0x000001b8, 0x00000051 },
1792 { 0x00009a70, 0x000001f8, 0x00000198 },
1793 { 0x00009a74, 0x00000038, 0x000001d8 },
1794 { 0x00009a78, 0x00000078, 0x00000018 },
1795 { 0x00009a7c, 0x00000199, 0x00000058 },
1796 { 0x00009a80, 0x000001d9, 0x00000098 },
1797 { 0x00009a84, 0x00000019, 0x00000159 },
1798 { 0x00009a88, 0x00000059, 0x00000199 },
1799 { 0x00009a8c, 0x00000099, 0x000001d9 },
1800 { 0x00009a90, 0x000000d9, 0x00000019 },
1801 { 0x00009a94, 0x000000f9, 0x00000059 },
1802 { 0x00009a98, 0x000000f9, 0x00000099 },
1803 { 0x00009a9c, 0x000000f9, 0x000000d9 },
1804 { 0x00009aa0, 0x000000f9, 0x000000f9 },
1805 { 0x00009aa4, 0x000000f9, 0x000000f9 },
1806 { 0x00009aa8, 0x000000f9, 0x000000f9 },
1807 { 0x00009aac, 0x000000f9, 0x000000f9 },
1808 { 0x00009ab0, 0x000000f9, 0x000000f9 },
1809 { 0x00009ab4, 0x000000f9, 0x000000f9 },
1810 { 0x00009ab8, 0x000000f9, 0x000000f9 },
1811 { 0x00009abc, 0x000000f9, 0x000000f9 },
1812 { 0x00009ac0, 0x000000f9, 0x000000f9 },
1813 { 0x00009ac4, 0x000000f9, 0x000000f9 },
1814 { 0x00009ac8, 0x000000f9, 0x000000f9 },
1815 { 0x00009acc, 0x000000f9, 0x000000f9 },
1816 { 0x00009ad0, 0x000000f9, 0x000000f9 },
1817 { 0x00009ad4, 0x000000f9, 0x000000f9 },
1818 { 0x00009ad8, 0x000000f9, 0x000000f9 },
1819 { 0x00009adc, 0x000000f9, 0x000000f9 },
1820 { 0x00009ae0, 0x000000f9, 0x000000f9 },
1821 { 0x00009ae4, 0x000000f9, 0x000000f9 },
1822 { 0x00009ae8, 0x000000f9, 0x000000f9 },
1823 { 0x00009aec, 0x000000f9, 0x000000f9 },
1824 { 0x00009af0, 0x000000f9, 0x000000f9 },
1825 { 0x00009af4, 0x000000f9, 0x000000f9 },
1826 { 0x00009af8, 0x000000f9, 0x000000f9 },
1827 { 0x00009afc, 0x000000f9, 0x000000f9 },
1828};
1829
1830static const u32 ar5416Bank1_9160[][2] = {
1831 { 0x000098b0, 0x02108421 },
1832 { 0x000098ec, 0x00000008 },
1833};
1834
1835static const u32 ar5416Bank2_9160[][2] = {
1836 { 0x000098b0, 0x0e73ff17 },
1837 { 0x000098e0, 0x00000420 },
1838};
1839
1840static const u32 ar5416Bank3_9160[][3] = {
1841 { 0x000098f0, 0x01400018, 0x01c00018 },
1842};
1843
1844static const u32 ar5416Bank6_9160[][3] = {
1845
1846 { 0x0000989c, 0x00000000, 0x00000000 },
1847 { 0x0000989c, 0x00000000, 0x00000000 },
1848 { 0x0000989c, 0x00000000, 0x00000000 },
1849 { 0x0000989c, 0x00e00000, 0x00e00000 },
1850 { 0x0000989c, 0x005e0000, 0x005e0000 },
1851 { 0x0000989c, 0x00120000, 0x00120000 },
1852 { 0x0000989c, 0x00620000, 0x00620000 },
1853 { 0x0000989c, 0x00020000, 0x00020000 },
1854 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1855 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1856 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1857 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1858 { 0x0000989c, 0x005f0000, 0x005f0000 },
1859 { 0x0000989c, 0x00870000, 0x00870000 },
1860 { 0x0000989c, 0x00f90000, 0x00f90000 },
1861 { 0x0000989c, 0x007b0000, 0x007b0000 },
1862 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1863 { 0x0000989c, 0x00f50000, 0x00f50000 },
1864 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1865 { 0x0000989c, 0x00110000, 0x00110000 },
1866 { 0x0000989c, 0x006100a8, 0x006100a8 },
1867 { 0x0000989c, 0x004210a2, 0x004210a2 },
1868 { 0x0000989c, 0x0014008f, 0x0014008f },
1869 { 0x0000989c, 0x00c40003, 0x00c40003 },
1870 { 0x0000989c, 0x003000f2, 0x003000f2 },
1871 { 0x0000989c, 0x00440016, 0x00440016 },
1872 { 0x0000989c, 0x00410040, 0x00410040 },
1873 { 0x0000989c, 0x0001805e, 0x0001805e },
1874 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1875 { 0x0000989c, 0x000000f1, 0x000000f1 },
1876 { 0x0000989c, 0x00002081, 0x00002081 },
1877 { 0x0000989c, 0x000000d4, 0x000000d4 },
1878 { 0x000098d0, 0x0000000f, 0x0010000f },
1879};
1880
1881static const u32 ar5416Bank6TPC_9160[][3] = {
1882 { 0x0000989c, 0x00000000, 0x00000000 },
1883 { 0x0000989c, 0x00000000, 0x00000000 },
1884 { 0x0000989c, 0x00000000, 0x00000000 },
1885 { 0x0000989c, 0x00e00000, 0x00e00000 },
1886 { 0x0000989c, 0x005e0000, 0x005e0000 },
1887 { 0x0000989c, 0x00120000, 0x00120000 },
1888 { 0x0000989c, 0x00620000, 0x00620000 },
1889 { 0x0000989c, 0x00020000, 0x00020000 },
1890 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1891 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1892 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1893 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1894 { 0x0000989c, 0x005f0000, 0x005f0000 },
1895 { 0x0000989c, 0x00870000, 0x00870000 },
1896 { 0x0000989c, 0x00f90000, 0x00f90000 },
1897 { 0x0000989c, 0x007b0000, 0x007b0000 },
1898 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1899 { 0x0000989c, 0x00f50000, 0x00f50000 },
1900 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1901 { 0x0000989c, 0x00110000, 0x00110000 },
1902 { 0x0000989c, 0x006100a8, 0x006100a8 },
1903 { 0x0000989c, 0x00423022, 0x00423022 },
1904 { 0x0000989c, 0x2014008f, 0x2014008f },
1905 { 0x0000989c, 0x00c40002, 0x00c40002 },
1906 { 0x0000989c, 0x003000f2, 0x003000f2 },
1907 { 0x0000989c, 0x00440016, 0x00440016 },
1908 { 0x0000989c, 0x00410040, 0x00410040 },
1909 { 0x0000989c, 0x0001805e, 0x0001805e },
1910 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1911 { 0x0000989c, 0x000000e1, 0x000000e1 },
1912 { 0x0000989c, 0x00007080, 0x00007080 },
1913 { 0x0000989c, 0x000000d4, 0x000000d4 },
1914 { 0x000098d0, 0x0000000f, 0x0010000f },
1915};
1916
1917static const u32 ar5416Bank7_9160[][2] = {
1918 { 0x0000989c, 0x00000500 },
1919 { 0x0000989c, 0x00000800 },
1920 { 0x000098cc, 0x0000000e },
1921};
1922
1923
1924static u32 ar5416Addac_9160[][2] = {
1925 {0x0000989c, 0x00000000 },
1926 {0x0000989c, 0x00000000 },
1927 {0x0000989c, 0x00000000 },
1928 {0x0000989c, 0x00000000 },
1929 {0x0000989c, 0x00000000 },
1930 {0x0000989c, 0x00000000 },
1931 {0x0000989c, 0x000000c0 },
1932 {0x0000989c, 0x00000018 },
1933 {0x0000989c, 0x00000004 },
1934 {0x0000989c, 0x00000000 },
1935 {0x0000989c, 0x00000000 },
1936 {0x0000989c, 0x00000000 },
1937 {0x0000989c, 0x00000000 },
1938 {0x0000989c, 0x00000000 },
1939 {0x0000989c, 0x00000000 },
1940 {0x0000989c, 0x00000000 },
1941 {0x0000989c, 0x00000000 },
1942 {0x0000989c, 0x00000000 },
1943 {0x0000989c, 0x00000000 },
1944 {0x0000989c, 0x00000000 },
1945 {0x0000989c, 0x00000000 },
1946 {0x0000989c, 0x000000c0 },
1947 {0x0000989c, 0x00000019 },
1948 {0x0000989c, 0x00000004 },
1949 {0x0000989c, 0x00000000 },
1950 {0x0000989c, 0x00000000 },
1951 {0x0000989c, 0x00000000 },
1952 {0x0000989c, 0x00000004 },
1953 {0x0000989c, 0x00000003 },
1954 {0x0000989c, 0x00000008 },
1955 {0x0000989c, 0x00000000 },
1956 {0x000098cc, 0x00000000 },
1957};
1958
1959
1960static u32 ar5416Addac_91601_1[][2] = {
1961 {0x0000989c, 0x00000000 },
1962 {0x0000989c, 0x00000000 },
1963 {0x0000989c, 0x00000000 },
1964 {0x0000989c, 0x00000000 },
1965 {0x0000989c, 0x00000000 },
1966 {0x0000989c, 0x00000000 },
1967 {0x0000989c, 0x000000c0 },
1968 {0x0000989c, 0x00000018 },
1969 {0x0000989c, 0x00000004 },
1970 {0x0000989c, 0x00000000 },
1971 {0x0000989c, 0x00000000 },
1972 {0x0000989c, 0x00000000 },
1973 {0x0000989c, 0x00000000 },
1974 {0x0000989c, 0x00000000 },
1975 {0x0000989c, 0x00000000 },
1976 {0x0000989c, 0x00000000 },
1977 {0x0000989c, 0x00000000 },
1978 {0x0000989c, 0x00000000 },
1979 {0x0000989c, 0x00000000 },
1980 {0x0000989c, 0x00000000 },
1981 {0x0000989c, 0x00000000 },
1982 {0x0000989c, 0x000000c0 },
1983 {0x0000989c, 0x00000019 },
1984 {0x0000989c, 0x00000004 },
1985 {0x0000989c, 0x00000000 },
1986 {0x0000989c, 0x00000000 },
1987 {0x0000989c, 0x00000000 },
1988 {0x0000989c, 0x00000000 },
1989 {0x0000989c, 0x00000000 },
1990 {0x0000989c, 0x00000000 },
1991 {0x0000989c, 0x00000000 },
1992 {0x000098cc, 0x00000000 },
1993};
1994
1995
1996
1997static const u32 ar9280Modes_9280[][6] = {
1998 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
1999 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
2000 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
2001 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
2002 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 },
2003 { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
2004 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
2005 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
2006 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2007 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
2008 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2009 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
2010 { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
2011 { 0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
2012 { 0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
2013 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
2014 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
2015 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
2016 { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20, 0x00049d18 },
2017 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
2018 { 0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190 },
2019 { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
2020 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
2021 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
2022 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
2023 { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 },
2024 { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2025 { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2026 { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
2027 { 0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a },
2028 { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
2029 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
2030 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
2031 { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
2032 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
2033 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
2034 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2035 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2036 { 0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214, 0x00000214 },
2037 { 0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218, 0x00000218 },
2038 { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224, 0x00000224 },
2039 { 0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228, 0x00000228 },
2040 { 0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c, 0x0000022c },
2041 { 0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230, 0x00000230 },
2042 { 0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4, 0x000002a4 },
2043 { 0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8, 0x000002a8 },
2044 { 0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac, 0x000002ac },
2045 { 0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0, 0x000002b0 },
2046 { 0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4, 0x000002b4 },
2047 { 0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8, 0x000002b8 },
2048 { 0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390, 0x00000390 },
2049 { 0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394, 0x00000394 },
2050 { 0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398, 0x00000398 },
2051 { 0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334, 0x00000334 },
2052 { 0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338, 0x00000338 },
2053 { 0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac, 0x000003ac },
2054 { 0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0, 0x000003b0 },
2055 { 0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4, 0x000003b4 },
2056 { 0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8, 0x000003b8 },
2057 { 0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5, 0x000003a5 },
2058 { 0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9, 0x000003a9 },
2059 { 0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad, 0x000003ad },
2060 { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
2061 { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
2062 { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
2063 { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
2064 { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
2065 { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
2066 { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
2067 { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
2068 { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
2069 { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
2070 { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
2071 { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
2072 { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
2073 { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
2074 { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
2075 { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
2076 { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
2077 { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
2078 { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
2079 { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
2080 { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
2081 { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
2082 { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
2083 { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
2084 { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
2085 { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
2086 { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
2087 { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
2088 { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
2089 { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
2090 { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
2091 { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
2092 { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
2093 { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
2094 { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
2095 { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
2096 { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
2097 { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
2098 { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
2099 { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
2100 { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
2101 { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
2102 { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
2103 { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
2104 { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
2105 { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
2106 { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
2107 { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
2108 { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
2109 { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
2110 { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
2111 { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
2112 { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
2113 { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
2114 { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
2115 { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
2116 { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
2117 { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
2118 { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
2119 { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
2120 { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
2121 { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
2122 { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
2123 { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
2124 { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
2125 { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
2126 { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
2127 { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
2128 { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
2129 { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
2130 { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
2131 { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
2132 { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
2133 { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
2134 { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
2135 { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
2136 { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
2137 { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
2138 { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2139 { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2140 { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2141 { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2142 { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2143 { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2144 { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2145 { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2146 { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2147 { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2148 { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2149 { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2150 { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2151 { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2152 { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2153 { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2154 { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2155 { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2156 { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2157 { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2158 { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2159 { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2160 { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2161 { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2162 { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2163 { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2164 { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
2165 { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 },
2166 { 0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
2167 { 0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
2168 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
2169 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
2170 { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
2171 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2172 { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
2173 { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
2174 { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
2175 { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
2176 { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
2177 { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
2178 { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
2179 { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
2180 { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
2181 { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
2182 { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
2183 { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
2184 { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
2185 { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
2186 { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
2187 { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
2188 { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
2189 { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
2190 { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
2191 { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
2192 { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
2193 { 0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c, 0x0e4d048c },
2194 { 0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828, 0x12035828 },
2195 { 0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000, 0x807ec000 },
2196 { 0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000, 0x00110000 },
2197};
2198
2199static const u32 ar9280Common_9280[][2] = {
2200 { 0x0000000c, 0x00000000 },
2201 { 0x00000030, 0x00020015 },
2202 { 0x00000034, 0x00000005 },
2203 { 0x00000040, 0x00000000 },
2204 { 0x00000044, 0x00000008 },
2205 { 0x00000048, 0x00000008 },
2206 { 0x0000004c, 0x00000010 },
2207 { 0x00000050, 0x00000000 },
2208 { 0x00000054, 0x0000001f },
2209 { 0x00000800, 0x00000000 },
2210 { 0x00000804, 0x00000000 },
2211 { 0x00000808, 0x00000000 },
2212 { 0x0000080c, 0x00000000 },
2213 { 0x00000810, 0x00000000 },
2214 { 0x00000814, 0x00000000 },
2215 { 0x00000818, 0x00000000 },
2216 { 0x0000081c, 0x00000000 },
2217 { 0x00000820, 0x00000000 },
2218 { 0x00000824, 0x00000000 },
2219 { 0x00001040, 0x002ffc0f },
2220 { 0x00001044, 0x002ffc0f },
2221 { 0x00001048, 0x002ffc0f },
2222 { 0x0000104c, 0x002ffc0f },
2223 { 0x00001050, 0x002ffc0f },
2224 { 0x00001054, 0x002ffc0f },
2225 { 0x00001058, 0x002ffc0f },
2226 { 0x0000105c, 0x002ffc0f },
2227 { 0x00001060, 0x002ffc0f },
2228 { 0x00001064, 0x002ffc0f },
2229 { 0x00001230, 0x00000000 },
2230 { 0x00001270, 0x00000000 },
2231 { 0x00001038, 0x00000000 },
2232 { 0x00001078, 0x00000000 },
2233 { 0x000010b8, 0x00000000 },
2234 { 0x000010f8, 0x00000000 },
2235 { 0x00001138, 0x00000000 },
2236 { 0x00001178, 0x00000000 },
2237 { 0x000011b8, 0x00000000 },
2238 { 0x000011f8, 0x00000000 },
2239 { 0x00001238, 0x00000000 },
2240 { 0x00001278, 0x00000000 },
2241 { 0x000012b8, 0x00000000 },
2242 { 0x000012f8, 0x00000000 },
2243 { 0x00001338, 0x00000000 },
2244 { 0x00001378, 0x00000000 },
2245 { 0x000013b8, 0x00000000 },
2246 { 0x000013f8, 0x00000000 },
2247 { 0x00001438, 0x00000000 },
2248 { 0x00001478, 0x00000000 },
2249 { 0x000014b8, 0x00000000 },
2250 { 0x000014f8, 0x00000000 },
2251 { 0x00001538, 0x00000000 },
2252 { 0x00001578, 0x00000000 },
2253 { 0x000015b8, 0x00000000 },
2254 { 0x000015f8, 0x00000000 },
2255 { 0x00001638, 0x00000000 },
2256 { 0x00001678, 0x00000000 },
2257 { 0x000016b8, 0x00000000 },
2258 { 0x000016f8, 0x00000000 },
2259 { 0x00001738, 0x00000000 },
2260 { 0x00001778, 0x00000000 },
2261 { 0x000017b8, 0x00000000 },
2262 { 0x000017f8, 0x00000000 },
2263 { 0x0000103c, 0x00000000 },
2264 { 0x0000107c, 0x00000000 },
2265 { 0x000010bc, 0x00000000 },
2266 { 0x000010fc, 0x00000000 },
2267 { 0x0000113c, 0x00000000 },
2268 { 0x0000117c, 0x00000000 },
2269 { 0x000011bc, 0x00000000 },
2270 { 0x000011fc, 0x00000000 },
2271 { 0x0000123c, 0x00000000 },
2272 { 0x0000127c, 0x00000000 },
2273 { 0x000012bc, 0x00000000 },
2274 { 0x000012fc, 0x00000000 },
2275 { 0x0000133c, 0x00000000 },
2276 { 0x0000137c, 0x00000000 },
2277 { 0x000013bc, 0x00000000 },
2278 { 0x000013fc, 0x00000000 },
2279 { 0x0000143c, 0x00000000 },
2280 { 0x0000147c, 0x00000000 },
2281 { 0x00004030, 0x00000002 },
2282 { 0x0000403c, 0x00000002 },
2283 { 0x00004024, 0x0000001f },
2284 { 0x00007010, 0x00000033 },
2285 { 0x00007038, 0x000004c2 },
2286 { 0x00008004, 0x00000000 },
2287 { 0x00008008, 0x00000000 },
2288 { 0x0000800c, 0x00000000 },
2289 { 0x00008018, 0x00000700 },
2290 { 0x00008020, 0x00000000 },
2291 { 0x00008038, 0x00000000 },
2292 { 0x0000803c, 0x00000000 },
2293 { 0x00008048, 0x40000000 },
2294 { 0x00008054, 0x00000000 },
2295 { 0x00008058, 0x00000000 },
2296 { 0x0000805c, 0x000fc78f },
2297 { 0x00008060, 0x0000000f },
2298 { 0x00008064, 0x00000000 },
2299 { 0x00008070, 0x00000000 },
2300 { 0x000080c0, 0x2a82301a },
2301 { 0x000080c4, 0x05dc01e0 },
2302 { 0x000080c8, 0x1f402710 },
2303 { 0x000080cc, 0x01f40000 },
2304 { 0x000080d0, 0x00001e00 },
2305 { 0x000080d4, 0x00000000 },
2306 { 0x000080d8, 0x00400000 },
2307 { 0x000080e0, 0xffffffff },
2308 { 0x000080e4, 0x0000ffff },
2309 { 0x000080e8, 0x003f3f3f },
2310 { 0x000080ec, 0x00000000 },
2311 { 0x000080f0, 0x00000000 },
2312 { 0x000080f4, 0x00000000 },
2313 { 0x000080f8, 0x00000000 },
2314 { 0x000080fc, 0x00020000 },
2315 { 0x00008100, 0x00020000 },
2316 { 0x00008104, 0x00000001 },
2317 { 0x00008108, 0x00000052 },
2318 { 0x0000810c, 0x00000000 },
2319 { 0x00008110, 0x00000168 },
2320 { 0x00008118, 0x000100aa },
2321 { 0x0000811c, 0x00003210 },
2322 { 0x00008120, 0x08f04800 },
2323 { 0x00008124, 0x00000000 },
2324 { 0x00008128, 0x00000000 },
2325 { 0x0000812c, 0x00000000 },
2326 { 0x00008130, 0x00000000 },
2327 { 0x00008134, 0x00000000 },
2328 { 0x00008138, 0x00000000 },
2329 { 0x0000813c, 0x00000000 },
2330 { 0x00008144, 0x00000000 },
2331 { 0x00008168, 0x00000000 },
2332 { 0x0000816c, 0x00000000 },
2333 { 0x00008170, 0x32143320 },
2334 { 0x00008174, 0xfaa4fa50 },
2335 { 0x00008178, 0x00000100 },
2336 { 0x0000817c, 0x00000000 },
2337 { 0x000081c4, 0x00000000 },
2338 { 0x000081d0, 0x00003210 },
2339 { 0x000081ec, 0x00000000 },
2340 { 0x000081f0, 0x00000000 },
2341 { 0x000081f4, 0x00000000 },
2342 { 0x000081f8, 0x00000000 },
2343 { 0x000081fc, 0x00000000 },
2344 { 0x00008200, 0x00000000 },
2345 { 0x00008204, 0x00000000 },
2346 { 0x00008208, 0x00000000 },
2347 { 0x0000820c, 0x00000000 },
2348 { 0x00008210, 0x00000000 },
2349 { 0x00008214, 0x00000000 },
2350 { 0x00008218, 0x00000000 },
2351 { 0x0000821c, 0x00000000 },
2352 { 0x00008220, 0x00000000 },
2353 { 0x00008224, 0x00000000 },
2354 { 0x00008228, 0x00000000 },
2355 { 0x0000822c, 0x00000000 },
2356 { 0x00008230, 0x00000000 },
2357 { 0x00008234, 0x00000000 },
2358 { 0x00008238, 0x00000000 },
2359 { 0x0000823c, 0x00000000 },
2360 { 0x00008240, 0x00100000 },
2361 { 0x00008244, 0x0010f400 },
2362 { 0x00008248, 0x00000100 },
2363 { 0x0000824c, 0x0001e800 },
2364 { 0x00008250, 0x00000000 },
2365 { 0x00008254, 0x00000000 },
2366 { 0x00008258, 0x00000000 },
2367 { 0x0000825c, 0x400000ff },
2368 { 0x00008260, 0x00080922 },
2369 { 0x00008270, 0x00000000 },
2370 { 0x00008274, 0x40000000 },
2371 { 0x00008278, 0x003e4180 },
2372 { 0x0000827c, 0x00000000 },
2373 { 0x00008284, 0x0000002c },
2374 { 0x00008288, 0x0000002c },
2375 { 0x0000828c, 0x00000000 },
2376 { 0x00008294, 0x00000000 },
2377 { 0x00008298, 0x00000000 },
2378 { 0x00008300, 0x00000000 },
2379 { 0x00008304, 0x00000000 },
2380 { 0x00008308, 0x00000000 },
2381 { 0x0000830c, 0x00000000 },
2382 { 0x00008310, 0x00000000 },
2383 { 0x00008314, 0x00000000 },
2384 { 0x00008318, 0x00000000 },
2385 { 0x00008328, 0x00000000 },
2386 { 0x0000832c, 0x00000007 },
2387 { 0x00008330, 0x00000302 },
2388 { 0x00008334, 0x00000e00 },
2389 { 0x00008338, 0x00000000 },
2390 { 0x0000833c, 0x00000000 },
2391 { 0x00008340, 0x000107ff },
2392 { 0x00008344, 0x00000000 },
2393 { 0x00009808, 0x00000000 },
2394 { 0x0000980c, 0xaf268e30 },
2395 { 0x00009810, 0xfd14e000 },
2396 { 0x00009814, 0x9c0a9f6b },
2397 { 0x0000981c, 0x00000000 },
2398 { 0x0000982c, 0x0000a000 },
2399 { 0x00009830, 0x00000000 },
2400 { 0x0000983c, 0x00200400 },
2401 { 0x00009840, 0x206a01ae },
2402 { 0x0000984c, 0x0040233c },
2403 { 0x0000a84c, 0x0040233c },
2404 { 0x00009854, 0x00000044 },
2405 { 0x00009900, 0x00000000 },
2406 { 0x00009904, 0x00000000 },
2407 { 0x00009908, 0x00000000 },
2408 { 0x0000990c, 0x00000000 },
2409 { 0x0000991c, 0x10000fff },
2410 { 0x00009920, 0x04900000 },
2411 { 0x0000a920, 0x04900000 },
2412 { 0x00009928, 0x00000001 },
2413 { 0x0000992c, 0x00000004 },
2414 { 0x00009934, 0x1e1f2022 },
2415 { 0x00009938, 0x0a0b0c0d },
2416 { 0x0000993c, 0x00000000 },
2417 { 0x00009948, 0x9280c00a },
2418 { 0x0000994c, 0x00020028 },
2419 { 0x00009954, 0xe250a51e },
2420 { 0x00009958, 0x3388ffff },
2421 { 0x00009940, 0x00781204 },
2422 { 0x0000c95c, 0x004b6a8e },
2423 { 0x0000c968, 0x000003ce },
2424 { 0x00009970, 0x190fb514 },
2425 { 0x00009974, 0x00000000 },
2426 { 0x00009978, 0x00000001 },
2427 { 0x0000997c, 0x00000000 },
2428 { 0x00009980, 0x00000000 },
2429 { 0x00009984, 0x00000000 },
2430 { 0x00009988, 0x00000000 },
2431 { 0x0000998c, 0x00000000 },
2432 { 0x00009990, 0x00000000 },
2433 { 0x00009994, 0x00000000 },
2434 { 0x00009998, 0x00000000 },
2435 { 0x0000999c, 0x00000000 },
2436 { 0x000099a0, 0x00000000 },
2437 { 0x000099a4, 0x00000001 },
2438 { 0x000099a8, 0x201fff00 },
2439 { 0x000099ac, 0x006f00c4 },
2440 { 0x000099b0, 0x03051000 },
2441 { 0x000099b4, 0x00000820 },
2442 { 0x000099dc, 0x00000000 },
2443 { 0x000099e0, 0x00000000 },
2444 { 0x000099e4, 0xaaaaaaaa },
2445 { 0x000099e8, 0x3c466478 },
2446 { 0x000099ec, 0x0cc80caa },
2447 { 0x000099fc, 0x00001042 },
2448 { 0x0000a210, 0x4080a333 },
2449 { 0x0000a214, 0x40206c10 },
2450 { 0x0000a218, 0x009c4060 },
2451 { 0x0000a220, 0x01834061 },
2452 { 0x0000a224, 0x00000400 },
2453 { 0x0000a228, 0x000003b5 },
2454 { 0x0000a22c, 0x23277200 },
2455 { 0x0000a234, 0x20202020 },
2456 { 0x0000a238, 0x20202020 },
2457 { 0x0000a23c, 0x13c889af },
2458 { 0x0000a240, 0x38490a20 },
2459 { 0x0000a244, 0x00007bb6 },
2460 { 0x0000a248, 0x0fff3ffc },
2461 { 0x0000a24c, 0x00000001 },
2462 { 0x0000a250, 0x001da000 },
2463 { 0x0000a254, 0x00000000 },
2464 { 0x0000a258, 0x0cdbd380 },
2465 { 0x0000a25c, 0x0f0f0f01 },
2466 { 0x0000a260, 0xdfa91f01 },
2467 { 0x0000a268, 0x00000000 },
2468 { 0x0000a26c, 0x0ebae9c6 },
2469 { 0x0000b26c, 0x0ebae9c6 },
2470 { 0x0000d270, 0x00820820 },
2471 { 0x0000a278, 0x1ce739ce },
2472 { 0x0000a27c, 0x050701ce },
2473 { 0x0000a358, 0x7999aa0f },
2474 { 0x0000d35c, 0x07ffffef },
2475 { 0x0000d360, 0x0fffffe7 },
2476 { 0x0000d364, 0x17ffffe5 },
2477 { 0x0000d368, 0x1fffffe4 },
2478 { 0x0000d36c, 0x37ffffe3 },
2479 { 0x0000d370, 0x3fffffe3 },
2480 { 0x0000d374, 0x57ffffe3 },
2481 { 0x0000d378, 0x5fffffe2 },
2482 { 0x0000d37c, 0x7fffffe2 },
2483 { 0x0000d380, 0x7f3c7bba },
2484 { 0x0000d384, 0xf3307ff0 },
2485 { 0x0000a388, 0x0c000000 },
2486 { 0x0000a38c, 0x20202020 },
2487 { 0x0000a390, 0x20202020 },
2488 { 0x0000a394, 0x1ce739ce },
2489 { 0x0000a398, 0x000001ce },
2490 { 0x0000a39c, 0x00000001 },
2491 { 0x0000a3a0, 0x00000000 },
2492 { 0x0000a3a4, 0x00000000 },
2493 { 0x0000a3a8, 0x00000000 },
2494 { 0x0000a3ac, 0x00000000 },
2495 { 0x0000a3b0, 0x00000000 },
2496 { 0x0000a3b4, 0x00000000 },
2497 { 0x0000a3b8, 0x00000000 },
2498 { 0x0000a3bc, 0x00000000 },
2499 { 0x0000a3c0, 0x00000000 },
2500 { 0x0000a3c4, 0x00000000 },
2501 { 0x0000a3c8, 0x00000246 },
2502 { 0x0000a3cc, 0x20202020 },
2503 { 0x0000a3d0, 0x20202020 },
2504 { 0x0000a3d4, 0x20202020 },
2505 { 0x0000a3dc, 0x1ce739ce },
2506 { 0x0000a3e0, 0x000001ce },
2507 { 0x0000a3e4, 0x00000000 },
2508 { 0x0000a3e8, 0x18c43433 },
2509 { 0x0000a3ec, 0x00f38081 },
2510 { 0x00007800, 0x00040000 },
2511 { 0x00007804, 0xdb005012 },
2512 { 0x00007808, 0x04924914 },
2513 { 0x0000780c, 0x21084210 },
2514 { 0x00007810, 0x6d801300 },
2515 { 0x00007814, 0x0019beff },
2516 { 0x00007818, 0x07e40000 },
2517 { 0x0000781c, 0x00492000 },
2518 { 0x00007820, 0x92492480 },
2519 { 0x00007824, 0x00040000 },
2520 { 0x00007828, 0xdb005012 },
2521 { 0x0000782c, 0x04924914 },
2522 { 0x00007830, 0x21084210 },
2523 { 0x00007834, 0x6d801300 },
2524 { 0x00007838, 0x0019beff },
2525 { 0x0000783c, 0x07e40000 },
2526 { 0x00007840, 0x00492000 },
2527 { 0x00007844, 0x92492480 },
2528 { 0x00007848, 0x00120000 },
2529 { 0x00007850, 0x54214514 },
2530 { 0x00007858, 0x92592692 },
2531 { 0x00007860, 0x52802000 },
2532 { 0x00007864, 0x0a8e370e },
2533 { 0x00007868, 0xc0102850 },
2534 { 0x0000786c, 0x812d4000 },
2535 { 0x00007874, 0x001b6db0 },
2536 { 0x00007878, 0x00376b63 },
2537 { 0x0000787c, 0x06db6db6 },
2538 { 0x00007880, 0x006d8000 },
2539 { 0x00007884, 0xffeffffe },
2540 { 0x00007888, 0xffeffffe },
2541 { 0x00007890, 0x00060aeb },
2542 { 0x00007894, 0x5a108000 },
2543 { 0x00007898, 0x2a850160 },
2544};
2545
2546
2547
2548
2549static const u32 ar9280Modes_9280_2[][6] = {
2550 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
2551 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
2552 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
2553 { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
2554 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
2555 { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
2556 { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
2557 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
2558 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
2559 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2560 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
2561 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2562 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
2563 { 0x00009840, 0x206a012e, 0x206a012e, 0x206a022e, 0x206a022e, 0x206a022e },
2564 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
2565 { 0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
2566 { 0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
2567 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
2568 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e },
2569 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
2570 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
2571 { 0x0000c864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
2572 { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
2573 { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
2574 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
2575 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
2576 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
2577 { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 },
2578 { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2579 { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2580 { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
2581 { 0x0000c9b8, 0x0000000f, 0x0000000f, 0x0000001c, 0x0000001c, 0x0000001c },
2582 { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
2583 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
2584 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
2585 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
2586 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
2587 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
2588 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2589 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2590 { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
2591 { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
2592 { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
2593 { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
2594 { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
2595 { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
2596 { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
2597 { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
2598 { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
2599 { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
2600 { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
2601 { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
2602 { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
2603 { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
2604 { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
2605 { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
2606 { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
2607 { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
2608 { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
2609 { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
2610 { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
2611 { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
2612 { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
2613 { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
2614 { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
2615 { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
2616 { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
2617 { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
2618 { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
2619 { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
2620 { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
2621 { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
2622 { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
2623 { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
2624 { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
2625 { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
2626 { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
2627 { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
2628 { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
2629 { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
2630 { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
2631 { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
2632 { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
2633 { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
2634 { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
2635 { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
2636 { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
2637 { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
2638 { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
2639 { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
2640 { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
2641 { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
2642 { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
2643 { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
2644 { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
2645 { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
2646 { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
2647 { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
2648 { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
2649 { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
2650 { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
2651 { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
2652 { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
2653 { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
2654 { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
2655 { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
2656 { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
2657 { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
2658 { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
2659 { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
2660 { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
2661 { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
2662 { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
2663 { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
2664 { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
2665 { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
2666 { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
2667 { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
2668 { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
2669 { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
2670 { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
2671 { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
2672 { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
2673 { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
2674 { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
2675 { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
2676 { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
2677 { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
2678 { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
2679 { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
2680 { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
2681 { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
2682 { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
2683 { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
2684 { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
2685 { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
2686 { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
2687 { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
2688 { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
2689 { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
2690 { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
2691 { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
2692 { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2693 { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2694 { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2695 { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2696 { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2697 { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2698 { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2699 { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2700 { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2701 { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2702 { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2703 { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2704 { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2705 { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2706 { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2707 { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2708 { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2709 { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2710 { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2711 { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2712 { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2713 { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2714 { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2715 { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2716 { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2717 { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2718 { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
2719 { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 },
2720 { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
2721 { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
2722 { 0x0000a21c, 0x1463800a, 0x1463800a, 0x1463800a, 0x1463800a, 0x1463800a },
2723 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
2724 { 0x0000a250, 0x001ff000, 0x001ff000, 0x001da000, 0x001da000, 0x001da000 },
2725 { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
2726 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2727 { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
2728 { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
2729 { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
2730 { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
2731 { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
2732 { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
2733 { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
2734 { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
2735 { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
2736 { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
2737 { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
2738 { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
2739 { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
2740 { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
2741 { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
2742 { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
2743 { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
2744 { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
2745 { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
2746 { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
2747 { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
2748 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
2749 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2750 { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
2751};
2752
2753static const u32 ar9280Common_9280_2[][2] = {
2754 { 0x0000000c, 0x00000000 },
2755 { 0x00000030, 0x00020015 },
2756 { 0x00000034, 0x00000005 },
2757 { 0x00000040, 0x00000000 },
2758 { 0x00000044, 0x00000008 },
2759 { 0x00000048, 0x00000008 },
2760 { 0x0000004c, 0x00000010 },
2761 { 0x00000050, 0x00000000 },
2762 { 0x00000054, 0x0000001f },
2763 { 0x00000800, 0x00000000 },
2764 { 0x00000804, 0x00000000 },
2765 { 0x00000808, 0x00000000 },
2766 { 0x0000080c, 0x00000000 },
2767 { 0x00000810, 0x00000000 },
2768 { 0x00000814, 0x00000000 },
2769 { 0x00000818, 0x00000000 },
2770 { 0x0000081c, 0x00000000 },
2771 { 0x00000820, 0x00000000 },
2772 { 0x00000824, 0x00000000 },
2773 { 0x00001040, 0x002ffc0f },
2774 { 0x00001044, 0x002ffc0f },
2775 { 0x00001048, 0x002ffc0f },
2776 { 0x0000104c, 0x002ffc0f },
2777 { 0x00001050, 0x002ffc0f },
2778 { 0x00001054, 0x002ffc0f },
2779 { 0x00001058, 0x002ffc0f },
2780 { 0x0000105c, 0x002ffc0f },
2781 { 0x00001060, 0x002ffc0f },
2782 { 0x00001064, 0x002ffc0f },
2783 { 0x00001230, 0x00000000 },
2784 { 0x00001270, 0x00000000 },
2785 { 0x00001038, 0x00000000 },
2786 { 0x00001078, 0x00000000 },
2787 { 0x000010b8, 0x00000000 },
2788 { 0x000010f8, 0x00000000 },
2789 { 0x00001138, 0x00000000 },
2790 { 0x00001178, 0x00000000 },
2791 { 0x000011b8, 0x00000000 },
2792 { 0x000011f8, 0x00000000 },
2793 { 0x00001238, 0x00000000 },
2794 { 0x00001278, 0x00000000 },
2795 { 0x000012b8, 0x00000000 },
2796 { 0x000012f8, 0x00000000 },
2797 { 0x00001338, 0x00000000 },
2798 { 0x00001378, 0x00000000 },
2799 { 0x000013b8, 0x00000000 },
2800 { 0x000013f8, 0x00000000 },
2801 { 0x00001438, 0x00000000 },
2802 { 0x00001478, 0x00000000 },
2803 { 0x000014b8, 0x00000000 },
2804 { 0x000014f8, 0x00000000 },
2805 { 0x00001538, 0x00000000 },
2806 { 0x00001578, 0x00000000 },
2807 { 0x000015b8, 0x00000000 },
2808 { 0x000015f8, 0x00000000 },
2809 { 0x00001638, 0x00000000 },
2810 { 0x00001678, 0x00000000 },
2811 { 0x000016b8, 0x00000000 },
2812 { 0x000016f8, 0x00000000 },
2813 { 0x00001738, 0x00000000 },
2814 { 0x00001778, 0x00000000 },
2815 { 0x000017b8, 0x00000000 },
2816 { 0x000017f8, 0x00000000 },
2817 { 0x0000103c, 0x00000000 },
2818 { 0x0000107c, 0x00000000 },
2819 { 0x000010bc, 0x00000000 },
2820 { 0x000010fc, 0x00000000 },
2821 { 0x0000113c, 0x00000000 },
2822 { 0x0000117c, 0x00000000 },
2823 { 0x000011bc, 0x00000000 },
2824 { 0x000011fc, 0x00000000 },
2825 { 0x0000123c, 0x00000000 },
2826 { 0x0000127c, 0x00000000 },
2827 { 0x000012bc, 0x00000000 },
2828 { 0x000012fc, 0x00000000 },
2829 { 0x0000133c, 0x00000000 },
2830 { 0x0000137c, 0x00000000 },
2831 { 0x000013bc, 0x00000000 },
2832 { 0x000013fc, 0x00000000 },
2833 { 0x0000143c, 0x00000000 },
2834 { 0x0000147c, 0x00000000 },
2835 { 0x00004030, 0x00000002 },
2836 { 0x0000403c, 0x00000002 },
2837 { 0x00004024, 0x0000001f },
2838 { 0x00004060, 0x00000000 },
2839 { 0x00004064, 0x00000000 },
2840 { 0x00007010, 0x00000033 },
2841 { 0x00007034, 0x00000002 },
2842 { 0x00007038, 0x000004c2 },
2843 { 0x00008004, 0x00000000 },
2844 { 0x00008008, 0x00000000 },
2845 { 0x0000800c, 0x00000000 },
2846 { 0x00008018, 0x00000700 },
2847 { 0x00008020, 0x00000000 },
2848 { 0x00008038, 0x00000000 },
2849 { 0x0000803c, 0x00000000 },
2850 { 0x00008048, 0x40000000 },
2851 { 0x00008054, 0x00000000 },
2852 { 0x00008058, 0x00000000 },
2853 { 0x0000805c, 0x000fc78f },
2854 { 0x00008060, 0x0000000f },
2855 { 0x00008064, 0x00000000 },
2856 { 0x00008070, 0x00000000 },
2857 { 0x000080c0, 0x2a80001a },
2858 { 0x000080c4, 0x05dc01e0 },
2859 { 0x000080c8, 0x1f402710 },
2860 { 0x000080cc, 0x01f40000 },
2861 { 0x000080d0, 0x00001e00 },
2862 { 0x000080d4, 0x00000000 },
2863 { 0x000080d8, 0x00400000 },
2864 { 0x000080e0, 0xffffffff },
2865 { 0x000080e4, 0x0000ffff },
2866 { 0x000080e8, 0x003f3f3f },
2867 { 0x000080ec, 0x00000000 },
2868 { 0x000080f0, 0x00000000 },
2869 { 0x000080f4, 0x00000000 },
2870 { 0x000080f8, 0x00000000 },
2871 { 0x000080fc, 0x00020000 },
2872 { 0x00008100, 0x00020000 },
2873 { 0x00008104, 0x00000001 },
2874 { 0x00008108, 0x00000052 },
2875 { 0x0000810c, 0x00000000 },
2876 { 0x00008110, 0x00000168 },
2877 { 0x00008118, 0x000100aa },
2878 { 0x0000811c, 0x00003210 },
2879 { 0x00008120, 0x08f04800 },
2880 { 0x00008124, 0x00000000 },
2881 { 0x00008128, 0x00000000 },
2882 { 0x0000812c, 0x00000000 },
2883 { 0x00008130, 0x00000000 },
2884 { 0x00008134, 0x00000000 },
2885 { 0x00008138, 0x00000000 },
2886 { 0x0000813c, 0x00000000 },
2887 { 0x00008144, 0x00000000 },
2888 { 0x00008168, 0x00000000 },
2889 { 0x0000816c, 0x00000000 },
2890 { 0x00008170, 0x32143320 },
2891 { 0x00008174, 0xfaa4fa50 },
2892 { 0x00008178, 0x00000100 },
2893 { 0x0000817c, 0x00000000 },
2894 { 0x000081c0, 0x00000000 },
2895 { 0x000081d0, 0x00003210 },
2896 { 0x000081ec, 0x00000000 },
2897 { 0x000081f0, 0x00000000 },
2898 { 0x000081f4, 0x00000000 },
2899 { 0x000081f8, 0x00000000 },
2900 { 0x000081fc, 0x00000000 },
2901 { 0x00008200, 0x00000000 },
2902 { 0x00008204, 0x00000000 },
2903 { 0x00008208, 0x00000000 },
2904 { 0x0000820c, 0x00000000 },
2905 { 0x00008210, 0x00000000 },
2906 { 0x00008214, 0x00000000 },
2907 { 0x00008218, 0x00000000 },
2908 { 0x0000821c, 0x00000000 },
2909 { 0x00008220, 0x00000000 },
2910 { 0x00008224, 0x00000000 },
2911 { 0x00008228, 0x00000000 },
2912 { 0x0000822c, 0x00000000 },
2913 { 0x00008230, 0x00000000 },
2914 { 0x00008234, 0x00000000 },
2915 { 0x00008238, 0x00000000 },
2916 { 0x0000823c, 0x00000000 },
2917 { 0x00008240, 0x00100000 },
2918 { 0x00008244, 0x0010f400 },
2919 { 0x00008248, 0x00000100 },
2920 { 0x0000824c, 0x0001e800 },
2921 { 0x00008250, 0x00000000 },
2922 { 0x00008254, 0x00000000 },
2923 { 0x00008258, 0x00000000 },
2924 { 0x0000825c, 0x400000ff },
2925 { 0x00008260, 0x00080922 },
2926 { 0x00008270, 0x00000000 },
2927 { 0x00008274, 0x40000000 },
2928 { 0x00008278, 0x003e4180 },
2929 { 0x0000827c, 0x00000000 },
2930 { 0x00008284, 0x0000002c },
2931 { 0x00008288, 0x0000002c },
2932 { 0x0000828c, 0x00000000 },
2933 { 0x00008294, 0x00000000 },
2934 { 0x00008298, 0x00000000 },
2935 { 0x0000829c, 0x00000000 },
2936 { 0x00008300, 0x00000040 },
2937 { 0x00008314, 0x00000000 },
2938 { 0x00008328, 0x00000000 },
2939 { 0x0000832c, 0x00000007 },
2940 { 0x00008330, 0x00000302 },
2941 { 0x00008334, 0x00000e00 },
2942 { 0x00008338, 0x00000000 },
2943 { 0x0000833c, 0x00000000 },
2944 { 0x00008340, 0x000107ff },
2945 { 0x00008344, 0x00581043 },
2946 { 0x00009808, 0x00000000 },
2947 { 0x0000980c, 0xafa68e30 },
2948 { 0x00009810, 0xfd14e000 },
2949 { 0x00009814, 0x9c0a9f6b },
2950 { 0x0000981c, 0x00000000 },
2951 { 0x0000982c, 0x0000a000 },
2952 { 0x00009830, 0x00000000 },
2953 { 0x0000983c, 0x00200400 },
2954 { 0x0000984c, 0x0040233c },
2955 { 0x0000a84c, 0x0040233c },
2956 { 0x00009854, 0x00000044 },
2957 { 0x00009900, 0x00000000 },
2958 { 0x00009904, 0x00000000 },
2959 { 0x00009908, 0x00000000 },
2960 { 0x0000990c, 0x00000000 },
2961 { 0x00009910, 0x01002310 },
2962 { 0x0000991c, 0x10000fff },
2963 { 0x00009920, 0x04900000 },
2964 { 0x0000a920, 0x04900000 },
2965 { 0x00009928, 0x00000001 },
2966 { 0x0000992c, 0x00000004 },
2967 { 0x00009934, 0x1e1f2022 },
2968 { 0x00009938, 0x0a0b0c0d },
2969 { 0x0000993c, 0x00000000 },
2970 { 0x00009948, 0x9280c00a },
2971 { 0x0000994c, 0x00020028 },
2972 { 0x00009954, 0x5f3ca3de },
2973 { 0x00009958, 0x2108ecff },
2974 { 0x00009940, 0x14750604 },
2975 { 0x0000c95c, 0x004b6a8e },
2976 { 0x0000c968, 0x000003ce },
2977 { 0x00009970, 0x190fb515 },
2978 { 0x00009974, 0x00000000 },
2979 { 0x00009978, 0x00000001 },
2980 { 0x0000997c, 0x00000000 },
2981 { 0x00009980, 0x00000000 },
2982 { 0x00009984, 0x00000000 },
2983 { 0x00009988, 0x00000000 },
2984 { 0x0000998c, 0x00000000 },
2985 { 0x00009990, 0x00000000 },
2986 { 0x00009994, 0x00000000 },
2987 { 0x00009998, 0x00000000 },
2988 { 0x0000999c, 0x00000000 },
2989 { 0x000099a0, 0x00000000 },
2990 { 0x000099a4, 0x00000001 },
2991 { 0x000099a8, 0x201fff00 },
2992 { 0x000099ac, 0x006f0000 },
2993 { 0x000099b0, 0x03051000 },
2994 { 0x000099b4, 0x00000820 },
2995 { 0x000099dc, 0x00000000 },
2996 { 0x000099e0, 0x00000000 },
2997 { 0x000099e4, 0xaaaaaaaa },
2998 { 0x000099e8, 0x3c466478 },
2999 { 0x000099ec, 0x0cc80caa },
3000 { 0x000099f0, 0x00000000 },
3001 { 0x000099fc, 0x00001042 },
3002 { 0x0000a210, 0x4080a333 },
3003 { 0x0000a214, 0x40206c10 },
3004 { 0x0000a218, 0x009c4060 },
3005 { 0x0000a220, 0x01834061 },
3006 { 0x0000a224, 0x00000400 },
3007 { 0x0000a228, 0x000003b5 },
3008 { 0x0000a22c, 0x233f71c0 },
3009 { 0x0000a234, 0x20202020 },
3010 { 0x0000a238, 0x20202020 },
3011 { 0x0000a23c, 0x13c88000 },
3012 { 0x0000a240, 0x38490a20 },
3013 { 0x0000a244, 0x00007bb6 },
3014 { 0x0000a248, 0x0fff3ffc },
3015 { 0x0000a24c, 0x00000000 },
3016 { 0x0000a254, 0x00000000 },
3017 { 0x0000a258, 0x0cdbd380 },
3018 { 0x0000a25c, 0x0f0f0f01 },
3019 { 0x0000a260, 0xdfa91f01 },
3020 { 0x0000a268, 0x00000000 },
3021 { 0x0000a26c, 0x0ebae9c6 },
3022 { 0x0000b26c, 0x0ebae9c6 },
3023 { 0x0000d270, 0x00820820 },
3024 { 0x0000a278, 0x1ce739ce },
3025 { 0x0000a27c, 0x050701ce },
3026 { 0x0000d35c, 0x07ffffef },
3027 { 0x0000d360, 0x0fffffe7 },
3028 { 0x0000d364, 0x17ffffe5 },
3029 { 0x0000d368, 0x1fffffe4 },
3030 { 0x0000d36c, 0x37ffffe3 },
3031 { 0x0000d370, 0x3fffffe3 },
3032 { 0x0000d374, 0x57ffffe3 },
3033 { 0x0000d378, 0x5fffffe2 },
3034 { 0x0000d37c, 0x7fffffe2 },
3035 { 0x0000d380, 0x7f3c7bba },
3036 { 0x0000d384, 0xf3307ff0 },
3037 { 0x0000a388, 0x0c000000 },
3038 { 0x0000a38c, 0x20202020 },
3039 { 0x0000a390, 0x20202020 },
3040 { 0x0000a394, 0x1ce739ce },
3041 { 0x0000a398, 0x000001ce },
3042 { 0x0000a39c, 0x00000001 },
3043 { 0x0000a3a0, 0x00000000 },
3044 { 0x0000a3a4, 0x00000000 },
3045 { 0x0000a3a8, 0x00000000 },
3046 { 0x0000a3ac, 0x00000000 },
3047 { 0x0000a3b0, 0x00000000 },
3048 { 0x0000a3b4, 0x00000000 },
3049 { 0x0000a3b8, 0x00000000 },
3050 { 0x0000a3bc, 0x00000000 },
3051 { 0x0000a3c0, 0x00000000 },
3052 { 0x0000a3c4, 0x00000000 },
3053 { 0x0000a3c8, 0x00000246 },
3054 { 0x0000a3cc, 0x20202020 },
3055 { 0x0000a3d0, 0x20202020 },
3056 { 0x0000a3d4, 0x20202020 },
3057 { 0x0000a3dc, 0x1ce739ce },
3058 { 0x0000a3e0, 0x000001ce },
3059 { 0x0000a3e4, 0x00000000 },
3060 { 0x0000a3e8, 0x18c43433 },
3061 { 0x0000a3ec, 0x00f70081 },
3062 { 0x00007800, 0x00040000 },
3063 { 0x00007804, 0xdb005012 },
3064 { 0x00007808, 0x04924914 },
3065 { 0x0000780c, 0x21084210 },
3066 { 0x00007810, 0x6d801300 },
3067 { 0x00007814, 0x0019beff },
3068 { 0x00007818, 0x07e41000 },
3069 { 0x0000781c, 0x00392000 },
3070 { 0x00007820, 0x92592480 },
3071 { 0x00007824, 0x00040000 },
3072 { 0x00007828, 0xdb005012 },
3073 { 0x0000782c, 0x04924914 },
3074 { 0x00007830, 0x21084210 },
3075 { 0x00007834, 0x6d801300 },
3076 { 0x00007838, 0x0019beff },
3077 { 0x0000783c, 0x07e40000 },
3078 { 0x00007840, 0x00392000 },
3079 { 0x00007844, 0x92592480 },
3080 { 0x00007848, 0x00100000 },
3081 { 0x0000784c, 0x773f0567 },
3082 { 0x00007850, 0x54214514 },
3083 { 0x00007854, 0x12035828 },
3084 { 0x00007858, 0x9259269a },
3085 { 0x00007860, 0x52802000 },
3086 { 0x00007864, 0x0a8e370e },
3087 { 0x00007868, 0xc0102850 },
3088 { 0x0000786c, 0x812d4000 },
3089 { 0x00007870, 0x807ec400 },
3090 { 0x00007874, 0x001b6db0 },
3091 { 0x00007878, 0x00376b63 },
3092 { 0x0000787c, 0x06db6db6 },
3093 { 0x00007880, 0x006d8000 },
3094 { 0x00007884, 0xffeffffe },
3095 { 0x00007888, 0xffeffffe },
3096 { 0x0000788c, 0x00010000 },
3097 { 0x00007890, 0x02060aeb },
3098 { 0x00007898, 0x2a850160 },
3099};
3100
3101static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
3102 { 0x00001030, 0x00000268, 0x000004d0 },
3103 { 0x00001070, 0x0000018c, 0x00000318 },
3104 { 0x000010b0, 0x00000fd0, 0x00001fa0 },
3105 { 0x00008014, 0x044c044c, 0x08980898 },
3106 { 0x0000801c, 0x148ec02b, 0x148ec057 },
3107 { 0x00008318, 0x000044c0, 0x00008980 },
3108 { 0x00009820, 0x02020200, 0x02020200 },
3109 { 0x00009824, 0x00000f0f, 0x00000f0f },
3110 { 0x00009828, 0x0b020001, 0x0b020001 },
3111 { 0x00009834, 0x00000f0f, 0x00000f0f },
3112 { 0x00009844, 0x03721821, 0x03721821 },
3113 { 0x00009914, 0x00000898, 0x00000898 },
3114 { 0x00009918, 0x0000000b, 0x00000016 },
3115 { 0x00009944, 0xdfbc1210, 0xdfbc1210 },
3116};
3117
3118
3119
3120static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
3121 {0x00004040, 0x9248fd00 },
3122 {0x00004040, 0x24924924 },
3123 {0x00004040, 0xa8000019 },
3124 {0x00004040, 0x13160820 },
3125 {0x00004040, 0xe5980560 },
3126 {0x00004040, 0x401dcffc },
3127 {0x00004040, 0x1aaabe40 },
3128 {0x00004040, 0xbe105554 },
3129 {0x00004040, 0x00043007 },
3130 {0x00004044, 0x00000000 },
3131};
3132
3133
3134
3135static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
3136 {0x00004040, 0x9248fd00 },
3137 {0x00004040, 0x24924924 },
3138 {0x00004040, 0xa8000019 },
3139 {0x00004040, 0x13160820 },
3140 {0x00004040, 0xe5980560 },
3141 {0x00004040, 0x401dcffd },
3142 {0x00004040, 0x1aaabe40 },
3143 {0x00004040, 0xbe105554 },
3144 {0x00004040, 0x00043007 },
3145 {0x00004044, 0x00000000 },
3146};
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
new file mode 100644
index 000000000000..2888778040e4
--- /dev/null
+++ b/drivers/net/wireless/ath9k/main.c
@@ -0,0 +1,1470 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/* mac80211 and PCI callbacks */
18
19#include <linux/nl80211.h>
20#include "core.h"
21
22#define ATH_PCI_VERSION "0.1"
23
24#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
25#define IEEE80211_ACTION_CAT_HT 7
26#define IEEE80211_ACTION_HT_TXCHWIDTH 0
27
28static char *dev_info = "ath9k";
29
30MODULE_AUTHOR("Atheros Communications");
31MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
32MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
33MODULE_LICENSE("Dual BSD/GPL");
34
35static struct pci_device_id ath_pci_id_table[] __devinitdata = {
36 { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
37 { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
38 { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
39 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
40 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
41 { 0 }
42};
43
44static int ath_get_channel(struct ath_softc *sc,
45 struct ieee80211_channel *chan)
46{
47 int i;
48
49 for (i = 0; i < sc->sc_ah->ah_nchan; i++) {
50 if (sc->sc_ah->ah_channels[i].channel == chan->center_freq)
51 return i;
52 }
53
54 return -1;
55}
56
57static u32 ath_get_extchanmode(struct ath_softc *sc,
58 struct ieee80211_channel *chan)
59{
60 u32 chanmode = 0;
61 u8 ext_chan_offset = sc->sc_ht_info.ext_chan_offset;
62 enum ath9k_ht_macmode tx_chan_width = sc->sc_ht_info.tx_chan_width;
63
64 switch (chan->band) {
65 case IEEE80211_BAND_2GHZ:
66 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
67 (tx_chan_width == ATH9K_HT_MACMODE_20))
68 chanmode = CHANNEL_G_HT20;
69 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
70 (tx_chan_width == ATH9K_HT_MACMODE_2040))
71 chanmode = CHANNEL_G_HT40PLUS;
72 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
73 (tx_chan_width == ATH9K_HT_MACMODE_2040))
74 chanmode = CHANNEL_G_HT40MINUS;
75 break;
76 case IEEE80211_BAND_5GHZ:
77 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
78 (tx_chan_width == ATH9K_HT_MACMODE_20))
79 chanmode = CHANNEL_A_HT20;
80 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
81 (tx_chan_width == ATH9K_HT_MACMODE_2040))
82 chanmode = CHANNEL_A_HT40PLUS;
83 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
84 (tx_chan_width == ATH9K_HT_MACMODE_2040))
85 chanmode = CHANNEL_A_HT40MINUS;
86 break;
87 default:
88 break;
89 }
90
91 return chanmode;
92}
93
94
95static int ath_setkey_tkip(struct ath_softc *sc,
96 struct ieee80211_key_conf *key,
97 struct ath9k_keyval *hk,
98 const u8 *addr)
99{
100 u8 *key_rxmic = NULL;
101 u8 *key_txmic = NULL;
102
103 key_txmic = key->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
104 key_rxmic = key->key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
105
106 if (addr == NULL) {
107 /* Group key installation */
108 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
109 return ath_keyset(sc, key->keyidx, hk, addr);
110 }
111 if (!sc->sc_splitmic) {
112 /*
113 * data key goes at first index,
114 * the hal handles the MIC keys at index+64.
115 */
116 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
117 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
118 return ath_keyset(sc, key->keyidx, hk, addr);
119 }
120 /*
121 * TX key goes at first index, RX key at +32.
122 * The hal handles the MIC keys at index+64.
123 */
124 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
125 if (!ath_keyset(sc, key->keyidx, hk, NULL)) {
126 /* Txmic entry failed. No need to proceed further */
127 DPRINTF(sc, ATH_DBG_KEYCACHE,
128 "%s Setting TX MIC Key Failed\n", __func__);
129 return 0;
130 }
131
132 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
133 /* XXX delete tx key on failure? */
134 return ath_keyset(sc, key->keyidx+32, hk, addr);
135}
136
137static int ath_key_config(struct ath_softc *sc,
138 const u8 *addr,
139 struct ieee80211_key_conf *key)
140{
141 struct ieee80211_vif *vif;
142 struct ath9k_keyval hk;
143 const u8 *mac = NULL;
144 int ret = 0;
145 enum ieee80211_if_types opmode;
146
147 memset(&hk, 0, sizeof(hk));
148
149 switch (key->alg) {
150 case ALG_WEP:
151 hk.kv_type = ATH9K_CIPHER_WEP;
152 break;
153 case ALG_TKIP:
154 hk.kv_type = ATH9K_CIPHER_TKIP;
155 break;
156 case ALG_CCMP:
157 hk.kv_type = ATH9K_CIPHER_AES_CCM;
158 break;
159 default:
160 return -EINVAL;
161 }
162
163 hk.kv_len = key->keylen;
164 memcpy(hk.kv_val, key->key, key->keylen);
165
166 if (!sc->sc_vaps[0])
167 return -EIO;
168
169 vif = sc->sc_vaps[0]->av_if_data;
170 opmode = vif->type;
171
172 /*
173 * Strategy:
174 * For _M_STA mc tx, we will not setup a key at all since we never
175 * tx mc.
176 * _M_STA mc rx, we will use the keyID.
177 * for _M_IBSS mc tx, we will use the keyID, and no macaddr.
178 * for _M_IBSS mc rx, we will alloc a slot and plumb the mac of the
179 * peer node. BUT we will plumb a cleartext key so that we can do
180 * perSta default key table lookup in software.
181 */
182 if (is_broadcast_ether_addr(addr)) {
183 switch (opmode) {
184 case IEEE80211_IF_TYPE_STA:
185 /* default key: could be group WPA key
186 * or could be static WEP key */
187 mac = NULL;
188 break;
189 case IEEE80211_IF_TYPE_IBSS:
190 break;
191 case IEEE80211_IF_TYPE_AP:
192 break;
193 default:
194 ASSERT(0);
195 break;
196 }
197 } else {
198 mac = addr;
199 }
200
201 if (key->alg == ALG_TKIP)
202 ret = ath_setkey_tkip(sc, key, &hk, mac);
203 else
204 ret = ath_keyset(sc, key->keyidx, &hk, mac);
205
206 if (!ret)
207 return -EIO;
208
209 sc->sc_keytype = hk.kv_type;
210 return 0;
211}
212
213static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
214{
215#define ATH_MAX_NUM_KEYS 4
216 int freeslot;
217
218 freeslot = (key->keyidx >= ATH_MAX_NUM_KEYS) ? 1 : 0;
219 ath_key_reset(sc, key->keyidx, freeslot);
220#undef ATH_MAX_NUM_KEYS
221}
222
223static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
224{
225/* Until mac80211 includes these fields */
226
227#define IEEE80211_HT_CAP_DSSSCCK40 0x1000
228#define IEEE80211_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
229#define IEEE80211_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
230
231 ht_info->ht_supported = 1;
232 ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
233 |(u16)IEEE80211_HT_CAP_MIMO_PS
234 |(u16)IEEE80211_HT_CAP_SGI_40
235 |(u16)IEEE80211_HT_CAP_DSSSCCK40;
236
237 ht_info->ampdu_factor = IEEE80211_HT_CAP_MAXRXAMPDU_65536;
238 ht_info->ampdu_density = IEEE80211_HT_CAP_MPDUDENSITY_8;
239 /* setup supported mcs set */
240 memset(ht_info->supp_mcs_set, 0, 16);
241 ht_info->supp_mcs_set[0] = 0xff;
242 ht_info->supp_mcs_set[1] = 0xff;
243 ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED;
244}
245
246static int ath_rate2idx(struct ath_softc *sc, int rate)
247{
248 int i = 0, cur_band, n_rates;
249 struct ieee80211_hw *hw = sc->hw;
250
251 cur_band = hw->conf.channel->band;
252 n_rates = sc->sbands[cur_band].n_bitrates;
253
254 for (i = 0; i < n_rates; i++) {
255 if (sc->sbands[cur_band].bitrates[i].bitrate == rate)
256 break;
257 }
258
259 /*
260 * NB:mac80211 validates rx rate index against the supported legacy rate
261 * index only (should be done against ht rates also), return the highest
262 * legacy rate index for rx rate which does not match any one of the
263 * supported basic and extended rates to make mac80211 happy.
264 * The following hack will be cleaned up once the issue with
265 * the rx rate index validation in mac80211 is fixed.
266 */
267 if (i == n_rates)
268 return n_rates - 1;
269 return i;
270}
271
272static void ath9k_rx_prepare(struct ath_softc *sc,
273 struct sk_buff *skb,
274 struct ath_recv_status *status,
275 struct ieee80211_rx_status *rx_status)
276{
277 struct ieee80211_hw *hw = sc->hw;
278 struct ieee80211_channel *curchan = hw->conf.channel;
279
280 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
281
282 rx_status->mactime = status->tsf;
283 rx_status->band = curchan->band;
284 rx_status->freq = curchan->center_freq;
285 rx_status->noise = ATH_DEFAULT_NOISE_FLOOR;
286 rx_status->signal = rx_status->noise + status->rssi;
287 rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100));
288 rx_status->antenna = status->antenna;
289 rx_status->qual = status->rssi * 100 / 64;
290
291 if (status->flags & ATH_RX_MIC_ERROR)
292 rx_status->flag |= RX_FLAG_MMIC_ERROR;
293 if (status->flags & ATH_RX_FCS_ERROR)
294 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
295
296 rx_status->flag |= RX_FLAG_TSFT;
297}
298
299static u8 parse_mpdudensity(u8 mpdudensity)
300{
301 /*
302 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
303 * 0 for no restriction
304 * 1 for 1/4 us
305 * 2 for 1/2 us
306 * 3 for 1 us
307 * 4 for 2 us
308 * 5 for 4 us
309 * 6 for 8 us
310 * 7 for 16 us
311 */
312 switch (mpdudensity) {
313 case 0:
314 return 0;
315 case 1:
316 case 2:
317 case 3:
318 /* Our lower layer calculations limit our precision to
319 1 microsecond */
320 return 1;
321 case 4:
322 return 2;
323 case 5:
324 return 4;
325 case 6:
326 return 8;
327 case 7:
328 return 16;
329 default:
330 return 0;
331 }
332}
333
334static int ath9k_start(struct ieee80211_hw *hw)
335{
336 struct ath_softc *sc = hw->priv;
337 struct ieee80211_channel *curchan = hw->conf.channel;
338 int error = 0, pos;
339
340 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with "
341 "initial channel: %d MHz\n", __func__, curchan->center_freq);
342
343 /* setup initial channel */
344
345 pos = ath_get_channel(sc, curchan);
346 if (pos == -1) {
347 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
348 return -EINVAL;
349 }
350
351 sc->sc_ah->ah_channels[pos].chanmode =
352 (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
353
354 /* open ath_dev */
355 error = ath_open(sc, &sc->sc_ah->ah_channels[pos]);
356 if (error) {
357 DPRINTF(sc, ATH_DBG_FATAL,
358 "%s: Unable to complete ath_open\n", __func__);
359 return error;
360 }
361
362 ieee80211_wake_queues(hw);
363 return 0;
364}
365
366static int ath9k_tx(struct ieee80211_hw *hw,
367 struct sk_buff *skb)
368{
369 struct ath_softc *sc = hw->priv;
370 int hdrlen, padsize;
371
372 /* Add the padding after the header if this is not already done */
373 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
374 if (hdrlen & 3) {
375 padsize = hdrlen % 4;
376 if (skb_headroom(skb) < padsize)
377 return -1;
378 skb_push(skb, padsize);
379 memmove(skb->data, skb->data + padsize, hdrlen);
380 }
381
382 DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting packet, skb: %p\n",
383 __func__,
384 skb);
385
386 if (ath_tx_start(sc, skb) != 0) {
387 DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__);
388 dev_kfree_skb_any(skb);
389 /* FIXME: Check for proper return value from ATH_DEV */
390 return 0;
391 }
392
393 return 0;
394}
395
396static void ath9k_stop(struct ieee80211_hw *hw)
397{
398 struct ath_softc *sc = hw->priv;
399 int error;
400
401 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__);
402
403 error = ath_suspend(sc);
404 if (error)
405 DPRINTF(sc, ATH_DBG_CONFIG,
406 "%s: Device is no longer present\n", __func__);
407
408 ieee80211_stop_queues(hw);
409}
410
411static int ath9k_add_interface(struct ieee80211_hw *hw,
412 struct ieee80211_if_init_conf *conf)
413{
414 struct ath_softc *sc = hw->priv;
415 int error, ic_opmode = 0;
416
417 /* Support only vap for now */
418
419 if (sc->sc_nvaps)
420 return -ENOBUFS;
421
422 switch (conf->type) {
423 case IEEE80211_IF_TYPE_STA:
424 ic_opmode = ATH9K_M_STA;
425 break;
426 case IEEE80211_IF_TYPE_IBSS:
427 ic_opmode = ATH9K_M_IBSS;
428 break;
429 default:
430 DPRINTF(sc, ATH_DBG_FATAL,
431 "%s: Only STA and IBSS are supported currently\n",
432 __func__);
433 return -EOPNOTSUPP;
434 }
435
436 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a VAP of type: %d\n",
437 __func__,
438 ic_opmode);
439
440 error = ath_vap_attach(sc, 0, conf->vif, ic_opmode);
441 if (error) {
442 DPRINTF(sc, ATH_DBG_FATAL,
443 "%s: Unable to attach vap, error: %d\n",
444 __func__, error);
445 return error;
446 }
447
448 return 0;
449}
450
451static void ath9k_remove_interface(struct ieee80211_hw *hw,
452 struct ieee80211_if_init_conf *conf)
453{
454 struct ath_softc *sc = hw->priv;
455 struct ath_vap *avp;
456 int error;
457
458 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__);
459
460 avp = sc->sc_vaps[0];
461 if (avp == NULL) {
462 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
463 __func__);
464 return;
465 }
466
467#ifdef CONFIG_SLOW_ANT_DIV
468 ath_slow_ant_div_stop(&sc->sc_antdiv);
469#endif
470
471 /* Update ratectrl */
472 ath_rate_newstate(sc, avp);
473
474 /* Reclaim beacon resources */
475 if (sc->sc_opmode == ATH9K_M_HOSTAP || sc->sc_opmode == ATH9K_M_IBSS) {
476 ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
477 ath_beacon_return(sc, avp);
478 }
479
480 /* Set interrupt mask */
481 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
482 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
483 sc->sc_beacons = 0;
484
485 error = ath_vap_detach(sc, 0);
486 if (error)
487 DPRINTF(sc, ATH_DBG_FATAL,
488 "%s: Unable to detach vap, error: %d\n",
489 __func__, error);
490}
491
492static int ath9k_config(struct ieee80211_hw *hw,
493 struct ieee80211_conf *conf)
494{
495 struct ath_softc *sc = hw->priv;
496 struct ieee80211_channel *curchan = hw->conf.channel;
497 int pos;
498
499 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
500 __func__,
501 curchan->center_freq);
502
503 pos = ath_get_channel(sc, curchan);
504 if (pos == -1) {
505 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
506 return -EINVAL;
507 }
508
509 sc->sc_ah->ah_channels[pos].chanmode =
510 (curchan->band == IEEE80211_BAND_2GHZ) ?
511 CHANNEL_G : CHANNEL_A;
512
513 if (sc->sc_curaid && hw->conf.ht_conf.ht_supported)
514 sc->sc_ah->ah_channels[pos].chanmode =
515 ath_get_extchanmode(sc, curchan);
516
517 sc->sc_config.txpowlimit = 2 * conf->power_level;
518
519 /* set h/w channel */
520 if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
521 DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to set channel\n",
522 __func__);
523
524 return 0;
525}
526
527static int ath9k_config_interface(struct ieee80211_hw *hw,
528 struct ieee80211_vif *vif,
529 struct ieee80211_if_conf *conf)
530{
531 struct ath_softc *sc = hw->priv;
532 struct ath_vap *avp;
533 u32 rfilt = 0;
534 int error, i;
535 DECLARE_MAC_BUF(mac);
536
537 avp = sc->sc_vaps[0];
538 if (avp == NULL) {
539 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
540 __func__);
541 return -EINVAL;
542 }
543
544 if ((conf->changed & IEEE80211_IFCC_BSSID) &&
545 !is_zero_ether_addr(conf->bssid)) {
546 switch (vif->type) {
547 case IEEE80211_IF_TYPE_STA:
548 case IEEE80211_IF_TYPE_IBSS:
549 /* Update ratectrl about the new state */
550 ath_rate_newstate(sc, avp);
551
552 /* Set rx filter */
553 rfilt = ath_calcrxfilter(sc);
554 ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
555
556 /* Set BSSID */
557 memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN);
558 sc->sc_curaid = 0;
559 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
560 sc->sc_curaid);
561
562 /* Set aggregation protection mode parameters */
563 sc->sc_config.ath_aggr_prot = 0;
564
565 /*
566 * Reset our TSF so that its value is lower than the
567 * beacon that we are trying to catch.
568 * Only then hw will update its TSF register with the
569 * new beacon. Reset the TSF before setting the BSSID
570 * to avoid allowing in any frames that would update
571 * our TSF only to have us clear it
572 * immediately thereafter.
573 */
574 ath9k_hw_reset_tsf(sc->sc_ah);
575
576 /* Disable BMISS interrupt when we're not associated */
577 ath9k_hw_set_interrupts(sc->sc_ah,
578 sc->sc_imask &
579 ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
580 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
581
582 DPRINTF(sc, ATH_DBG_CONFIG,
583 "%s: RX filter 0x%x bssid %s aid 0x%x\n",
584 __func__, rfilt,
585 print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
586
587 /* need to reconfigure the beacon */
588 sc->sc_beacons = 0;
589
590 break;
591 default:
592 break;
593 }
594 }
595
596 if ((conf->changed & IEEE80211_IFCC_BEACON) &&
597 (vif->type == IEEE80211_IF_TYPE_IBSS)) {
598 /*
599 * Allocate and setup the beacon frame.
600 *
601 * Stop any previous beacon DMA. This may be
602 * necessary, for example, when an ibss merge
603 * causes reconfiguration; we may be called
604 * with beacon transmission active.
605 */
606 ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
607
608 error = ath_beacon_alloc(sc, 0);
609 if (error != 0)
610 return error;
611
612 ath_beacon_sync(sc, 0);
613 }
614
615 /* Check for WLAN_CAPABILITY_PRIVACY ? */
616 if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) {
617 for (i = 0; i < IEEE80211_WEP_NKID; i++)
618 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
619 ath9k_hw_keysetmac(sc->sc_ah,
620 (u16)i,
621 sc->sc_curbssid);
622 }
623
624 /* Only legacy IBSS for now */
625 if (vif->type == IEEE80211_IF_TYPE_IBSS)
626 ath_update_chainmask(sc, 0);
627
628 return 0;
629}
630
631#define SUPPORTED_FILTERS \
632 (FIF_PROMISC_IN_BSS | \
633 FIF_ALLMULTI | \
634 FIF_CONTROL | \
635 FIF_OTHER_BSS | \
636 FIF_BCN_PRBRESP_PROMISC | \
637 FIF_FCSFAIL)
638
639/* Accept unicast, bcast and mcast frames */
640
641static void ath9k_configure_filter(struct ieee80211_hw *hw,
642 unsigned int changed_flags,
643 unsigned int *total_flags,
644 int mc_count,
645 struct dev_mc_list *mclist)
646{
647 struct ath_softc *sc = hw->priv;
648
649 changed_flags &= SUPPORTED_FILTERS;
650 *total_flags &= SUPPORTED_FILTERS;
651
652 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
653 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
654 ath_scan_start(sc);
655 else
656 ath_scan_end(sc);
657 }
658}
659
660static void ath9k_sta_notify(struct ieee80211_hw *hw,
661 struct ieee80211_vif *vif,
662 enum sta_notify_cmd cmd,
663 const u8 *addr)
664{
665 struct ath_softc *sc = hw->priv;
666 struct ath_node *an;
667 unsigned long flags;
668 DECLARE_MAC_BUF(mac);
669
670 spin_lock_irqsave(&sc->node_lock, flags);
671 an = ath_node_find(sc, (u8 *) addr);
672 spin_unlock_irqrestore(&sc->node_lock, flags);
673
674 switch (cmd) {
675 case STA_NOTIFY_ADD:
676 spin_lock_irqsave(&sc->node_lock, flags);
677 if (!an) {
678 ath_node_attach(sc, (u8 *)addr, 0);
679 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %s\n",
680 __func__,
681 print_mac(mac, addr));
682 } else {
683 ath_node_get(sc, (u8 *)addr);
684 }
685 spin_unlock_irqrestore(&sc->node_lock, flags);
686 break;
687 case STA_NOTIFY_REMOVE:
688 if (!an)
689 DPRINTF(sc, ATH_DBG_FATAL,
690 "%s: Removal of a non-existent node\n",
691 __func__);
692 else {
693 ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT);
694 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %s\n",
695 __func__,
696 print_mac(mac, addr));
697 }
698 break;
699 default:
700 break;
701 }
702}
703
704static int ath9k_conf_tx(struct ieee80211_hw *hw,
705 u16 queue,
706 const struct ieee80211_tx_queue_params *params)
707{
708 struct ath_softc *sc = hw->priv;
709 struct ath9k_tx_queue_info qi;
710 int ret = 0, qnum;
711
712 if (queue >= WME_NUM_AC)
713 return 0;
714
715 qi.tqi_aifs = params->aifs;
716 qi.tqi_cwmin = params->cw_min;
717 qi.tqi_cwmax = params->cw_max;
718 qi.tqi_burstTime = params->txop;
719 qnum = ath_get_hal_qnum(queue, sc);
720
721 DPRINTF(sc, ATH_DBG_CONFIG,
722 "%s: Configure tx [queue/halq] [%d/%d], "
723 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
724 __func__,
725 queue,
726 qnum,
727 params->aifs,
728 params->cw_min,
729 params->cw_max,
730 params->txop);
731
732 ret = ath_txq_update(sc, qnum, &qi);
733 if (ret)
734 DPRINTF(sc, ATH_DBG_FATAL,
735 "%s: TXQ Update failed\n", __func__);
736
737 return ret;
738}
739
740static int ath9k_set_key(struct ieee80211_hw *hw,
741 enum set_key_cmd cmd,
742 const u8 *local_addr,
743 const u8 *addr,
744 struct ieee80211_key_conf *key)
745{
746 struct ath_softc *sc = hw->priv;
747 int ret = 0;
748
749 DPRINTF(sc, ATH_DBG_KEYCACHE, " %s: Set HW Key\n", __func__);
750
751 switch (cmd) {
752 case SET_KEY:
753 ret = ath_key_config(sc, addr, key);
754 if (!ret) {
755 set_bit(key->keyidx, sc->sc_keymap);
756 key->hw_key_idx = key->keyidx;
757 /* push IV and Michael MIC generation to stack */
758 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
759 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
760 }
761 break;
762 case DISABLE_KEY:
763 ath_key_delete(sc, key);
764 clear_bit(key->keyidx, sc->sc_keymap);
765 sc->sc_keytype = ATH9K_CIPHER_CLR;
766 break;
767 default:
768 ret = -EINVAL;
769 }
770
771 return ret;
772}
773
774static void ath9k_ht_conf(struct ath_softc *sc,
775 struct ieee80211_bss_conf *bss_conf)
776{
777#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14)
778 struct ath_ht_info *ht_info = &sc->sc_ht_info;
779
780 if (bss_conf->assoc_ht) {
781 ht_info->ext_chan_offset =
782 bss_conf->ht_bss_conf->bss_cap &
783 IEEE80211_HT_IE_CHA_SEC_OFFSET;
784
785 if (!(bss_conf->ht_conf->cap &
786 IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
787 (bss_conf->ht_bss_conf->bss_cap &
788 IEEE80211_HT_IE_CHA_WIDTH))
789 ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040;
790 else
791 ht_info->tx_chan_width = ATH9K_HT_MACMODE_20;
792
793 ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width);
794 ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
795 bss_conf->ht_conf->ampdu_factor);
796 ht_info->mpdudensity =
797 parse_mpdudensity(bss_conf->ht_conf->ampdu_density);
798
799 }
800
801#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT
802}
803
804static void ath9k_bss_assoc_info(struct ath_softc *sc,
805 struct ieee80211_bss_conf *bss_conf)
806{
807 struct ieee80211_hw *hw = sc->hw;
808 struct ieee80211_channel *curchan = hw->conf.channel;
809 struct ath_vap *avp;
810 int pos;
811 DECLARE_MAC_BUF(mac);
812
813 if (bss_conf->assoc) {
814 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n",
815 __func__,
816 bss_conf->aid);
817
818 avp = sc->sc_vaps[0];
819 if (avp == NULL) {
820 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
821 __func__);
822 return;
823 }
824
825 /* New association, store aid */
826 if (avp->av_opmode == ATH9K_M_STA) {
827 sc->sc_curaid = bss_conf->aid;
828 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
829 sc->sc_curaid);
830 }
831
832 /* Configure the beacon */
833 ath_beacon_config(sc, 0);
834 sc->sc_beacons = 1;
835
836 /* Reset rssi stats */
837 sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
838 sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
839 sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
840 sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
841
842 /* Update chainmask */
843 ath_update_chainmask(sc, bss_conf->assoc_ht);
844
845 DPRINTF(sc, ATH_DBG_CONFIG,
846 "%s: bssid %s aid 0x%x\n",
847 __func__,
848 print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
849
850 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
851 __func__,
852 curchan->center_freq);
853
854 pos = ath_get_channel(sc, curchan);
855 if (pos == -1) {
856 DPRINTF(sc, ATH_DBG_FATAL,
857 "%s: Invalid channel\n", __func__);
858 return;
859 }
860
861 if (hw->conf.ht_conf.ht_supported)
862 sc->sc_ah->ah_channels[pos].chanmode =
863 ath_get_extchanmode(sc, curchan);
864 else
865 sc->sc_ah->ah_channels[pos].chanmode =
866 (curchan->band == IEEE80211_BAND_2GHZ) ?
867 CHANNEL_G : CHANNEL_A;
868
869 /* set h/w channel */
870 if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
871 DPRINTF(sc, ATH_DBG_FATAL,
872 "%s: Unable to set channel\n",
873 __func__);
874
875 ath_rate_newstate(sc, avp);
876 /* Update ratectrl about the new state */
877 ath_rc_node_update(hw, avp->rc_node);
878 } else {
879 DPRINTF(sc, ATH_DBG_CONFIG,
880 "%s: Bss Info DISSOC\n", __func__);
881 sc->sc_curaid = 0;
882 }
883}
884
885static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
886 struct ieee80211_vif *vif,
887 struct ieee80211_bss_conf *bss_conf,
888 u32 changed)
889{
890 struct ath_softc *sc = hw->priv;
891
892 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
893 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed PREAMBLE %d\n",
894 __func__,
895 bss_conf->use_short_preamble);
896 if (bss_conf->use_short_preamble)
897 sc->sc_flags |= ATH_PREAMBLE_SHORT;
898 else
899 sc->sc_flags &= ~ATH_PREAMBLE_SHORT;
900 }
901
902 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
903 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed CTS PROT %d\n",
904 __func__,
905 bss_conf->use_cts_prot);
906 if (bss_conf->use_cts_prot &&
907 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
908 sc->sc_flags |= ATH_PROTECT_ENABLE;
909 else
910 sc->sc_flags &= ~ATH_PROTECT_ENABLE;
911 }
912
913 if (changed & BSS_CHANGED_HT) {
914 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n",
915 __func__,
916 bss_conf->assoc_ht);
917 ath9k_ht_conf(sc, bss_conf);
918 }
919
920 if (changed & BSS_CHANGED_ASSOC) {
921 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
922 __func__,
923 bss_conf->assoc);
924 ath9k_bss_assoc_info(sc, bss_conf);
925 }
926}
927
928static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
929{
930 u64 tsf;
931 struct ath_softc *sc = hw->priv;
932 struct ath_hal *ah = sc->sc_ah;
933
934 tsf = ath9k_hw_gettsf64(ah);
935
936 return tsf;
937}
938
939static void ath9k_reset_tsf(struct ieee80211_hw *hw)
940{
941 struct ath_softc *sc = hw->priv;
942 struct ath_hal *ah = sc->sc_ah;
943
944 ath9k_hw_reset_tsf(ah);
945}
946
947static int ath9k_ampdu_action(struct ieee80211_hw *hw,
948 enum ieee80211_ampdu_mlme_action action,
949 const u8 *addr,
950 u16 tid,
951 u16 *ssn)
952{
953 struct ath_softc *sc = hw->priv;
954 int ret = 0;
955
956 switch (action) {
957 case IEEE80211_AMPDU_RX_START:
958 ret = ath_rx_aggr_start(sc, addr, tid, ssn);
959 if (ret < 0)
960 DPRINTF(sc, ATH_DBG_FATAL,
961 "%s: Unable to start RX aggregation\n",
962 __func__);
963 break;
964 case IEEE80211_AMPDU_RX_STOP:
965 ret = ath_rx_aggr_stop(sc, addr, tid);
966 if (ret < 0)
967 DPRINTF(sc, ATH_DBG_FATAL,
968 "%s: Unable to stop RX aggregation\n",
969 __func__);
970 break;
971 case IEEE80211_AMPDU_TX_START:
972 ret = ath_tx_aggr_start(sc, addr, tid, ssn);
973 if (ret < 0)
974 DPRINTF(sc, ATH_DBG_FATAL,
975 "%s: Unable to start TX aggregation\n",
976 __func__);
977 else
978 ieee80211_start_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid);
979 break;
980 case IEEE80211_AMPDU_TX_STOP:
981 ret = ath_tx_aggr_stop(sc, addr, tid);
982 if (ret < 0)
983 DPRINTF(sc, ATH_DBG_FATAL,
984 "%s: Unable to stop TX aggregation\n",
985 __func__);
986
987 ieee80211_stop_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid);
988 break;
989 default:
990 DPRINTF(sc, ATH_DBG_FATAL,
991 "%s: Unknown AMPDU action\n", __func__);
992 }
993
994 return ret;
995}
996
997static struct ieee80211_ops ath9k_ops = {
998 .tx = ath9k_tx,
999 .start = ath9k_start,
1000 .stop = ath9k_stop,
1001 .add_interface = ath9k_add_interface,
1002 .remove_interface = ath9k_remove_interface,
1003 .config = ath9k_config,
1004 .config_interface = ath9k_config_interface,
1005 .configure_filter = ath9k_configure_filter,
1006 .get_stats = NULL,
1007 .sta_notify = ath9k_sta_notify,
1008 .conf_tx = ath9k_conf_tx,
1009 .get_tx_stats = NULL,
1010 .bss_info_changed = ath9k_bss_info_changed,
1011 .set_tim = NULL,
1012 .set_key = ath9k_set_key,
1013 .hw_scan = NULL,
1014 .get_tkip_seq = NULL,
1015 .set_rts_threshold = NULL,
1016 .set_frag_threshold = NULL,
1017 .set_retry_limit = NULL,
1018 .get_tsf = ath9k_get_tsf,
1019 .reset_tsf = ath9k_reset_tsf,
1020 .tx_last_beacon = NULL,
1021 .ampdu_action = ath9k_ampdu_action
1022};
1023
1024void ath_get_beaconconfig(struct ath_softc *sc,
1025 int if_id,
1026 struct ath_beacon_config *conf)
1027{
1028 struct ieee80211_hw *hw = sc->hw;
1029
1030 /* fill in beacon config data */
1031
1032 conf->beacon_interval = hw->conf.beacon_int;
1033 conf->listen_interval = 100;
1034 conf->dtim_count = 1;
1035 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
1036}
1037
1038int ath_update_beacon(struct ath_softc *sc,
1039 int if_id,
1040 struct ath_beacon_offset *bo,
1041 struct sk_buff *skb,
1042 int mcast)
1043{
1044 return 0;
1045}
1046
1047void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1048 struct ath_xmit_status *tx_status, struct ath_node *an)
1049{
1050 struct ieee80211_hw *hw = sc->hw;
1051 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1052
1053 DPRINTF(sc, ATH_DBG_XMIT,
1054 "%s: TX complete: skb: %p\n", __func__, skb);
1055
1056 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
1057 tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
1058 /* free driver's private data area of tx_info */
1059 if (tx_info->driver_data[0] != NULL)
1060 kfree(tx_info->driver_data[0]);
1061 tx_info->driver_data[0] = NULL;
1062 }
1063
1064 if (tx_status->flags & ATH_TX_BAR) {
1065 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1066 tx_status->flags &= ~ATH_TX_BAR;
1067 }
1068 if (tx_status->flags)
1069 tx_info->status.excessive_retries = 1;
1070
1071 tx_info->status.retry_count = tx_status->retries;
1072
1073 ieee80211_tx_status(hw, skb);
1074 if (an)
1075 ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE);
1076}
1077
1078int ath__rx_indicate(struct ath_softc *sc,
1079 struct sk_buff *skb,
1080 struct ath_recv_status *status,
1081 u16 keyix)
1082{
1083 struct ieee80211_hw *hw = sc->hw;
1084 struct ath_node *an = NULL;
1085 struct ieee80211_rx_status rx_status;
1086 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1087 int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1088 int padsize;
1089 enum ATH_RX_TYPE st;
1090
1091 /* see if any padding is done by the hw and remove it */
1092 if (hdrlen & 3) {
1093 padsize = hdrlen % 4;
1094 memmove(skb->data + padsize, skb->data, hdrlen);
1095 skb_pull(skb, padsize);
1096 }
1097
1098 /* remove FCS before passing up to protocol stack */
1099 skb_trim(skb, (skb->len - FCS_LEN));
1100
1101 /* Prepare rx status */
1102 ath9k_rx_prepare(sc, skb, status, &rx_status);
1103
1104 if (!(keyix == ATH9K_RXKEYIX_INVALID) &&
1105 !(status->flags & ATH_RX_DECRYPT_ERROR)) {
1106 rx_status.flag |= RX_FLAG_DECRYPTED;
1107 } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
1108 && !(status->flags & ATH_RX_DECRYPT_ERROR)
1109 && skb->len >= hdrlen + 4) {
1110 keyix = skb->data[hdrlen + 3] >> 6;
1111
1112 if (test_bit(keyix, sc->sc_keymap))
1113 rx_status.flag |= RX_FLAG_DECRYPTED;
1114 }
1115
1116 spin_lock_bh(&sc->node_lock);
1117 an = ath_node_find(sc, hdr->addr2);
1118 spin_unlock_bh(&sc->node_lock);
1119
1120 if (an) {
1121 ath_rx_input(sc, an,
1122 hw->conf.ht_conf.ht_supported,
1123 skb, status, &st);
1124 }
1125 if (!an || (st != ATH_RX_CONSUMED))
1126 __ieee80211_rx(hw, skb, &rx_status);
1127
1128 return 0;
1129}
1130
1131int ath_rx_subframe(struct ath_node *an,
1132 struct sk_buff *skb,
1133 struct ath_recv_status *status)
1134{
1135 struct ath_softc *sc = an->an_sc;
1136 struct ieee80211_hw *hw = sc->hw;
1137 struct ieee80211_rx_status rx_status;
1138
1139 /* Prepare rx status */
1140 ath9k_rx_prepare(sc, skb, status, &rx_status);
1141 if (!(status->flags & ATH_RX_DECRYPT_ERROR))
1142 rx_status.flag |= RX_FLAG_DECRYPTED;
1143
1144 __ieee80211_rx(hw, skb, &rx_status);
1145
1146 return 0;
1147}
1148
1149enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc)
1150{
1151 return sc->sc_ht_info.tx_chan_width;
1152}
1153
1154static int ath_detach(struct ath_softc *sc)
1155{
1156 struct ieee80211_hw *hw = sc->hw;
1157
1158 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
1159
1160 /* Unregister hw */
1161
1162 ieee80211_unregister_hw(hw);
1163
1164 /* unregister Rate control */
1165 ath_rate_control_unregister();
1166
1167 /* tx/rx cleanup */
1168
1169 ath_rx_cleanup(sc);
1170 ath_tx_cleanup(sc);
1171
1172 /* Deinit */
1173
1174 ath_deinit(sc);
1175
1176 return 0;
1177}
1178
1179static int ath_attach(u16 devid,
1180 struct ath_softc *sc)
1181{
1182 struct ieee80211_hw *hw = sc->hw;
1183 int error = 0;
1184
1185 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__);
1186
1187 error = ath_init(devid, sc);
1188 if (error != 0)
1189 return error;
1190
1191 /* Init nodes */
1192
1193 INIT_LIST_HEAD(&sc->node_list);
1194 spin_lock_init(&sc->node_lock);
1195
1196 /* get mac address from hardware and set in mac80211 */
1197
1198 SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
1199
1200 /* setup channels and rates */
1201
1202 sc->sbands[IEEE80211_BAND_2GHZ].channels =
1203 sc->channels[IEEE80211_BAND_2GHZ];
1204 sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
1205 sc->rates[IEEE80211_BAND_2GHZ];
1206 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
1207
1208 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
1209 /* Setup HT capabilities for 2.4Ghz*/
1210 setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info);
1211
1212 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1213 &sc->sbands[IEEE80211_BAND_2GHZ];
1214
1215 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
1216 sc->sbands[IEEE80211_BAND_5GHZ].channels =
1217 sc->channels[IEEE80211_BAND_5GHZ];
1218 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1219 sc->rates[IEEE80211_BAND_5GHZ];
1220 sc->sbands[IEEE80211_BAND_5GHZ].band =
1221 IEEE80211_BAND_5GHZ;
1222
1223 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
1224 /* Setup HT capabilities for 5Ghz*/
1225 setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info);
1226
1227 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1228 &sc->sbands[IEEE80211_BAND_5GHZ];
1229 }
1230
1231 /* FIXME: Have to figure out proper hw init values later */
1232
1233 hw->queues = 4;
1234 hw->ampdu_queues = 1;
1235
1236 /* Register rate control */
1237 hw->rate_control_algorithm = "ath9k_rate_control";
1238 error = ath_rate_control_register();
1239 if (error != 0) {
1240 DPRINTF(sc, ATH_DBG_FATAL,
1241 "%s: Unable to register rate control "
1242 "algorithm:%d\n", __func__, error);
1243 ath_rate_control_unregister();
1244 goto bad;
1245 }
1246
1247 error = ieee80211_register_hw(hw);
1248 if (error != 0) {
1249 ath_rate_control_unregister();
1250 goto bad;
1251 }
1252
1253 /* initialize tx/rx engine */
1254
1255 error = ath_tx_init(sc, ATH_TXBUF);
1256 if (error != 0)
1257 goto bad1;
1258
1259 error = ath_rx_init(sc, ATH_RXBUF);
1260 if (error != 0)
1261 goto bad1;
1262
1263 return 0;
1264bad1:
1265 ath_detach(sc);
1266bad:
1267 return error;
1268}
1269
1270static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1271{
1272 void __iomem *mem;
1273 struct ath_softc *sc;
1274 struct ieee80211_hw *hw;
1275 const char *athname;
1276 u8 csz;
1277 u32 val;
1278 int ret = 0;
1279
1280 if (pci_enable_device(pdev))
1281 return -EIO;
1282
1283 /* XXX 32-bit addressing only */
1284 if (pci_set_dma_mask(pdev, 0xffffffff)) {
1285 printk(KERN_ERR "ath_pci: 32-bit DMA not available\n");
1286 ret = -ENODEV;
1287 goto bad;
1288 }
1289
1290 /*
1291 * Cache line size is used to size and align various
1292 * structures used to communicate with the hardware.
1293 */
1294 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
1295 if (csz == 0) {
1296 /*
1297 * Linux 2.4.18 (at least) writes the cache line size
1298 * register as a 16-bit wide register which is wrong.
1299 * We must have this setup properly for rx buffer
1300 * DMA to work so force a reasonable value here if it
1301 * comes up zero.
1302 */
1303 csz = L1_CACHE_BYTES / sizeof(u32);
1304 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
1305 }
1306 /*
1307 * The default setting of latency timer yields poor results,
1308 * set it to the value used by other systems. It may be worth
1309 * tweaking this setting more.
1310 */
1311 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
1312
1313 pci_set_master(pdev);
1314
1315 /*
1316 * Disable the RETRY_TIMEOUT register (0x41) to keep
1317 * PCI Tx retries from interfering with C3 CPU state.
1318 */
1319 pci_read_config_dword(pdev, 0x40, &val);
1320 if ((val & 0x0000ff00) != 0)
1321 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1322
1323 ret = pci_request_region(pdev, 0, "ath9k");
1324 if (ret) {
1325 dev_err(&pdev->dev, "PCI memory region reserve error\n");
1326 ret = -ENODEV;
1327 goto bad;
1328 }
1329
1330 mem = pci_iomap(pdev, 0, 0);
1331 if (!mem) {
1332 printk(KERN_ERR "PCI memory map error\n") ;
1333 ret = -EIO;
1334 goto bad1;
1335 }
1336
1337 hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
1338 if (hw == NULL) {
1339 printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
1340 goto bad2;
1341 }
1342
1343 hw->flags = IEEE80211_HW_SIGNAL_DBM |
1344 IEEE80211_HW_NOISE_DBM;
1345
1346 SET_IEEE80211_DEV(hw, &pdev->dev);
1347 pci_set_drvdata(pdev, hw);
1348
1349 sc = hw->priv;
1350 sc->hw = hw;
1351 sc->pdev = pdev;
1352 sc->mem = mem;
1353
1354 if (ath_attach(id->device, sc) != 0) {
1355 ret = -ENODEV;
1356 goto bad3;
1357 }
1358
1359 /* setup interrupt service routine */
1360
1361 if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
1362 printk(KERN_ERR "%s: request_irq failed\n",
1363 wiphy_name(hw->wiphy));
1364 ret = -EIO;
1365 goto bad4;
1366 }
1367
1368 athname = ath9k_hw_probe(id->vendor, id->device);
1369
1370 printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
1371 wiphy_name(hw->wiphy),
1372 athname ? athname : "Atheros ???",
1373 (unsigned long)mem, pdev->irq);
1374
1375 return 0;
1376bad4:
1377 ath_detach(sc);
1378bad3:
1379 ieee80211_free_hw(hw);
1380bad2:
1381 pci_iounmap(pdev, mem);
1382bad1:
1383 pci_release_region(pdev, 0);
1384bad:
1385 pci_disable_device(pdev);
1386 return ret;
1387}
1388
1389static void ath_pci_remove(struct pci_dev *pdev)
1390{
1391 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
1392 struct ath_softc *sc = hw->priv;
1393
1394 if (pdev->irq)
1395 free_irq(pdev->irq, sc);
1396 ath_detach(sc);
1397 pci_iounmap(pdev, sc->mem);
1398 pci_release_region(pdev, 0);
1399 pci_disable_device(pdev);
1400 ieee80211_free_hw(hw);
1401}
1402
1403#ifdef CONFIG_PM
1404
1405static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1406{
1407 pci_save_state(pdev);
1408 pci_disable_device(pdev);
1409 pci_set_power_state(pdev, 3);
1410
1411 return 0;
1412}
1413
1414static int ath_pci_resume(struct pci_dev *pdev)
1415{
1416 u32 val;
1417 int err;
1418
1419 err = pci_enable_device(pdev);
1420 if (err)
1421 return err;
1422 pci_restore_state(pdev);
1423 /*
1424 * Suspend/Resume resets the PCI configuration space, so we have to
1425 * re-disable the RETRY_TIMEOUT register (0x41) to keep
1426 * PCI Tx retries from interfering with C3 CPU state
1427 */
1428 pci_read_config_dword(pdev, 0x40, &val);
1429 if ((val & 0x0000ff00) != 0)
1430 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1431
1432 return 0;
1433}
1434
1435#endif /* CONFIG_PM */
1436
1437MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
1438
1439static struct pci_driver ath_pci_driver = {
1440 .name = "ath9k",
1441 .id_table = ath_pci_id_table,
1442 .probe = ath_pci_probe,
1443 .remove = ath_pci_remove,
1444#ifdef CONFIG_PM
1445 .suspend = ath_pci_suspend,
1446 .resume = ath_pci_resume,
1447#endif /* CONFIG_PM */
1448};
1449
1450static int __init init_ath_pci(void)
1451{
1452 printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION);
1453
1454 if (pci_register_driver(&ath_pci_driver) < 0) {
1455 printk(KERN_ERR
1456 "ath_pci: No devices found, driver not installed.\n");
1457 pci_unregister_driver(&ath_pci_driver);
1458 return -ENODEV;
1459 }
1460
1461 return 0;
1462}
1463module_init(init_ath_pci);
1464
1465static void __exit exit_ath_pci(void)
1466{
1467 pci_unregister_driver(&ath_pci_driver);
1468 printk(KERN_INFO "%s: driver unloaded\n", dev_info);
1469}
1470module_exit(exit_ath_pci);
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
new file mode 100644
index 000000000000..eb9121fdfd38
--- /dev/null
+++ b/drivers/net/wireless/ath9k/phy.c
@@ -0,0 +1,436 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "core.h"
18#include "hw.h"
19#include "reg.h"
20#include "phy.h"
21
22void
23ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex,
24 int regWrites)
25{
26 struct ath_hal_5416 *ahp = AH5416(ah);
27
28 REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
29}
30
31bool
32ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
33{
34 u32 channelSel = 0;
35 u32 bModeSynth = 0;
36 u32 aModeRefSel = 0;
37 u32 reg32 = 0;
38 u16 freq;
39 struct chan_centers centers;
40
41 ath9k_hw_get_channel_centers(ah, chan, &centers);
42 freq = centers.synth_center;
43
44 if (freq < 4800) {
45 u32 txctl;
46
47 if (((freq - 2192) % 5) == 0) {
48 channelSel = ((freq - 672) * 2 - 3040) / 10;
49 bModeSynth = 0;
50 } else if (((freq - 2224) % 5) == 0) {
51 channelSel = ((freq - 704) * 2 - 3040) / 10;
52 bModeSynth = 1;
53 } else {
54 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
55 "%s: invalid channel %u MHz\n", __func__,
56 freq);
57 return false;
58 }
59
60 channelSel = (channelSel << 2) & 0xff;
61 channelSel = ath9k_hw_reverse_bits(channelSel, 8);
62
63 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
64 if (freq == 2484) {
65
66 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
67 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
68 } else {
69 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
70 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
71 }
72
73 } else if ((freq % 20) == 0 && freq >= 5120) {
74 channelSel =
75 ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
76 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
77 } else if ((freq % 10) == 0) {
78 channelSel =
79 ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
80 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
81 aModeRefSel = ath9k_hw_reverse_bits(2, 2);
82 else
83 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
84 } else if ((freq % 5) == 0) {
85 channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
86 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
87 } else {
88 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
89 "%s: invalid channel %u MHz\n", __func__, freq);
90 return false;
91 }
92
93 reg32 =
94 (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
95 (1 << 5) | 0x1;
96
97 REG_WRITE(ah, AR_PHY(0x37), reg32);
98
99 ah->ah_curchan = chan;
100
101 AH5416(ah)->ah_curchanRadIndex = -1;
102
103 return true;
104}
105
106bool
107ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
108 struct ath9k_channel *chan)
109{
110 u16 bMode, fracMode, aModeRefSel = 0;
111 u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
112 struct chan_centers centers;
113 u32 refDivA = 24;
114
115 ath9k_hw_get_channel_centers(ah, chan, &centers);
116 freq = centers.synth_center;
117
118 reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
119 reg32 &= 0xc0000000;
120
121 if (freq < 4800) {
122 u32 txctl;
123
124 bMode = 1;
125 fracMode = 1;
126 aModeRefSel = 0;
127 channelSel = (freq * 0x10000) / 15;
128
129 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
130 if (freq == 2484) {
131
132 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
133 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
134 } else {
135 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
136 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
137 }
138 } else {
139 bMode = 0;
140 fracMode = 0;
141
142 if ((freq % 20) == 0) {
143 aModeRefSel = 3;
144 } else if ((freq % 10) == 0) {
145 aModeRefSel = 2;
146 } else {
147 aModeRefSel = 0;
148
149 fracMode = 1;
150 refDivA = 1;
151 channelSel = (freq * 0x8000) / 15;
152
153 REG_RMW_FIELD(ah, AR_AN_SYNTH9,
154 AR_AN_SYNTH9_REFDIVA, refDivA);
155 }
156 if (!fracMode) {
157 ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
158 channelSel = ndiv & 0x1ff;
159 channelFrac = (ndiv & 0xfffffe00) * 2;
160 channelSel = (channelSel << 17) | channelFrac;
161 }
162 }
163
164 reg32 = reg32 |
165 (bMode << 29) |
166 (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
167
168 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
169
170 ah->ah_curchan = chan;
171
172 AH5416(ah)->ah_curchanRadIndex = -1;
173
174 return true;
175}
176
177static void
178ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
179 u32 numBits, u32 firstBit,
180 u32 column)
181{
182 u32 tmp32, mask, arrayEntry, lastBit;
183 int32_t bitPosition, bitsLeft;
184
185 tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
186 arrayEntry = (firstBit - 1) / 8;
187 bitPosition = (firstBit - 1) % 8;
188 bitsLeft = numBits;
189 while (bitsLeft > 0) {
190 lastBit = (bitPosition + bitsLeft > 8) ?
191 8 : bitPosition + bitsLeft;
192 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
193 (column * 8);
194 rfBuf[arrayEntry] &= ~mask;
195 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
196 (column * 8)) & mask;
197 bitsLeft -= 8 - bitPosition;
198 tmp32 = tmp32 >> (8 - bitPosition);
199 bitPosition = 0;
200 arrayEntry++;
201 }
202}
203
204bool
205ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
206 u16 modesIndex)
207{
208 struct ath_hal_5416 *ahp = AH5416(ah);
209
210 u32 eepMinorRev;
211 u32 ob5GHz = 0, db5GHz = 0;
212 u32 ob2GHz = 0, db2GHz = 0;
213 int regWrites = 0;
214
215 if (AR_SREV_9280_10_OR_LATER(ah))
216 return true;
217
218 eepMinorRev = ath9k_hw_get_eeprom(ahp, EEP_MINOR_REV);
219
220 RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
221
222 RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
223
224 RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
225
226 RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
227 modesIndex);
228 {
229 int i;
230 for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
231 ahp->ah_analogBank6Data[i] =
232 INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
233 }
234 }
235
236 if (eepMinorRev >= 2) {
237 if (IS_CHAN_2GHZ(chan)) {
238 ob2GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_2);
239 db2GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_2);
240 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
241 ob2GHz, 3, 197, 0);
242 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
243 db2GHz, 3, 194, 0);
244 } else {
245 ob5GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_5);
246 db5GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_5);
247 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
248 ob5GHz, 3, 203, 0);
249 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
250 db5GHz, 3, 200, 0);
251 }
252 }
253
254 RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
255
256 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
257 regWrites);
258 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
259 regWrites);
260 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
261 regWrites);
262 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
263 regWrites);
264 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
265 regWrites);
266 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
267 regWrites);
268
269 return true;
270}
271
272void
273ath9k_hw_rfdetach(struct ath_hal *ah)
274{
275 struct ath_hal_5416 *ahp = AH5416(ah);
276
277 if (ahp->ah_analogBank0Data != NULL) {
278 kfree(ahp->ah_analogBank0Data);
279 ahp->ah_analogBank0Data = NULL;
280 }
281 if (ahp->ah_analogBank1Data != NULL) {
282 kfree(ahp->ah_analogBank1Data);
283 ahp->ah_analogBank1Data = NULL;
284 }
285 if (ahp->ah_analogBank2Data != NULL) {
286 kfree(ahp->ah_analogBank2Data);
287 ahp->ah_analogBank2Data = NULL;
288 }
289 if (ahp->ah_analogBank3Data != NULL) {
290 kfree(ahp->ah_analogBank3Data);
291 ahp->ah_analogBank3Data = NULL;
292 }
293 if (ahp->ah_analogBank6Data != NULL) {
294 kfree(ahp->ah_analogBank6Data);
295 ahp->ah_analogBank6Data = NULL;
296 }
297 if (ahp->ah_analogBank6TPCData != NULL) {
298 kfree(ahp->ah_analogBank6TPCData);
299 ahp->ah_analogBank6TPCData = NULL;
300 }
301 if (ahp->ah_analogBank7Data != NULL) {
302 kfree(ahp->ah_analogBank7Data);
303 ahp->ah_analogBank7Data = NULL;
304 }
305 if (ahp->ah_addac5416_21 != NULL) {
306 kfree(ahp->ah_addac5416_21);
307 ahp->ah_addac5416_21 = NULL;
308 }
309 if (ahp->ah_bank6Temp != NULL) {
310 kfree(ahp->ah_bank6Temp);
311 ahp->ah_bank6Temp = NULL;
312 }
313}
314
315bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
316{
317 struct ath_hal_5416 *ahp = AH5416(ah);
318
319 if (!AR_SREV_9280_10_OR_LATER(ah)) {
320
321 ahp->ah_analogBank0Data =
322 kzalloc((sizeof(u32) *
323 ahp->ah_iniBank0.ia_rows), GFP_KERNEL);
324 ahp->ah_analogBank1Data =
325 kzalloc((sizeof(u32) *
326 ahp->ah_iniBank1.ia_rows), GFP_KERNEL);
327 ahp->ah_analogBank2Data =
328 kzalloc((sizeof(u32) *
329 ahp->ah_iniBank2.ia_rows), GFP_KERNEL);
330 ahp->ah_analogBank3Data =
331 kzalloc((sizeof(u32) *
332 ahp->ah_iniBank3.ia_rows), GFP_KERNEL);
333 ahp->ah_analogBank6Data =
334 kzalloc((sizeof(u32) *
335 ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
336 ahp->ah_analogBank6TPCData =
337 kzalloc((sizeof(u32) *
338 ahp->ah_iniBank6TPC.ia_rows), GFP_KERNEL);
339 ahp->ah_analogBank7Data =
340 kzalloc((sizeof(u32) *
341 ahp->ah_iniBank7.ia_rows), GFP_KERNEL);
342
343 if (ahp->ah_analogBank0Data == NULL
344 || ahp->ah_analogBank1Data == NULL
345 || ahp->ah_analogBank2Data == NULL
346 || ahp->ah_analogBank3Data == NULL
347 || ahp->ah_analogBank6Data == NULL
348 || ahp->ah_analogBank6TPCData == NULL
349 || ahp->ah_analogBank7Data == NULL) {
350 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
351 "%s: cannot allocate RF banks\n",
352 __func__);
353 *status = -ENOMEM;
354 return false;
355 }
356
357 ahp->ah_addac5416_21 =
358 kzalloc((sizeof(u32) *
359 ahp->ah_iniAddac.ia_rows *
360 ahp->ah_iniAddac.ia_columns), GFP_KERNEL);
361 if (ahp->ah_addac5416_21 == NULL) {
362 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
363 "%s: cannot allocate ah_addac5416_21\n",
364 __func__);
365 *status = -ENOMEM;
366 return false;
367 }
368
369 ahp->ah_bank6Temp =
370 kzalloc((sizeof(u32) *
371 ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
372 if (ahp->ah_bank6Temp == NULL) {
373 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
374 "%s: cannot allocate ah_bank6Temp\n",
375 __func__);
376 *status = -ENOMEM;
377 return false;
378 }
379 }
380
381 return true;
382}
383
384void
385ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
386{
387 int i, regWrites = 0;
388 struct ath_hal_5416 *ahp = AH5416(ah);
389 u32 bank6SelMask;
390 u32 *bank6Temp = ahp->ah_bank6Temp;
391
392 switch (ahp->ah_diversityControl) {
393 case ATH9K_ANT_FIXED_A:
394 bank6SelMask =
395 (ahp->
396 ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
397 REDUCE_CHAIN_1;
398 break;
399 case ATH9K_ANT_FIXED_B:
400 bank6SelMask =
401 (ahp->
402 ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
403 REDUCE_CHAIN_0;
404 break;
405 case ATH9K_ANT_VARIABLE:
406 return;
407 break;
408 default:
409 return;
410 break;
411 }
412
413 for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
414 bank6Temp[i] = ahp->ah_analogBank6Data[i];
415
416 REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
417
418 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
419 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
420 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
421 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
422 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
423 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
424 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
425 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
426 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
427
428 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
429
430 REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
431#ifdef ALTER_SWITCH
432 REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
433 (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
434 | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
435#endif
436}
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
new file mode 100644
index 000000000000..0cd399a5344a
--- /dev/null
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -0,0 +1,543 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef PHY_H
18#define PHY_H
19
20bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
21 struct ath9k_channel
22 *chan);
23bool ath9k_hw_set_channel(struct ath_hal *ah,
24 struct ath9k_channel *chan);
25void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
26 u32 freqIndex, int regWrites);
27bool ath9k_hw_set_rf_regs(struct ath_hal *ah,
28 struct ath9k_channel *chan,
29 u16 modesIndex);
30void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
31 struct ath9k_channel *chan);
32bool ath9k_hw_init_rf(struct ath_hal *ah,
33 int *status);
34
35#define AR_PHY_BASE 0x9800
36#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2))
37
38#define AR_PHY_TEST 0x9800
39#define PHY_AGC_CLR 0x10000000
40#define RFSILENT_BB 0x00002000
41
42#define AR_PHY_TURBO 0x9804
43#define AR_PHY_FC_TURBO_MODE 0x00000001
44#define AR_PHY_FC_TURBO_SHORT 0x00000002
45#define AR_PHY_FC_DYN2040_EN 0x00000004
46#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
47#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
48#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
49#define AR_PHY_FC_HT_EN 0x00000040
50#define AR_PHY_FC_SHORT_GI_40 0x00000080
51#define AR_PHY_FC_WALSH 0x00000100
52#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
53
54#define AR_PHY_TIMING2 0x9810
55#define AR_PHY_TIMING3 0x9814
56#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
57#define AR_PHY_TIMING3_DSC_MAN_S 17
58#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
59#define AR_PHY_TIMING3_DSC_EXP_S 13
60
61#define AR_PHY_CHIP_ID 0x9818
62#define AR_PHY_CHIP_ID_REV_0 0x80
63#define AR_PHY_CHIP_ID_REV_1 0x81
64#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
65
66#define AR_PHY_ACTIVE 0x981C
67#define AR_PHY_ACTIVE_EN 0x00000001
68#define AR_PHY_ACTIVE_DIS 0x00000000
69
70#define AR_PHY_RF_CTL2 0x9824
71#define AR_PHY_TX_END_DATA_START 0x000000FF
72#define AR_PHY_TX_END_DATA_START_S 0
73#define AR_PHY_TX_END_PA_ON 0x0000FF00
74#define AR_PHY_TX_END_PA_ON_S 8
75
76#define AR_PHY_RF_CTL3 0x9828
77#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
78#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
79
80#define AR_PHY_ADC_CTL 0x982C
81#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
82#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
83#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
84#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
85#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
86#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
87#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
88
89#define AR_PHY_ADC_SERIAL_CTL 0x9830
90#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
91#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
92
93#define AR_PHY_RF_CTL4 0x9834
94#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000
95#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
96#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000
97#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
98#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00
99#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
100#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
101#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
102
103#define AR_PHY_SETTLING 0x9844
104#define AR_PHY_SETTLING_SWITCH 0x00003F80
105#define AR_PHY_SETTLING_SWITCH_S 7
106
107#define AR_PHY_RXGAIN 0x9848
108#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
109#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
110#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
111#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
112#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
113#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
114#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
115#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
116
117#define AR_PHY_DESIRED_SZ 0x9850
118#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
119#define AR_PHY_DESIRED_SZ_ADC_S 0
120#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
121#define AR_PHY_DESIRED_SZ_PGA_S 8
122#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
123#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
124
125#define AR_PHY_FIND_SIG 0x9858
126#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
127#define AR_PHY_FIND_SIG_FIRSTEP_S 12
128#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
129#define AR_PHY_FIND_SIG_FIRPWR_S 18
130
131#define AR_PHY_AGC_CTL1 0x985C
132#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
133#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
134#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000
135#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
136
137#define AR_PHY_AGC_CONTROL 0x9860
138#define AR_PHY_AGC_CONTROL_CAL 0x00000001
139#define AR_PHY_AGC_CONTROL_NF 0x00000002
140#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
141#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
142#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
143
144#define AR_PHY_CCA 0x9864
145#define AR_PHY_MINCCA_PWR 0x0FF80000
146#define AR_PHY_MINCCA_PWR_S 19
147#define AR_PHY_CCA_THRESH62 0x0007F000
148#define AR_PHY_CCA_THRESH62_S 12
149#define AR9280_PHY_MINCCA_PWR 0x1FF00000
150#define AR9280_PHY_MINCCA_PWR_S 20
151#define AR9280_PHY_CCA_THRESH62 0x000FF000
152#define AR9280_PHY_CCA_THRESH62_S 12
153
154#define AR_PHY_SFCORR_LOW 0x986C
155#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
156#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
157#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
158#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
159#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
160#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
161#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
162
163#define AR_PHY_SFCORR 0x9868
164#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
165#define AR_PHY_SFCORR_M2COUNT_THR_S 0
166#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
167#define AR_PHY_SFCORR_M1_THRESH_S 17
168#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
169#define AR_PHY_SFCORR_M2_THRESH_S 24
170
171#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
172#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
173#define AR_PHY_SYNTH_CONTROL 0x9874
174#define AR_PHY_SLEEP_SCAL 0x9878
175
176#define AR_PHY_PLL_CTL 0x987c
177#define AR_PHY_PLL_CTL_40 0xaa
178#define AR_PHY_PLL_CTL_40_5413 0x04
179#define AR_PHY_PLL_CTL_44 0xab
180#define AR_PHY_PLL_CTL_44_2133 0xeb
181#define AR_PHY_PLL_CTL_40_2133 0xea
182
183#define AR_PHY_RX_DELAY 0x9914
184#define AR_PHY_SEARCH_START_DELAY 0x9918
185#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
186
187#define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12))
188#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
189#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
190#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
191#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
192#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
193#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
194#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
195#define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000
196
197#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
198#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
199#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
200#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
201
202#define AR_PHY_TIMING5 0x9924
203#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
204#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
205
206#define AR_PHY_POWER_TX_RATE1 0x9934
207#define AR_PHY_POWER_TX_RATE2 0x9938
208#define AR_PHY_POWER_TX_RATE_MAX 0x993c
209#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
210
211#define AR_PHY_FRAME_CTL 0x9944
212#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038
213#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
214
215#define AR_PHY_TXPWRADJ 0x994C
216#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0
217#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
218#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000
219#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
220
221#define AR_PHY_RADAR_EXT 0x9940
222#define AR_PHY_RADAR_EXT_ENA 0x00004000
223
224#define AR_PHY_RADAR_0 0x9954
225#define AR_PHY_RADAR_0_ENA 0x00000001
226#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
227#define AR_PHY_RADAR_0_INBAND 0x0000003e
228#define AR_PHY_RADAR_0_INBAND_S 1
229#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
230#define AR_PHY_RADAR_0_PRSSI_S 6
231#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
232#define AR_PHY_RADAR_0_HEIGHT_S 12
233#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
234#define AR_PHY_RADAR_0_RRSSI_S 18
235#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
236#define AR_PHY_RADAR_0_FIRPWR_S 24
237
238#define AR_PHY_RADAR_1 0x9958
239#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
240#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
241#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
242#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
243#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
244#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
245#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
246#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
247#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
248#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
249#define AR_PHY_RADAR_1_MAXLEN_S 0
250
251#define AR_PHY_SWITCH_CHAIN_0 0x9960
252#define AR_PHY_SWITCH_COM 0x9964
253
254#define AR_PHY_SIGMA_DELTA 0x996C
255#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
256#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
257#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8
258#define AR_PHY_SIGMA_DELTA_FILT2_S 3
259#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00
260#define AR_PHY_SIGMA_DELTA_FILT1_S 8
261#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000
262#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
263
264#define AR_PHY_RESTART 0x9970
265#define AR_PHY_RESTART_DIV_GC 0x001C0000
266#define AR_PHY_RESTART_DIV_GC_S 18
267
268#define AR_PHY_RFBUS_REQ 0x997C
269#define AR_PHY_RFBUS_REQ_EN 0x00000001
270
271#define AR_PHY_TIMING7 0x9980
272#define AR_PHY_TIMING8 0x9984
273#define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF
274#define AR_PHY_TIMING8_PILOT_MASK_2_S 0
275
276#define AR_PHY_BIN_MASK2_1 0x9988
277#define AR_PHY_BIN_MASK2_2 0x998c
278#define AR_PHY_BIN_MASK2_3 0x9990
279#define AR_PHY_BIN_MASK2_4 0x9994
280
281#define AR_PHY_BIN_MASK_1 0x9900
282#define AR_PHY_BIN_MASK_2 0x9904
283#define AR_PHY_BIN_MASK_3 0x9908
284
285#define AR_PHY_MASK_CTL 0x990c
286
287#define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF
288#define AR_PHY_BIN_MASK2_4_MASK_4_S 0
289
290#define AR_PHY_TIMING9 0x9998
291#define AR_PHY_TIMING10 0x999c
292#define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF
293#define AR_PHY_TIMING10_PILOT_MASK_2_S 0
294
295#define AR_PHY_TIMING11 0x99a0
296#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
297#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
298#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
299#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
300#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
301#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
302
303#define AR_PHY_RX_CHAINMASK 0x99a4
304#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
305#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
306#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
307#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
308
309#define AR_PHY_EXT_CCA0 0x99b8
310#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
311#define AR_PHY_EXT_CCA0_THRESH62_S 0
312
313#define AR_PHY_EXT_CCA 0x99bc
314#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
315#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
316#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
317#define AR_PHY_EXT_CCA_THRESH62_S 16
318#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
319#define AR_PHY_EXT_MINCCA_PWR_S 23
320#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
321#define AR9280_PHY_EXT_MINCCA_PWR_S 16
322
323#define AR_PHY_SFCORR_EXT 0x99c0
324#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
325#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
326#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
327#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
328#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
329#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
330#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
331#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
332#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
333
334#define AR_PHY_HALFGI 0x99D0
335#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0
336#define AR_PHY_HALFGI_DSC_MAN_S 4
337#define AR_PHY_HALFGI_DSC_EXP 0x0000000F
338#define AR_PHY_HALFGI_DSC_EXP_S 0
339
340#define AR_PHY_CHAN_INFO_MEMORY 0x99DC
341#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
342
343#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
344
345#define AR_PHY_M_SLEEP 0x99f0
346#define AR_PHY_REFCLKDLY 0x99f4
347#define AR_PHY_REFCLKPD 0x99f8
348
349#define AR_PHY_CALMODE 0x99f0
350
351#define AR_PHY_CALMODE_IQ 0x00000000
352#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
353#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
354#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
355
356#define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12))
357#define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12))
358#define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12))
359#define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12))
360
361#define AR_PHY_CURRENT_RSSI 0x9c1c
362#define AR9280_PHY_CURRENT_RSSI 0x9c3c
363
364#define AR_PHY_RFBUS_GRANT 0x9C20
365#define AR_PHY_RFBUS_GRANT_EN 0x00000001
366
367#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
368#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
369
370#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
371
372#define AR_PHY_MODE 0xA200
373#define AR_PHY_MODE_AR2133 0x08
374#define AR_PHY_MODE_AR5111 0x00
375#define AR_PHY_MODE_AR5112 0x08
376#define AR_PHY_MODE_DYNAMIC 0x04
377#define AR_PHY_MODE_RF2GHZ 0x02
378#define AR_PHY_MODE_RF5GHZ 0x00
379#define AR_PHY_MODE_CCK 0x01
380#define AR_PHY_MODE_OFDM 0x00
381#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
382
383#define AR_PHY_CCK_TX_CTRL 0xA204
384#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
385
386#define AR_PHY_CCK_DETECT 0xA208
387#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
388#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
389/* [12:6] settling time for antenna switch */
390#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
391#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
392#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
393
394#define AR_PHY_GAIN_2GHZ 0xA20C
395#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
396#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
397#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00
398#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
399#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F
400#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
401
402#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000
403#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
404#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000
405#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
406#define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0
407#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
408#define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F
409#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
410
411#define AR_PHY_CCK_RXCTRL4 0xA21C
412#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000
413#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
414
415#define AR_PHY_DAG_CTRLCCK 0xA228
416#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
417#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
418#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
419
420#define AR_PHY_FORCE_CLKEN_CCK 0xA22C
421#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
422
423#define AR_PHY_POWER_TX_RATE3 0xA234
424#define AR_PHY_POWER_TX_RATE4 0xA238
425
426#define AR_PHY_SCRM_SEQ_XR 0xA23C
427#define AR_PHY_HEADER_DETECT_XR 0xA240
428#define AR_PHY_CHIRP_DETECTED_XR 0xA244
429#define AR_PHY_BLUETOOTH 0xA254
430
431#define AR_PHY_TPCRG1 0xA258
432#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
433#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
434
435#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
436#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
437#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
438#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
439#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
440#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
441
442#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
443#define AR_PHY_MASK2_M_31_45 0xa3a4
444#define AR_PHY_MASK2_M_16_30 0xa3a8
445#define AR_PHY_MASK2_M_00_15 0xa3ac
446#define AR_PHY_MASK2_P_15_01 0xa3b8
447#define AR_PHY_MASK2_P_30_16 0xa3bc
448#define AR_PHY_MASK2_P_45_31 0xa3c0
449#define AR_PHY_MASK2_P_61_45 0xa3c4
450#define AR_PHY_SPUR_REG 0x994c
451
452#define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18)
453#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
454
455#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
456#define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9)
457#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
458#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
459#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F
460#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
461
462#define AR_PHY_PILOT_MASK_01_30 0xa3b0
463#define AR_PHY_PILOT_MASK_31_60 0xa3b4
464
465#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
466#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
467
468#define AR_PHY_ANALOG_SWAP 0xa268
469#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
470
471#define AR_PHY_TPCRG5 0xA26C
472#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
473#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
474#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
475#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
476#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
477#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
478#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
479#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
480#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
481#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
482
483#define AR_PHY_POWER_TX_RATE5 0xA38C
484#define AR_PHY_POWER_TX_RATE6 0xA390
485
486#define AR_PHY_CAL_CHAINMASK 0xA39C
487
488#define AR_PHY_POWER_TX_SUB 0xA3C8
489#define AR_PHY_POWER_TX_RATE7 0xA3CC
490#define AR_PHY_POWER_TX_RATE8 0xA3D0
491#define AR_PHY_POWER_TX_RATE9 0xA3D4
492
493#define AR_PHY_XPA_CFG 0xA3D8
494#define AR_PHY_FORCE_XPA_CFG 0x000000001
495#define AR_PHY_FORCE_XPA_CFG_S 0
496
497#define AR_PHY_CH1_CCA 0xa864
498#define AR_PHY_CH1_MINCCA_PWR 0x0FF80000
499#define AR_PHY_CH1_MINCCA_PWR_S 19
500#define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000
501#define AR9280_PHY_CH1_MINCCA_PWR_S 20
502
503#define AR_PHY_CH2_CCA 0xb864
504#define AR_PHY_CH2_MINCCA_PWR 0x0FF80000
505#define AR_PHY_CH2_MINCCA_PWR_S 19
506
507#define AR_PHY_CH1_EXT_CCA 0xa9bc
508#define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000
509#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
510#define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
511#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
512
513#define AR_PHY_CH2_EXT_CCA 0xb9bc
514#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
515#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
516
517#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
518 int r; \
519 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
520 REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
521 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, \
522 "RF 0x%x V 0x%x\n", \
523 INI_RA((iniarray), r, 0), (regData)[r]); \
524 DO_DELAY(regWr); \
525 } \
526 } while (0)
527
528#define ATH9K_KEY_XOR 0xaa
529
530#define ATH9K_IS_MIC_ENABLED(ah) \
531 (AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
532
533#define ANTSWAP_AB 0x0001
534#define REDUCE_CHAIN_0 0x00000050
535#define REDUCE_CHAIN_1 0x00000051
536
537#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \
538 int i; \
539 for (i = 0; i < (_iniarray)->ia_rows; i++) \
540 (_bank)[i] = INI_RA((_iniarray), i, _col);; \
541 } while (0)
542
543#endif
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
new file mode 100644
index 000000000000..73c460ad355f
--- /dev/null
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -0,0 +1,2126 @@
1/*
2 * Copyright (c) 2004 Video54 Technologies, Inc.
3 * Copyright (c) 2004-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/*
19 * Atheros rate control algorithm
20 */
21
22#include "core.h"
23#include "../net/mac80211/rate.h"
24
25static u32 tx_triglevel_max;
26
27static struct ath_rate_table ar5416_11na_ratetable = {
28 42,
29 {
30 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
31 5400, 0x0b, 0x00, 12,
32 0, 2, 1, 0, 0, 0, 0, 0 },
33 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
34 7800, 0x0f, 0x00, 18,
35 0, 3, 1, 1, 1, 1, 1, 0 },
36 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
37 10000, 0x0a, 0x00, 24,
38 2, 4, 2, 2, 2, 2, 2, 0 },
39 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
40 13900, 0x0e, 0x00, 36,
41 2, 6, 2, 3, 3, 3, 3, 0 },
42 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
43 17300, 0x09, 0x00, 48,
44 4, 10, 3, 4, 4, 4, 4, 0 },
45 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
46 23000, 0x0d, 0x00, 72,
47 4, 14, 3, 5, 5, 5, 5, 0 },
48 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
49 27400, 0x08, 0x00, 96,
50 4, 20, 3, 6, 6, 6, 6, 0 },
51 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
52 29300, 0x0c, 0x00, 108,
53 4, 23, 3, 7, 7, 7, 7, 0 },
54 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 6500, /* 6.5 Mb */
55 6400, 0x80, 0x00, 0,
56 0, 2, 3, 8, 24, 8, 24, 3216 },
57 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 13000, /* 13 Mb */
58 12700, 0x81, 0x00, 1,
59 2, 4, 3, 9, 25, 9, 25, 6434 },
60 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 19500, /* 19.5 Mb */
61 18800, 0x82, 0x00, 2,
62 2, 6, 3, 10, 26, 10, 26, 9650 },
63 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 26000, /* 26 Mb */
64 25000, 0x83, 0x00, 3,
65 4, 10, 3, 11, 27, 11, 27, 12868 },
66 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 39000, /* 39 Mb */
67 36700, 0x84, 0x00, 4,
68 4, 14, 3, 12, 28, 12, 28, 19304 },
69 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 52000, /* 52 Mb */
70 48100, 0x85, 0x00, 5,
71 4, 20, 3, 13, 29, 13, 29, 25740 },
72 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 58500, /* 58.5 Mb */
73 53500, 0x86, 0x00, 6,
74 4, 23, 3, 14, 30, 14, 30, 28956 },
75 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 65000, /* 65 Mb */
76 59000, 0x87, 0x00, 7,
77 4, 25, 3, 15, 31, 15, 32, 32180 },
78 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 13000, /* 13 Mb */
79 12700, 0x88, 0x00,
80 8, 0, 2, 3, 16, 33, 16, 33, 6430 },
81 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 26000, /* 26 Mb */
82 24800, 0x89, 0x00, 9,
83 2, 4, 3, 17, 34, 17, 34, 12860 },
84 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 39000, /* 39 Mb */
85 36600, 0x8a, 0x00, 10,
86 2, 6, 3, 18, 35, 18, 35, 19300 },
87 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 52000, /* 52 Mb */
88 48100, 0x8b, 0x00, 11,
89 4, 10, 3, 19, 36, 19, 36, 25736 },
90 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 78000, /* 78 Mb */
91 69500, 0x8c, 0x00, 12,
92 4, 14, 3, 20, 37, 20, 37, 38600 },
93 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 104000, /* 104 Mb */
94 89500, 0x8d, 0x00, 13,
95 4, 20, 3, 21, 38, 21, 38, 51472 },
96 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 117000, /* 117 Mb */
97 98900, 0x8e, 0x00, 14,
98 4, 23, 3, 22, 39, 22, 39, 57890 },
99 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 130000, /* 130 Mb */
100 108300, 0x8f, 0x00, 15,
101 4, 25, 3, 23, 40, 23, 41, 64320 },
102 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 13500, /* 13.5 Mb */
103 13200, 0x80, 0x00, 0,
104 0, 2, 3, 8, 24, 24, 24, 6684 },
105 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 27500, /* 27.0 Mb */
106 25900, 0x81, 0x00, 1,
107 2, 4, 3, 9, 25, 25, 25, 13368 },
108 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 40500, /* 40.5 Mb */
109 38600, 0x82, 0x00, 2,
110 2, 6, 3, 10, 26, 26, 26, 20052 },
111 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 54000, /* 54 Mb */
112 49800, 0x83, 0x00, 3,
113 4, 10, 3, 11, 27, 27, 27, 26738 },
114 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 81500, /* 81 Mb */
115 72200, 0x84, 0x00, 4,
116 4, 14, 3, 12, 28, 28, 28, 40104 },
117 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 108000, /* 108 Mb */
118 92900, 0x85, 0x00, 5,
119 4, 20, 3, 13, 29, 29, 29, 53476 },
120 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 121500, /* 121.5 Mb */
121 102700, 0x86, 0x00, 6,
122 4, 23, 3, 14, 30, 30, 30, 60156 },
123 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 135000, /* 135 Mb */
124 112000, 0x87, 0x00, 7,
125 4, 25, 3, 15, 31, 32, 32, 66840 },
126 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
127 122000, 0x87, 0x00, 7,
128 4, 25, 3, 15, 31, 32, 32, 74200 },
129 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 27000, /* 27 Mb */
130 25800, 0x88, 0x00, 8,
131 0, 2, 3, 16, 33, 33, 33, 13360 },
132 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 54000, /* 54 Mb */
133 49800, 0x89, 0x00, 9,
134 2, 4, 3, 17, 34, 34, 34, 26720 },
135 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 81000, /* 81 Mb */
136 71900, 0x8a, 0x00, 10,
137 2, 6, 3, 18, 35, 35, 35, 40080 },
138 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 108000, /* 108 Mb */
139 92500, 0x8b, 0x00, 11,
140 4, 10, 3, 19, 36, 36, 36, 53440 },
141 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 162000, /* 162 Mb */
142 130300, 0x8c, 0x00, 12,
143 4, 14, 3, 20, 37, 37, 37, 80160 },
144 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 216000, /* 216 Mb */
145 162800, 0x8d, 0x00, 13,
146 4, 20, 3, 21, 38, 38, 38, 106880 },
147 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 243000, /* 243 Mb */
148 178200, 0x8e, 0x00, 14,
149 4, 23, 3, 22, 39, 39, 39, 120240 },
150 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 270000, /* 270 Mb */
151 192100, 0x8f, 0x00, 15,
152 4, 25, 3, 23, 40, 41, 41, 133600 },
153 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
154 207000, 0x8f, 0x00, 15,
155 4, 25, 3, 23, 40, 41, 41, 148400 },
156 },
157 50, /* probe interval */
158 50, /* rssi reduce interval */
159 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
160};
161
162/* TRUE_ALL - valid for 20/40/Legacy,
163 * TRUE - Legacy only,
164 * TRUE_20 - HT 20 only,
165 * TRUE_40 - HT 40 only */
166
167/* 4ms frame limit not used for NG mode. The values filled
168 * for HT are the 64K max aggregate limit */
169
170static struct ath_rate_table ar5416_11ng_ratetable = {
171 46,
172 {
173 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 1000, /* 1 Mb */
174 900, 0x1b, 0x00, 2,
175 0, 0, 1, 0, 0, 0, 0, 0 },
176 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 2000, /* 2 Mb */
177 1900, 0x1a, 0x04, 4,
178 1, 1, 1, 1, 1, 1, 1, 0 },
179 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 5500, /* 5.5 Mb */
180 4900, 0x19, 0x04, 11,
181 2, 2, 2, 2, 2, 2, 2, 0 },
182 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 11000, /* 11 Mb */
183 8100, 0x18, 0x04, 22,
184 3, 3, 2, 3, 3, 3, 3, 0 },
185 { FALSE, FALSE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
186 5400, 0x0b, 0x00, 12,
187 4, 2, 1, 4, 4, 4, 4, 0 },
188 { FALSE, FALSE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
189 7800, 0x0f, 0x00, 18,
190 4, 3, 1, 5, 5, 5, 5, 0 },
191 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
192 10100, 0x0a, 0x00, 24,
193 6, 4, 1, 6, 6, 6, 6, 0 },
194 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
195 14100, 0x0e, 0x00, 36,
196 6, 6, 2, 7, 7, 7, 7, 0 },
197 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
198 17700, 0x09, 0x00, 48,
199 8, 10, 3, 8, 8, 8, 8, 0 },
200 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
201 23700, 0x0d, 0x00, 72,
202 8, 14, 3, 9, 9, 9, 9, 0 },
203 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
204 27400, 0x08, 0x00, 96,
205 8, 20, 3, 10, 10, 10, 10, 0 },
206 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
207 30900, 0x0c, 0x00, 108,
208 8, 23, 3, 11, 11, 11, 11, 0 },
209 { FALSE, FALSE, WLAN_PHY_HT_20_SS, 6500, /* 6.5 Mb */
210 6400, 0x80, 0x00, 0,
211 4, 2, 3, 12, 28, 12, 28, 3216 },
212 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 13000, /* 13 Mb */
213 12700, 0x81, 0x00, 1,
214 6, 4, 3, 13, 29, 13, 29, 6434 },
215 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 19500, /* 19.5 Mb */
216 18800, 0x82, 0x00, 2,
217 6, 6, 3, 14, 30, 14, 30, 9650 },
218 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 26000, /* 26 Mb */
219 25000, 0x83, 0x00, 3,
220 8, 10, 3, 15, 31, 15, 31, 12868 },
221 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 39000, /* 39 Mb */
222 36700, 0x84, 0x00, 4,
223 8, 14, 3, 16, 32, 16, 32, 19304 },
224 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 52000, /* 52 Mb */
225 48100, 0x85, 0x00, 5,
226 8, 20, 3, 17, 33, 17, 33, 25740 },
227 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 58500, /* 58.5 Mb */
228 53500, 0x86, 0x00, 6,
229 8, 23, 3, 18, 34, 18, 34, 28956 },
230 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 65000, /* 65 Mb */
231 59000, 0x87, 0x00, 7,
232 8, 25, 3, 19, 35, 19, 36, 32180 },
233 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 13000, /* 13 Mb */
234 12700, 0x88, 0x00, 8,
235 4, 2, 3, 20, 37, 20, 37, 6430 },
236 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 26000, /* 26 Mb */
237 24800, 0x89, 0x00, 9,
238 6, 4, 3, 21, 38, 21, 38, 12860 },
239 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 39000, /* 39 Mb */
240 36600, 0x8a, 0x00, 10,
241 6, 6, 3, 22, 39, 22, 39, 19300 },
242 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 52000, /* 52 Mb */
243 48100, 0x8b, 0x00, 11,
244 8, 10, 3, 23, 40, 23, 40, 25736 },
245 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 78000, /* 78 Mb */
246 69500, 0x8c, 0x00, 12,
247 8, 14, 3, 24, 41, 24, 41, 38600 },
248 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 104000, /* 104 Mb */
249 89500, 0x8d, 0x00, 13,
250 8, 20, 3, 25, 42, 25, 42, 51472 },
251 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 117000, /* 117 Mb */
252 98900, 0x8e, 0x00, 14,
253 8, 23, 3, 26, 43, 26, 44, 57890 },
254 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 130000, /* 130 Mb */
255 108300, 0x8f, 0x00, 15,
256 8, 25, 3, 27, 44, 27, 45, 64320 },
257 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 13500, /* 13.5 Mb */
258 13200, 0x80, 0x00, 0,
259 8, 2, 3, 12, 28, 28, 28, 6684 },
260 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 27500, /* 27.0 Mb */
261 25900, 0x81, 0x00, 1,
262 8, 4, 3, 13, 29, 29, 29, 13368 },
263 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 40500, /* 40.5 Mb */
264 38600, 0x82, 0x00, 2,
265 8, 6, 3, 14, 30, 30, 30, 20052 },
266 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 54000, /* 54 Mb */
267 49800, 0x83, 0x00, 3,
268 8, 10, 3, 15, 31, 31, 31, 26738 },
269 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 81500, /* 81 Mb */
270 72200, 0x84, 0x00, 4,
271 8, 14, 3, 16, 32, 32, 32, 40104 },
272 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 108000, /* 108 Mb */
273 92900, 0x85, 0x00, 5,
274 8, 20, 3, 17, 33, 33, 33, 53476 },
275 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 121500, /* 121.5 Mb */
276 102700, 0x86, 0x00, 6,
277 8, 23, 3, 18, 34, 34, 34, 60156 },
278 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 135000, /* 135 Mb */
279 112000, 0x87, 0x00, 7,
280 8, 23, 3, 19, 35, 36, 36, 66840 },
281 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
282 122000, 0x87, 0x00, 7,
283 8, 25, 3, 19, 35, 36, 36, 74200 },
284 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 27000, /* 27 Mb */
285 25800, 0x88, 0x00, 8,
286 8, 2, 3, 20, 37, 37, 37, 13360 },
287 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 54000, /* 54 Mb */
288 49800, 0x89, 0x00, 9,
289 8, 4, 3, 21, 38, 38, 38, 26720 },
290 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 81000, /* 81 Mb */
291 71900, 0x8a, 0x00, 10,
292 8, 6, 3, 22, 39, 39, 39, 40080 },
293 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 108000, /* 108 Mb */
294 92500, 0x8b, 0x00, 11,
295 8, 10, 3, 23, 40, 40, 40, 53440 },
296 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 162000, /* 162 Mb */
297 130300, 0x8c, 0x00, 12,
298 8, 14, 3, 24, 41, 41, 41, 80160 },
299 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 216000, /* 216 Mb */
300 162800, 0x8d, 0x00, 13,
301 8, 20, 3, 25, 42, 42, 42, 106880 },
302 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 243000, /* 243 Mb */
303 178200, 0x8e, 0x00, 14,
304 8, 23, 3, 26, 43, 43, 43, 120240 },
305 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 270000, /* 270 Mb */
306 192100, 0x8f, 0x00, 15,
307 8, 23, 3, 27, 44, 45, 45, 133600 },
308 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
309 207000, 0x8f, 0x00, 15,
310 8, 25, 3, 27, 44, 45, 45, 148400 },
311 },
312 50, /* probe interval */
313 50, /* rssi reduce interval */
314 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
315};
316
317static struct ath_rate_table ar5416_11a_ratetable = {
318 8,
319 {
320 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
321 5400, 0x0b, 0x00, (0x80|12),
322 0, 2, 1, 0, 0 },
323 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
324 7800, 0x0f, 0x00, 18,
325 0, 3, 1, 1, 0 },
326 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
327 10000, 0x0a, 0x00, (0x80|24),
328 2, 4, 2, 2, 0 },
329 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
330 13900, 0x0e, 0x00, 36,
331 2, 6, 2, 3, 0 },
332 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
333 17300, 0x09, 0x00, (0x80|48),
334 4, 10, 3, 4, 0 },
335 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
336 23000, 0x0d, 0x00, 72,
337 4, 14, 3, 5, 0 },
338 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
339 27400, 0x08, 0x00, 96,
340 4, 19, 3, 6, 0 },
341 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
342 29300, 0x0c, 0x00, 108,
343 4, 23, 3, 7, 0 },
344 },
345 50, /* probe interval */
346 50, /* rssi reduce interval */
347 0, /* Phy rates allowed initially */
348};
349
350static struct ath_rate_table ar5416_11a_ratetable_Half = {
351 8,
352 {
353 { TRUE, TRUE, WLAN_PHY_OFDM, 3000, /* 6 Mb */
354 2700, 0x0b, 0x00, (0x80|6),
355 0, 2, 1, 0, 0},
356 { TRUE, TRUE, WLAN_PHY_OFDM, 4500, /* 9 Mb */
357 3900, 0x0f, 0x00, 9,
358 0, 3, 1, 1, 0 },
359 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 12 Mb */
360 5000, 0x0a, 0x00, (0x80|12),
361 2, 4, 2, 2, 0 },
362 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 18 Mb */
363 6950, 0x0e, 0x00, 18,
364 2, 6, 2, 3, 0 },
365 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 24 Mb */
366 8650, 0x09, 0x00, (0x80|24),
367 4, 10, 3, 4, 0 },
368 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 36 Mb */
369 11500, 0x0d, 0x00, 36,
370 4, 14, 3, 5, 0 },
371 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 48 Mb */
372 13700, 0x08, 0x00, 48,
373 4, 19, 3, 6, 0 },
374 { TRUE, TRUE, WLAN_PHY_OFDM, 27000, /* 54 Mb */
375 14650, 0x0c, 0x00, 54,
376 4, 23, 3, 7, 0 },
377 },
378 50, /* probe interval */
379 50, /* rssi reduce interval */
380 0, /* Phy rates allowed initially */
381};
382
383static struct ath_rate_table ar5416_11a_ratetable_Quarter = {
384 8,
385 {
386 { TRUE, TRUE, WLAN_PHY_OFDM, 1500, /* 6 Mb */
387 1350, 0x0b, 0x00, (0x80|3),
388 0, 2, 1, 0, 0 },
389 { TRUE, TRUE, WLAN_PHY_OFDM, 2250, /* 9 Mb */
390 1950, 0x0f, 0x00, 4,
391 0, 3, 1, 1, 0 },
392 { TRUE, TRUE, WLAN_PHY_OFDM, 3000, /* 12 Mb */
393 2500, 0x0a, 0x00, (0x80|6),
394 2, 4, 2, 2, 0 },
395 { TRUE, TRUE, WLAN_PHY_OFDM, 4500, /* 18 Mb */
396 3475, 0x0e, 0x00, 9,
397 2, 6, 2, 3, 0 },
398 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 25 Mb */
399 4325, 0x09, 0x00, (0x80|12),
400 4, 10, 3, 4, 0 },
401 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 36 Mb */
402 5750, 0x0d, 0x00, 18,
403 4, 14, 3, 5, 0 },
404 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 48 Mb */
405 6850, 0x08, 0x00, 24,
406 4, 19, 3, 6, 0 },
407 { TRUE, TRUE, WLAN_PHY_OFDM, 13500, /* 54 Mb */
408 7325, 0x0c, 0x00, 27,
409 4, 23, 3, 7, 0 },
410 },
411 50, /* probe interval */
412 50, /* rssi reduce interval */
413 0, /* Phy rates allowed initially */
414};
415
416static struct ath_rate_table ar5416_11g_ratetable = {
417 12,
418 {
419 { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */
420 900, 0x1b, 0x00, 2,
421 0, 0, 1, 0, 0 },
422 { TRUE, TRUE, WLAN_PHY_CCK, 2000, /* 2 Mb */
423 1900, 0x1a, 0x04, 4,
424 1, 1, 1, 1, 0 },
425 { TRUE, TRUE, WLAN_PHY_CCK, 5500, /* 5.5 Mb */
426 4900, 0x19, 0x04, 11,
427 2, 2, 2, 2, 0 },
428 { TRUE, TRUE, WLAN_PHY_CCK, 11000, /* 11 Mb */
429 8100, 0x18, 0x04, 22,
430 3, 3, 2, 3, 0 },
431 { FALSE, FALSE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
432 5400, 0x0b, 0x00, 12,
433 4, 2, 1, 4, 0 },
434 { FALSE, FALSE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
435 7800, 0x0f, 0x00, 18,
436 4, 3, 1, 5, 0 },
437 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
438 10000, 0x0a, 0x00, 24,
439 6, 4, 1, 6, 0 },
440 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
441 13900, 0x0e, 0x00, 36,
442 6, 6, 2, 7, 0 },
443 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
444 17300, 0x09, 0x00, 48,
445 8, 10, 3, 8, 0 },
446 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
447 23000, 0x0d, 0x00, 72,
448 8, 14, 3, 9, 0 },
449 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
450 27400, 0x08, 0x00, 96,
451 8, 19, 3, 10, 0 },
452 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
453 29300, 0x0c, 0x00, 108,
454 8, 23, 3, 11, 0 },
455 },
456 50, /* probe interval */
457 50, /* rssi reduce interval */
458 0, /* Phy rates allowed initially */
459};
460
461static struct ath_rate_table ar5416_11b_ratetable = {
462 4,
463 {
464 { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */
465 900, 0x1b, 0x00, (0x80|2),
466 0, 0, 1, 0, 0 },
467 { TRUE, TRUE, WLAN_PHY_CCK, 2000, /* 2 Mb */
468 1800, 0x1a, 0x04, (0x80|4),
469 1, 1, 1, 1, 0 },
470 { TRUE, TRUE, WLAN_PHY_CCK, 5500, /* 5.5 Mb */
471 4300, 0x19, 0x04, (0x80|11),
472 1, 2, 2, 2, 0 },
473 { TRUE, TRUE, WLAN_PHY_CCK, 11000, /* 11 Mb */
474 7100, 0x18, 0x04, (0x80|22),
475 1, 4, 100, 3, 0 },
476 },
477 100, /* probe interval */
478 100, /* rssi reduce interval */
479 0, /* Phy rates allowed initially */
480};
481
482static void ar5416_attach_ratetables(struct ath_rate_softc *sc)
483{
484 /*
485 * Attach rate tables.
486 */
487 sc->hw_rate_table[ATH9K_MODE_11B] = &ar5416_11b_ratetable;
488 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable;
489 sc->hw_rate_table[ATH9K_MODE_11G] = &ar5416_11g_ratetable;
490
491 sc->hw_rate_table[ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable;
492 sc->hw_rate_table[ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable;
493 sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
494 &ar5416_11na_ratetable;
495 sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
496 &ar5416_11na_ratetable;
497 sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
498 &ar5416_11ng_ratetable;
499 sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
500 &ar5416_11ng_ratetable;
501}
502
503static void ar5416_setquarter_ratetable(struct ath_rate_softc *sc)
504{
505 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable_Quarter;
506 return;
507}
508
509static void ar5416_sethalf_ratetable(struct ath_rate_softc *sc)
510{
511 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable_Half;
512 return;
513}
514
515static void ar5416_setfull_ratetable(struct ath_rate_softc *sc)
516{
517 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable;
518 return;
519}
520
521/*
522 * Return the median of three numbers
523 */
524static inline int8_t median(int8_t a, int8_t b, int8_t c)
525{
526 if (a >= b) {
527 if (b >= c)
528 return b;
529 else if (a > c)
530 return c;
531 else
532 return a;
533 } else {
534 if (a >= c)
535 return a;
536 else if (b >= c)
537 return c;
538 else
539 return b;
540 }
541}
542
543static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
544 struct ath_tx_ratectrl *rate_ctrl)
545{
546 u8 i, j, idx, idx_next;
547
548 for (i = rate_ctrl->max_valid_rate - 1; i > 0; i--) {
549 for (j = 0; j <= i-1; j++) {
550 idx = rate_ctrl->valid_rate_index[j];
551 idx_next = rate_ctrl->valid_rate_index[j+1];
552
553 if (rate_table->info[idx].ratekbps >
554 rate_table->info[idx_next].ratekbps) {
555 rate_ctrl->valid_rate_index[j] = idx_next;
556 rate_ctrl->valid_rate_index[j+1] = idx;
557 }
558 }
559 }
560}
561
562/* Access functions for valid_txrate_mask */
563
564static void ath_rc_init_valid_txmask(struct ath_tx_ratectrl *rate_ctrl)
565{
566 u8 i;
567
568 for (i = 0; i < rate_ctrl->rate_table_size; i++)
569 rate_ctrl->valid_rate_index[i] = FALSE;
570}
571
572static inline void ath_rc_set_valid_txmask(struct ath_tx_ratectrl *rate_ctrl,
573 u8 index, int valid_tx_rate)
574{
575 ASSERT(index <= rate_ctrl->rate_table_size);
576 rate_ctrl->valid_rate_index[index] = valid_tx_rate ? TRUE : FALSE;
577}
578
579static inline int ath_rc_isvalid_txmask(struct ath_tx_ratectrl *rate_ctrl,
580 u8 index)
581{
582 ASSERT(index <= rate_ctrl->rate_table_size);
583 return rate_ctrl->valid_rate_index[index];
584}
585
586/* Iterators for valid_txrate_mask */
587static inline int
588ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
589 struct ath_tx_ratectrl *rate_ctrl,
590 u8 cur_valid_txrate,
591 u8 *next_idx)
592{
593 u8 i;
594
595 for (i = 0; i < rate_ctrl->max_valid_rate - 1; i++) {
596 if (rate_ctrl->valid_rate_index[i] == cur_valid_txrate) {
597 *next_idx = rate_ctrl->valid_rate_index[i+1];
598 return TRUE;
599 }
600 }
601
602 /* No more valid rates */
603 *next_idx = 0;
604 return FALSE;
605}
606
607/* Return true only for single stream */
608
609static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
610{
611 if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG))
612 return FALSE;
613 if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
614 return FALSE;
615 if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
616 return FALSE;
617 if (!ignore_cw && WLAN_RC_PHY_HT(phy))
618 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
619 return FALSE;
620 if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
621 return FALSE;
622 return TRUE;
623}
624
625static inline int
626ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table,
627 struct ath_tx_ratectrl *rate_ctrl,
628 u8 cur_valid_txrate, u8 *next_idx)
629{
630 int8_t i;
631
632 for (i = 1; i < rate_ctrl->max_valid_rate ; i++) {
633 if (rate_ctrl->valid_rate_index[i] == cur_valid_txrate) {
634 *next_idx = rate_ctrl->valid_rate_index[i-1];
635 return TRUE;
636 }
637 }
638 return FALSE;
639}
640
641/*
642 * Initialize the Valid Rate Index from valid entries in Rate Table
643 */
644static u8
645ath_rc_sib_init_validrates(struct ath_rate_node *ath_rc_priv,
646 const struct ath_rate_table *rate_table,
647 u32 capflag)
648{
649 struct ath_tx_ratectrl *rate_ctrl;
650 u8 i, hi = 0;
651 u32 valid;
652
653 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
654 for (i = 0; i < rate_table->rate_cnt; i++) {
655 valid = (ath_rc_priv->single_stream ?
656 rate_table->info[i].valid_single_stream :
657 rate_table->info[i].valid);
658 if (valid == TRUE) {
659 u32 phy = rate_table->info[i].phy;
660 u8 valid_rate_count = 0;
661
662 if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
663 continue;
664
665 valid_rate_count = rate_ctrl->valid_phy_ratecnt[phy];
666
667 rate_ctrl->valid_phy_rateidx[phy][valid_rate_count] = i;
668 rate_ctrl->valid_phy_ratecnt[phy] += 1;
669 ath_rc_set_valid_txmask(rate_ctrl, i, TRUE);
670 hi = A_MAX(hi, i);
671 }
672 }
673 return hi;
674}
675
676/*
677 * Initialize the Valid Rate Index from Rate Set
678 */
679static u8
680ath_rc_sib_setvalid_rates(struct ath_rate_node *ath_rc_priv,
681 const struct ath_rate_table *rate_table,
682 struct ath_rateset *rateset,
683 u32 capflag)
684{
685 /* XXX: Clean me up and make identation friendly */
686 u8 i, j, hi = 0;
687 struct ath_tx_ratectrl *rate_ctrl =
688 (struct ath_tx_ratectrl *)(ath_rc_priv);
689
690 /* Use intersection of working rates and valid rates */
691 for (i = 0; i < rateset->rs_nrates; i++) {
692 for (j = 0; j < rate_table->rate_cnt; j++) {
693 u32 phy = rate_table->info[j].phy;
694 u32 valid = (ath_rc_priv->single_stream ?
695 rate_table->info[j].valid_single_stream :
696 rate_table->info[j].valid);
697
698 /* We allow a rate only if its valid and the
699 * capflag matches one of the validity
700 * (TRUE/TRUE_20/TRUE_40) flags */
701
702 /* XXX: catch the negative of this branch
703 * first and then continue */
704 if (((rateset->rs_rates[i] & 0x7F) ==
705 (rate_table->info[j].dot11rate & 0x7F)) &&
706 ((valid & WLAN_RC_CAP_MODE(capflag)) ==
707 WLAN_RC_CAP_MODE(capflag)) &&
708 !WLAN_RC_PHY_HT(phy)) {
709
710 u8 valid_rate_count = 0;
711
712 if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
713 continue;
714
715 valid_rate_count =
716 rate_ctrl->valid_phy_ratecnt[phy];
717
718 rate_ctrl->valid_phy_rateidx[phy]
719 [valid_rate_count] = j;
720 rate_ctrl->valid_phy_ratecnt[phy] += 1;
721 ath_rc_set_valid_txmask(rate_ctrl, j, TRUE);
722 hi = A_MAX(hi, j);
723 }
724 }
725 }
726 return hi;
727}
728
729static u8
730ath_rc_sib_setvalid_htrates(struct ath_rate_node *ath_rc_priv,
731 const struct ath_rate_table *rate_table,
732 u8 *mcs_set, u32 capflag)
733{
734 u8 i, j, hi = 0;
735 struct ath_tx_ratectrl *rate_ctrl =
736 (struct ath_tx_ratectrl *)(ath_rc_priv);
737
738 /* Use intersection of working rates and valid rates */
739 for (i = 0; i < ((struct ath_rateset *)mcs_set)->rs_nrates; i++) {
740 for (j = 0; j < rate_table->rate_cnt; j++) {
741 u32 phy = rate_table->info[j].phy;
742 u32 valid = (ath_rc_priv->single_stream ?
743 rate_table->info[j].valid_single_stream :
744 rate_table->info[j].valid);
745
746 if (((((struct ath_rateset *)
747 mcs_set)->rs_rates[i] & 0x7F) !=
748 (rate_table->info[j].dot11rate & 0x7F)) ||
749 !WLAN_RC_PHY_HT(phy) ||
750 !WLAN_RC_PHY_HT_VALID(valid, capflag))
751 continue;
752
753 if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
754 continue;
755
756 rate_ctrl->valid_phy_rateidx[phy]
757 [rate_ctrl->valid_phy_ratecnt[phy]] = j;
758 rate_ctrl->valid_phy_ratecnt[phy] += 1;
759 ath_rc_set_valid_txmask(rate_ctrl, j, TRUE);
760 hi = A_MAX(hi, j);
761 }
762 }
763 return hi;
764}
765
766/*
767 * Attach to a device instance. Setup the public definition
768 * of how much per-node space we need and setup the private
769 * phy tables that have rate control parameters.
770 */
771struct ath_rate_softc *ath_rate_attach(struct ath_hal *ah)
772{
773 struct ath_rate_softc *asc;
774
775 /* we are only in user context so we can sleep for memory */
776 asc = kzalloc(sizeof(struct ath_rate_softc), GFP_KERNEL);
777 if (asc == NULL)
778 return NULL;
779
780 ar5416_attach_ratetables(asc);
781
782 /* Save Maximum TX Trigger Level (used for 11n) */
783 tx_triglevel_max = ah->ah_caps.tx_triglevel_max;
784 /* return alias for ath_rate_softc * */
785 return asc;
786}
787
788static struct ath_rate_node *ath_rate_node_alloc(struct ath_vap *avp,
789 struct ath_rate_softc *rsc,
790 gfp_t gfp)
791{
792 struct ath_rate_node *anode;
793
794 anode = kzalloc(sizeof(struct ath_rate_node), gfp);
795 if (anode == NULL)
796 return NULL;
797
798 anode->avp = avp;
799 anode->asc = rsc;
800 avp->rc_node = anode;
801
802 return anode;
803}
804
805static void ath_rate_node_free(struct ath_rate_node *anode)
806{
807 if (anode != NULL)
808 kfree(anode);
809}
810
811void ath_rate_detach(struct ath_rate_softc *asc)
812{
813 if (asc != NULL)
814 kfree(asc);
815}
816
817u8 ath_rate_findrateix(struct ath_softc *sc,
818 u8 dot11rate)
819{
820 const struct ath_rate_table *ratetable;
821 struct ath_rate_softc *rsc = sc->sc_rc;
822 int i;
823
824 ratetable = rsc->hw_rate_table[sc->sc_curmode];
825
826 if (WARN_ON(!ratetable))
827 return 0;
828
829 for (i = 0; i < ratetable->rate_cnt; i++) {
830 if ((ratetable->info[i].dot11rate & 0x7f) == (dot11rate & 0x7f))
831 return i;
832 }
833
834 return 0;
835}
836
837/*
838 * Update rate-control state on a device state change. When
839 * operating as a station this includes associate/reassociate
840 * with an AP. Otherwise this gets called, for example, when
841 * the we transition to run state when operating as an AP.
842 */
843void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp)
844{
845 struct ath_rate_softc *asc = sc->sc_rc;
846
847 /* For half and quarter rate channles use different
848 * rate tables
849 */
850 if (sc->sc_curchan.channelFlags & CHANNEL_HALF)
851 ar5416_sethalf_ratetable(asc);
852 else if (sc->sc_curchan.channelFlags & CHANNEL_QUARTER)
853 ar5416_setquarter_ratetable(asc);
854 else /* full rate */
855 ar5416_setfull_ratetable(asc);
856
857 if (avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) {
858 asc->fixedrix =
859 sc->sc_rixmap[avp->av_config.av_fixed_rateset & 0xff];
860 /* NB: check the fixed rate exists */
861 if (asc->fixedrix == 0xff)
862 asc->fixedrix = IEEE80211_FIXED_RATE_NONE;
863 } else {
864 asc->fixedrix = IEEE80211_FIXED_RATE_NONE;
865 }
866}
867
868static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
869 struct ath_rate_node *ath_rc_priv,
870 const struct ath_rate_table *rate_table,
871 int probe_allowed, int *is_probing,
872 int is_retry)
873{
874 u32 dt, best_thruput, this_thruput, now_msec;
875 u8 rate, next_rate, best_rate, maxindex, minindex;
876 int8_t rssi_last, rssi_reduce = 0, index = 0;
877 struct ath_tx_ratectrl *rate_ctrl = NULL;
878
879 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv ?
880 (ath_rc_priv) : NULL);
881
882 *is_probing = FALSE;
883
884 rssi_last = median(rate_ctrl->rssi_last,
885 rate_ctrl->rssi_last_prev,
886 rate_ctrl->rssi_last_prev2);
887
888 /*
889 * Age (reduce) last ack rssi based on how old it is.
890 * The bizarre numbers are so the delta is 160msec,
891 * meaning we divide by 16.
892 * 0msec <= dt <= 25msec: don't derate
893 * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB
894 * 185msec <= dt: derate by 10dB
895 */
896
897 now_msec = jiffies_to_msecs(jiffies);
898 dt = now_msec - rate_ctrl->rssi_time;
899
900 if (dt >= 185)
901 rssi_reduce = 10;
902 else if (dt >= 25)
903 rssi_reduce = (u8)((dt - 25) >> 4);
904
905 /* Now reduce rssi_last by rssi_reduce */
906 if (rssi_last < rssi_reduce)
907 rssi_last = 0;
908 else
909 rssi_last -= rssi_reduce;
910
911 /*
912 * Now look up the rate in the rssi table and return it.
913 * If no rates match then we return 0 (lowest rate)
914 */
915
916 best_thruput = 0;
917 maxindex = rate_ctrl->max_valid_rate-1;
918
919 minindex = 0;
920 best_rate = minindex;
921
922 /*
923 * Try the higher rate first. It will reduce memory moving time
924 * if we have very good channel characteristics.
925 */
926 for (index = maxindex; index >= minindex ; index--) {
927 u8 per_thres;
928
929 rate = rate_ctrl->valid_rate_index[index];
930 if (rate > rate_ctrl->rate_max_phy)
931 continue;
932
933 /*
934 * For TCP the average collision rate is around 11%,
935 * so we ignore PERs less than this. This is to
936 * prevent the rate we are currently using (whose
937 * PER might be in the 10-15 range because of TCP
938 * collisions) looking worse than the next lower
939 * rate whose PER has decayed close to 0. If we
940 * used to next lower rate, its PER would grow to
941 * 10-15 and we would be worse off then staying
942 * at the current rate.
943 */
944 per_thres = rate_ctrl->state[rate].per;
945 if (per_thres < 12)
946 per_thres = 12;
947
948 this_thruput = rate_table->info[rate].user_ratekbps *
949 (100 - per_thres);
950
951 if (best_thruput <= this_thruput) {
952 best_thruput = this_thruput;
953 best_rate = rate;
954 }
955 }
956
957 rate = best_rate;
958
959 /* if we are retrying for more than half the number
960 * of max retries, use the min rate for the next retry
961 */
962 if (is_retry)
963 rate = rate_ctrl->valid_rate_index[minindex];
964
965 rate_ctrl->rssi_last_lookup = rssi_last;
966
967 /*
968 * Must check the actual rate (ratekbps) to account for
969 * non-monoticity of 11g's rate table
970 */
971
972 if (rate >= rate_ctrl->rate_max_phy && probe_allowed) {
973 rate = rate_ctrl->rate_max_phy;
974
975 /* Probe the next allowed phy state */
976 /* FIXME:XXXX Check to make sure ratMax is checked properly */
977 if (ath_rc_get_nextvalid_txrate(rate_table,
978 rate_ctrl, rate, &next_rate) &&
979 (now_msec - rate_ctrl->probe_time >
980 rate_table->probe_interval) &&
981 (rate_ctrl->hw_maxretry_pktcnt >= 1)) {
982 rate = next_rate;
983 rate_ctrl->probe_rate = rate;
984 rate_ctrl->probe_time = now_msec;
985 rate_ctrl->hw_maxretry_pktcnt = 0;
986 *is_probing = TRUE;
987 }
988 }
989
990 /*
991 * Make sure rate is not higher than the allowed maximum.
992 * We should also enforce the min, but I suspect the min is
993 * normally 1 rather than 0 because of the rate 9 vs 6 issue
994 * in the old code.
995 */
996 if (rate > (rate_ctrl->rate_table_size - 1))
997 rate = rate_ctrl->rate_table_size - 1;
998
999 ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
1000 (rate_table->info[rate].valid_single_stream &&
1001 ath_rc_priv->single_stream));
1002
1003 return rate;
1004}
1005
1006static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table ,
1007 struct ath_rc_series *series,
1008 u8 tries,
1009 u8 rix,
1010 int rtsctsenable)
1011{
1012 series->tries = tries;
1013 series->flags = (rtsctsenable ? ATH_RC_RTSCTS_FLAG : 0) |
1014 (WLAN_RC_PHY_DS(rate_table->info[rix].phy) ?
1015 ATH_RC_DS_FLAG : 0) |
1016 (WLAN_RC_PHY_40(rate_table->info[rix].phy) ?
1017 ATH_RC_CW40_FLAG : 0) |
1018 (WLAN_RC_PHY_SGI(rate_table->info[rix].phy) ?
1019 ATH_RC_SGI_FLAG : 0);
1020
1021 series->rix = rate_table->info[rix].base_index;
1022 series->max_4ms_framelen = rate_table->info[rix].max_4ms_framelen;
1023}
1024
1025static u8 ath_rc_rate_getidx(struct ath_softc *sc,
1026 struct ath_rate_node *ath_rc_priv,
1027 const struct ath_rate_table *rate_table,
1028 u8 rix, u16 stepdown,
1029 u16 min_rate)
1030{
1031 u32 j;
1032 u8 nextindex;
1033 struct ath_tx_ratectrl *rate_ctrl =
1034 (struct ath_tx_ratectrl *)(ath_rc_priv);
1035
1036 if (min_rate) {
1037 for (j = RATE_TABLE_SIZE; j > 0; j--) {
1038 if (ath_rc_get_nextlowervalid_txrate(rate_table,
1039 rate_ctrl, rix, &nextindex))
1040 rix = nextindex;
1041 else
1042 break;
1043 }
1044 } else {
1045 for (j = stepdown; j > 0; j--) {
1046 if (ath_rc_get_nextlowervalid_txrate(rate_table,
1047 rate_ctrl, rix, &nextindex))
1048 rix = nextindex;
1049 else
1050 break;
1051 }
1052 }
1053 return rix;
1054}
1055
1056static void ath_rc_ratefind(struct ath_softc *sc,
1057 struct ath_rate_node *ath_rc_priv,
1058 int num_tries, int num_rates, unsigned int rcflag,
1059 struct ath_rc_series series[], int *is_probe,
1060 int is_retry)
1061{
1062 u8 try_per_rate = 0, i = 0, rix, nrix;
1063 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1064 struct ath_rate_table *rate_table;
1065
1066 rate_table =
1067 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
1068 rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table,
1069 (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0,
1070 is_probe, is_retry);
1071 nrix = rix;
1072
1073 if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*is_probe)) {
1074 /* set one try for probe rates. For the
1075 * probes don't enable rts */
1076 ath_rc_rate_set_series(rate_table,
1077 &series[i++], 1, nrix, FALSE);
1078
1079 try_per_rate = (num_tries/num_rates);
1080 /* Get the next tried/allowed rate. No RTS for the next series
1081 * after the probe rate
1082 */
1083 nrix = ath_rc_rate_getidx(sc,
1084 ath_rc_priv, rate_table, nrix, 1, FALSE);
1085 ath_rc_rate_set_series(rate_table,
1086 &series[i++], try_per_rate, nrix, 0);
1087 } else {
1088 try_per_rate = (num_tries/num_rates);
1089 /* Set the choosen rate. No RTS for first series entry. */
1090 ath_rc_rate_set_series(rate_table,
1091 &series[i++], try_per_rate, nrix, FALSE);
1092 }
1093
1094 /* Fill in the other rates for multirate retry */
1095 for ( ; i < num_rates; i++) {
1096 u8 try_num;
1097 u8 min_rate;
1098
1099 try_num = ((i + 1) == num_rates) ?
1100 num_tries - (try_per_rate * i) : try_per_rate ;
1101 min_rate = (((i + 1) == num_rates) &&
1102 (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0;
1103
1104 nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
1105 rate_table, nrix, 1, min_rate);
1106 /* All other rates in the series have RTS enabled */
1107 ath_rc_rate_set_series(rate_table,
1108 &series[i], try_num, nrix, TRUE);
1109 }
1110
1111 /*
1112 * NB:Change rate series to enable aggregation when operating
1113 * at lower MCS rates. When first rate in series is MCS2
1114 * in HT40 @ 2.4GHz, series should look like:
1115 *
1116 * {MCS2, MCS1, MCS0, MCS0}.
1117 *
1118 * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
1119 * look like:
1120 *
1121 * {MCS3, MCS2, MCS1, MCS1}
1122 *
1123 * So, set fourth rate in series to be same as third one for
1124 * above conditions.
1125 */
1126 if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) ||
1127 (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) ||
1128 (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) {
1129 u8 dot11rate = rate_table->info[rix].dot11rate;
1130 u8 phy = rate_table->info[rix].phy;
1131 if (i == 4 &&
1132 ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
1133 (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
1134 series[3].rix = series[2].rix;
1135 series[3].flags = series[2].flags;
1136 series[3].max_4ms_framelen = series[2].max_4ms_framelen;
1137 }
1138 }
1139}
1140
1141/*
1142 * Return the Tx rate series.
1143 */
1144void ath_rate_findrate(struct ath_softc *sc,
1145 struct ath_rate_node *ath_rc_priv,
1146 int num_tries,
1147 int num_rates,
1148 unsigned int rcflag,
1149 struct ath_rc_series series[],
1150 int *is_probe,
1151 int is_retry)
1152{
1153 struct ath_vap *avp = ath_rc_priv->avp;
1154
1155 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
1156 if (!num_rates || !num_tries)
1157 return;
1158
1159 if (avp->av_config.av_fixed_rateset == IEEE80211_FIXED_RATE_NONE) {
1160 ath_rc_ratefind(sc, ath_rc_priv, num_tries, num_rates,
1161 rcflag, series, is_probe, is_retry);
1162 } else {
1163 /* Fixed rate */
1164 int idx;
1165 u8 flags;
1166 u32 rix;
1167 struct ath_rate_softc *asc = ath_rc_priv->asc;
1168 struct ath_rate_table *rate_table;
1169
1170 rate_table = (struct ath_rate_table *)
1171 asc->hw_rate_table[sc->sc_curmode];
1172
1173 for (idx = 0; idx < 4; idx++) {
1174 unsigned int mcs;
1175 u8 series_rix = 0;
1176
1177 series[idx].tries =
1178 IEEE80211_RATE_IDX_ENTRY(
1179 avp->av_config.av_fixed_retryset, idx);
1180
1181 mcs = IEEE80211_RATE_IDX_ENTRY(
1182 avp->av_config.av_fixed_rateset, idx);
1183
1184 if (idx == 3 && (mcs & 0xf0) == 0x70)
1185 mcs = (mcs & ~0xf0)|0x80;
1186
1187 if (!(mcs & 0x80))
1188 flags = 0;
1189 else
1190 flags = ((ath_rc_priv->ht_cap &
1191 WLAN_RC_DS_FLAG) ?
1192 ATH_RC_DS_FLAG : 0) |
1193 ((ath_rc_priv->ht_cap &
1194 WLAN_RC_40_FLAG) ?
1195 ATH_RC_CW40_FLAG : 0) |
1196 ((ath_rc_priv->ht_cap &
1197 WLAN_RC_SGI_FLAG) ?
1198 ((ath_rc_priv->ht_cap &
1199 WLAN_RC_40_FLAG) ?
1200 ATH_RC_SGI_FLAG : 0) : 0);
1201
1202 series[idx].rix = sc->sc_rixmap[mcs];
1203 series_rix = series[idx].rix;
1204
1205 /* XXX: Give me some cleanup love */
1206 if ((flags & ATH_RC_CW40_FLAG) &&
1207 (flags & ATH_RC_SGI_FLAG))
1208 rix = rate_table->info[series_rix].ht_index;
1209 else if (flags & ATH_RC_SGI_FLAG)
1210 rix = rate_table->info[series_rix].sgi_index;
1211 else if (flags & ATH_RC_CW40_FLAG)
1212 rix = rate_table->info[series_rix].cw40index;
1213 else
1214 rix = rate_table->info[series_rix].base_index;
1215 series[idx].max_4ms_framelen =
1216 rate_table->info[rix].max_4ms_framelen;
1217 series[idx].flags = flags;
1218 }
1219 }
1220}
1221
1222static void ath_rc_update_ht(struct ath_softc *sc,
1223 struct ath_rate_node *ath_rc_priv,
1224 struct ath_tx_info_priv *info_priv,
1225 int tx_rate, int xretries, int retries)
1226{
1227 struct ath_tx_ratectrl *rate_ctrl;
1228 u32 now_msec = jiffies_to_msecs(jiffies);
1229 int state_change = FALSE, rate, count;
1230 u8 last_per;
1231 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1232 struct ath_rate_table *rate_table =
1233 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
1234
1235 static u32 nretry_to_per_lookup[10] = {
1236 100 * 0 / 1,
1237 100 * 1 / 4,
1238 100 * 1 / 2,
1239 100 * 3 / 4,
1240 100 * 4 / 5,
1241 100 * 5 / 6,
1242 100 * 6 / 7,
1243 100 * 7 / 8,
1244 100 * 8 / 9,
1245 100 * 9 / 10
1246 };
1247
1248 if (!ath_rc_priv)
1249 return;
1250
1251 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
1252
1253 ASSERT(tx_rate >= 0);
1254 if (tx_rate < 0)
1255 return;
1256
1257 /* To compensate for some imbalance between ctrl and ext. channel */
1258
1259 if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
1260 info_priv->tx.ts_rssi =
1261 info_priv->tx.ts_rssi < 3 ? 0 :
1262 info_priv->tx.ts_rssi - 3;
1263
1264 last_per = rate_ctrl->state[tx_rate].per;
1265
1266 if (xretries) {
1267 /* Update the PER. */
1268 if (xretries == 1) {
1269 rate_ctrl->state[tx_rate].per += 30;
1270 if (rate_ctrl->state[tx_rate].per > 100)
1271 rate_ctrl->state[tx_rate].per = 100;
1272 } else {
1273 /* xretries == 2 */
1274 count = sizeof(nretry_to_per_lookup) /
1275 sizeof(nretry_to_per_lookup[0]);
1276 if (retries >= count)
1277 retries = count - 1;
1278 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
1279 rate_ctrl->state[tx_rate].per =
1280 (u8)(rate_ctrl->state[tx_rate].per -
1281 (rate_ctrl->state[tx_rate].per >> 3) +
1282 ((100) >> 3));
1283 }
1284
1285 /* xretries == 1 or 2 */
1286
1287 if (rate_ctrl->probe_rate == tx_rate)
1288 rate_ctrl->probe_rate = 0;
1289
1290 } else { /* xretries == 0 */
1291 /* Update the PER. */
1292 /* Make sure it doesn't index out of array's bounds. */
1293 count = sizeof(nretry_to_per_lookup) /
1294 sizeof(nretry_to_per_lookup[0]);
1295 if (retries >= count)
1296 retries = count - 1;
1297 if (info_priv->n_bad_frames) {
1298 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
1299 /*
1300 * Assuming that n_frames is not 0. The current PER
1301 * from the retries is 100 * retries / (retries+1),
1302 * since the first retries attempts failed, and the
1303 * next one worked. For the one that worked,
1304 * n_bad_frames subframes out of n_frames wored,
1305 * so the PER for that part is
1306 * 100 * n_bad_frames / n_frames, and it contributes
1307 * 100 * n_bad_frames / (n_frames * (retries+1)) to
1308 * the above PER. The expression below is a
1309 * simplified version of the sum of these two terms.
1310 */
1311 if (info_priv->n_frames > 0)
1312 rate_ctrl->state[tx_rate].per
1313 = (u8)
1314 (rate_ctrl->state[tx_rate].per -
1315 (rate_ctrl->state[tx_rate].per >> 3) +
1316 ((100*(retries*info_priv->n_frames +
1317 info_priv->n_bad_frames) /
1318 (info_priv->n_frames *
1319 (retries+1))) >> 3));
1320 } else {
1321 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
1322
1323 rate_ctrl->state[tx_rate].per = (u8)
1324 (rate_ctrl->state[tx_rate].per -
1325 (rate_ctrl->state[tx_rate].per >> 3) +
1326 (nretry_to_per_lookup[retries] >> 3));
1327 }
1328
1329 rate_ctrl->rssi_last_prev2 = rate_ctrl->rssi_last_prev;
1330 rate_ctrl->rssi_last_prev = rate_ctrl->rssi_last;
1331 rate_ctrl->rssi_last = info_priv->tx.ts_rssi;
1332 rate_ctrl->rssi_time = now_msec;
1333
1334 /*
1335 * If we got at most one retry then increase the max rate if
1336 * this was a probe. Otherwise, ignore the probe.
1337 */
1338
1339 if (rate_ctrl->probe_rate && rate_ctrl->probe_rate == tx_rate) {
1340 if (retries > 0 || 2 * info_priv->n_bad_frames >
1341 info_priv->n_frames) {
1342 /*
1343 * Since we probed with just a single attempt,
1344 * any retries means the probe failed. Also,
1345 * if the attempt worked, but more than half
1346 * the subframes were bad then also consider
1347 * the probe a failure.
1348 */
1349 rate_ctrl->probe_rate = 0;
1350 } else {
1351 u8 probe_rate = 0;
1352
1353 rate_ctrl->rate_max_phy = rate_ctrl->probe_rate;
1354 probe_rate = rate_ctrl->probe_rate;
1355
1356 if (rate_ctrl->state[probe_rate].per > 30)
1357 rate_ctrl->state[probe_rate].per = 20;
1358
1359 rate_ctrl->probe_rate = 0;
1360
1361 /*
1362 * Since this probe succeeded, we allow the next
1363 * probe twice as soon. This allows the maxRate
1364 * to move up faster if the probes are
1365 * succesful.
1366 */
1367 rate_ctrl->probe_time = now_msec -
1368 rate_table->probe_interval / 2;
1369 }
1370 }
1371
1372 if (retries > 0) {
1373 /*
1374 * Don't update anything. We don't know if
1375 * this was because of collisions or poor signal.
1376 *
1377 * Later: if rssi_ack is close to
1378 * rate_ctrl->state[txRate].rssi_thres and we see lots
1379 * of retries, then we could increase
1380 * rate_ctrl->state[txRate].rssi_thres.
1381 */
1382 rate_ctrl->hw_maxretry_pktcnt = 0;
1383 } else {
1384 /*
1385 * It worked with no retries. First ignore bogus (small)
1386 * rssi_ack values.
1387 */
1388 if (tx_rate == rate_ctrl->rate_max_phy &&
1389 rate_ctrl->hw_maxretry_pktcnt < 255) {
1390 rate_ctrl->hw_maxretry_pktcnt++;
1391 }
1392
1393 if (info_priv->tx.ts_rssi >=
1394 rate_table->info[tx_rate].rssi_ack_validmin) {
1395 /* Average the rssi */
1396 if (tx_rate != rate_ctrl->rssi_sum_rate) {
1397 rate_ctrl->rssi_sum_rate = tx_rate;
1398 rate_ctrl->rssi_sum =
1399 rate_ctrl->rssi_sum_cnt = 0;
1400 }
1401
1402 rate_ctrl->rssi_sum += info_priv->tx.ts_rssi;
1403 rate_ctrl->rssi_sum_cnt++;
1404
1405 if (rate_ctrl->rssi_sum_cnt > 4) {
1406 int32_t rssi_ackAvg =
1407 (rate_ctrl->rssi_sum + 2) / 4;
1408 int8_t rssi_thres =
1409 rate_ctrl->state[tx_rate].
1410 rssi_thres;
1411 int8_t rssi_ack_vmin =
1412 rate_table->info[tx_rate].
1413 rssi_ack_validmin;
1414
1415 rate_ctrl->rssi_sum =
1416 rate_ctrl->rssi_sum_cnt = 0;
1417
1418 /* Now reduce the current
1419 * rssi threshold. */
1420 if ((rssi_ackAvg < rssi_thres + 2) &&
1421 (rssi_thres > rssi_ack_vmin)) {
1422 rate_ctrl->state[tx_rate].
1423 rssi_thres--;
1424 }
1425
1426 state_change = TRUE;
1427 }
1428 }
1429 }
1430 }
1431
1432 /* For all cases */
1433
1434 /*
1435 * If this rate looks bad (high PER) then stop using it for
1436 * a while (except if we are probing).
1437 */
1438 if (rate_ctrl->state[tx_rate].per >= 55 && tx_rate > 0 &&
1439 rate_table->info[tx_rate].ratekbps <=
1440 rate_table->info[rate_ctrl->rate_max_phy].ratekbps) {
1441 ath_rc_get_nextlowervalid_txrate(rate_table, rate_ctrl,
1442 (u8) tx_rate, &rate_ctrl->rate_max_phy);
1443
1444 /* Don't probe for a little while. */
1445 rate_ctrl->probe_time = now_msec;
1446 }
1447
1448 if (state_change) {
1449 /*
1450 * Make sure the rates above this have higher rssi thresholds.
1451 * (Note: Monotonicity is kept within the OFDM rates and
1452 * within the CCK rates. However, no adjustment is
1453 * made to keep the rssi thresholds monotonically
1454 * increasing between the CCK and OFDM rates.)
1455 */
1456 for (rate = tx_rate; rate <
1457 rate_ctrl->rate_table_size - 1; rate++) {
1458 if (rate_table->info[rate+1].phy !=
1459 rate_table->info[tx_rate].phy)
1460 break;
1461
1462 if (rate_ctrl->state[rate].rssi_thres +
1463 rate_table->info[rate].rssi_ack_deltamin >
1464 rate_ctrl->state[rate+1].rssi_thres) {
1465 rate_ctrl->state[rate+1].rssi_thres =
1466 rate_ctrl->state[rate].
1467 rssi_thres +
1468 rate_table->info[rate].
1469 rssi_ack_deltamin;
1470 }
1471 }
1472
1473 /* Make sure the rates below this have lower rssi thresholds. */
1474 for (rate = tx_rate - 1; rate >= 0; rate--) {
1475 if (rate_table->info[rate].phy !=
1476 rate_table->info[tx_rate].phy)
1477 break;
1478
1479 if (rate_ctrl->state[rate].rssi_thres +
1480 rate_table->info[rate].rssi_ack_deltamin >
1481 rate_ctrl->state[rate+1].rssi_thres) {
1482 if (rate_ctrl->state[rate+1].rssi_thres <
1483 rate_table->info[rate].
1484 rssi_ack_deltamin)
1485 rate_ctrl->state[rate].rssi_thres = 0;
1486 else {
1487 rate_ctrl->state[rate].rssi_thres =
1488 rate_ctrl->state[rate+1].
1489 rssi_thres -
1490 rate_table->info[rate].
1491 rssi_ack_deltamin;
1492 }
1493
1494 if (rate_ctrl->state[rate].rssi_thres <
1495 rate_table->info[rate].
1496 rssi_ack_validmin) {
1497 rate_ctrl->state[rate].rssi_thres =
1498 rate_table->info[rate].
1499 rssi_ack_validmin;
1500 }
1501 }
1502 }
1503 }
1504
1505 /* Make sure the rates below this have lower PER */
1506 /* Monotonicity is kept only for rates below the current rate. */
1507 if (rate_ctrl->state[tx_rate].per < last_per) {
1508 for (rate = tx_rate - 1; rate >= 0; rate--) {
1509 if (rate_table->info[rate].phy !=
1510 rate_table->info[tx_rate].phy)
1511 break;
1512
1513 if (rate_ctrl->state[rate].per >
1514 rate_ctrl->state[rate+1].per) {
1515 rate_ctrl->state[rate].per =
1516 rate_ctrl->state[rate+1].per;
1517 }
1518 }
1519 }
1520
1521 /* Maintain monotonicity for rates above the current rate */
1522 for (rate = tx_rate; rate < rate_ctrl->rate_table_size - 1; rate++) {
1523 if (rate_ctrl->state[rate+1].per < rate_ctrl->state[rate].per)
1524 rate_ctrl->state[rate+1].per =
1525 rate_ctrl->state[rate].per;
1526 }
1527
1528 /* Every so often, we reduce the thresholds and
1529 * PER (different for CCK and OFDM). */
1530 if (now_msec - rate_ctrl->rssi_down_time >=
1531 rate_table->rssi_reduce_interval) {
1532
1533 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
1534 if (rate_ctrl->state[rate].rssi_thres >
1535 rate_table->info[rate].rssi_ack_validmin)
1536 rate_ctrl->state[rate].rssi_thres -= 1;
1537 }
1538 rate_ctrl->rssi_down_time = now_msec;
1539 }
1540
1541 /* Every so often, we reduce the thresholds
1542 * and PER (different for CCK and OFDM). */
1543 if (now_msec - rate_ctrl->per_down_time >=
1544 rate_table->rssi_reduce_interval) {
1545 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
1546 rate_ctrl->state[rate].per =
1547 7 * rate_ctrl->state[rate].per / 8;
1548 }
1549
1550 rate_ctrl->per_down_time = now_msec;
1551 }
1552}
1553
1554/*
1555 * This routine is called in rate control callback tx_status() to give
1556 * the status of previous frames.
1557 */
1558static void ath_rc_update(struct ath_softc *sc,
1559 struct ath_rate_node *ath_rc_priv,
1560 struct ath_tx_info_priv *info_priv, int final_ts_idx,
1561 int xretries, int long_retry)
1562{
1563 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1564 struct ath_rate_table *rate_table;
1565 struct ath_tx_ratectrl *rate_ctrl;
1566 struct ath_rc_series rcs[4];
1567 u8 flags;
1568 u32 series = 0, rix;
1569
1570 memcpy(rcs, info_priv->rcs, 4 * sizeof(rcs[0]));
1571 rate_table = (struct ath_rate_table *)
1572 asc->hw_rate_table[sc->sc_curmode];
1573 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
1574 ASSERT(rcs[0].tries != 0);
1575
1576 /*
1577 * If the first rate is not the final index, there
1578 * are intermediate rate failures to be processed.
1579 */
1580 if (final_ts_idx != 0) {
1581 /* Process intermediate rates that failed.*/
1582 for (series = 0; series < final_ts_idx ; series++) {
1583 if (rcs[series].tries != 0) {
1584 flags = rcs[series].flags;
1585 /* If HT40 and we have switched mode from
1586 * 40 to 20 => don't update */
1587 if ((flags & ATH_RC_CW40_FLAG) &&
1588 (rate_ctrl->rc_phy_mode !=
1589 (flags & ATH_RC_CW40_FLAG)))
1590 return;
1591 if ((flags & ATH_RC_CW40_FLAG) &&
1592 (flags & ATH_RC_SGI_FLAG))
1593 rix = rate_table->info[
1594 rcs[series].rix].ht_index;
1595 else if (flags & ATH_RC_SGI_FLAG)
1596 rix = rate_table->info[
1597 rcs[series].rix].sgi_index;
1598 else if (flags & ATH_RC_CW40_FLAG)
1599 rix = rate_table->info[
1600 rcs[series].rix].cw40index;
1601 else
1602 rix = rate_table->info[
1603 rcs[series].rix].base_index;
1604 ath_rc_update_ht(sc, ath_rc_priv,
1605 info_priv, rix,
1606 xretries ? 1 : 2,
1607 rcs[series].tries);
1608 }
1609 }
1610 } else {
1611 /*
1612 * Handle the special case of MIMO PS burst, where the second
1613 * aggregate is sent out with only one rate and one try.
1614 * Treating it as an excessive retry penalizes the rate
1615 * inordinately.
1616 */
1617 if (rcs[0].tries == 1 && xretries == 1)
1618 xretries = 2;
1619 }
1620
1621 flags = rcs[series].flags;
1622 /* If HT40 and we have switched mode from 40 to 20 => don't update */
1623 if ((flags & ATH_RC_CW40_FLAG) &&
1624 (rate_ctrl->rc_phy_mode != (flags & ATH_RC_CW40_FLAG)))
1625 return;
1626
1627 if ((flags & ATH_RC_CW40_FLAG) && (flags & ATH_RC_SGI_FLAG))
1628 rix = rate_table->info[rcs[series].rix].ht_index;
1629 else if (flags & ATH_RC_SGI_FLAG)
1630 rix = rate_table->info[rcs[series].rix].sgi_index;
1631 else if (flags & ATH_RC_CW40_FLAG)
1632 rix = rate_table->info[rcs[series].rix].cw40index;
1633 else
1634 rix = rate_table->info[rcs[series].rix].base_index;
1635
1636 ath_rc_update_ht(sc, ath_rc_priv, info_priv, rix,
1637 xretries, long_retry);
1638}
1639
1640
1641/*
1642 * Process a tx descriptor for a completed transmit (success or failure).
1643 */
1644static void ath_rate_tx_complete(struct ath_softc *sc,
1645 struct ath_node *an,
1646 struct ath_rate_node *rc_priv,
1647 struct ath_tx_info_priv *info_priv)
1648{
1649 int final_ts_idx = info_priv->tx.ts_rateindex;
1650 int tx_status = 0, is_underrun = 0;
1651 struct ath_vap *avp;
1652
1653 avp = rc_priv->avp;
1654 if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE)
1655 || info_priv->tx.ts_status & ATH9K_TXERR_FILT)
1656 return;
1657
1658 if (info_priv->tx.ts_rssi > 0) {
1659 ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi,
1660 info_priv->tx.ts_rssi);
1661 }
1662
1663 /*
1664 * If underrun error is seen assume it as an excessive retry only
1665 * if prefetch trigger level have reached the max (0x3f for 5416)
1666 * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
1667 * times. This affects how ratectrl updates PER for the failed rate.
1668 */
1669 if (info_priv->tx.ts_flags &
1670 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
1671 ((sc->sc_ah->ah_txTrigLevel) >= tx_triglevel_max)) {
1672 tx_status = 1;
1673 is_underrun = 1;
1674 }
1675
1676 if ((info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
1677 (info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
1678 tx_status = 1;
1679
1680 ath_rc_update(sc, rc_priv, info_priv, final_ts_idx, tx_status,
1681 (is_underrun) ? ATH_11N_TXMAXTRY :
1682 info_priv->tx.ts_longretry);
1683}
1684
1685
1686/*
1687 * Update the SIB's rate control information
1688 *
1689 * This should be called when the supported rates change
1690 * (e.g. SME operation, wireless mode change)
1691 *
1692 * It will determine which rates are valid for use.
1693 */
1694static void ath_rc_sib_update(struct ath_softc *sc,
1695 struct ath_rate_node *ath_rc_priv,
1696 u32 capflag, int keep_state,
1697 struct ath_rateset *negotiated_rates,
1698 struct ath_rateset *negotiated_htrates)
1699{
1700 struct ath_rate_table *rate_table = NULL;
1701 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1702 struct ath_rateset *rateset = negotiated_rates;
1703 u8 *ht_mcs = (u8 *)negotiated_htrates;
1704 struct ath_tx_ratectrl *rate_ctrl = (struct ath_tx_ratectrl *)
1705 (ath_rc_priv);
1706 u8 i, j, k, hi = 0, hthi = 0;
1707
1708 rate_table = (struct ath_rate_table *)
1709 asc->hw_rate_table[sc->sc_curmode];
1710
1711 /* Initial rate table size. Will change depending
1712 * on the working rate set */
1713 rate_ctrl->rate_table_size = MAX_TX_RATE_TBL;
1714
1715 /* Initialize thresholds according to the global rate table */
1716 for (i = 0 ; (i < rate_ctrl->rate_table_size) && (!keep_state); i++) {
1717 rate_ctrl->state[i].rssi_thres =
1718 rate_table->info[i].rssi_ack_validmin;
1719 rate_ctrl->state[i].per = 0;
1720 }
1721
1722 /* Determine the valid rates */
1723 ath_rc_init_valid_txmask(rate_ctrl);
1724
1725 for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
1726 for (j = 0; j < MAX_TX_RATE_PHY; j++)
1727 rate_ctrl->valid_phy_rateidx[i][j] = 0;
1728 rate_ctrl->valid_phy_ratecnt[i] = 0;
1729 }
1730 rate_ctrl->rc_phy_mode = (capflag & WLAN_RC_40_FLAG);
1731
1732 /* Set stream capability */
1733 ath_rc_priv->single_stream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
1734
1735 if (!rateset->rs_nrates) {
1736 /* No working rate, just initialize valid rates */
1737 hi = ath_rc_sib_init_validrates(ath_rc_priv, rate_table,
1738 capflag);
1739 } else {
1740 /* Use intersection of working rates and valid rates */
1741 hi = ath_rc_sib_setvalid_rates(ath_rc_priv, rate_table,
1742 rateset, capflag);
1743 if (capflag & WLAN_RC_HT_FLAG) {
1744 hthi = ath_rc_sib_setvalid_htrates(ath_rc_priv,
1745 rate_table,
1746 ht_mcs,
1747 capflag);
1748 }
1749 hi = A_MAX(hi, hthi);
1750 }
1751
1752 rate_ctrl->rate_table_size = hi + 1;
1753 rate_ctrl->rate_max_phy = 0;
1754 ASSERT(rate_ctrl->rate_table_size <= MAX_TX_RATE_TBL);
1755
1756 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1757 for (j = 0; j < rate_ctrl->valid_phy_ratecnt[i]; j++) {
1758 rate_ctrl->valid_rate_index[k++] =
1759 rate_ctrl->valid_phy_rateidx[i][j];
1760 }
1761
1762 if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, TRUE)
1763 || !rate_ctrl->valid_phy_ratecnt[i])
1764 continue;
1765
1766 rate_ctrl->rate_max_phy = rate_ctrl->valid_phy_rateidx[i][j-1];
1767 }
1768 ASSERT(rate_ctrl->rate_table_size <= MAX_TX_RATE_TBL);
1769 ASSERT(k <= MAX_TX_RATE_TBL);
1770
1771 rate_ctrl->max_valid_rate = k;
1772 /*
1773 * Some third party vendors don't send the supported rate series in
1774 * order. So sorting to make sure its in order, otherwise our RateFind
1775 * Algo will select wrong rates
1776 */
1777 ath_rc_sort_validrates(rate_table, rate_ctrl);
1778 rate_ctrl->rate_max_phy = rate_ctrl->valid_rate_index[k-4];
1779}
1780
1781/*
1782 * Update rate-control state on station associate/reassociate.
1783 */
1784static int ath_rate_newassoc(struct ath_softc *sc,
1785 struct ath_rate_node *ath_rc_priv,
1786 unsigned int capflag,
1787 struct ath_rateset *negotiated_rates,
1788 struct ath_rateset *negotiated_htrates)
1789{
1790
1791
1792 ath_rc_priv->ht_cap =
1793 ((capflag & ATH_RC_DS_FLAG) ? WLAN_RC_DS_FLAG : 0) |
1794 ((capflag & ATH_RC_SGI_FLAG) ? WLAN_RC_SGI_FLAG : 0) |
1795 ((capflag & ATH_RC_HT_FLAG) ? WLAN_RC_HT_FLAG : 0) |
1796 ((capflag & ATH_RC_CW40_FLAG) ? WLAN_RC_40_FLAG : 0);
1797
1798 ath_rc_sib_update(sc, ath_rc_priv, ath_rc_priv->ht_cap, 0,
1799 negotiated_rates, negotiated_htrates);
1800
1801 return 0;
1802}
1803
1804/*
1805 * This routine is called to initialize the rate control parameters
1806 * in the SIB. It is called initially during system initialization
1807 * or when a station is associated with the AP.
1808 */
1809static void ath_rc_sib_init(struct ath_rate_node *ath_rc_priv)
1810{
1811 struct ath_tx_ratectrl *rate_ctrl;
1812
1813 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
1814 rate_ctrl->rssi_down_time = jiffies_to_msecs(jiffies);
1815}
1816
1817
1818static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta)
1819
1820{
1821 struct ieee80211_supported_band *sband;
1822 struct ieee80211_hw *hw = local_to_hw(local);
1823 struct ath_softc *sc = hw->priv;
1824 struct ath_rate_node *rc_priv = sta->rate_ctrl_priv;
1825 int i, j = 0;
1826
1827 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
1828 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1829 for (i = 0; i < sband->n_bitrates; i++) {
1830 if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) {
1831 rc_priv->neg_rates.rs_rates[j]
1832 = (sband->bitrates[i].bitrate * 2) / 10;
1833 j++;
1834 }
1835 }
1836 rc_priv->neg_rates.rs_nrates = j;
1837}
1838
1839void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv)
1840{
1841 struct ath_softc *sc = hw->priv;
1842 u32 capflag = 0;
1843
1844 if (hw->conf.ht_conf.ht_supported) {
1845 capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG;
1846 if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040)
1847 capflag |= ATH_RC_CW40_FLAG;
1848 }
1849
1850 ath_rate_newassoc(sc, rc_priv, capflag,
1851 &rc_priv->neg_rates,
1852 &rc_priv->neg_ht_rates);
1853
1854}
1855
1856/* Rate Control callbacks */
1857static void ath_tx_status(void *priv, struct net_device *dev,
1858 struct sk_buff *skb)
1859{
1860 struct ath_softc *sc = priv;
1861 struct ath_tx_info_priv *tx_info_priv;
1862 struct ath_node *an;
1863 struct sta_info *sta;
1864 struct ieee80211_local *local;
1865 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1866 struct ieee80211_hdr *hdr;
1867 __le16 fc;
1868
1869 local = hw_to_local(sc->hw);
1870 hdr = (struct ieee80211_hdr *)skb->data;
1871 fc = hdr->frame_control;
1872 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
1873
1874 spin_lock_bh(&sc->node_lock);
1875 an = ath_node_find(sc, hdr->addr1);
1876 spin_unlock_bh(&sc->node_lock);
1877
1878 sta = sta_info_get(local, hdr->addr1);
1879 if (!an || !sta || !ieee80211_is_data(fc)) {
1880 if (tx_info->driver_data[0] != NULL) {
1881 kfree(tx_info->driver_data[0]);
1882 tx_info->driver_data[0] = NULL;
1883 }
1884 return;
1885 }
1886 if (tx_info->driver_data[0] != NULL) {
1887 ath_rate_tx_complete(sc, an, sta->rate_ctrl_priv, tx_info_priv);
1888 kfree(tx_info->driver_data[0]);
1889 tx_info->driver_data[0] = NULL;
1890 }
1891}
1892
1893static void ath_tx_aggr_resp(struct ath_softc *sc,
1894 struct sta_info *sta,
1895 struct ath_node *an,
1896 u8 tidno)
1897{
1898 struct ieee80211_hw *hw = sc->hw;
1899 struct ieee80211_local *local;
1900 struct ath_atx_tid *txtid;
1901 struct ieee80211_supported_band *sband;
1902 u16 buffersize = 0;
1903 int state;
1904 DECLARE_MAC_BUF(mac);
1905
1906 if (!sc->sc_txaggr)
1907 return;
1908
1909 txtid = ATH_AN_2_TID(an, tidno);
1910 if (!txtid->paused)
1911 return;
1912
1913 local = hw_to_local(sc->hw);
1914 sband = hw->wiphy->bands[hw->conf.channel->band];
1915 buffersize = IEEE80211_MIN_AMPDU_BUF <<
1916 sband->ht_info.ampdu_factor; /* FIXME */
1917 state = sta->ampdu_mlme.tid_state_tx[tidno];
1918
1919 if (state & HT_ADDBA_RECEIVED_MSK) {
1920 txtid->addba_exchangecomplete = 1;
1921 txtid->addba_exchangeinprogress = 0;
1922 txtid->baw_size = buffersize;
1923
1924 DPRINTF(sc, ATH_DBG_AGGR,
1925 "%s: Resuming tid, buffersize: %d\n",
1926 __func__,
1927 buffersize);
1928
1929 ath_tx_resume_tid(sc, txtid);
1930 }
1931}
1932
1933static void ath_get_rate(void *priv, struct net_device *dev,
1934 struct ieee80211_supported_band *sband,
1935 struct sk_buff *skb,
1936 struct rate_selection *sel)
1937{
1938 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1939 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1940 struct sta_info *sta;
1941 struct ath_softc *sc = (struct ath_softc *)priv;
1942 struct ieee80211_hw *hw = sc->hw;
1943 struct ath_tx_info_priv *tx_info_priv;
1944 struct ath_rate_node *ath_rc_priv;
1945 struct ath_node *an;
1946 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1947 int is_probe, chk, ret;
1948 s8 lowest_idx;
1949 __le16 fc = hdr->frame_control;
1950 u8 *qc, tid;
1951 DECLARE_MAC_BUF(mac);
1952
1953 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
1954
1955 /* allocate driver private area of tx_info */
1956 tx_info->driver_data[0] = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
1957 ASSERT(tx_info->driver_data[0] != NULL);
1958 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
1959
1960 sta = sta_info_get(local, hdr->addr1);
1961 lowest_idx = rate_lowest_index(local, sband, sta);
1962 tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10;
1963 /* lowest rate for management and multicast/broadcast frames */
1964 if (!ieee80211_is_data(fc) ||
1965 is_multicast_ether_addr(hdr->addr1) || !sta) {
1966 sel->rate_idx = lowest_idx;
1967 return;
1968 }
1969
1970 ath_rc_priv = sta->rate_ctrl_priv;
1971
1972 /* Find tx rate for unicast frames */
1973 ath_rate_findrate(sc, ath_rc_priv,
1974 ATH_11N_TXMAXTRY, 4,
1975 ATH_RC_PROBE_ALLOWED,
1976 tx_info_priv->rcs,
1977 &is_probe,
1978 false);
1979 if (is_probe)
1980 sel->probe_idx = ((struct ath_tx_ratectrl *)
1981 sta->rate_ctrl_priv)->probe_rate;
1982
1983 /* Ratecontrol sometimes returns invalid rate index */
1984 if (tx_info_priv->rcs[0].rix != 0xff)
1985 ath_rc_priv->prev_data_rix = tx_info_priv->rcs[0].rix;
1986 else
1987 tx_info_priv->rcs[0].rix = ath_rc_priv->prev_data_rix;
1988
1989 sel->rate_idx = tx_info_priv->rcs[0].rix;
1990
1991 /* Check if aggregation has to be enabled for this tid */
1992
1993 if (hw->conf.ht_conf.ht_supported) {
1994 if (ieee80211_is_data_qos(fc)) {
1995 qc = ieee80211_get_qos_ctl(hdr);
1996 tid = qc[0] & 0xf;
1997
1998 spin_lock_bh(&sc->node_lock);
1999 an = ath_node_find(sc, hdr->addr1);
2000 spin_unlock_bh(&sc->node_lock);
2001
2002 if (!an) {
2003 DPRINTF(sc, ATH_DBG_AGGR,
2004 "%s: Node not found to "
2005 "init/chk TX aggr\n", __func__);
2006 return;
2007 }
2008
2009 chk = ath_tx_aggr_check(sc, an, tid);
2010 if (chk == AGGR_REQUIRED) {
2011 ret = ieee80211_start_tx_ba_session(hw,
2012 hdr->addr1, tid);
2013 if (ret)
2014 DPRINTF(sc, ATH_DBG_AGGR,
2015 "%s: Unable to start tx "
2016 "aggr for: %s\n",
2017 __func__,
2018 print_mac(mac, hdr->addr1));
2019 else
2020 DPRINTF(sc, ATH_DBG_AGGR,
2021 "%s: Started tx aggr for: %s\n",
2022 __func__,
2023 print_mac(mac, hdr->addr1));
2024 } else if (chk == AGGR_EXCHANGE_PROGRESS)
2025 ath_tx_aggr_resp(sc, sta, an, tid);
2026 }
2027 }
2028}
2029
2030static void ath_rate_init(void *priv, void *priv_sta,
2031 struct ieee80211_local *local,
2032 struct sta_info *sta)
2033{
2034 struct ieee80211_supported_band *sband;
2035 struct ieee80211_hw *hw = local_to_hw(local);
2036 struct ieee80211_conf *conf = &local->hw.conf;
2037 struct ath_softc *sc = hw->priv;
2038 int i, j = 0;
2039
2040 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
2041
2042 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2043 sta->txrate_idx = rate_lowest_index(local, sband, sta);
2044
2045 ath_setup_rates(local, sta);
2046 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
2047 for (i = 0; i < MCS_SET_SIZE; i++) {
2048 if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
2049 ((struct ath_rate_node *)
2050 priv_sta)->neg_ht_rates.rs_rates[j++] = i;
2051 if (j == ATH_RATE_MAX)
2052 break;
2053 }
2054 ((struct ath_rate_node *)priv_sta)->neg_ht_rates.rs_nrates = j;
2055 }
2056 ath_rc_node_update(hw, priv_sta);
2057}
2058
2059static void ath_rate_clear(void *priv)
2060{
2061 return;
2062}
2063
2064static void *ath_rate_alloc(struct ieee80211_local *local)
2065{
2066 struct ieee80211_hw *hw = local_to_hw(local);
2067 struct ath_softc *sc = hw->priv;
2068
2069 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
2070 return local->hw.priv;
2071}
2072
2073static void ath_rate_free(void *priv)
2074{
2075 return;
2076}
2077
2078static void *ath_rate_alloc_sta(void *priv, gfp_t gfp)
2079{
2080 struct ath_softc *sc = priv;
2081 struct ath_vap *avp = sc->sc_vaps[0];
2082 struct ath_rate_node *rate_priv;
2083
2084 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
2085 rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp);
2086 if (!rate_priv) {
2087 DPRINTF(sc, ATH_DBG_FATAL, "%s:Unable to allocate"
2088 "private rate control structure", __func__);
2089 return NULL;
2090 }
2091 ath_rc_sib_init(rate_priv);
2092 return rate_priv;
2093}
2094
2095static void ath_rate_free_sta(void *priv, void *priv_sta)
2096{
2097 struct ath_rate_node *rate_priv = priv_sta;
2098 struct ath_softc *sc = priv;
2099
2100 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
2101 ath_rate_node_free(rate_priv);
2102}
2103
2104static struct rate_control_ops ath_rate_ops = {
2105 .module = NULL,
2106 .name = "ath9k_rate_control",
2107 .tx_status = ath_tx_status,
2108 .get_rate = ath_get_rate,
2109 .rate_init = ath_rate_init,
2110 .clear = ath_rate_clear,
2111 .alloc = ath_rate_alloc,
2112 .free = ath_rate_free,
2113 .alloc_sta = ath_rate_alloc_sta,
2114 .free_sta = ath_rate_free_sta
2115};
2116
2117int ath_rate_control_register(void)
2118{
2119 return ieee80211_rate_control_register(&ath_rate_ops);
2120}
2121
2122void ath_rate_control_unregister(void)
2123{
2124 ieee80211_rate_control_unregister(&ath_rate_ops);
2125}
2126
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
new file mode 100644
index 000000000000..71aef9c75232
--- /dev/null
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -0,0 +1,316 @@
1/*
2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
3 * Copyright (c) 2004 Video54 Technologies, Inc.
4 * Copyright (c) 2008 Atheros Communications Inc.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef RC_H
20#define RC_H
21
22#include "ath9k.h"
23/*
24 * Interface definitions for transmit rate control modules for the
25 * Atheros driver.
26 *
27 * A rate control module is responsible for choosing the transmit rate
28 * for each data frame. Management+control frames are always sent at
29 * a fixed rate.
30 *
31 * Only one module may be present at a time; the driver references
32 * rate control interfaces by symbol name. If multiple modules are
33 * to be supported we'll need to switch to a registration-based scheme
34 * as is currently done, for example, for authentication modules.
35 *
36 * An instance of the rate control module is attached to each device
37 * at attach time and detached when the device is destroyed. The module
38 * may associate data with each device and each node (station). Both
39 * sets of storage are opaque except for the size of the per-node storage
40 * which must be provided when the module is attached.
41 *
42 * The rate control module is notified for each state transition and
43 * station association/reassociation. Otherwise it is queried for a
44 * rate for each outgoing frame and provided status from each transmitted
45 * frame. Any ancillary processing is the responsibility of the module
46 * (e.g. if periodic processing is required then the module should setup
47 * it's own timer).
48 *
49 * In addition to the transmit rate for each frame the module must also
50 * indicate the number of attempts to make at the specified rate. If this
51 * number is != ATH_TXMAXTRY then an additional callback is made to setup
52 * additional transmit state. The rate control code is assumed to write
53 * this additional data directly to the transmit descriptor.
54 */
55
56struct ath_softc;
57
58#define TRUE 1
59#define FALSE 0
60
61#define ATH_RATE_MAX 30
62#define MCS_SET_SIZE 128
63
64enum ieee80211_fixed_rate_mode {
65 IEEE80211_FIXED_RATE_NONE = 0,
66 IEEE80211_FIXED_RATE_MCS = 1 /* HT rates */
67};
68
69/*
70 * Use the hal os glue code to get ms time
71 */
72#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8)))
73
74#define SHORT_PRE 1
75#define LONG_PRE 0
76
77#define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS
78#define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS
79#define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI
80#define WLAN_PHY_HT_40_SS WLAN_RC_PHY_HT_40_SS
81#define WLAN_PHY_HT_40_SS_HGI WLAN_RC_PHY_HT_40_SS_HGI
82#define WLAN_PHY_HT_40_DS WLAN_RC_PHY_HT_40_DS
83#define WLAN_PHY_HT_40_DS_HGI WLAN_RC_PHY_HT_40_DS_HGI
84
85#define WLAN_PHY_OFDM PHY_OFDM
86#define WLAN_PHY_CCK PHY_CCK
87
88#define TRUE_20 0x2
89#define TRUE_40 0x4
90#define TRUE_2040 (TRUE_20|TRUE_40)
91#define TRUE_ALL (TRUE_2040|TRUE)
92
93enum {
94 WLAN_RC_PHY_HT_20_SS = 4,
95 WLAN_RC_PHY_HT_20_DS,
96 WLAN_RC_PHY_HT_40_SS,
97 WLAN_RC_PHY_HT_40_DS,
98 WLAN_RC_PHY_HT_20_SS_HGI,
99 WLAN_RC_PHY_HT_20_DS_HGI,
100 WLAN_RC_PHY_HT_40_SS_HGI,
101 WLAN_RC_PHY_HT_40_DS_HGI,
102 WLAN_RC_PHY_MAX
103};
104
105#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
106 || (_phy == WLAN_RC_PHY_HT_40_DS) \
107 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
108 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
109#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
110 || (_phy == WLAN_RC_PHY_HT_40_DS) \
111 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
112 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
113#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
114 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
115 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
116 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
117
118#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
119
120/* Returns the capflag mode */
121#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \
122 (capflag & WLAN_RC_40_FLAG) ? TRUE_40 : TRUE_20 : TRUE))
123
124/* Return TRUE if flag supports HT20 && client supports HT20 or
125 * return TRUE if flag supports HT40 && client supports HT40.
126 * This is used becos some rates overlap between HT20/HT40.
127 */
128
129#define WLAN_RC_PHY_HT_VALID(flag, capflag) (((flag & TRUE_20) && !(capflag \
130 & WLAN_RC_40_FLAG)) || ((flag & TRUE_40) && \
131 (capflag & WLAN_RC_40_FLAG)))
132
133#define WLAN_RC_DS_FLAG (0x01)
134#define WLAN_RC_40_FLAG (0x02)
135#define WLAN_RC_SGI_FLAG (0x04)
136#define WLAN_RC_HT_FLAG (0x08)
137
138/* Index into the rate table */
139#define INIT_RATE_MAX_20 23
140#define INIT_RATE_MAX_40 40
141
142#define RATE_TABLE_SIZE 64
143
144/* XXX: Convert to kdoc */
145struct ath_rate_table {
146 int rate_cnt;
147 struct {
148 int valid; /* Valid for use in rate control */
149 int valid_single_stream;/* Valid for use in rate control
150 for single stream operation */
151 u8 phy; /* CCK/OFDM/TURBO/XR */
152 u32 ratekbps; /* Rate in Kbits per second */
153 u32 user_ratekbps; /* User rate in KBits per second */
154 u8 ratecode; /* rate that goes into
155 hw descriptors */
156 u8 short_preamble; /* Mask for enabling short preamble
157 in rate code for CCK */
158 u8 dot11rate; /* Value that goes into supported
159 rates info element of MLME */
160 u8 ctrl_rate; /* Index of next lower basic rate,
161 used for duration computation */
162 int8_t rssi_ack_validmin; /* Rate control related */
163 int8_t rssi_ack_deltamin; /* Rate control related */
164 u8 base_index; /* base rate index */
165 u8 cw40index; /* 40cap rate index */
166 u8 sgi_index; /* shortgi rate index */
167 u8 ht_index; /* shortgi rate index */
168 u32 max_4ms_framelen; /* Maximum frame length(bytes)
169 for 4ms tx duration */
170 } info[RATE_TABLE_SIZE];
171 u32 probe_interval; /* interval for ratectrl to
172 probe for other rates */
173 u32 rssi_reduce_interval; /* interval for ratectrl
174 to reduce RSSI */
175 u8 initial_ratemax; /* the initial ratemax value used
176 in ath_rc_sib_update() */
177};
178
179#define ATH_RC_PROBE_ALLOWED 0x00000001
180#define ATH_RC_MINRATE_LASTRATE 0x00000002
181#define ATH_RC_SHORT_PREAMBLE 0x00000004
182
183struct ath_rc_series {
184 u8 rix;
185 u8 tries;
186 u8 flags;
187 u32 max_4ms_framelen;
188};
189
190/* rcs_flags definition */
191#define ATH_RC_DS_FLAG 0x01
192#define ATH_RC_CW40_FLAG 0x02 /* CW 40 */
193#define ATH_RC_SGI_FLAG 0x04 /* Short Guard Interval */
194#define ATH_RC_HT_FLAG 0x08 /* HT */
195#define ATH_RC_RTSCTS_FLAG 0x10 /* RTS-CTS */
196
197/*
198 * State structures for new rate adaptation code
199 */
200#define MAX_TX_RATE_TBL 64
201#define MAX_TX_RATE_PHY 48
202
203struct ath_tx_ratectrl_state {
204 int8_t rssi_thres; /* required rssi for this rate (dB) */
205 u8 per; /* recent estimate of packet error rate (%) */
206};
207
208struct ath_tx_ratectrl {
209 struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL]; /* state */
210 int8_t rssi_last; /* last ack rssi */
211 int8_t rssi_last_lookup; /* last ack rssi used for lookup */
212 int8_t rssi_last_prev; /* previous last ack rssi */
213 int8_t rssi_last_prev2; /* 2nd previous last ack rssi */
214 int32_t rssi_sum_cnt; /* count of rssi_sum for averaging */
215 int32_t rssi_sum_rate; /* rate that we are averaging */
216 int32_t rssi_sum; /* running sum of rssi for averaging */
217 u32 valid_txrate_mask; /* mask of valid rates */
218 u8 rate_table_size; /* rate table size */
219 u8 rate_max; /* max rate that has recently worked */
220 u8 probe_rate; /* rate we are probing at */
221 u32 rssi_time; /* msec timestamp for last ack rssi */
222 u32 rssi_down_time; /* msec timestamp for last down step */
223 u32 probe_time; /* msec timestamp for last probe */
224 u8 hw_maxretry_pktcnt; /* num packets since we got
225 HW max retry error */
226 u8 max_valid_rate; /* maximum number of valid rate */
227 u8 valid_rate_index[MAX_TX_RATE_TBL]; /* valid rate index */
228 u32 per_down_time; /* msec timstamp for last
229 PER down step */
230
231 /* 11n state */
232 u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; /* valid rate count */
233 u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL];
234 u8 rc_phy_mode;
235 u8 rate_max_phy; /* Phy index for the max rate */
236 u32 rate_max_lastused; /* msec timstamp of when we
237 last used rateMaxPhy */
238 u32 probe_interval; /* interval for ratectrl to probe
239 for other rates */
240};
241
242struct ath_rateset {
243 u8 rs_nrates;
244 u8 rs_rates[ATH_RATE_MAX];
245};
246
247/* per-device state */
248struct ath_rate_softc {
249 /* phy tables that contain rate control data */
250 const void *hw_rate_table[ATH9K_MODE_MAX];
251 int fixedrix; /* -1 or index of fixed rate */
252};
253
254/* per-node state */
255struct ath_rate_node {
256 struct ath_tx_ratectrl tx_ratectrl; /* rate control state proper */
257 u32 prev_data_rix; /* rate idx of last data frame */
258
259 /* map of rate ix -> negotiated rate set ix */
260 u8 rixmap[MAX_TX_RATE_TBL];
261
262 /* map of ht rate ix -> negotiated rate set ix */
263 u8 ht_rixmap[MAX_TX_RATE_TBL];
264
265 u8 ht_cap; /* ht capabilities */
266 u8 ant_tx; /* current transmit antenna */
267
268 u8 single_stream; /* When TRUE, only single
269 stream Tx possible */
270 struct ath_rateset neg_rates; /* Negotiated rates */
271 struct ath_rateset neg_ht_rates; /* Negotiated HT rates */
272 struct ath_rate_softc *asc; /* back pointer to atheros softc */
273 struct ath_vap *avp; /* back pointer to vap */
274};
275
276/* Driver data of ieee80211_tx_info */
277struct ath_tx_info_priv {
278 struct ath_rc_series rcs[4];
279 struct ath_tx_status tx;
280 int n_frames;
281 int n_bad_frames;
282 u8 min_rate;
283};
284
285/*
286 * Attach/detach a rate control module.
287 */
288struct ath_rate_softc *ath_rate_attach(struct ath_hal *ah);
289void ath_rate_detach(struct ath_rate_softc *asc);
290
291/*
292 * Update/reset rate control state for 802.11 state transitions.
293 * Important mostly as the analog to ath_rate_newassoc when operating
294 * in station mode.
295 */
296void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv);
297void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp);
298
299/*
300 * Return the tx rate series.
301 */
302void ath_rate_findrate(struct ath_softc *sc, struct ath_rate_node *ath_rc_priv,
303 int num_tries, int num_rates,
304 unsigned int rcflag, struct ath_rc_series[],
305 int *is_probe, int isretry);
306/*
307 * Return rate index for given Dot11 Rate.
308 */
309u8 ath_rate_findrateix(struct ath_softc *sc,
310 u8 dot11_rate);
311
312/* Routines to register/unregister rate control algorithm */
313int ath_rate_control_register(void);
314void ath_rate_control_unregister(void);
315
316#endif /* RC_H */
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
new file mode 100644
index 000000000000..2fe806175c01
--- /dev/null
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -0,0 +1,1318 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * Implementation of receive path.
19 */
20
21#include "core.h"
22
23/*
24 * Setup and link descriptors.
25 *
26 * 11N: we can no longer afford to self link the last descriptor.
27 * MAC acknowledges BA status as long as it copies frames to host
28 * buffer (or rx fifo). This can incorrectly acknowledge packets
29 * to a sender if last desc is self-linked.
30 *
31 * NOTE: Caller should hold the rxbuf lock.
32 */
33
34static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
35{
36 struct ath_hal *ah = sc->sc_ah;
37 struct ath_desc *ds;
38 struct sk_buff *skb;
39
40 ATH_RXBUF_RESET(bf);
41
42 ds = bf->bf_desc;
43 ds->ds_link = 0; /* link to null */
44 ds->ds_data = bf->bf_buf_addr;
45
46 /* XXX For RADAR?
47 * virtual addr of the beginning of the buffer. */
48 skb = bf->bf_mpdu;
49 ASSERT(skb != NULL);
50 ds->ds_vdata = skb->data;
51
52 /* setup rx descriptors */
53 ath9k_hw_setuprxdesc(ah,
54 ds,
55 skb_tailroom(skb), /* buffer size */
56 0);
57
58 if (sc->sc_rxlink == NULL)
59 ath9k_hw_putrxbuf(ah, bf->bf_daddr);
60 else
61 *sc->sc_rxlink = bf->bf_daddr;
62
63 sc->sc_rxlink = &ds->ds_link;
64 ath9k_hw_rxena(ah);
65}
66
67/* Process received BAR frame */
68
69static int ath_bar_rx(struct ath_softc *sc,
70 struct ath_node *an,
71 struct sk_buff *skb)
72{
73 struct ieee80211_bar *bar;
74 struct ath_arx_tid *rxtid;
75 struct sk_buff *tskb;
76 struct ath_recv_status *rx_status;
77 int tidno, index, cindex;
78 u16 seqno;
79
80 /* look at BAR contents */
81
82 bar = (struct ieee80211_bar *)skb->data;
83 tidno = (le16_to_cpu(bar->control) & IEEE80211_BAR_CTL_TID_M)
84 >> IEEE80211_BAR_CTL_TID_S;
85 seqno = le16_to_cpu(bar->start_seq_num) >> IEEE80211_SEQ_SEQ_SHIFT;
86
87 /* process BAR - indicate all pending RX frames till the BAR seqno */
88
89 rxtid = &an->an_aggr.rx.tid[tidno];
90
91 spin_lock_bh(&rxtid->tidlock);
92
93 /* get relative index */
94
95 index = ATH_BA_INDEX(rxtid->seq_next, seqno);
96
97 /* drop BAR if old sequence (index is too large) */
98
99 if ((index > rxtid->baw_size) &&
100 (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))))
101 /* discard frame, ieee layer may not treat frame as a dup */
102 goto unlock_and_free;
103
104 /* complete receive processing for all pending frames upto BAR seqno */
105
106 cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
107 while ((rxtid->baw_head != rxtid->baw_tail) &&
108 (rxtid->baw_head != cindex)) {
109 tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
110 rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
111 rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;
112
113 if (tskb != NULL)
114 ath_rx_subframe(an, tskb, rx_status);
115
116 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
117 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
118 }
119
120 /* ... and indicate rest of the frames in-order */
121
122 while (rxtid->baw_head != rxtid->baw_tail &&
123 rxtid->rxbuf[rxtid->baw_head].rx_wbuf != NULL) {
124 tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
125 rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
126 rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;
127
128 ath_rx_subframe(an, tskb, rx_status);
129
130 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
131 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
132 }
133
134unlock_and_free:
135 spin_unlock_bh(&rxtid->tidlock);
136 /* free bar itself */
137 dev_kfree_skb(skb);
138 return IEEE80211_FTYPE_CTL;
139}
140
141/* Function to handle a subframe of aggregation when HT is enabled */
142
143static int ath_ampdu_input(struct ath_softc *sc,
144 struct ath_node *an,
145 struct sk_buff *skb,
146 struct ath_recv_status *rx_status)
147{
148 struct ieee80211_hdr *hdr;
149 struct ath_arx_tid *rxtid;
150 struct ath_rxbuf *rxbuf;
151 u8 type, subtype;
152 u16 rxseq;
153 int tid = 0, index, cindex, rxdiff;
154 __le16 fc;
155 u8 *qc;
156
157 hdr = (struct ieee80211_hdr *)skb->data;
158 fc = hdr->frame_control;
159
160 /* collect stats of frames with non-zero version */
161
162 if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_VERS) != 0) {
163 dev_kfree_skb(skb);
164 return -1;
165 }
166
167 type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE;
168 subtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
169
170 if (ieee80211_is_back_req(fc))
171 return ath_bar_rx(sc, an, skb);
172
173 /* special aggregate processing only for qos unicast data frames */
174
175 if (!ieee80211_is_data(fc) ||
176 !ieee80211_is_data_qos(fc) ||
177 is_multicast_ether_addr(hdr->addr1))
178 return ath_rx_subframe(an, skb, rx_status);
179
180 /* lookup rx tid state */
181
182 if (ieee80211_is_data_qos(fc)) {
183 qc = ieee80211_get_qos_ctl(hdr);
184 tid = qc[0] & 0xf;
185 }
186
187 if (sc->sc_opmode == ATH9K_M_STA) {
188 /* Drop the frame not belonging to me. */
189 if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) {
190 dev_kfree_skb(skb);
191 return -1;
192 }
193 }
194
195 rxtid = &an->an_aggr.rx.tid[tid];
196
197 spin_lock(&rxtid->tidlock);
198
199 rxdiff = (rxtid->baw_tail - rxtid->baw_head) &
200 (ATH_TID_MAX_BUFS - 1);
201
202 /*
203 * If the ADDBA exchange has not been completed by the source,
204 * process via legacy path (i.e. no reordering buffer is needed)
205 */
206 if (!rxtid->addba_exchangecomplete) {
207 spin_unlock(&rxtid->tidlock);
208 return ath_rx_subframe(an, skb, rx_status);
209 }
210
211 /* extract sequence number from recvd frame */
212
213 rxseq = le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT;
214
215 if (rxtid->seq_reset) {
216 rxtid->seq_reset = 0;
217 rxtid->seq_next = rxseq;
218 }
219
220 index = ATH_BA_INDEX(rxtid->seq_next, rxseq);
221
222 /* drop frame if old sequence (index is too large) */
223
224 if (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))) {
225 /* discard frame, ieee layer may not treat frame as a dup */
226 spin_unlock(&rxtid->tidlock);
227 dev_kfree_skb(skb);
228 return IEEE80211_FTYPE_DATA;
229 }
230
231 /* sequence number is beyond block-ack window */
232
233 if (index >= rxtid->baw_size) {
234
235 /* complete receive processing for all pending frames */
236
237 while (index >= rxtid->baw_size) {
238
239 rxbuf = rxtid->rxbuf + rxtid->baw_head;
240
241 if (rxbuf->rx_wbuf != NULL) {
242 ath_rx_subframe(an, rxbuf->rx_wbuf,
243 &rxbuf->rx_status);
244 rxbuf->rx_wbuf = NULL;
245 }
246
247 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
248 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
249
250 index--;
251 }
252 }
253
254 /* add buffer to the recv ba window */
255
256 cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
257 rxbuf = rxtid->rxbuf + cindex;
258
259 if (rxbuf->rx_wbuf != NULL) {
260 spin_unlock(&rxtid->tidlock);
261 /* duplicate frame */
262 dev_kfree_skb(skb);
263 return IEEE80211_FTYPE_DATA;
264 }
265
266 rxbuf->rx_wbuf = skb;
267 rxbuf->rx_time = get_timestamp();
268 rxbuf->rx_status = *rx_status;
269
270 /* advance tail if sequence received is newer
271 * than any received so far */
272
273 if (index >= rxdiff) {
274 rxtid->baw_tail = cindex;
275 INCR(rxtid->baw_tail, ATH_TID_MAX_BUFS);
276 }
277
278 /* indicate all in-order received frames */
279
280 while (rxtid->baw_head != rxtid->baw_tail) {
281 rxbuf = rxtid->rxbuf + rxtid->baw_head;
282 if (!rxbuf->rx_wbuf)
283 break;
284
285 ath_rx_subframe(an, rxbuf->rx_wbuf, &rxbuf->rx_status);
286 rxbuf->rx_wbuf = NULL;
287
288 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
289 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
290 }
291
292 /*
293 * start a timer to flush all received frames if there are pending
294 * receive frames
295 */
296 if (rxtid->baw_head != rxtid->baw_tail)
297 mod_timer(&rxtid->timer, ATH_RX_TIMEOUT);
298 else
299 del_timer_sync(&rxtid->timer);
300
301 spin_unlock(&rxtid->tidlock);
302 return IEEE80211_FTYPE_DATA;
303}
304
305/* Timer to flush all received sub-frames */
306
307static void ath_rx_timer(unsigned long data)
308{
309 struct ath_arx_tid *rxtid = (struct ath_arx_tid *)data;
310 struct ath_node *an = rxtid->an;
311 struct ath_rxbuf *rxbuf;
312 int nosched;
313
314 spin_lock_bh(&rxtid->tidlock);
315 while (rxtid->baw_head != rxtid->baw_tail) {
316 rxbuf = rxtid->rxbuf + rxtid->baw_head;
317 if (!rxbuf->rx_wbuf) {
318 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
319 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
320 continue;
321 }
322
323 /*
324 * Stop if the next one is a very recent frame.
325 *
326 * Call get_timestamp in every iteration to protect against the
327 * case in which a new frame is received while we are executing
328 * this function. Using a timestamp obtained before entering
329 * the loop could lead to a very large time interval
330 * (a negative value typecast to unsigned), breaking the
331 * function's logic.
332 */
333 if ((get_timestamp() - rxbuf->rx_time) <
334 (ATH_RX_TIMEOUT * HZ / 1000))
335 break;
336
337 ath_rx_subframe(an, rxbuf->rx_wbuf,
338 &rxbuf->rx_status);
339 rxbuf->rx_wbuf = NULL;
340
341 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
342 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
343 }
344
345 /*
346 * start a timer to flush all received frames if there are pending
347 * receive frames
348 */
349 if (rxtid->baw_head != rxtid->baw_tail)
350 nosched = 0;
351 else
352 nosched = 1; /* no need to re-arm the timer again */
353
354 spin_unlock_bh(&rxtid->tidlock);
355}
356
357/* Free all pending sub-frames in the re-ordering buffer */
358
359static void ath_rx_flush_tid(struct ath_softc *sc,
360 struct ath_arx_tid *rxtid, int drop)
361{
362 struct ath_rxbuf *rxbuf;
363
364 spin_lock_bh(&rxtid->tidlock);
365 while (rxtid->baw_head != rxtid->baw_tail) {
366 rxbuf = rxtid->rxbuf + rxtid->baw_head;
367 if (!rxbuf->rx_wbuf) {
368 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
369 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
370 continue;
371 }
372
373 if (drop)
374 dev_kfree_skb(rxbuf->rx_wbuf);
375 else
376 ath_rx_subframe(rxtid->an,
377 rxbuf->rx_wbuf,
378 &rxbuf->rx_status);
379
380 rxbuf->rx_wbuf = NULL;
381
382 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
383 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
384 }
385 spin_unlock_bh(&rxtid->tidlock);
386}
387
388static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc,
389 u32 len)
390{
391 struct sk_buff *skb;
392 u32 off;
393
394 /*
395 * Cache-line-align. This is important (for the
396 * 5210 at least) as not doing so causes bogus data
397 * in rx'd frames.
398 */
399
400 skb = dev_alloc_skb(len + sc->sc_cachelsz - 1);
401 if (skb != NULL) {
402 off = ((unsigned long) skb->data) % sc->sc_cachelsz;
403 if (off != 0)
404 skb_reserve(skb, sc->sc_cachelsz - off);
405 } else {
406 DPRINTF(sc, ATH_DBG_FATAL,
407 "%s: skbuff alloc of size %u failed\n",
408 __func__, len);
409 return NULL;
410 }
411
412 return skb;
413}
414
415static void ath_rx_requeue(struct ath_softc *sc, struct sk_buff *skb)
416{
417 struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf;
418
419 ASSERT(bf != NULL);
420
421 spin_lock_bh(&sc->sc_rxbuflock);
422 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
423 /*
424 * This buffer is still held for hw acess.
425 * Mark it as free to be re-queued it later.
426 */
427 bf->bf_status |= ATH_BUFSTATUS_FREE;
428 } else {
429 /* XXX: we probably never enter here, remove after
430 * verification */
431 list_add_tail(&bf->list, &sc->sc_rxbuf);
432 ath_rx_buf_link(sc, bf);
433 }
434 spin_unlock_bh(&sc->sc_rxbuflock);
435}
436
437/*
438 * The skb indicated to upper stack won't be returned to us.
439 * So we have to allocate a new one and queue it by ourselves.
440 */
441static int ath_rx_indicate(struct ath_softc *sc,
442 struct sk_buff *skb,
443 struct ath_recv_status *status,
444 u16 keyix)
445{
446 struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf;
447 struct sk_buff *nskb;
448 int type;
449
450 /* indicate frame to the stack, which will free the old skb. */
451 type = ath__rx_indicate(sc, skb, status, keyix);
452
453 /* allocate a new skb and queue it to for H/W processing */
454 nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
455 if (nskb != NULL) {
456 bf->bf_mpdu = nskb;
457 bf->bf_buf_addr = ath_skb_map_single(sc,
458 nskb,
459 PCI_DMA_FROMDEVICE,
460 /* XXX: Remove get_dma_mem_context() */
461 get_dma_mem_context(bf, bf_dmacontext));
462 ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf;
463
464 /* queue the new wbuf to H/W */
465 ath_rx_requeue(sc, nskb);
466 }
467
468 return type;
469}
470
471static void ath_opmode_init(struct ath_softc *sc)
472{
473 struct ath_hal *ah = sc->sc_ah;
474 u32 rfilt, mfilt[2];
475
476 /* configure rx filter */
477 rfilt = ath_calcrxfilter(sc);
478 ath9k_hw_setrxfilter(ah, rfilt);
479
480 /* configure bssid mask */
481 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
482 ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
483
484 /* configure operational mode */
485 ath9k_hw_setopmode(ah);
486
487 /* Handle any link-level address change. */
488 ath9k_hw_setmac(ah, sc->sc_myaddr);
489
490 /* calculate and install multicast filter */
491 mfilt[0] = mfilt[1] = ~0;
492
493 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
494 DPRINTF(sc, ATH_DBG_CONFIG ,
495 "%s: RX filter 0x%x, MC filter %08x:%08x\n",
496 __func__, rfilt, mfilt[0], mfilt[1]);
497}
498
499int ath_rx_init(struct ath_softc *sc, int nbufs)
500{
501 struct sk_buff *skb;
502 struct ath_buf *bf;
503 int error = 0;
504
505 do {
506 spin_lock_init(&sc->sc_rxflushlock);
507 sc->sc_rxflush = 0;
508 spin_lock_init(&sc->sc_rxbuflock);
509
510 /*
511 * Cisco's VPN software requires that drivers be able to
512 * receive encapsulated frames that are larger than the MTU.
513 * Since we can't be sure how large a frame we'll get, setup
514 * to handle the larges on possible.
515 */
516 sc->sc_rxbufsize = roundup(IEEE80211_MAX_MPDU_LEN,
517 min(sc->sc_cachelsz,
518 (u16)64));
519
520 DPRINTF(sc, ATH_DBG_CONFIG, "%s: cachelsz %u rxbufsize %u\n",
521 __func__, sc->sc_cachelsz, sc->sc_rxbufsize);
522
523 /* Initialize rx descriptors */
524
525 error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
526 "rx", nbufs, 1);
527 if (error != 0) {
528 DPRINTF(sc, ATH_DBG_FATAL,
529 "%s: failed to allocate rx descriptors: %d\n",
530 __func__, error);
531 break;
532 }
533
534 /* Pre-allocate a wbuf for each rx buffer */
535
536 list_for_each_entry(bf, &sc->sc_rxbuf, list) {
537 skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
538 if (skb == NULL) {
539 error = -ENOMEM;
540 break;
541 }
542
543 bf->bf_mpdu = skb;
544 bf->bf_buf_addr =
545 ath_skb_map_single(sc, skb, PCI_DMA_FROMDEVICE,
546 get_dma_mem_context(bf, bf_dmacontext));
547 ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf;
548 }
549 sc->sc_rxlink = NULL;
550
551 } while (0);
552
553 if (error)
554 ath_rx_cleanup(sc);
555
556 return error;
557}
558
559/* Reclaim all rx queue resources */
560
561void ath_rx_cleanup(struct ath_softc *sc)
562{
563 struct sk_buff *skb;
564 struct ath_buf *bf;
565
566 list_for_each_entry(bf, &sc->sc_rxbuf, list) {
567 skb = bf->bf_mpdu;
568 if (skb)
569 dev_kfree_skb(skb);
570 }
571
572 /* cleanup rx descriptors */
573
574 if (sc->sc_rxdma.dd_desc_len != 0)
575 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
576}
577
578/*
579 * Calculate the receive filter according to the
580 * operating mode and state:
581 *
582 * o always accept unicast, broadcast, and multicast traffic
583 * o maintain current state of phy error reception (the hal
584 * may enable phy error frames for noise immunity work)
585 * o probe request frames are accepted only when operating in
586 * hostap, adhoc, or monitor modes
587 * o enable promiscuous mode according to the interface state
588 * o accept beacons:
589 * - when operating in adhoc mode so the 802.11 layer creates
590 * node table entries for peers,
591 * - when operating in station mode for collecting rssi data when
592 * the station is otherwise quiet, or
593 * - when operating as a repeater so we see repeater-sta beacons
594 * - when scanning
595 */
596
597u32 ath_calcrxfilter(struct ath_softc *sc)
598{
599#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
600 u32 rfilt;
601
602 rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
603 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
604 | ATH9K_RX_FILTER_MCAST;
605
606 /* If not a STA, enable processing of Probe Requests */
607 if (sc->sc_opmode != ATH9K_M_STA)
608 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
609
610 /* Can't set HOSTAP into promiscous mode */
611 if (sc->sc_opmode == ATH9K_M_MONITOR) {
612 rfilt |= ATH9K_RX_FILTER_PROM;
613 /* ??? To prevent from sending ACK */
614 rfilt &= ~ATH9K_RX_FILTER_UCAST;
615 }
616
617 if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS ||
618 sc->sc_scanning)
619 rfilt |= ATH9K_RX_FILTER_BEACON;
620
621 /* If in HOSTAP mode, want to enable reception of PSPOLL frames
622 & beacon frames */
623 if (sc->sc_opmode == ATH9K_M_HOSTAP)
624 rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
625 return rfilt;
626#undef RX_FILTER_PRESERVE
627}
628
629/* Enable the receive h/w following a reset. */
630
631int ath_startrecv(struct ath_softc *sc)
632{
633 struct ath_hal *ah = sc->sc_ah;
634 struct ath_buf *bf, *tbf;
635
636 spin_lock_bh(&sc->sc_rxbuflock);
637 if (list_empty(&sc->sc_rxbuf))
638 goto start_recv;
639
640 sc->sc_rxlink = NULL;
641 list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) {
642 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
643 /* restarting h/w, no need for holding descriptors */
644 bf->bf_status &= ~ATH_BUFSTATUS_STALE;
645 /*
646 * Upper layer may not be done with the frame yet so
647 * we can't just re-queue it to hardware. Remove it
648 * from h/w queue. It'll be re-queued when upper layer
649 * returns the frame and ath_rx_requeue_mpdu is called.
650 */
651 if (!(bf->bf_status & ATH_BUFSTATUS_FREE)) {
652 list_del(&bf->list);
653 continue;
654 }
655 }
656 /* chain descriptors */
657 ath_rx_buf_link(sc, bf);
658 }
659
660 /* We could have deleted elements so the list may be empty now */
661 if (list_empty(&sc->sc_rxbuf))
662 goto start_recv;
663
664 bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
665 ath9k_hw_putrxbuf(ah, bf->bf_daddr);
666 ath9k_hw_rxena(ah); /* enable recv descriptors */
667
668start_recv:
669 spin_unlock_bh(&sc->sc_rxbuflock);
670 ath_opmode_init(sc); /* set filters, etc. */
671 ath9k_hw_startpcureceive(ah); /* re-enable PCU/DMA engine */
672 return 0;
673}
674
675/* Disable the receive h/w in preparation for a reset. */
676
677bool ath_stoprecv(struct ath_softc *sc)
678{
679 struct ath_hal *ah = sc->sc_ah;
680 u64 tsf;
681 bool stopped;
682
683 ath9k_hw_stoppcurecv(ah); /* disable PCU */
684 ath9k_hw_setrxfilter(ah, 0); /* clear recv filter */
685 stopped = ath9k_hw_stopdmarecv(ah); /* disable DMA engine */
686 mdelay(3); /* 3ms is long enough for 1 frame */
687 tsf = ath9k_hw_gettsf64(ah);
688 sc->sc_rxlink = NULL; /* just in case */
689 return stopped;
690}
691
692/* Flush receive queue */
693
694void ath_flushrecv(struct ath_softc *sc)
695{
696 /*
697 * ath_rx_tasklet may be used to handle rx interrupt and flush receive
698 * queue at the same time. Use a lock to serialize the access of rx
699 * queue.
700 * ath_rx_tasklet cannot hold the spinlock while indicating packets.
701 * Instead, do not claim the spinlock but check for a flush in
702 * progress (see references to sc_rxflush)
703 */
704 spin_lock_bh(&sc->sc_rxflushlock);
705 sc->sc_rxflush = 1;
706
707 ath_rx_tasklet(sc, 1);
708
709 sc->sc_rxflush = 0;
710 spin_unlock_bh(&sc->sc_rxflushlock);
711}
712
713/* Process an individual frame */
714
715int ath_rx_input(struct ath_softc *sc,
716 struct ath_node *an,
717 int is_ampdu,
718 struct sk_buff *skb,
719 struct ath_recv_status *rx_status,
720 enum ATH_RX_TYPE *status)
721{
722 if (is_ampdu && sc->sc_rxaggr) {
723 *status = ATH_RX_CONSUMED;
724 return ath_ampdu_input(sc, an, skb, rx_status);
725 } else {
726 *status = ATH_RX_NON_CONSUMED;
727 return -1;
728 }
729}
730
731/* Process receive queue, as well as LED, etc. */
732
733int ath_rx_tasklet(struct ath_softc *sc, int flush)
734{
735#define PA2DESC(_sc, _pa) \
736 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
737 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
738
739 struct ath_buf *bf, *bf_held = NULL;
740 struct ath_desc *ds;
741 struct ieee80211_hdr *hdr;
742 struct sk_buff *skb = NULL;
743 struct ath_recv_status rx_status;
744 struct ath_hal *ah = sc->sc_ah;
745 int type, rx_processed = 0;
746 u32 phyerr;
747 u8 chainreset = 0;
748 int retval;
749 __le16 fc;
750
751 do {
752 /* If handling rx interrupt and flush is in progress => exit */
753 if (sc->sc_rxflush && (flush == 0))
754 break;
755
756 spin_lock_bh(&sc->sc_rxbuflock);
757 if (list_empty(&sc->sc_rxbuf)) {
758 sc->sc_rxlink = NULL;
759 spin_unlock_bh(&sc->sc_rxbuflock);
760 break;
761 }
762
763 bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
764
765 /*
766 * There is a race condition that BH gets scheduled after sw
767 * writes RxE and before hw re-load the last descriptor to get
768 * the newly chained one. Software must keep the last DONE
769 * descriptor as a holding descriptor - software does so by
770 * marking it with the STALE flag.
771 */
772 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
773 bf_held = bf;
774 if (list_is_last(&bf_held->list, &sc->sc_rxbuf)) {
775 /*
776 * The holding descriptor is the last
777 * descriptor in queue. It's safe to
778 * remove the last holding descriptor
779 * in BH context.
780 */
781 list_del(&bf_held->list);
782 bf_held->bf_status &= ~ATH_BUFSTATUS_STALE;
783 sc->sc_rxlink = NULL;
784
785 if (bf_held->bf_status & ATH_BUFSTATUS_FREE) {
786 list_add_tail(&bf_held->list,
787 &sc->sc_rxbuf);
788 ath_rx_buf_link(sc, bf_held);
789 }
790 spin_unlock_bh(&sc->sc_rxbuflock);
791 break;
792 }
793 bf = list_entry(bf->list.next, struct ath_buf, list);
794 }
795
796 ds = bf->bf_desc;
797 ++rx_processed;
798
799 /*
800 * Must provide the virtual address of the current
801 * descriptor, the physical address, and the virtual
802 * address of the next descriptor in the h/w chain.
803 * This allows the HAL to look ahead to see if the
804 * hardware is done with a descriptor by checking the
805 * done bit in the following descriptor and the address
806 * of the current descriptor the DMA engine is working
807 * on. All this is necessary because of our use of
808 * a self-linked list to avoid rx overruns.
809 */
810 retval = ath9k_hw_rxprocdesc(ah,
811 ds,
812 bf->bf_daddr,
813 PA2DESC(sc, ds->ds_link),
814 0);
815 if (retval == -EINPROGRESS) {
816 struct ath_buf *tbf;
817 struct ath_desc *tds;
818
819 if (list_is_last(&bf->list, &sc->sc_rxbuf)) {
820 spin_unlock_bh(&sc->sc_rxbuflock);
821 break;
822 }
823
824 tbf = list_entry(bf->list.next, struct ath_buf, list);
825
826 /*
827 * On some hardware the descriptor status words could
828 * get corrupted, including the done bit. Because of
829 * this, check if the next descriptor's done bit is
830 * set or not.
831 *
832 * If the next descriptor's done bit is set, the current
833 * descriptor has been corrupted. Force s/w to discard
834 * this descriptor and continue...
835 */
836
837 tds = tbf->bf_desc;
838 retval = ath9k_hw_rxprocdesc(ah,
839 tds, tbf->bf_daddr,
840 PA2DESC(sc, tds->ds_link), 0);
841 if (retval == -EINPROGRESS) {
842 spin_unlock_bh(&sc->sc_rxbuflock);
843 break;
844 }
845 }
846
847 /* XXX: we do not support frames spanning
848 * multiple descriptors */
849 bf->bf_status |= ATH_BUFSTATUS_DONE;
850
851 skb = bf->bf_mpdu;
852 if (skb == NULL) { /* XXX ??? can this happen */
853 spin_unlock_bh(&sc->sc_rxbuflock);
854 continue;
855 }
856 /*
857 * Now we know it's a completed frame, we can indicate the
858 * frame. Remove the previous holding descriptor and leave
859 * this one in the queue as the new holding descriptor.
860 */
861 if (bf_held) {
862 list_del(&bf_held->list);
863 bf_held->bf_status &= ~ATH_BUFSTATUS_STALE;
864 if (bf_held->bf_status & ATH_BUFSTATUS_FREE) {
865 list_add_tail(&bf_held->list, &sc->sc_rxbuf);
866 /* try to requeue this descriptor */
867 ath_rx_buf_link(sc, bf_held);
868 }
869 }
870
871 bf->bf_status |= ATH_BUFSTATUS_STALE;
872 bf_held = bf;
873 /*
874 * Release the lock here in case ieee80211_input() return
875 * the frame immediately by calling ath_rx_mpdu_requeue().
876 */
877 spin_unlock_bh(&sc->sc_rxbuflock);
878
879 if (flush) {
880 /*
881 * If we're asked to flush receive queue, directly
882 * chain it back at the queue without processing it.
883 */
884 goto rx_next;
885 }
886
887 hdr = (struct ieee80211_hdr *)skb->data;
888 fc = hdr->frame_control;
889 memzero(&rx_status, sizeof(struct ath_recv_status));
890
891 if (ds->ds_rxstat.rs_more) {
892 /*
893 * Frame spans multiple descriptors; this
894 * cannot happen yet as we don't support
895 * jumbograms. If not in monitor mode,
896 * discard the frame.
897 */
898#ifndef ERROR_FRAMES
899 /*
900 * Enable this if you want to see
901 * error frames in Monitor mode.
902 */
903 if (sc->sc_opmode != ATH9K_M_MONITOR)
904 goto rx_next;
905#endif
906 /* fall thru for monitor mode handling... */
907 } else if (ds->ds_rxstat.rs_status != 0) {
908 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
909 rx_status.flags |= ATH_RX_FCS_ERROR;
910 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
911 phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
912 goto rx_next;
913 }
914
915 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
916 /*
917 * Decrypt error. We only mark packet status
918 * here and always push up the frame up to let
919 * mac80211 handle the actual error case, be
920 * it no decryption key or real decryption
921 * error. This let us keep statistics there.
922 */
923 rx_status.flags |= ATH_RX_DECRYPT_ERROR;
924 } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
925 /*
926 * Demic error. We only mark frame status here
927 * and always push up the frame up to let
928 * mac80211 handle the actual error case. This
929 * let us keep statistics there. Hardware may
930 * post a false-positive MIC error.
931 */
932 if (ieee80211_is_ctl(fc))
933 /*
934 * Sometimes, we get invalid
935 * MIC failures on valid control frames.
936 * Remove these mic errors.
937 */
938 ds->ds_rxstat.rs_status &=
939 ~ATH9K_RXERR_MIC;
940 else
941 rx_status.flags |= ATH_RX_MIC_ERROR;
942 }
943 /*
944 * Reject error frames with the exception of
945 * decryption and MIC failures. For monitor mode,
946 * we also ignore the CRC error.
947 */
948 if (sc->sc_opmode == ATH9K_M_MONITOR) {
949 if (ds->ds_rxstat.rs_status &
950 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
951 ATH9K_RXERR_CRC))
952 goto rx_next;
953 } else {
954 if (ds->ds_rxstat.rs_status &
955 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
956 goto rx_next;
957 }
958 }
959 }
960 /*
961 * The status portion of the descriptor could get corrupted.
962 */
963 if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen)
964 goto rx_next;
965 /*
966 * Sync and unmap the frame. At this point we're
967 * committed to passing the sk_buff somewhere so
968 * clear buf_skb; this means a new sk_buff must be
969 * allocated when the rx descriptor is setup again
970 * to receive another frame.
971 */
972 skb_put(skb, ds->ds_rxstat.rs_datalen);
973 skb->protocol = cpu_to_be16(ETH_P_CONTROL);
974 rx_status.tsf = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
975 rx_status.rateieee =
976 sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate;
977 rx_status.rateKbps =
978 sc->sc_hwmap[ds->ds_rxstat.rs_rate].rateKbps;
979 rx_status.ratecode = ds->ds_rxstat.rs_rate;
980
981 /* HT rate */
982 if (rx_status.ratecode & 0x80) {
983 /* TODO - add table to avoid division */
984 if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) {
985 rx_status.flags |= ATH_RX_40MHZ;
986 rx_status.rateKbps =
987 (rx_status.rateKbps * 27) / 13;
988 }
989 if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
990 rx_status.rateKbps =
991 (rx_status.rateKbps * 10) / 9;
992 else
993 rx_status.flags |= ATH_RX_SHORT_GI;
994 }
995
996 /* sc->sc_noise_floor is only available when the station
997 attaches to an AP, so we use a default value
998 if we are not yet attached. */
999
1000 /* XXX we should use either sc->sc_noise_floor or
1001 * ath_hal_getChanNoise(ah, &sc->sc_curchan)
1002 * to calculate the noise floor.
1003 * However, the value returned by ath_hal_getChanNoise
1004 * seems to be incorrect (-31dBm on the last test),
1005 * so we will use a hard-coded value until we
1006 * figure out what is going on.
1007 */
1008 rx_status.abs_rssi =
1009 ds->ds_rxstat.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
1010
1011 pci_dma_sync_single_for_cpu(sc->pdev,
1012 bf->bf_buf_addr,
1013 skb_tailroom(skb),
1014 PCI_DMA_FROMDEVICE);
1015 pci_unmap_single(sc->pdev,
1016 bf->bf_buf_addr,
1017 sc->sc_rxbufsize,
1018 PCI_DMA_FROMDEVICE);
1019
1020 /* XXX: Ah! make me more readable, use a helper */
1021 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
1022 if (ds->ds_rxstat.rs_moreaggr == 0) {
1023 rx_status.rssictl[0] =
1024 ds->ds_rxstat.rs_rssi_ctl0;
1025 rx_status.rssictl[1] =
1026 ds->ds_rxstat.rs_rssi_ctl1;
1027 rx_status.rssictl[2] =
1028 ds->ds_rxstat.rs_rssi_ctl2;
1029 rx_status.rssi = ds->ds_rxstat.rs_rssi;
1030 if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) {
1031 rx_status.rssiextn[0] =
1032 ds->ds_rxstat.rs_rssi_ext0;
1033 rx_status.rssiextn[1] =
1034 ds->ds_rxstat.rs_rssi_ext1;
1035 rx_status.rssiextn[2] =
1036 ds->ds_rxstat.rs_rssi_ext2;
1037 rx_status.flags |=
1038 ATH_RX_RSSI_EXTN_VALID;
1039 }
1040 rx_status.flags |= ATH_RX_RSSI_VALID |
1041 ATH_RX_CHAIN_RSSI_VALID;
1042 }
1043 } else {
1044 /*
1045 * Need to insert the "combined" rssi into the
1046 * status structure for upper layer processing
1047 */
1048 rx_status.rssi = ds->ds_rxstat.rs_rssi;
1049 rx_status.flags |= ATH_RX_RSSI_VALID;
1050 }
1051
1052 /* Pass frames up to the stack. */
1053
1054 type = ath_rx_indicate(sc, skb,
1055 &rx_status, ds->ds_rxstat.rs_keyix);
1056
1057 /*
1058 * change the default rx antenna if rx diversity chooses the
1059 * other antenna 3 times in a row.
1060 */
1061 if (sc->sc_defant != ds->ds_rxstat.rs_antenna) {
1062 if (++sc->sc_rxotherant >= 3)
1063 ath_setdefantenna(sc,
1064 ds->ds_rxstat.rs_antenna);
1065 } else {
1066 sc->sc_rxotherant = 0;
1067 }
1068
1069#ifdef CONFIG_SLOW_ANT_DIV
1070 if ((rx_status.flags & ATH_RX_RSSI_VALID) &&
1071 ieee80211_is_beacon(fc)) {
1072 ath_slow_ant_div(&sc->sc_antdiv, hdr, &ds->ds_rxstat);
1073 }
1074#endif
1075 /*
1076 * For frames successfully indicated, the buffer will be
1077 * returned to us by upper layers by calling
1078 * ath_rx_mpdu_requeue, either synchronusly or asynchronously.
1079 * So we don't want to do it here in this loop.
1080 */
1081 continue;
1082
1083rx_next:
1084 bf->bf_status |= ATH_BUFSTATUS_FREE;
1085 } while (TRUE);
1086
1087 if (chainreset) {
1088 DPRINTF(sc, ATH_DBG_CONFIG,
1089 "%s: Reset rx chain mask. "
1090 "Do internal reset\n", __func__);
1091 ASSERT(flush == 0);
1092 ath_internal_reset(sc);
1093 }
1094
1095 return 0;
1096#undef PA2DESC
1097}
1098
1099/* Process ADDBA request in per-TID data structure */
1100
1101int ath_rx_aggr_start(struct ath_softc *sc,
1102 const u8 *addr,
1103 u16 tid,
1104 u16 *ssn)
1105{
1106 struct ath_arx_tid *rxtid;
1107 struct ath_node *an;
1108 struct ieee80211_hw *hw = sc->hw;
1109 struct ieee80211_supported_band *sband;
1110 u16 buffersize = 0;
1111
1112 spin_lock_bh(&sc->node_lock);
1113 an = ath_node_find(sc, (u8 *) addr);
1114 spin_unlock_bh(&sc->node_lock);
1115
1116 if (!an) {
1117 DPRINTF(sc, ATH_DBG_AGGR,
1118 "%s: Node not found to initialize RX aggregation\n",
1119 __func__);
1120 return -1;
1121 }
1122
1123 sband = hw->wiphy->bands[hw->conf.channel->band];
1124 buffersize = IEEE80211_MIN_AMPDU_BUF <<
1125 sband->ht_info.ampdu_factor; /* FIXME */
1126
1127 rxtid = &an->an_aggr.rx.tid[tid];
1128
1129 spin_lock_bh(&rxtid->tidlock);
1130 if (sc->sc_rxaggr) {
1131 /* Allow aggregation reception
1132 * Adjust rx BA window size. Peer might indicate a
1133 * zero buffer size for a _dont_care_ condition.
1134 */
1135 if (buffersize)
1136 rxtid->baw_size = min(buffersize, rxtid->baw_size);
1137
1138 /* set rx sequence number */
1139 rxtid->seq_next = *ssn;
1140
1141 /* Allocate the receive buffers for this TID */
1142 DPRINTF(sc, ATH_DBG_AGGR,
1143 "%s: Allcating rxbuffer for TID %d\n", __func__, tid);
1144
1145 if (rxtid->rxbuf == NULL) {
1146 /*
1147 * If the rxbuff is not NULL at this point, we *probably*
1148 * already allocated the buffer on a previous ADDBA,
1149 * and this is a subsequent ADDBA that got through.
1150 * Don't allocate, but use the value in the pointer,
1151 * we zero it out when we de-allocate.
1152 */
1153 rxtid->rxbuf = kmalloc(ATH_TID_MAX_BUFS *
1154 sizeof(struct ath_rxbuf), GFP_ATOMIC);
1155 }
1156 if (rxtid->rxbuf == NULL) {
1157 DPRINTF(sc, ATH_DBG_AGGR,
1158 "%s: Unable to allocate RX buffer, "
1159 "refusing ADDBA\n", __func__);
1160 } else {
1161 /* Ensure the memory is zeroed out (all internal
1162 * pointers are null) */
1163 memzero(rxtid->rxbuf, ATH_TID_MAX_BUFS *
1164 sizeof(struct ath_rxbuf));
1165 DPRINTF(sc, ATH_DBG_AGGR,
1166 "%s: Allocated @%p\n", __func__, rxtid->rxbuf);
1167
1168 /* Allow aggregation reception */
1169 rxtid->addba_exchangecomplete = 1;
1170 }
1171 }
1172 spin_unlock_bh(&rxtid->tidlock);
1173
1174 return 0;
1175}
1176
1177/* Process DELBA */
1178
1179int ath_rx_aggr_stop(struct ath_softc *sc,
1180 const u8 *addr,
1181 u16 tid)
1182{
1183 struct ath_node *an;
1184
1185 spin_lock_bh(&sc->node_lock);
1186 an = ath_node_find(sc, (u8 *) addr);
1187 spin_unlock_bh(&sc->node_lock);
1188
1189 if (!an) {
1190 DPRINTF(sc, ATH_DBG_AGGR,
1191 "%s: RX aggr stop for non-existent node\n", __func__);
1192 return -1;
1193 }
1194
1195 ath_rx_aggr_teardown(sc, an, tid);
1196 return 0;
1197}
1198
1199/* Rx aggregation tear down */
1200
1201void ath_rx_aggr_teardown(struct ath_softc *sc,
1202 struct ath_node *an, u8 tid)
1203{
1204 struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid];
1205
1206 if (!rxtid->addba_exchangecomplete)
1207 return;
1208
1209 del_timer_sync(&rxtid->timer);
1210 ath_rx_flush_tid(sc, rxtid, 0);
1211 rxtid->addba_exchangecomplete = 0;
1212
1213 /* De-allocate the receive buffer array allocated when addba started */
1214
1215 if (rxtid->rxbuf) {
1216 DPRINTF(sc, ATH_DBG_AGGR,
1217 "%s: Deallocating TID %d rxbuff @%p\n",
1218 __func__, tid, rxtid->rxbuf);
1219 kfree(rxtid->rxbuf);
1220
1221 /* Set pointer to null to avoid reuse*/
1222 rxtid->rxbuf = NULL;
1223 }
1224}
1225
1226/* Initialize per-node receive state */
1227
1228void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
1229{
1230 if (sc->sc_rxaggr) {
1231 struct ath_arx_tid *rxtid;
1232 int tidno;
1233
1234 /* Init per tid rx state */
1235 for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno];
1236 tidno < WME_NUM_TID;
1237 tidno++, rxtid++) {
1238 rxtid->an = an;
1239 rxtid->seq_reset = 1;
1240 rxtid->seq_next = 0;
1241 rxtid->baw_size = WME_MAX_BA;
1242 rxtid->baw_head = rxtid->baw_tail = 0;
1243
1244 /*
1245 * Ensure the buffer pointer is null at this point
1246 * (needs to be allocated when addba is received)
1247 */
1248
1249 rxtid->rxbuf = NULL;
1250 setup_timer(&rxtid->timer, ath_rx_timer,
1251 (unsigned long)rxtid);
1252 spin_lock_init(&rxtid->tidlock);
1253
1254 /* ADDBA state */
1255 rxtid->addba_exchangecomplete = 0;
1256 }
1257 }
1258}
1259
1260void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
1261{
1262 if (sc->sc_rxaggr) {
1263 struct ath_arx_tid *rxtid;
1264 int tidno, i;
1265
1266 /* Init per tid rx state */
1267 for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno];
1268 tidno < WME_NUM_TID;
1269 tidno++, rxtid++) {
1270
1271 if (!rxtid->addba_exchangecomplete)
1272 continue;
1273
1274 /* must cancel timer first */
1275 del_timer_sync(&rxtid->timer);
1276
1277 /* drop any pending sub-frames */
1278 ath_rx_flush_tid(sc, rxtid, 1);
1279
1280 for (i = 0; i < ATH_TID_MAX_BUFS; i++)
1281 ASSERT(rxtid->rxbuf[i].rx_wbuf == NULL);
1282
1283 rxtid->addba_exchangecomplete = 0;
1284 }
1285 }
1286
1287}
1288
1289/* Cleanup per-node receive state */
1290
1291void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an)
1292{
1293 ath_rx_node_cleanup(sc, an);
1294}
1295
1296dma_addr_t ath_skb_map_single(struct ath_softc *sc,
1297 struct sk_buff *skb,
1298 int direction,
1299 dma_addr_t *pa)
1300{
1301 /*
1302 * NB: do NOT use skb->len, which is 0 on initialization.
1303 * Use skb's entire data area instead.
1304 */
1305 *pa = pci_map_single(sc->pdev, skb->data,
1306 skb_end_pointer(skb) - skb->head, direction);
1307 return *pa;
1308}
1309
1310void ath_skb_unmap_single(struct ath_softc *sc,
1311 struct sk_buff *skb,
1312 int direction,
1313 dma_addr_t *pa)
1314{
1315 /* Unmap skb's entire data area */
1316 pci_unmap_single(sc->pdev, *pa,
1317 skb_end_pointer(skb) - skb->head, direction);
1318}
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
new file mode 100644
index 000000000000..42b0890a4685
--- /dev/null
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -0,0 +1,1385 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef REG_H
18#define REG_H
19
20#define AR_CR 0x0008
21#define AR_CR_RXE 0x00000004
22#define AR_CR_RXD 0x00000020
23#define AR_CR_SWI 0x00000040
24
25#define AR_RXDP 0x000C
26
27#define AR_CFG 0x0014
28#define AR_CFG_SWTD 0x00000001
29#define AR_CFG_SWTB 0x00000002
30#define AR_CFG_SWRD 0x00000004
31#define AR_CFG_SWRB 0x00000008
32#define AR_CFG_SWRG 0x00000010
33#define AR_CFG_AP_ADHOC_INDICATION 0x00000020
34#define AR_CFG_PHOK 0x00000100
35#define AR_CFG_CLK_GATE_DIS 0x00000400
36#define AR_CFG_EEBS 0x00000200
37#define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000
38#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17
39
40#define AR_MIRT 0x0020
41#define AR_MIRT_VAL 0x0000ffff
42#define AR_MIRT_VAL_S 16
43
44#define AR_IER 0x0024
45#define AR_IER_ENABLE 0x00000001
46#define AR_IER_DISABLE 0x00000000
47
48#define AR_TIMT 0x0028
49#define AR_TIMT_LAST 0x0000ffff
50#define AR_TIMT_LAST_S 0
51#define AR_TIMT_FIRST 0xffff0000
52#define AR_TIMT_FIRST_S 16
53
54#define AR_RIMT 0x002C
55#define AR_RIMT_LAST 0x0000ffff
56#define AR_RIMT_LAST_S 0
57#define AR_RIMT_FIRST 0xffff0000
58#define AR_RIMT_FIRST_S 16
59
60#define AR_DMASIZE_4B 0x00000000
61#define AR_DMASIZE_8B 0x00000001
62#define AR_DMASIZE_16B 0x00000002
63#define AR_DMASIZE_32B 0x00000003
64#define AR_DMASIZE_64B 0x00000004
65#define AR_DMASIZE_128B 0x00000005
66#define AR_DMASIZE_256B 0x00000006
67#define AR_DMASIZE_512B 0x00000007
68
69#define AR_TXCFG 0x0030
70#define AR_TXCFG_DMASZ_MASK 0x00000003
71#define AR_TXCFG_DMASZ_4B 0
72#define AR_TXCFG_DMASZ_8B 1
73#define AR_TXCFG_DMASZ_16B 2
74#define AR_TXCFG_DMASZ_32B 3
75#define AR_TXCFG_DMASZ_64B 4
76#define AR_TXCFG_DMASZ_128B 5
77#define AR_TXCFG_DMASZ_256B 6
78#define AR_TXCFG_DMASZ_512B 7
79#define AR_FTRIG 0x000003F0
80#define AR_FTRIG_S 4
81#define AR_FTRIG_IMMED 0x00000000
82#define AR_FTRIG_64B 0x00000010
83#define AR_FTRIG_128B 0x00000020
84#define AR_FTRIG_192B 0x00000030
85#define AR_FTRIG_256B 0x00000040
86#define AR_FTRIG_512B 0x00000080
87#define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800
88
89#define AR_RXCFG 0x0034
90#define AR_RXCFG_CHIRP 0x00000008
91#define AR_RXCFG_ZLFDMA 0x00000010
92#define AR_RXCFG_DMASZ_MASK 0x00000007
93#define AR_RXCFG_DMASZ_4B 0
94#define AR_RXCFG_DMASZ_8B 1
95#define AR_RXCFG_DMASZ_16B 2
96#define AR_RXCFG_DMASZ_32B 3
97#define AR_RXCFG_DMASZ_64B 4
98#define AR_RXCFG_DMASZ_128B 5
99#define AR_RXCFG_DMASZ_256B 6
100#define AR_RXCFG_DMASZ_512B 7
101
102#define AR_MIBC 0x0040
103#define AR_MIBC_COW 0x00000001
104#define AR_MIBC_FMC 0x00000002
105#define AR_MIBC_CMC 0x00000004
106#define AR_MIBC_MCS 0x00000008
107
108#define AR_TOPS 0x0044
109#define AR_TOPS_MASK 0x0000FFFF
110
111#define AR_RXNPTO 0x0048
112#define AR_RXNPTO_MASK 0x000003FF
113
114#define AR_TXNPTO 0x004C
115#define AR_TXNPTO_MASK 0x000003FF
116#define AR_TXNPTO_QCU_MASK 0x000FFC00
117
118#define AR_RPGTO 0x0050
119#define AR_RPGTO_MASK 0x000003FF
120
121#define AR_RPCNT 0x0054
122#define AR_RPCNT_MASK 0x0000001F
123
124#define AR_MACMISC 0x0058
125#define AR_MACMISC_PCI_EXT_FORCE 0x00000010
126#define AR_MACMISC_DMA_OBS 0x000001E0
127#define AR_MACMISC_DMA_OBS_S 5
128#define AR_MACMISC_DMA_OBS_LINE_0 0
129#define AR_MACMISC_DMA_OBS_LINE_1 1
130#define AR_MACMISC_DMA_OBS_LINE_2 2
131#define AR_MACMISC_DMA_OBS_LINE_3 3
132#define AR_MACMISC_DMA_OBS_LINE_4 4
133#define AR_MACMISC_DMA_OBS_LINE_5 5
134#define AR_MACMISC_DMA_OBS_LINE_6 6
135#define AR_MACMISC_DMA_OBS_LINE_7 7
136#define AR_MACMISC_DMA_OBS_LINE_8 8
137#define AR_MACMISC_MISC_OBS 0x00000E00
138#define AR_MACMISC_MISC_OBS_S 9
139#define AR_MACMISC_MISC_OBS_BUS_LSB 0x00007000
140#define AR_MACMISC_MISC_OBS_BUS_LSB_S 12
141#define AR_MACMISC_MISC_OBS_BUS_MSB 0x00038000
142#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15
143#define AR_MACMISC_MISC_OBS_BUS_1 1
144
145#define AR_GTXTO 0x0064
146#define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF
147#define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000
148#define AR_GTXTO_TIMEOUT_LIMIT_S 16
149
150#define AR_GTTM 0x0068
151#define AR_GTTM_USEC 0x00000001
152#define AR_GTTM_IGNORE_IDLE 0x00000002
153#define AR_GTTM_RESET_IDLE 0x00000004
154#define AR_GTTM_CST_USEC 0x00000008
155
156#define AR_CST 0x006C
157#define AR_CST_TIMEOUT_COUNTER 0x0000FFFF
158#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000
159#define AR_CST_TIMEOUT_LIMIT_S 16
160
161#define AR_SREV_VERSION_9100 0x014
162
163#define AR_SREV_5416_V20_OR_LATER(_ah) \
164 (AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
165#define AR_SREV_5416_V22_OR_LATER(_ah) \
166 (AR_SREV_9100((_ah)) || AR_SREV_5416_22_OR_LATER(_ah))
167
168#define AR_ISR 0x0080
169#define AR_ISR_RXOK 0x00000001
170#define AR_ISR_RXDESC 0x00000002
171#define AR_ISR_RXERR 0x00000004
172#define AR_ISR_RXNOPKT 0x00000008
173#define AR_ISR_RXEOL 0x00000010
174#define AR_ISR_RXORN 0x00000020
175#define AR_ISR_TXOK 0x00000040
176#define AR_ISR_TXDESC 0x00000080
177#define AR_ISR_TXERR 0x00000100
178#define AR_ISR_TXNOPKT 0x00000200
179#define AR_ISR_TXEOL 0x00000400
180#define AR_ISR_TXURN 0x00000800
181#define AR_ISR_MIB 0x00001000
182#define AR_ISR_SWI 0x00002000
183#define AR_ISR_RXPHY 0x00004000
184#define AR_ISR_RXKCM 0x00008000
185#define AR_ISR_SWBA 0x00010000
186#define AR_ISR_BRSSI 0x00020000
187#define AR_ISR_BMISS 0x00040000
188#define AR_ISR_BNR 0x00100000
189#define AR_ISR_RXCHIRP 0x00200000
190#define AR_ISR_BCNMISC 0x00800000
191#define AR_ISR_TIM 0x00800000
192#define AR_ISR_QCBROVF 0x02000000
193#define AR_ISR_QCBRURN 0x04000000
194#define AR_ISR_QTRIG 0x08000000
195#define AR_ISR_GENTMR 0x10000000
196
197#define AR_ISR_TXMINTR 0x00080000
198#define AR_ISR_RXMINTR 0x01000000
199#define AR_ISR_TXINTM 0x40000000
200#define AR_ISR_RXINTM 0x80000000
201
202#define AR_ISR_S0 0x0084
203#define AR_ISR_S0_QCU_TXOK 0x000003FF
204#define AR_ISR_S0_QCU_TXOK_S 0
205#define AR_ISR_S0_QCU_TXDESC 0x03FF0000
206#define AR_ISR_S0_QCU_TXDESC_S 16
207
208#define AR_ISR_S1 0x0088
209#define AR_ISR_S1_QCU_TXERR 0x000003FF
210#define AR_ISR_S1_QCU_TXERR_S 0
211#define AR_ISR_S1_QCU_TXEOL 0x03FF0000
212#define AR_ISR_S1_QCU_TXEOL_S 16
213
214#define AR_ISR_S2 0x008c
215#define AR_ISR_S2_QCU_TXURN 0x000003FF
216#define AR_ISR_S2_CST 0x00400000
217#define AR_ISR_S2_GTT 0x00800000
218#define AR_ISR_S2_TIM 0x01000000
219#define AR_ISR_S2_CABEND 0x02000000
220#define AR_ISR_S2_DTIMSYNC 0x04000000
221#define AR_ISR_S2_BCNTO 0x08000000
222#define AR_ISR_S2_CABTO 0x10000000
223#define AR_ISR_S2_DTIM 0x20000000
224#define AR_ISR_S2_TSFOOR 0x40000000
225#define AR_ISR_S2_TBTT_TIME 0x80000000
226
227#define AR_ISR_S3 0x0090
228#define AR_ISR_S3_QCU_QCBROVF 0x000003FF
229#define AR_ISR_S3_QCU_QCBRURN 0x03FF0000
230
231#define AR_ISR_S4 0x0094
232#define AR_ISR_S4_QCU_QTRIG 0x000003FF
233#define AR_ISR_S4_RESV0 0xFFFFFC00
234
235#define AR_ISR_S5 0x0098
236#define AR_ISR_S5_TIMER_TRIG 0x000000FF
237#define AR_ISR_S5_TIMER_THRESH 0x0007FE00
238#define AR_ISR_S5_TIM_TIMER 0x00000010
239#define AR_ISR_S5_DTIM_TIMER 0x00000020
240#define AR_ISR_S5_S 0x00d8
241#define AR_IMR_S5 0x00b8
242#define AR_IMR_S5_TIM_TIMER 0x00000010
243#define AR_IMR_S5_DTIM_TIMER 0x00000020
244
245
246#define AR_IMR 0x00a0
247#define AR_IMR_RXOK 0x00000001
248#define AR_IMR_RXDESC 0x00000002
249#define AR_IMR_RXERR 0x00000004
250#define AR_IMR_RXNOPKT 0x00000008
251#define AR_IMR_RXEOL 0x00000010
252#define AR_IMR_RXORN 0x00000020
253#define AR_IMR_TXOK 0x00000040
254#define AR_IMR_TXDESC 0x00000080
255#define AR_IMR_TXERR 0x00000100
256#define AR_IMR_TXNOPKT 0x00000200
257#define AR_IMR_TXEOL 0x00000400
258#define AR_IMR_TXURN 0x00000800
259#define AR_IMR_MIB 0x00001000
260#define AR_IMR_SWI 0x00002000
261#define AR_IMR_RXPHY 0x00004000
262#define AR_IMR_RXKCM 0x00008000
263#define AR_IMR_SWBA 0x00010000
264#define AR_IMR_BRSSI 0x00020000
265#define AR_IMR_BMISS 0x00040000
266#define AR_IMR_BNR 0x00100000
267#define AR_IMR_RXCHIRP 0x00200000
268#define AR_IMR_BCNMISC 0x00800000
269#define AR_IMR_TIM 0x00800000
270#define AR_IMR_QCBROVF 0x02000000
271#define AR_IMR_QCBRURN 0x04000000
272#define AR_IMR_QTRIG 0x08000000
273#define AR_IMR_GENTMR 0x10000000
274
275#define AR_IMR_TXMINTR 0x00080000
276#define AR_IMR_RXMINTR 0x01000000
277#define AR_IMR_TXINTM 0x40000000
278#define AR_IMR_RXINTM 0x80000000
279
280#define AR_IMR_S0 0x00a4
281#define AR_IMR_S0_QCU_TXOK 0x000003FF
282#define AR_IMR_S0_QCU_TXOK_S 0
283#define AR_IMR_S0_QCU_TXDESC 0x03FF0000
284#define AR_IMR_S0_QCU_TXDESC_S 16
285
286#define AR_IMR_S1 0x00a8
287#define AR_IMR_S1_QCU_TXERR 0x000003FF
288#define AR_IMR_S1_QCU_TXERR_S 0
289#define AR_IMR_S1_QCU_TXEOL 0x03FF0000
290#define AR_IMR_S1_QCU_TXEOL_S 16
291
292#define AR_IMR_S2 0x00ac
293#define AR_IMR_S2_QCU_TXURN 0x000003FF
294#define AR_IMR_S2_QCU_TXURN_S 0
295#define AR_IMR_S2_CST 0x00400000
296#define AR_IMR_S2_GTT 0x00800000
297#define AR_IMR_S2_TIM 0x01000000
298#define AR_IMR_S2_CABEND 0x02000000
299#define AR_IMR_S2_DTIMSYNC 0x04000000
300#define AR_IMR_S2_BCNTO 0x08000000
301#define AR_IMR_S2_CABTO 0x10000000
302#define AR_IMR_S2_DTIM 0x20000000
303#define AR_IMR_S2_TSFOOR 0x40000000
304
305#define AR_IMR_S3 0x00b0
306#define AR_IMR_S3_QCU_QCBROVF 0x000003FF
307#define AR_IMR_S3_QCU_QCBRURN 0x03FF0000
308#define AR_IMR_S3_QCU_QCBRURN_S 16
309
310#define AR_IMR_S4 0x00b4
311#define AR_IMR_S4_QCU_QTRIG 0x000003FF
312#define AR_IMR_S4_RESV0 0xFFFFFC00
313
314#define AR_IMR_S5 0x00b8
315#define AR_IMR_S5_TIMER_TRIG 0x000000FF
316#define AR_IMR_S5_TIMER_THRESH 0x0000FF00
317
318
319#define AR_ISR_RAC 0x00c0
320#define AR_ISR_S0_S 0x00c4
321#define AR_ISR_S0_QCU_TXOK 0x000003FF
322#define AR_ISR_S0_QCU_TXOK_S 0
323#define AR_ISR_S0_QCU_TXDESC 0x03FF0000
324#define AR_ISR_S0_QCU_TXDESC_S 16
325
326#define AR_ISR_S1_S 0x00c8
327#define AR_ISR_S1_QCU_TXERR 0x000003FF
328#define AR_ISR_S1_QCU_TXERR_S 0
329#define AR_ISR_S1_QCU_TXEOL 0x03FF0000
330#define AR_ISR_S1_QCU_TXEOL_S 16
331
332#define AR_ISR_S2_S 0x00cc
333#define AR_ISR_S3_S 0x00d0
334#define AR_ISR_S4_S 0x00d4
335#define AR_ISR_S5_S 0x00d8
336#define AR_DMADBG_0 0x00e0
337#define AR_DMADBG_1 0x00e4
338#define AR_DMADBG_2 0x00e8
339#define AR_DMADBG_3 0x00ec
340#define AR_DMADBG_4 0x00f0
341#define AR_DMADBG_5 0x00f4
342#define AR_DMADBG_6 0x00f8
343#define AR_DMADBG_7 0x00fc
344
345#define AR_NUM_QCU 10
346#define AR_QCU_0 0x0001
347#define AR_QCU_1 0x0002
348#define AR_QCU_2 0x0004
349#define AR_QCU_3 0x0008
350#define AR_QCU_4 0x0010
351#define AR_QCU_5 0x0020
352#define AR_QCU_6 0x0040
353#define AR_QCU_7 0x0080
354#define AR_QCU_8 0x0100
355#define AR_QCU_9 0x0200
356
357#define AR_Q0_TXDP 0x0800
358#define AR_Q1_TXDP 0x0804
359#define AR_Q2_TXDP 0x0808
360#define AR_Q3_TXDP 0x080c
361#define AR_Q4_TXDP 0x0810
362#define AR_Q5_TXDP 0x0814
363#define AR_Q6_TXDP 0x0818
364#define AR_Q7_TXDP 0x081c
365#define AR_Q8_TXDP 0x0820
366#define AR_Q9_TXDP 0x0824
367#define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2))
368
369#define AR_Q_TXE 0x0840
370#define AR_Q_TXE_M 0x000003FF
371
372#define AR_Q_TXD 0x0880
373#define AR_Q_TXD_M 0x000003FF
374
375#define AR_Q0_CBRCFG 0x08c0
376#define AR_Q1_CBRCFG 0x08c4
377#define AR_Q2_CBRCFG 0x08c8
378#define AR_Q3_CBRCFG 0x08cc
379#define AR_Q4_CBRCFG 0x08d0
380#define AR_Q5_CBRCFG 0x08d4
381#define AR_Q6_CBRCFG 0x08d8
382#define AR_Q7_CBRCFG 0x08dc
383#define AR_Q8_CBRCFG 0x08e0
384#define AR_Q9_CBRCFG 0x08e4
385#define AR_QCBRCFG(_i) (AR_Q0_CBRCFG + ((_i)<<2))
386#define AR_Q_CBRCFG_INTERVAL 0x00FFFFFF
387#define AR_Q_CBRCFG_INTERVAL_S 0
388#define AR_Q_CBRCFG_OVF_THRESH 0xFF000000
389#define AR_Q_CBRCFG_OVF_THRESH_S 24
390
391#define AR_Q0_RDYTIMECFG 0x0900
392#define AR_Q1_RDYTIMECFG 0x0904
393#define AR_Q2_RDYTIMECFG 0x0908
394#define AR_Q3_RDYTIMECFG 0x090c
395#define AR_Q4_RDYTIMECFG 0x0910
396#define AR_Q5_RDYTIMECFG 0x0914
397#define AR_Q6_RDYTIMECFG 0x0918
398#define AR_Q7_RDYTIMECFG 0x091c
399#define AR_Q8_RDYTIMECFG 0x0920
400#define AR_Q9_RDYTIMECFG 0x0924
401#define AR_QRDYTIMECFG(_i) (AR_Q0_RDYTIMECFG + ((_i)<<2))
402#define AR_Q_RDYTIMECFG_DURATION 0x00FFFFFF
403#define AR_Q_RDYTIMECFG_DURATION_S 0
404#define AR_Q_RDYTIMECFG_EN 0x01000000
405
406#define AR_Q_ONESHOTARM_SC 0x0940
407#define AR_Q_ONESHOTARM_SC_M 0x000003FF
408#define AR_Q_ONESHOTARM_SC_RESV0 0xFFFFFC00
409
410#define AR_Q_ONESHOTARM_CC 0x0980
411#define AR_Q_ONESHOTARM_CC_M 0x000003FF
412#define AR_Q_ONESHOTARM_CC_RESV0 0xFFFFFC00
413
414#define AR_Q0_MISC 0x09c0
415#define AR_Q1_MISC 0x09c4
416#define AR_Q2_MISC 0x09c8
417#define AR_Q3_MISC 0x09cc
418#define AR_Q4_MISC 0x09d0
419#define AR_Q5_MISC 0x09d4
420#define AR_Q6_MISC 0x09d8
421#define AR_Q7_MISC 0x09dc
422#define AR_Q8_MISC 0x09e0
423#define AR_Q9_MISC 0x09e4
424#define AR_QMISC(_i) (AR_Q0_MISC + ((_i)<<2))
425#define AR_Q_MISC_FSP 0x0000000F
426#define AR_Q_MISC_FSP_ASAP 0
427#define AR_Q_MISC_FSP_CBR 1
428#define AR_Q_MISC_FSP_DBA_GATED 2
429#define AR_Q_MISC_FSP_TIM_GATED 3
430#define AR_Q_MISC_FSP_BEACON_SENT_GATED 4
431#define AR_Q_MISC_FSP_BEACON_RCVD_GATED 5
432#define AR_Q_MISC_ONE_SHOT_EN 0x00000010
433#define AR_Q_MISC_CBR_INCR_DIS1 0x00000020
434#define AR_Q_MISC_CBR_INCR_DIS0 0x00000040
435#define AR_Q_MISC_BEACON_USE 0x00000080
436#define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN 0x00000100
437#define AR_Q_MISC_RDYTIME_EXP_POLICY 0x00000200
438#define AR_Q_MISC_RESET_CBR_EXP_CTR 0x00000400
439#define AR_Q_MISC_DCU_EARLY_TERM_REQ 0x00000800
440#define AR_Q_MISC_RESV0 0xFFFFF000
441
442#define AR_Q0_STS 0x0a00
443#define AR_Q1_STS 0x0a04
444#define AR_Q2_STS 0x0a08
445#define AR_Q3_STS 0x0a0c
446#define AR_Q4_STS 0x0a10
447#define AR_Q5_STS 0x0a14
448#define AR_Q6_STS 0x0a18
449#define AR_Q7_STS 0x0a1c
450#define AR_Q8_STS 0x0a20
451#define AR_Q9_STS 0x0a24
452#define AR_QSTS(_i) (AR_Q0_STS + ((_i)<<2))
453#define AR_Q_STS_PEND_FR_CNT 0x00000003
454#define AR_Q_STS_RESV0 0x000000FC
455#define AR_Q_STS_CBR_EXP_CNT 0x0000FF00
456#define AR_Q_STS_RESV1 0xFFFF0000
457
458#define AR_Q_RDYTIMESHDN 0x0a40
459#define AR_Q_RDYTIMESHDN_M 0x000003FF
460
461
462#define AR_NUM_DCU 10
463#define AR_DCU_0 0x0001
464#define AR_DCU_1 0x0002
465#define AR_DCU_2 0x0004
466#define AR_DCU_3 0x0008
467#define AR_DCU_4 0x0010
468#define AR_DCU_5 0x0020
469#define AR_DCU_6 0x0040
470#define AR_DCU_7 0x0080
471#define AR_DCU_8 0x0100
472#define AR_DCU_9 0x0200
473
474#define AR_D0_QCUMASK 0x1000
475#define AR_D1_QCUMASK 0x1004
476#define AR_D2_QCUMASK 0x1008
477#define AR_D3_QCUMASK 0x100c
478#define AR_D4_QCUMASK 0x1010
479#define AR_D5_QCUMASK 0x1014
480#define AR_D6_QCUMASK 0x1018
481#define AR_D7_QCUMASK 0x101c
482#define AR_D8_QCUMASK 0x1020
483#define AR_D9_QCUMASK 0x1024
484#define AR_DQCUMASK(_i) (AR_D0_QCUMASK + ((_i)<<2))
485#define AR_D_QCUMASK 0x000003FF
486#define AR_D_QCUMASK_RESV0 0xFFFFFC00
487
488#define AR_D_TXBLK_CMD 0x1038
489#define AR_D_TXBLK_DATA(i) (AR_D_TXBLK_CMD+(i))
490
491#define AR_D0_LCL_IFS 0x1040
492#define AR_D1_LCL_IFS 0x1044
493#define AR_D2_LCL_IFS 0x1048
494#define AR_D3_LCL_IFS 0x104c
495#define AR_D4_LCL_IFS 0x1050
496#define AR_D5_LCL_IFS 0x1054
497#define AR_D6_LCL_IFS 0x1058
498#define AR_D7_LCL_IFS 0x105c
499#define AR_D8_LCL_IFS 0x1060
500#define AR_D9_LCL_IFS 0x1064
501#define AR_DLCL_IFS(_i) (AR_D0_LCL_IFS + ((_i)<<2))
502#define AR_D_LCL_IFS_CWMIN 0x000003FF
503#define AR_D_LCL_IFS_CWMIN_S 0
504#define AR_D_LCL_IFS_CWMAX 0x000FFC00
505#define AR_D_LCL_IFS_CWMAX_S 10
506#define AR_D_LCL_IFS_AIFS 0x0FF00000
507#define AR_D_LCL_IFS_AIFS_S 20
508
509#define AR_D_LCL_IFS_RESV0 0xF0000000
510
511#define AR_D0_RETRY_LIMIT 0x1080
512#define AR_D1_RETRY_LIMIT 0x1084
513#define AR_D2_RETRY_LIMIT 0x1088
514#define AR_D3_RETRY_LIMIT 0x108c
515#define AR_D4_RETRY_LIMIT 0x1090
516#define AR_D5_RETRY_LIMIT 0x1094
517#define AR_D6_RETRY_LIMIT 0x1098
518#define AR_D7_RETRY_LIMIT 0x109c
519#define AR_D8_RETRY_LIMIT 0x10a0
520#define AR_D9_RETRY_LIMIT 0x10a4
521#define AR_DRETRY_LIMIT(_i) (AR_D0_RETRY_LIMIT + ((_i)<<2))
522#define AR_D_RETRY_LIMIT_FR_SH 0x0000000F
523#define AR_D_RETRY_LIMIT_FR_SH_S 0
524#define AR_D_RETRY_LIMIT_STA_SH 0x00003F00
525#define AR_D_RETRY_LIMIT_STA_SH_S 8
526#define AR_D_RETRY_LIMIT_STA_LG 0x000FC000
527#define AR_D_RETRY_LIMIT_STA_LG_S 14
528#define AR_D_RETRY_LIMIT_RESV0 0xFFF00000
529
530#define AR_D0_CHNTIME 0x10c0
531#define AR_D1_CHNTIME 0x10c4
532#define AR_D2_CHNTIME 0x10c8
533#define AR_D3_CHNTIME 0x10cc
534#define AR_D4_CHNTIME 0x10d0
535#define AR_D5_CHNTIME 0x10d4
536#define AR_D6_CHNTIME 0x10d8
537#define AR_D7_CHNTIME 0x10dc
538#define AR_D8_CHNTIME 0x10e0
539#define AR_D9_CHNTIME 0x10e4
540#define AR_DCHNTIME(_i) (AR_D0_CHNTIME + ((_i)<<2))
541#define AR_D_CHNTIME_DUR 0x000FFFFF
542#define AR_D_CHNTIME_DUR_S 0
543#define AR_D_CHNTIME_EN 0x00100000
544#define AR_D_CHNTIME_RESV0 0xFFE00000
545
546#define AR_D0_MISC 0x1100
547#define AR_D1_MISC 0x1104
548#define AR_D2_MISC 0x1108
549#define AR_D3_MISC 0x110c
550#define AR_D4_MISC 0x1110
551#define AR_D5_MISC 0x1114
552#define AR_D6_MISC 0x1118
553#define AR_D7_MISC 0x111c
554#define AR_D8_MISC 0x1120
555#define AR_D9_MISC 0x1124
556#define AR_DMISC(_i) (AR_D0_MISC + ((_i)<<2))
557#define AR_D_MISC_BKOFF_THRESH 0x0000003F
558#define AR_D_MISC_RETRY_CNT_RESET_EN 0x00000040
559#define AR_D_MISC_CW_RESET_EN 0x00000080
560#define AR_D_MISC_FRAG_WAIT_EN 0x00000100
561#define AR_D_MISC_FRAG_BKOFF_EN 0x00000200
562#define AR_D_MISC_CW_BKOFF_EN 0x00001000
563#define AR_D_MISC_VIR_COL_HANDLING 0x0000C000
564#define AR_D_MISC_VIR_COL_HANDLING_S 14
565#define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0
566#define AR_D_MISC_VIR_COL_HANDLING_IGNORE 1
567#define AR_D_MISC_BEACON_USE 0x00010000
568#define AR_D_MISC_ARB_LOCKOUT_CNTRL 0x00060000
569#define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17
570#define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE 0
571#define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1
572#define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL 2
573#define AR_D_MISC_ARB_LOCKOUT_IGNORE 0x00080000
574#define AR_D_MISC_SEQ_NUM_INCR_DIS 0x00100000
575#define AR_D_MISC_POST_FR_BKOFF_DIS 0x00200000
576#define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000
577#define AR_D_MISC_BLOWN_IFS_RETRY_EN 0x00800000
578#define AR_D_MISC_RESV0 0xFF000000
579
580#define AR_D_SEQNUM 0x1140
581
582#define AR_D_GBL_IFS_SIFS 0x1030
583#define AR_D_GBL_IFS_SIFS_M 0x0000FFFF
584#define AR_D_GBL_IFS_SIFS_RESV0 0xFFFFFFFF
585
586#define AR_D_TXBLK_BASE 0x1038
587#define AR_D_TXBLK_WRITE_BITMASK 0x0000FFFF
588#define AR_D_TXBLK_WRITE_BITMASK_S 0
589#define AR_D_TXBLK_WRITE_SLICE 0x000F0000
590#define AR_D_TXBLK_WRITE_SLICE_S 16
591#define AR_D_TXBLK_WRITE_DCU 0x00F00000
592#define AR_D_TXBLK_WRITE_DCU_S 20
593#define AR_D_TXBLK_WRITE_COMMAND 0x0F000000
594#define AR_D_TXBLK_WRITE_COMMAND_S 24
595
596#define AR_D_GBL_IFS_SLOT 0x1070
597#define AR_D_GBL_IFS_SLOT_M 0x0000FFFF
598#define AR_D_GBL_IFS_SLOT_RESV0 0xFFFF0000
599
600#define AR_D_GBL_IFS_EIFS 0x10b0
601#define AR_D_GBL_IFS_EIFS_M 0x0000FFFF
602#define AR_D_GBL_IFS_EIFS_RESV0 0xFFFF0000
603
604#define AR_D_GBL_IFS_MISC 0x10f0
605#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007
606#define AR_D_GBL_IFS_MISC_TURBO_MODE 0x00000008
607#define AR_D_GBL_IFS_MISC_USEC_DURATION 0x000FFC00
608#define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY 0x00300000
609#define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000
610#define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN 0x06000000
611#define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000
612#define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF 0x10000000
613
614#define AR_D_FPCTL 0x1230
615#define AR_D_FPCTL_DCU 0x0000000F
616#define AR_D_FPCTL_DCU_S 0
617#define AR_D_FPCTL_PREFETCH_EN 0x00000010
618#define AR_D_FPCTL_BURST_PREFETCH 0x00007FE0
619#define AR_D_FPCTL_BURST_PREFETCH_S 5
620
621#define AR_D_TXPSE 0x1270
622#define AR_D_TXPSE_CTRL 0x000003FF
623#define AR_D_TXPSE_RESV0 0x0000FC00
624#define AR_D_TXPSE_STATUS 0x00010000
625#define AR_D_TXPSE_RESV1 0xFFFE0000
626
627#define AR_D_TXSLOTMASK 0x12f0
628#define AR_D_TXSLOTMASK_NUM 0x0000000F
629
630#define AR_CFG_LED 0x1f04
631#define AR_CFG_SCLK_RATE_IND 0x00000003
632#define AR_CFG_SCLK_RATE_IND_S 0
633#define AR_CFG_SCLK_32MHZ 0x00000000
634#define AR_CFG_SCLK_4MHZ 0x00000001
635#define AR_CFG_SCLK_1MHZ 0x00000002
636#define AR_CFG_SCLK_32KHZ 0x00000003
637#define AR_CFG_LED_BLINK_SLOW 0x00000008
638#define AR_CFG_LED_BLINK_THRESH_SEL 0x00000070
639#define AR_CFG_LED_MODE_SEL 0x00000380
640#define AR_CFG_LED_MODE_SEL_S 7
641#define AR_CFG_LED_POWER 0x00000280
642#define AR_CFG_LED_POWER_S 7
643#define AR_CFG_LED_NETWORK 0x00000300
644#define AR_CFG_LED_NETWORK_S 7
645#define AR_CFG_LED_MODE_PROP 0x0
646#define AR_CFG_LED_MODE_RPROP 0x1
647#define AR_CFG_LED_MODE_SPLIT 0x2
648#define AR_CFG_LED_MODE_RAND 0x3
649#define AR_CFG_LED_MODE_POWER_OFF 0x4
650#define AR_CFG_LED_MODE_POWER_ON 0x5
651#define AR_CFG_LED_MODE_NETWORK_OFF 0x4
652#define AR_CFG_LED_MODE_NETWORK_ON 0x6
653#define AR_CFG_LED_ASSOC_CTL 0x00000c00
654#define AR_CFG_LED_ASSOC_CTL_S 10
655#define AR_CFG_LED_ASSOC_NONE 0x0
656#define AR_CFG_LED_ASSOC_ACTIVE 0x1
657#define AR_CFG_LED_ASSOC_PENDING 0x2
658
659#define AR_CFG_LED_BLINK_SLOW 0x00000008
660#define AR_CFG_LED_BLINK_SLOW_S 3
661
662#define AR_CFG_LED_BLINK_THRESH_SEL 0x00000070
663#define AR_CFG_LED_BLINK_THRESH_SEL_S 4
664
665#define AR_MAC_SLEEP 0x1f00
666#define AR_MAC_SLEEP_MAC_AWAKE 0x00000000
667#define AR_MAC_SLEEP_MAC_ASLEEP 0x00000001
668
669#define AR_RC 0x4000
670#define AR_RC_AHB 0x00000001
671#define AR_RC_APB 0x00000002
672#define AR_RC_HOSTIF 0x00000100
673
674#define AR_WA 0x4004
675
676#define AR_PM_STATE 0x4008
677#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
678
679#define AR_HOST_TIMEOUT 0x4018
680#define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF
681#define AR_HOST_TIMEOUT_APB_CNTR_S 0
682#define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000
683#define AR_HOST_TIMEOUT_LCL_CNTR_S 16
684
685#define AR_EEPROM 0x401c
686#define AR_EEPROM_ABSENT 0x00000100
687#define AR_EEPROM_CORRUPT 0x00000200
688#define AR_EEPROM_PROT_MASK 0x03FFFC00
689#define AR_EEPROM_PROT_MASK_S 10
690
691#define EEPROM_PROTECT_RP_0_31 0x0001
692#define EEPROM_PROTECT_WP_0_31 0x0002
693#define EEPROM_PROTECT_RP_32_63 0x0004
694#define EEPROM_PROTECT_WP_32_63 0x0008
695#define EEPROM_PROTECT_RP_64_127 0x0010
696#define EEPROM_PROTECT_WP_64_127 0x0020
697#define EEPROM_PROTECT_RP_128_191 0x0040
698#define EEPROM_PROTECT_WP_128_191 0x0080
699#define EEPROM_PROTECT_RP_192_255 0x0100
700#define EEPROM_PROTECT_WP_192_255 0x0200
701#define EEPROM_PROTECT_RP_256_511 0x0400
702#define EEPROM_PROTECT_WP_256_511 0x0800
703#define EEPROM_PROTECT_RP_512_1023 0x1000
704#define EEPROM_PROTECT_WP_512_1023 0x2000
705#define EEPROM_PROTECT_RP_1024_2047 0x4000
706#define EEPROM_PROTECT_WP_1024_2047 0x8000
707
708#define AR_SREV \
709 ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
710
711#define AR_SREV_ID \
712 ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
713#define AR_SREV_VERSION 0x000000F0
714#define AR_SREV_VERSION_S 4
715#define AR_SREV_REVISION 0x00000007
716
717#define AR_SREV_ID2 0xFFFFFFFF
718#define AR_SREV_VERSION2 0xFFFC0000
719#define AR_SREV_VERSION2_S 18
720#define AR_SREV_TYPE2 0x0003F000
721#define AR_SREV_TYPE2_S 12
722#define AR_SREV_TYPE2_CHAIN 0x00001000
723#define AR_SREV_TYPE2_HOST_MODE 0x00002000
724#define AR_SREV_REVISION2 0x00000F00
725#define AR_SREV_REVISION2_S 8
726
727#define AR_SREV_VERSION_5416_PCI 0xD
728#define AR_SREV_VERSION_5416_PCIE 0xC
729#define AR_SREV_REVISION_5416_10 0
730#define AR_SREV_REVISION_5416_20 1
731#define AR_SREV_REVISION_5416_22 2
732#define AR_SREV_VERSION_9160 0x40
733#define AR_SREV_REVISION_9160_10 0
734#define AR_SREV_REVISION_9160_11 1
735#define AR_SREV_VERSION_9280 0x80
736#define AR_SREV_REVISION_9280_10 0
737#define AR_SREV_REVISION_9280_20 1
738#define AR_SREV_REVISION_9280_21 2
739#define AR_SREV_VERSION_9285 0xC0
740#define AR_SREV_REVISION_9285_10 0
741
742#define AR_SREV_9100_OR_LATER(_ah) \
743 (((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
744#define AR_SREV_5416_20_OR_LATER(_ah) \
745 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
746 ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_20))
747#define AR_SREV_5416_22_OR_LATER(_ah) \
748 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
749 ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_22))
750#define AR_SREV_9160(_ah) \
751 (((_ah)->ah_macVersion == AR_SREV_VERSION_9160))
752#define AR_SREV_9160_10_OR_LATER(_ah) \
753 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160))
754#define AR_SREV_9160_11(_ah) \
755 (AR_SREV_9160(_ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9160_11))
756#define AR_SREV_9280(_ah) \
757 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280))
758#define AR_SREV_9280_10_OR_LATER(_ah) \
759 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9280))
760#define AR_SREV_9280_20(_ah) \
761 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
762 ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20))
763#define AR_SREV_9280_20_OR_LATER(_ah) \
764 (((_ah)->ah_macVersion > AR_SREV_VERSION_9280) || \
765 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
766 ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20)))
767
768#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
769#define AR_SREV_9285_10_OR_LATER(_ah) \
770 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
771
772#define AR_RADIO_SREV_MAJOR 0xf0
773#define AR_RAD5133_SREV_MAJOR 0xc0
774#define AR_RAD2133_SREV_MAJOR 0xd0
775#define AR_RAD5122_SREV_MAJOR 0xe0
776#define AR_RAD2122_SREV_MAJOR 0xf0
777
778#define AR_AHB_MODE 0x4024
779#define AR_AHB_EXACT_WR_EN 0x00000000
780#define AR_AHB_BUF_WR_EN 0x00000001
781#define AR_AHB_EXACT_RD_EN 0x00000000
782#define AR_AHB_CACHELINE_RD_EN 0x00000002
783#define AR_AHB_PREFETCH_RD_EN 0x00000004
784#define AR_AHB_PAGE_SIZE_1K 0x00000000
785#define AR_AHB_PAGE_SIZE_2K 0x00000008
786#define AR_AHB_PAGE_SIZE_4K 0x00000010
787
788#define AR_INTR_RTC_IRQ 0x00000001
789#define AR_INTR_MAC_IRQ 0x00000002
790#define AR_INTR_EEP_PROT_ACCESS 0x00000004
791#define AR_INTR_MAC_AWAKE 0x00020000
792#define AR_INTR_MAC_ASLEEP 0x00040000
793#define AR_INTR_SPURIOUS 0xFFFFFFFF
794
795
796#define AR_INTR_SYNC_CAUSE_CLR 0x4028
797
798#define AR_INTR_SYNC_CAUSE 0x4028
799
800#define AR_INTR_SYNC_ENABLE 0x402c
801#define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000
802#define AR_INTR_SYNC_ENABLE_GPIO_S 18
803
804enum {
805 AR_INTR_SYNC_RTC_IRQ = 0x00000001,
806 AR_INTR_SYNC_MAC_IRQ = 0x00000002,
807 AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS = 0x00000004,
808 AR_INTR_SYNC_APB_TIMEOUT = 0x00000008,
809 AR_INTR_SYNC_PCI_MODE_CONFLICT = 0x00000010,
810 AR_INTR_SYNC_HOST1_FATAL = 0x00000020,
811 AR_INTR_SYNC_HOST1_PERR = 0x00000040,
812 AR_INTR_SYNC_TRCV_FIFO_PERR = 0x00000080,
813 AR_INTR_SYNC_RADM_CPL_EP = 0x00000100,
814 AR_INTR_SYNC_RADM_CPL_DLLP_ABORT = 0x00000200,
815 AR_INTR_SYNC_RADM_CPL_TLP_ABORT = 0x00000400,
816 AR_INTR_SYNC_RADM_CPL_ECRC_ERR = 0x00000800,
817 AR_INTR_SYNC_RADM_CPL_TIMEOUT = 0x00001000,
818 AR_INTR_SYNC_LOCAL_TIMEOUT = 0x00002000,
819 AR_INTR_SYNC_PM_ACCESS = 0x00004000,
820 AR_INTR_SYNC_MAC_AWAKE = 0x00008000,
821 AR_INTR_SYNC_MAC_ASLEEP = 0x00010000,
822 AR_INTR_SYNC_MAC_SLEEP_ACCESS = 0x00020000,
823 AR_INTR_SYNC_ALL = 0x0003FFFF,
824
825
826 AR_INTR_SYNC_DEFAULT = (AR_INTR_SYNC_HOST1_FATAL |
827 AR_INTR_SYNC_HOST1_PERR |
828 AR_INTR_SYNC_RADM_CPL_EP |
829 AR_INTR_SYNC_RADM_CPL_DLLP_ABORT |
830 AR_INTR_SYNC_RADM_CPL_TLP_ABORT |
831 AR_INTR_SYNC_RADM_CPL_ECRC_ERR |
832 AR_INTR_SYNC_RADM_CPL_TIMEOUT |
833 AR_INTR_SYNC_LOCAL_TIMEOUT |
834 AR_INTR_SYNC_MAC_SLEEP_ACCESS),
835
836 AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
837
838};
839
840#define AR_INTR_ASYNC_MASK 0x4030
841#define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000
842#define AR_INTR_ASYNC_MASK_GPIO_S 18
843
844#define AR_INTR_SYNC_MASK 0x4034
845#define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000
846#define AR_INTR_SYNC_MASK_GPIO_S 18
847
848#define AR_INTR_ASYNC_CAUSE_CLR 0x4038
849#define AR_INTR_ASYNC_CAUSE 0x4038
850
851#define AR_INTR_ASYNC_ENABLE 0x403c
852#define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000
853#define AR_INTR_ASYNC_ENABLE_GPIO_S 18
854
855#define AR_PCIE_SERDES 0x4040
856#define AR_PCIE_SERDES2 0x4044
857#define AR_PCIE_PM_CTRL 0x4014
858#define AR_PCIE_PM_CTRL_ENA 0x00080000
859
860#define AR_NUM_GPIO 14
861#define AR928X_NUM_GPIO 10
862
863#define AR_GPIO_IN_OUT 0x4048
864#define AR_GPIO_IN_VAL 0x0FFFC000
865#define AR_GPIO_IN_VAL_S 14
866#define AR928X_GPIO_IN_VAL 0x000FFC00
867#define AR928X_GPIO_IN_VAL_S 10
868
869#define AR_GPIO_OE_OUT 0x404c
870#define AR_GPIO_OE_OUT_DRV 0x3
871#define AR_GPIO_OE_OUT_DRV_NO 0x0
872#define AR_GPIO_OE_OUT_DRV_LOW 0x1
873#define AR_GPIO_OE_OUT_DRV_HI 0x2
874#define AR_GPIO_OE_OUT_DRV_ALL 0x3
875
876#define AR_GPIO_INTR_POL 0x4050
877#define AR_GPIO_INTR_POL_VAL 0x00001FFF
878#define AR_GPIO_INTR_POL_VAL_S 0
879
880#define AR_GPIO_INPUT_EN_VAL 0x4054
881#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080
882#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7
883#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000
884#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15
885#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
886#define AR_GPIO_JTAG_DISABLE 0x00020000
887
888#define AR_GPIO_INPUT_MUX1 0x4058
889
890#define AR_GPIO_INPUT_MUX2 0x405c
891#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
892#define AR_GPIO_INPUT_MUX2_CLK25_S 0
893#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
894#define AR_GPIO_INPUT_MUX2_RFSILENT_S 4
895#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
896#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
897
898#define AR_GPIO_OUTPUT_MUX1 0x4060
899#define AR_GPIO_OUTPUT_MUX2 0x4064
900#define AR_GPIO_OUTPUT_MUX3 0x4068
901
902#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
903#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
904#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
905#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
906#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
907
908#define AR_INPUT_STATE 0x406c
909
910#define AR_EEPROM_STATUS_DATA 0x407c
911#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
912#define AR_EEPROM_STATUS_DATA_VAL_S 0
913#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
914#define AR_EEPROM_STATUS_DATA_BUSY_ACCESS 0x00020000
915#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
916#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
917
918#define AR_OBS 0x4080
919
920#define AR_PCIE_MSI 0x4094
921#define AR_PCIE_MSI_ENABLE 0x00000001
922
923
924#define AR_RTC_9160_PLL_DIV 0x000003ff
925#define AR_RTC_9160_PLL_DIV_S 0
926#define AR_RTC_9160_PLL_REFDIV 0x00003C00
927#define AR_RTC_9160_PLL_REFDIV_S 10
928#define AR_RTC_9160_PLL_CLKSEL 0x0000C000
929#define AR_RTC_9160_PLL_CLKSEL_S 14
930
931#define AR_RTC_BASE 0x00020000
932#define AR_RTC_RC \
933 (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000
934#define AR_RTC_RC_M 0x00000003
935#define AR_RTC_RC_MAC_WARM 0x00000001
936#define AR_RTC_RC_MAC_COLD 0x00000002
937#define AR_RTC_RC_COLD_RESET 0x00000004
938#define AR_RTC_RC_WARM_RESET 0x00000008
939
940#define AR_RTC_PLL_CONTROL \
941 (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014
942
943#define AR_RTC_PLL_DIV 0x0000001f
944#define AR_RTC_PLL_DIV_S 0
945#define AR_RTC_PLL_DIV2 0x00000020
946#define AR_RTC_PLL_REFDIV_5 0x000000c0
947#define AR_RTC_PLL_CLKSEL 0x00000300
948#define AR_RTC_PLL_CLKSEL_S 8
949
950
951
952#define AR_RTC_RESET \
953 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
954#define AR_RTC_RESET_EN (0x00000001)
955
956#define AR_RTC_STATUS \
957 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0044) : 0x7044)
958
959#define AR_RTC_STATUS_M \
960 ((AR_SREV_9100(ah)) ? 0x0000003f : 0x0000000f)
961
962#define AR_RTC_PM_STATUS_M 0x0000000f
963
964#define AR_RTC_STATUS_SHUTDOWN 0x00000001
965#define AR_RTC_STATUS_ON 0x00000002
966#define AR_RTC_STATUS_SLEEP 0x00000004
967#define AR_RTC_STATUS_WAKEUP 0x00000008
968
969#define AR_RTC_SLEEP_CLK \
970 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
971#define AR_RTC_FORCE_DERIVED_CLK 0x2
972
973#define AR_RTC_FORCE_WAKE \
974 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
975#define AR_RTC_FORCE_WAKE_EN 0x00000001
976#define AR_RTC_FORCE_WAKE_ON_INT 0x00000002
977
978
979#define AR_RTC_INTR_CAUSE \
980 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0050) : 0x7050)
981
982#define AR_RTC_INTR_ENABLE \
983 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0054) : 0x7054)
984
985#define AR_RTC_INTR_MASK \
986 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
987
988#define AR_SEQ_MASK 0x8060
989
990#define AR_AN_RF2G1_CH0 0x7810
991#define AR_AN_RF2G1_CH0_OB 0x03800000
992#define AR_AN_RF2G1_CH0_OB_S 23
993#define AR_AN_RF2G1_CH0_DB 0x1C000000
994#define AR_AN_RF2G1_CH0_DB_S 26
995
996#define AR_AN_RF5G1_CH0 0x7818
997#define AR_AN_RF5G1_CH0_OB5 0x00070000
998#define AR_AN_RF5G1_CH0_OB5_S 16
999#define AR_AN_RF5G1_CH0_DB5 0x00380000
1000#define AR_AN_RF5G1_CH0_DB5_S 19
1001
1002#define AR_AN_RF2G1_CH1 0x7834
1003#define AR_AN_RF2G1_CH1_OB 0x03800000
1004#define AR_AN_RF2G1_CH1_OB_S 23
1005#define AR_AN_RF2G1_CH1_DB 0x1C000000
1006#define AR_AN_RF2G1_CH1_DB_S 26
1007
1008#define AR_AN_RF5G1_CH1 0x783C
1009#define AR_AN_RF5G1_CH1_OB5 0x00070000
1010#define AR_AN_RF5G1_CH1_OB5_S 16
1011#define AR_AN_RF5G1_CH1_DB5 0x00380000
1012#define AR_AN_RF5G1_CH1_DB5_S 19
1013
1014#define AR_AN_TOP2 0x7894
1015#define AR_AN_TOP2_XPABIAS_LVL 0xC0000000
1016#define AR_AN_TOP2_XPABIAS_LVL_S 30
1017#define AR_AN_TOP2_LOCALBIAS 0x00200000
1018#define AR_AN_TOP2_LOCALBIAS_S 21
1019#define AR_AN_TOP2_PWDCLKIND 0x00400000
1020#define AR_AN_TOP2_PWDCLKIND_S 22
1021
1022#define AR_AN_SYNTH9 0x7868
1023#define AR_AN_SYNTH9_REFDIVA 0xf8000000
1024#define AR_AN_SYNTH9_REFDIVA_S 27
1025
1026#define AR_STA_ID0 0x8000
1027#define AR_STA_ID1 0x8004
1028#define AR_STA_ID1_SADH_MASK 0x0000FFFF
1029#define AR_STA_ID1_STA_AP 0x00010000
1030#define AR_STA_ID1_ADHOC 0x00020000
1031#define AR_STA_ID1_PWR_SAV 0x00040000
1032#define AR_STA_ID1_KSRCHDIS 0x00080000
1033#define AR_STA_ID1_PCF 0x00100000
1034#define AR_STA_ID1_USE_DEFANT 0x00200000
1035#define AR_STA_ID1_DEFANT_UPDATE 0x00400000
1036#define AR_STA_ID1_RTS_USE_DEF 0x00800000
1037#define AR_STA_ID1_ACKCTS_6MB 0x01000000
1038#define AR_STA_ID1_BASE_RATE_11B 0x02000000
1039#define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000
1040#define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000
1041#define AR_STA_ID1_KSRCH_MODE 0x10000000
1042#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000
1043#define AR_STA_ID1_CBCIV_ENDIAN 0x40000000
1044#define AR_STA_ID1_MCAST_KSRCH 0x80000000
1045
1046#define AR_BSS_ID0 0x8008
1047#define AR_BSS_ID1 0x800C
1048#define AR_BSS_ID1_U16 0x0000FFFF
1049#define AR_BSS_ID1_AID 0x07FF0000
1050#define AR_BSS_ID1_AID_S 16
1051
1052#define AR_BCN_RSSI_AVE 0x8010
1053#define AR_BCN_RSSI_AVE_MASK 0x00000FFF
1054
1055#define AR_TIME_OUT 0x8014
1056#define AR_TIME_OUT_ACK 0x00003FFF
1057#define AR_TIME_OUT_ACK_S 0
1058#define AR_TIME_OUT_CTS 0x3FFF0000
1059#define AR_TIME_OUT_CTS_S 16
1060
1061#define AR_RSSI_THR 0x8018
1062#define AR_RSSI_THR_MASK 0x000000FF
1063#define AR_RSSI_THR_BM_THR 0x0000FF00
1064#define AR_RSSI_THR_BM_THR_S 8
1065#define AR_RSSI_BCN_WEIGHT 0x1F000000
1066#define AR_RSSI_BCN_WEIGHT_S 24
1067#define AR_RSSI_BCN_RSSI_RST 0x20000000
1068
1069#define AR_USEC 0x801c
1070#define AR_USEC_USEC 0x0000007F
1071#define AR_USEC_TX_LAT 0x007FC000
1072#define AR_USEC_TX_LAT_S 14
1073#define AR_USEC_RX_LAT 0x1F800000
1074#define AR_USEC_RX_LAT_S 23
1075
1076#define AR_RESET_TSF 0x8020
1077#define AR_RESET_TSF_ONCE 0x01000000
1078
1079#define AR_MAX_CFP_DUR 0x8038
1080#define AR_CFP_VAL 0x0000FFFF
1081
1082#define AR_RX_FILTER 0x803C
1083#define AR_RX_FILTER_ALL 0x00000000
1084#define AR_RX_UCAST 0x00000001
1085#define AR_RX_MCAST 0x00000002
1086#define AR_RX_BCAST 0x00000004
1087#define AR_RX_CONTROL 0x00000008
1088#define AR_RX_BEACON 0x00000010
1089#define AR_RX_PROM 0x00000020
1090#define AR_RX_PROBE_REQ 0x00000080
1091#define AR_RX_MY_BEACON 0x00000200
1092#define AR_RX_COMPR_BAR 0x00000400
1093#define AR_RX_COMPR_BA 0x00000800
1094#define AR_RX_UNCOM_BA_BAR 0x00001000
1095
1096#define AR_MCAST_FIL0 0x8040
1097#define AR_MCAST_FIL1 0x8044
1098
1099#define AR_DIAG_SW 0x8048
1100#define AR_DIAG_CACHE_ACK 0x00000001
1101#define AR_DIAG_ACK_DIS 0x00000002
1102#define AR_DIAG_CTS_DIS 0x00000004
1103#define AR_DIAG_ENCRYPT_DIS 0x00000008
1104#define AR_DIAG_DECRYPT_DIS 0x00000010
1105#define AR_DIAG_RX_DIS 0x00000020
1106#define AR_DIAG_LOOP_BACK 0x00000040
1107#define AR_DIAG_CORR_FCS 0x00000080
1108#define AR_DIAG_CHAN_INFO 0x00000100
1109#define AR_DIAG_SCRAM_SEED 0x0001FE00
1110#define AR_DIAG_SCRAM_SEED_S 8
1111#define AR_DIAG_FRAME_NV0 0x00020000
1112#define AR_DIAG_OBS_PT_SEL1 0x000C0000
1113#define AR_DIAG_OBS_PT_SEL1_S 18
1114#define AR_DIAG_FORCE_RX_CLEAR 0x00100000
1115#define AR_DIAG_IGNORE_VIRT_CS 0x00200000
1116#define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000
1117#define AR_DIAG_EIFS_CTRL_ENA 0x00800000
1118#define AR_DIAG_DUAL_CHAIN_INFO 0x01000000
1119#define AR_DIAG_RX_ABORT 0x02000000
1120#define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000
1121#define AR_DIAG_OBS_PT_SEL2 0x08000000
1122#define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000
1123#define AR_DIAG_RX_CLEAR_EXT_LOW 0x20000000
1124
1125#define AR_TSF_L32 0x804c
1126#define AR_TSF_U32 0x8050
1127
1128#define AR_TST_ADDAC 0x8054
1129#define AR_DEF_ANTENNA 0x8058
1130
1131#define AR_AES_MUTE_MASK0 0x805c
1132#define AR_AES_MUTE_MASK0_FC 0x0000FFFF
1133#define AR_AES_MUTE_MASK0_QOS 0xFFFF0000
1134#define AR_AES_MUTE_MASK0_QOS_S 16
1135
1136#define AR_AES_MUTE_MASK1 0x8060
1137#define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF
1138
1139#define AR_GATED_CLKS 0x8064
1140#define AR_GATED_CLKS_TX 0x00000002
1141#define AR_GATED_CLKS_RX 0x00000004
1142#define AR_GATED_CLKS_REG 0x00000008
1143
1144#define AR_OBS_BUS_CTRL 0x8068
1145#define AR_OBS_BUS_SEL_1 0x00040000
1146#define AR_OBS_BUS_SEL_2 0x00080000
1147#define AR_OBS_BUS_SEL_3 0x000C0000
1148#define AR_OBS_BUS_SEL_4 0x08040000
1149#define AR_OBS_BUS_SEL_5 0x08080000
1150
1151#define AR_OBS_BUS_1 0x806c
1152#define AR_OBS_BUS_1_PCU 0x00000001
1153#define AR_OBS_BUS_1_RX_END 0x00000002
1154#define AR_OBS_BUS_1_RX_WEP 0x00000004
1155#define AR_OBS_BUS_1_RX_BEACON 0x00000008
1156#define AR_OBS_BUS_1_RX_FILTER 0x00000010
1157#define AR_OBS_BUS_1_TX_HCF 0x00000020
1158#define AR_OBS_BUS_1_QUIET_TIME 0x00000040
1159#define AR_OBS_BUS_1_CHAN_IDLE 0x00000080
1160#define AR_OBS_BUS_1_TX_HOLD 0x00000100
1161#define AR_OBS_BUS_1_TX_FRAME 0x00000200
1162#define AR_OBS_BUS_1_RX_FRAME 0x00000400
1163#define AR_OBS_BUS_1_RX_CLEAR 0x00000800
1164#define AR_OBS_BUS_1_WEP_STATE 0x0003F000
1165#define AR_OBS_BUS_1_WEP_STATE_S 12
1166#define AR_OBS_BUS_1_RX_STATE 0x01F00000
1167#define AR_OBS_BUS_1_RX_STATE_S 20
1168#define AR_OBS_BUS_1_TX_STATE 0x7E000000
1169#define AR_OBS_BUS_1_TX_STATE_S 25
1170
1171#define AR_LAST_TSTP 0x8080
1172#define AR_NAV 0x8084
1173#define AR_RTS_OK 0x8088
1174#define AR_RTS_FAIL 0x808c
1175#define AR_ACK_FAIL 0x8090
1176#define AR_FCS_FAIL 0x8094
1177#define AR_BEACON_CNT 0x8098
1178
1179#define AR_SLEEP1 0x80d4
1180#define AR_SLEEP1_ASSUME_DTIM 0x00080000
1181#define AR_SLEEP1_CAB_TIMEOUT 0xFFE00000
1182#define AR_SLEEP1_CAB_TIMEOUT_S 21
1183
1184#define AR_SLEEP2 0x80d8
1185#define AR_SLEEP2_BEACON_TIMEOUT 0xFFE00000
1186#define AR_SLEEP2_BEACON_TIMEOUT_S 21
1187
1188#define AR_BSSMSKL 0x80e0
1189#define AR_BSSMSKU 0x80e4
1190
1191#define AR_TPC 0x80e8
1192#define AR_TPC_ACK 0x0000003f
1193#define AR_TPC_ACK_S 0x00
1194#define AR_TPC_CTS 0x00003f00
1195#define AR_TPC_CTS_S 0x08
1196#define AR_TPC_CHIRP 0x003f0000
1197#define AR_TPC_CHIRP_S 0x16
1198
1199#define AR_TFCNT 0x80ec
1200#define AR_RFCNT 0x80f0
1201#define AR_RCCNT 0x80f4
1202#define AR_CCCNT 0x80f8
1203
1204#define AR_QUIET1 0x80fc
1205#define AR_QUIET1_NEXT_QUIET_S 0
1206#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff
1207#define AR_QUIET1_QUIET_ENABLE 0x00010000
1208#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000
1209#define AR_QUIET2 0x8100
1210#define AR_QUIET2_QUIET_PERIOD_S 0
1211#define AR_QUIET2_QUIET_PERIOD_M 0x0000ffff
1212#define AR_QUIET2_QUIET_DUR_S 16
1213#define AR_QUIET2_QUIET_DUR 0xffff0000
1214
1215#define AR_TSF_PARM 0x8104
1216#define AR_TSF_INCREMENT_M 0x000000ff
1217#define AR_TSF_INCREMENT_S 0x00
1218
1219#define AR_QOS_NO_ACK 0x8108
1220#define AR_QOS_NO_ACK_TWO_BIT 0x0000000f
1221#define AR_QOS_NO_ACK_TWO_BIT_S 0
1222#define AR_QOS_NO_ACK_BIT_OFF 0x00000070
1223#define AR_QOS_NO_ACK_BIT_OFF_S 4
1224#define AR_QOS_NO_ACK_BYTE_OFF 0x00000180
1225#define AR_QOS_NO_ACK_BYTE_OFF_S 7
1226
1227#define AR_PHY_ERR 0x810c
1228
1229#define AR_PHY_ERR_DCHIRP 0x00000008
1230#define AR_PHY_ERR_RADAR 0x00000020
1231#define AR_PHY_ERR_OFDM_TIMING 0x00020000
1232#define AR_PHY_ERR_CCK_TIMING 0x02000000
1233
1234#define AR_RXFIFO_CFG 0x8114
1235
1236
1237#define AR_MIC_QOS_CONTROL 0x8118
1238#define AR_MIC_QOS_SELECT 0x811c
1239
1240#define AR_PCU_MISC 0x8120
1241#define AR_PCU_FORCE_BSSID_MATCH 0x00000001
1242#define AR_PCU_MIC_NEW_LOC_ENA 0x00000004
1243#define AR_PCU_TX_ADD_TSF 0x00000008
1244#define AR_PCU_CCK_SIFS_MODE 0x00000010
1245#define AR_PCU_RX_ANT_UPDT 0x00000800
1246#define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000
1247#define AR_PCU_MISS_BCN_IN_SLEEP 0x00004000
1248#define AR_PCU_BUG_12306_FIX_ENA 0x00020000
1249#define AR_PCU_FORCE_QUIET_COLL 0x00040000
1250#define AR_PCU_TBTT_PROTECT 0x00200000
1251#define AR_PCU_CLEAR_VMF 0x01000000
1252#define AR_PCU_CLEAR_BA_VALID 0x04000000
1253
1254
1255#define AR_FILT_OFDM 0x8124
1256#define AR_FILT_OFDM_COUNT 0x00FFFFFF
1257
1258#define AR_FILT_CCK 0x8128
1259#define AR_FILT_CCK_COUNT 0x00FFFFFF
1260
1261#define AR_PHY_ERR_1 0x812c
1262#define AR_PHY_ERR_1_COUNT 0x00FFFFFF
1263#define AR_PHY_ERR_MASK_1 0x8130
1264
1265#define AR_PHY_ERR_2 0x8134
1266#define AR_PHY_ERR_2_COUNT 0x00FFFFFF
1267#define AR_PHY_ERR_MASK_2 0x8138
1268
1269#define AR_PHY_COUNTMAX (3 << 22)
1270#define AR_MIBCNT_INTRMASK (3 << 22)
1271
1272#define AR_TSF_THRESHOLD 0x813c
1273#define AR_TSF_THRESHOLD_VAL 0x0000FFFF
1274
1275#define AR_PHY_ERR_EIFS_MASK 8144
1276
1277#define AR_PHY_ERR_3 0x8168
1278#define AR_PHY_ERR_3_COUNT 0x00FFFFFF
1279#define AR_PHY_ERR_MASK_3 0x816c
1280
1281#define AR_TXSIFS 0x81d0
1282#define AR_TXSIFS_TIME 0x000000FF
1283#define AR_TXSIFS_TX_LATENCY 0x00000F00
1284#define AR_TXSIFS_TX_LATENCY_S 8
1285#define AR_TXSIFS_ACK_SHIFT 0x00007000
1286#define AR_TXSIFS_ACK_SHIFT_S 12
1287
1288#define AR_TXOP_X 0x81ec
1289#define AR_TXOP_X_VAL 0x000000FF
1290
1291
1292#define AR_TXOP_0_3 0x81f0
1293#define AR_TXOP_4_7 0x81f4
1294#define AR_TXOP_8_11 0x81f8
1295#define AR_TXOP_12_15 0x81fc
1296
1297
1298#define AR_NEXT_TBTT_TIMER 0x8200
1299#define AR_NEXT_DMA_BEACON_ALERT 0x8204
1300#define AR_NEXT_SWBA 0x8208
1301#define AR_NEXT_CFP 0x8208
1302#define AR_NEXT_HCF 0x820C
1303#define AR_NEXT_TIM 0x8210
1304#define AR_NEXT_DTIM 0x8214
1305#define AR_NEXT_QUIET_TIMER 0x8218
1306#define AR_NEXT_NDP_TIMER 0x821C
1307
1308#define AR_BEACON_PERIOD 0x8220
1309#define AR_DMA_BEACON_PERIOD 0x8224
1310#define AR_SWBA_PERIOD 0x8228
1311#define AR_HCF_PERIOD 0x822C
1312#define AR_TIM_PERIOD 0x8230
1313#define AR_DTIM_PERIOD 0x8234
1314#define AR_QUIET_PERIOD 0x8238
1315#define AR_NDP_PERIOD 0x823C
1316
1317#define AR_TIMER_MODE 0x8240
1318#define AR_TBTT_TIMER_EN 0x00000001
1319#define AR_DBA_TIMER_EN 0x00000002
1320#define AR_SWBA_TIMER_EN 0x00000004
1321#define AR_HCF_TIMER_EN 0x00000008
1322#define AR_TIM_TIMER_EN 0x00000010
1323#define AR_DTIM_TIMER_EN 0x00000020
1324#define AR_QUIET_TIMER_EN 0x00000040
1325#define AR_NDP_TIMER_EN 0x00000080
1326#define AR_TIMER_OVERFLOW_INDEX 0x00000700
1327#define AR_TIMER_OVERFLOW_INDEX_S 8
1328#define AR_TIMER_THRESH 0xFFFFF000
1329#define AR_TIMER_THRESH_S 12
1330
1331#define AR_SLP32_MODE 0x8244
1332#define AR_SLP32_HALF_CLK_LATENCY 0x000FFFFF
1333#define AR_SLP32_ENA 0x00100000
1334#define AR_SLP32_TSF_WRITE_STATUS 0x00200000
1335
1336#define AR_SLP32_WAKE 0x8248
1337#define AR_SLP32_WAKE_XTL_TIME 0x0000FFFF
1338
1339#define AR_SLP32_INC 0x824c
1340#define AR_SLP32_TST_INC 0x000FFFFF
1341
1342#define AR_SLP_CNT 0x8250
1343#define AR_SLP_CYCLE_CNT 0x8254
1344
1345#define AR_SLP_MIB_CTRL 0x8258
1346#define AR_SLP_MIB_CLEAR 0x00000001
1347#define AR_SLP_MIB_PENDING 0x00000002
1348
1349#define AR_2040_MODE 0x8318
1350#define AR_2040_JOINED_RX_CLEAR 0x00000001
1351
1352
1353#define AR_EXTRCCNT 0x8328
1354
1355#define AR_SELFGEN_MASK 0x832c
1356
1357#define AR_PCU_TXBUF_CTRL 0x8340
1358#define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF
1359#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
1360#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
1361
1362#define AR_KEYTABLE_0 0x8800
1363#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
1364#define AR_KEY_CACHE_SIZE 128
1365#define AR_RSVD_KEYTABLE_ENTRIES 4
1366#define AR_KEY_TYPE 0x00000007
1367#define AR_KEYTABLE_TYPE_40 0x00000000
1368#define AR_KEYTABLE_TYPE_104 0x00000001
1369#define AR_KEYTABLE_TYPE_128 0x00000003
1370#define AR_KEYTABLE_TYPE_TKIP 0x00000004
1371#define AR_KEYTABLE_TYPE_AES 0x00000005
1372#define AR_KEYTABLE_TYPE_CCM 0x00000006
1373#define AR_KEYTABLE_TYPE_CLR 0x00000007
1374#define AR_KEYTABLE_ANT 0x00000008
1375#define AR_KEYTABLE_VALID 0x00008000
1376#define AR_KEYTABLE_KEY0(_n) (AR_KEYTABLE(_n) + 0)
1377#define AR_KEYTABLE_KEY1(_n) (AR_KEYTABLE(_n) + 4)
1378#define AR_KEYTABLE_KEY2(_n) (AR_KEYTABLE(_n) + 8)
1379#define AR_KEYTABLE_KEY3(_n) (AR_KEYTABLE(_n) + 12)
1380#define AR_KEYTABLE_KEY4(_n) (AR_KEYTABLE(_n) + 16)
1381#define AR_KEYTABLE_TYPE(_n) (AR_KEYTABLE(_n) + 20)
1382#define AR_KEYTABLE_MAC0(_n) (AR_KEYTABLE(_n) + 24)
1383#define AR_KEYTABLE_MAC1(_n) (AR_KEYTABLE(_n) + 28)
1384
1385#endif
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
new file mode 100644
index 000000000000..62e28887ccd3
--- /dev/null
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -0,0 +1,1026 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/kernel.h>
18#include <linux/slab.h>
19#include "core.h"
20#include "hw.h"
21#include "regd.h"
22#include "regd_common.h"
23
24static int ath9k_regd_chansort(const void *a, const void *b)
25{
26 const struct ath9k_channel *ca = a;
27 const struct ath9k_channel *cb = b;
28
29 return (ca->channel == cb->channel) ?
30 (ca->channelFlags & CHAN_FLAGS) -
31 (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel;
32}
33
34static void
35ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp)
36{
37 u8 *aa = a;
38 u8 *ai, *t;
39
40 for (ai = aa + size; --n >= 1; ai += size)
41 for (t = ai; t > aa; t -= size) {
42 u8 *u = t - size;
43 if (cmp(u, t) <= 0)
44 break;
45 swap(u, t, size);
46 }
47}
48
49static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah)
50{
51 return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG;
52}
53
54static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask)
55{
56 int i;
57
58 for (i = 0; i < BMLEN; i++) {
59 if (bitmask[i] != 0)
60 return false;
61 }
62 return true;
63}
64
65static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
66{
67 u16 rd = ath9k_regd_get_eepromRD(ah);
68 int i;
69
70 if (rd & COUNTRY_ERD_FLAG) {
71 u16 cc = rd & ~COUNTRY_ERD_FLAG;
72 for (i = 0; i < ARRAY_SIZE(allCountries); i++)
73 if (allCountries[i].countryCode == cc)
74 return true;
75 } else {
76 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
77 if (regDomainPairs[i].regDmnEnum == rd)
78 return true;
79 }
80 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
81 "%s: invalid regulatory domain/country code 0x%x\n",
82 __func__, rd);
83 return false;
84}
85
86static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah)
87{
88 u32 regcap;
89
90 regcap = ah->ah_caps.reg_cap;
91
92 if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND)
93 return true;
94 else
95 return false;
96}
97
98static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah,
99 u16 cc)
100{
101 u16 rd;
102 int i;
103
104 if (cc == CTRY_DEFAULT)
105 return true;
106 if (cc == CTRY_DEBUG)
107 return true;
108
109 rd = ath9k_regd_get_eepromRD(ah);
110 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n",
111 __func__, rd);
112
113 if (rd & COUNTRY_ERD_FLAG) {
114 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
115 "%s: EEPROM setting is country code %u\n",
116 __func__, rd & ~COUNTRY_ERD_FLAG);
117 return cc == (rd & ~COUNTRY_ERD_FLAG);
118 }
119
120 for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
121 if (cc == allCountries[i].countryCode) {
122#ifdef AH_SUPPORT_11D
123 if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)
124 return true;
125#endif
126 if (allCountries[i].regDmnEnum == rd ||
127 rd == DEBUG_REG_DMN || rd == NO_ENUMRD)
128 return true;
129 }
130 }
131 return false;
132}
133
134static void
135ath9k_regd_get_wmodes_nreg(struct ath_hal *ah,
136 struct country_code_to_enum_rd *country,
137 struct regDomain *rd5GHz,
138 unsigned long *modes_allowed)
139{
140 bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX);
141
142 if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) &&
143 (!country->allow11g))
144 clear_bit(ATH9K_MODE_11G, modes_allowed);
145
146 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) &&
147 (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
148 clear_bit(ATH9K_MODE_11A, modes_allowed);
149
150 if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes)
151 && (!country->allow11ng20))
152 clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed);
153
154 if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes)
155 && (!country->allow11na20))
156 clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed);
157
158 if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) &&
159 (!country->allow11ng40))
160 clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed);
161
162 if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) &&
163 (!country->allow11ng40))
164 clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed);
165
166 if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) &&
167 (!country->allow11na40))
168 clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed);
169
170 if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) &&
171 (!country->allow11na40))
172 clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed);
173}
174
175bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah)
176{
177 u16 rd;
178
179 rd = ath9k_regd_get_eepromRD(ah);
180
181 switch (rd) {
182 case FCC4_FCCA:
183 case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG):
184 return true;
185 case DEBUG_REG_DMN:
186 case NO_ENUMRD:
187 if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49)
188 return true;
189 break;
190 }
191 return false;
192}
193
194static struct country_code_to_enum_rd*
195ath9k_regd_find_country(u16 countryCode)
196{
197 int i;
198
199 for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
200 if (allCountries[i].countryCode == countryCode)
201 return &allCountries[i];
202 }
203 return NULL;
204}
205
206static u16 ath9k_regd_get_default_country(struct ath_hal *ah)
207{
208 u16 rd;
209 int i;
210
211 rd = ath9k_regd_get_eepromRD(ah);
212 if (rd & COUNTRY_ERD_FLAG) {
213 struct country_code_to_enum_rd *country = NULL;
214 u16 cc = rd & ~COUNTRY_ERD_FLAG;
215
216 country = ath9k_regd_find_country(cc);
217 if (country != NULL)
218 return cc;
219 }
220
221 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
222 if (regDomainPairs[i].regDmnEnum == rd) {
223 if (regDomainPairs[i].singleCC != 0)
224 return regDomainPairs[i].singleCC;
225 else
226 i = ARRAY_SIZE(regDomainPairs);
227 }
228 return CTRY_DEFAULT;
229}
230
231static bool ath9k_regd_is_valid_reg_domain(int regDmn,
232 struct regDomain *rd)
233{
234 int i;
235
236 for (i = 0; i < ARRAY_SIZE(regDomains); i++) {
237 if (regDomains[i].regDmnEnum == regDmn) {
238 if (rd != NULL) {
239 memcpy(rd, &regDomains[i],
240 sizeof(struct regDomain));
241 }
242 return true;
243 }
244 }
245 return false;
246}
247
248static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair)
249{
250 int i;
251
252 if (regDmnPair == NO_ENUMRD)
253 return false;
254 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
255 if (regDomainPairs[i].regDmnEnum == regDmnPair)
256 return true;
257 }
258 return false;
259}
260
261static bool
262ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
263 u16 channelFlag, struct regDomain *rd)
264{
265 int i, found;
266 u64 flags = NO_REQ;
267 struct reg_dmn_pair_mapping *regPair = NULL;
268 int regOrg;
269
270 regOrg = regDmn;
271 if (regDmn == CTRY_DEFAULT) {
272 u16 rdnum;
273 rdnum = ath9k_regd_get_eepromRD(ah);
274
275 if (!(rdnum & COUNTRY_ERD_FLAG)) {
276 if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) ||
277 ath9k_regd_is_valid_reg_domainPair(rdnum)) {
278 regDmn = rdnum;
279 }
280 }
281 }
282
283 if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
284 for (i = 0, found = 0;
285 (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
286 if (regDomainPairs[i].regDmnEnum == regDmn) {
287 regPair = &regDomainPairs[i];
288 found = 1;
289 }
290 }
291 if (!found) {
292 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
293 "%s: Failed to find reg domain pair %u\n",
294 __func__, regDmn);
295 return false;
296 }
297 if (!(channelFlag & CHANNEL_2GHZ)) {
298 regDmn = regPair->regDmn5GHz;
299 flags = regPair->flags5GHz;
300 }
301 if (channelFlag & CHANNEL_2GHZ) {
302 regDmn = regPair->regDmn2GHz;
303 flags = regPair->flags2GHz;
304 }
305 }
306
307 found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
308 if (!found) {
309 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
310 "%s: Failed to find unitary reg domain %u\n",
311 __func__, regDmn);
312 return false;
313 } else {
314 rd->pscan &= regPair->pscanMask;
315 if (((regOrg & MULTI_DOMAIN_MASK) == 0) &&
316 (flags != NO_REQ)) {
317 rd->flags = flags;
318 }
319
320 rd->flags &= (channelFlag & CHANNEL_2GHZ) ?
321 REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK;
322 return true;
323 }
324}
325
326static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask)
327{
328 int byteOffset, bitnum;
329 u64 val;
330
331 byteOffset = bit / 64;
332 bitnum = bit - byteOffset * 64;
333 val = ((u64) 1) << bitnum;
334 if (bitmask[byteOffset] & val)
335 return true;
336 else
337 return false;
338}
339
340static void
341ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids,
342 u32 *nregids, u8 regclassid)
343{
344 int i;
345
346 if (regclassid == 0)
347 return;
348
349 for (i = 0; i < maxregids; i++) {
350 if (regclassids[i] == regclassid)
351 return;
352 if (regclassids[i] == 0)
353 break;
354 }
355
356 if (i == maxregids)
357 return;
358 else {
359 regclassids[i] = regclassid;
360 *nregids += 1;
361 }
362
363 return;
364}
365
366static bool
367ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah,
368 enum reg_ext_bitmap bit)
369{
370 return (ah->ah_currentRDExt & (1 << bit)) ? true : false;
371}
372
373#ifdef ATH_NF_PER_CHAN
374
375static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans,
376 int nchans)
377{
378 int i, j, next;
379
380 for (next = 0; next < nchans; next++) {
381 for (i = 0; i < NUM_NF_READINGS; i++) {
382 ichans[next].nfCalHist[i].currIndex = 0;
383 ichans[next].nfCalHist[i].privNF =
384 AR_PHY_CCA_MAX_GOOD_VALUE;
385 ichans[next].nfCalHist[i].invalidNFcount =
386 AR_PHY_CCA_FILTERWINDOW_LENGTH;
387 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
388 ichans[next].nfCalHist[i].nfCalBuffer[j] =
389 AR_PHY_CCA_MAX_GOOD_VALUE;
390 }
391 }
392 }
393}
394#endif
395
396static int ath9k_regd_is_chan_present(struct ath_hal *ah,
397 u16 c)
398{
399 int i;
400
401 for (i = 0; i < 150; i++) {
402 if (!ah->ah_channels[i].channel)
403 return -1;
404 else if (ah->ah_channels[i].channel == c)
405 return i;
406 }
407
408 return -1;
409}
410
411static bool
412ath9k_regd_add_channel(struct ath_hal *ah,
413 u16 c,
414 u16 c_lo,
415 u16 c_hi,
416 u16 maxChan,
417 u8 ctl,
418 int pos,
419 struct regDomain rd5GHz,
420 struct RegDmnFreqBand *fband,
421 struct regDomain *rd,
422 const struct cmode *cm,
423 struct ath9k_channel *ichans,
424 bool enableExtendedChannels)
425{
426 struct ath9k_channel *chan;
427 int ret;
428 u32 channelFlags = 0;
429 u8 privFlags = 0;
430
431 if (!(c_lo <= c && c <= c_hi)) {
432 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
433 "%s: c %u out of range [%u..%u]\n",
434 __func__, c, c_lo, c_hi);
435 return false;
436 }
437 if ((fband->channelBW == CHANNEL_HALF_BW) &&
438 !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) {
439 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
440 "%s: Skipping %u half rate channel\n",
441 __func__, c);
442 return false;
443 }
444
445 if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
446 !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) {
447 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
448 "%s: Skipping %u quarter rate channel\n",
449 __func__, c);
450 return false;
451 }
452
453 if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
454 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
455 "%s: c %u > maxChan %u\n",
456 __func__, c, maxChan);
457 return false;
458 }
459
460 if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) {
461 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
462 "Skipping ecm channel\n");
463 return false;
464 }
465
466 if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == ATH9K_M_HOSTAP)) {
467 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
468 "Skipping HOSTAP channel\n");
469 return false;
470 }
471
472 if (IS_HT40_MODE(cm->mode) &&
473 !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) &&
474 (fband->useDfs) &&
475 (rd->conformanceTestLimit != MKK)) {
476 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
477 "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n");
478 return false;
479 }
480
481 if (IS_HT40_MODE(cm->mode) &&
482 !(ath9k_regd_get_eeprom_reg_ext_bits(ah,
483 REG_EXT_JAPAN_NONDFS_HT40)) &&
484 !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) {
485 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
486 "Skipping HT40 channel (en_jap_ht40 = 0)\n");
487 return false;
488 }
489
490 if (IS_HT40_MODE(cm->mode) &&
491 !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) &&
492 (fband->useDfs) &&
493 (rd->conformanceTestLimit == MKK)) {
494 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
495 "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n");
496 return false;
497 }
498
499 /* Calculate channel flags */
500
501 channelFlags = cm->flags;
502
503 switch (fband->channelBW) {
504 case CHANNEL_HALF_BW:
505 channelFlags |= CHANNEL_HALF;
506 break;
507 case CHANNEL_QUARTER_BW:
508 channelFlags |= CHANNEL_QUARTER;
509 break;
510 }
511
512 if (fband->usePassScan & rd->pscan)
513 channelFlags |= CHANNEL_PASSIVE;
514 else
515 channelFlags &= ~CHANNEL_PASSIVE;
516 if (fband->useDfs & rd->dfsMask)
517 privFlags = CHANNEL_DFS;
518 else
519 privFlags = 0;
520 if (rd->flags & LIMIT_FRAME_4MS)
521 privFlags |= CHANNEL_4MS_LIMIT;
522 if (privFlags & CHANNEL_DFS)
523 privFlags |= CHANNEL_DISALLOW_ADHOC;
524 if (rd->flags & ADHOC_PER_11D)
525 privFlags |= CHANNEL_PER_11D_ADHOC;
526
527 if (channelFlags & CHANNEL_PASSIVE) {
528 if ((c < 2412) || (c > 2462)) {
529 if (rd5GHz.regDmnEnum == MKK1 ||
530 rd5GHz.regDmnEnum == MKK2) {
531 u32 regcap = ah->ah_caps.reg_cap;
532 if (!(regcap &
533 (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
534 AR_EEPROM_EEREGCAP_EN_KK_U2 |
535 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
536 isUNII1OddChan(c)) {
537 channelFlags &= ~CHANNEL_PASSIVE;
538 } else {
539 privFlags |= CHANNEL_DISALLOW_ADHOC;
540 }
541 } else {
542 privFlags |= CHANNEL_DISALLOW_ADHOC;
543 }
544 }
545 }
546
547 if ((cm->mode == ATH9K_MODE_11A) ||
548 (cm->mode == ATH9K_MODE_11NA_HT20) ||
549 (cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
550 (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) {
551 if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
552 privFlags |= CHANNEL_DISALLOW_ADHOC;
553 }
554
555 /* Fill in channel details */
556
557 ret = ath9k_regd_is_chan_present(ah, c);
558 if (ret == -1) {
559 chan = &ah->ah_channels[pos];
560 chan->channel = c;
561 chan->maxRegTxPower = fband->powerDfs;
562 chan->antennaMax = fband->antennaMax;
563 chan->regDmnFlags = rd->flags;
564 chan->maxTxPower = AR5416_MAX_RATE_POWER;
565 chan->minTxPower = AR5416_MAX_RATE_POWER;
566 chan->channelFlags = channelFlags;
567 chan->privFlags = privFlags;
568 } else {
569 chan = &ah->ah_channels[ret];
570 chan->channelFlags |= channelFlags;
571 chan->privFlags |= privFlags;
572 }
573
574 /* Set CTLs */
575
576 if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
577 chan->conformanceTestLimit[0] = ctl;
578 else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
579 chan->conformanceTestLimit[1] = ctl;
580 else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
581 chan->conformanceTestLimit[2] = ctl;
582
583 return (ret == -1) ? true : false;
584}
585
586static bool ath9k_regd_japan_check(struct ath_hal *ah,
587 int b,
588 struct regDomain *rd5GHz)
589{
590 bool skipband = false;
591 int i;
592 u32 regcap;
593
594 for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) {
595 if (j_bandcheck[i].freqbandbit == b) {
596 regcap = ah->ah_caps.reg_cap;
597 if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) {
598 skipband = true;
599 } else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) ||
600 (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) {
601 rd5GHz->dfsMask |= DFS_MKK4;
602 rd5GHz->pscan |= PSCAN_MKK3;
603 }
604 break;
605 }
606 }
607
608 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
609 "%s: Skipping %d freq band\n",
610 __func__, j_bandcheck[i].freqbandbit);
611
612 return skipband;
613}
614
615bool
616ath9k_regd_init_channels(struct ath_hal *ah,
617 u32 maxchans,
618 u32 *nchans, u8 *regclassids,
619 u32 maxregids, u32 *nregids, u16 cc,
620 bool enableOutdoor,
621 bool enableExtendedChannels)
622{
623 u16 maxChan = 7000;
624 struct country_code_to_enum_rd *country = NULL;
625 struct regDomain rd5GHz, rd2GHz;
626 const struct cmode *cm;
627 struct ath9k_channel *ichans = &ah->ah_channels[0];
628 int next = 0, b;
629 u8 ctl;
630 int regdmn;
631 u16 chanSep;
632 unsigned long *modes_avail;
633 DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX);
634
635 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u %s %s\n",
636 __func__, cc,
637 enableOutdoor ? "Enable outdoor" : "",
638 enableExtendedChannels ? "Enable ecm" : "");
639
640 if (!ath9k_regd_is_ccode_valid(ah, cc)) {
641 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
642 "%s: invalid country code %d\n", __func__, cc);
643 return false;
644 }
645
646 if (!ath9k_regd_is_eeprom_valid(ah)) {
647 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
648 "%s: invalid EEPROM contents\n", __func__);
649 return false;
650 }
651
652 ah->ah_countryCode = ath9k_regd_get_default_country(ah);
653
654 if (ah->ah_countryCode == CTRY_DEFAULT) {
655 ah->ah_countryCode = cc & COUNTRY_CODE_MASK;
656 if ((ah->ah_countryCode == CTRY_DEFAULT) &&
657 (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) {
658 ah->ah_countryCode = CTRY_UNITED_STATES;
659 }
660 }
661
662#ifdef AH_SUPPORT_11D
663 if (ah->ah_countryCode == CTRY_DEFAULT) {
664 regdmn = ath9k_regd_get_eepromRD(ah);
665 country = NULL;
666 } else {
667#endif
668 country = ath9k_regd_find_country(ah->ah_countryCode);
669 if (country == NULL) {
670 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
671 "Country is NULL!!!!, cc= %d\n",
672 ah->ah_countryCode);
673 return false;
674 } else {
675 regdmn = country->regDmnEnum;
676#ifdef AH_SUPPORT_11D
677 if (((ath9k_regd_get_eepromRD(ah) &
678 WORLD_SKU_MASK) == WORLD_SKU_PREFIX) &&
679 (cc == CTRY_UNITED_STATES)) {
680 if (!isWwrSKU_NoMidband(ah)
681 && ath9k_regd_is_fcc_midband_supported(ah))
682 regdmn = FCC3_FCCA;
683 else
684 regdmn = FCC1_FCCA;
685 }
686#endif
687 }
688#ifdef AH_SUPPORT_11D
689 }
690#endif
691 if (!ath9k_regd_get_wmode_regdomain(ah,
692 regdmn,
693 ~CHANNEL_2GHZ,
694 &rd5GHz)) {
695 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
696 "%s: couldn't find unitary "
697 "5GHz reg domain for country %u\n",
698 __func__, ah->ah_countryCode);
699 return false;
700 }
701 if (!ath9k_regd_get_wmode_regdomain(ah,
702 regdmn,
703 CHANNEL_2GHZ,
704 &rd2GHz)) {
705 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
706 "%s: couldn't find unitary 2GHz "
707 "reg domain for country %u\n",
708 __func__, ah->ah_countryCode);
709 return false;
710 }
711
712 if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) ||
713 (rd5GHz.regDmnEnum == FCC2))) {
714 if (ath9k_regd_is_fcc_midband_supported(ah)) {
715 if (!ath9k_regd_get_wmode_regdomain(ah,
716 FCC3_FCCA,
717 ~CHANNEL_2GHZ,
718 &rd5GHz)) {
719 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
720 "%s: couldn't find unitary 5GHz "
721 "reg domain for country %u\n",
722 __func__, ah->ah_countryCode);
723 return false;
724 }
725 }
726 }
727
728 if (country == NULL) {
729 modes_avail = ah->ah_caps.wireless_modes;
730 } else {
731 ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed);
732 modes_avail = modes_allowed;
733
734 if (!enableOutdoor)
735 maxChan = country->outdoorChanStart;
736 }
737
738 next = 0;
739
740 if (maxchans > ARRAY_SIZE(ah->ah_channels))
741 maxchans = ARRAY_SIZE(ah->ah_channels);
742
743 for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
744 u16 c, c_hi, c_lo;
745 u64 *channelBM = NULL;
746 struct regDomain *rd = NULL;
747 struct RegDmnFreqBand *fband = NULL, *freqs;
748 int8_t low_adj = 0, hi_adj = 0;
749
750 if (!test_bit(cm->mode, modes_avail)) {
751 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
752 "%s: !avail mode %d flags 0x%x\n",
753 __func__, cm->mode, cm->flags);
754 continue;
755 }
756 if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
757 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
758 "%s: channels 0x%x not supported "
759 "by hardware\n",
760 __func__, cm->flags);
761 continue;
762 }
763
764 switch (cm->mode) {
765 case ATH9K_MODE_11A:
766 case ATH9K_MODE_11NA_HT20:
767 case ATH9K_MODE_11NA_HT40PLUS:
768 case ATH9K_MODE_11NA_HT40MINUS:
769 rd = &rd5GHz;
770 channelBM = rd->chan11a;
771 freqs = &regDmn5GhzFreq[0];
772 ctl = rd->conformanceTestLimit;
773 break;
774 case ATH9K_MODE_11B:
775 rd = &rd2GHz;
776 channelBM = rd->chan11b;
777 freqs = &regDmn2GhzFreq[0];
778 ctl = rd->conformanceTestLimit | CTL_11B;
779 break;
780 case ATH9K_MODE_11G:
781 case ATH9K_MODE_11NG_HT20:
782 case ATH9K_MODE_11NG_HT40PLUS:
783 case ATH9K_MODE_11NG_HT40MINUS:
784 rd = &rd2GHz;
785 channelBM = rd->chan11g;
786 freqs = &regDmn2Ghz11gFreq[0];
787 ctl = rd->conformanceTestLimit | CTL_11G;
788 break;
789 default:
790 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
791 "%s: Unknown HAL mode 0x%x\n", __func__,
792 cm->mode);
793 continue;
794 }
795
796 if (ath9k_regd_is_chan_bm_zero(channelBM))
797 continue;
798
799 if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
800 (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) {
801 hi_adj = -20;
802 }
803
804 if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) ||
805 (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) {
806 low_adj = 20;
807 }
808
809 /* XXX: Add a helper here instead */
810 for (b = 0; b < 64 * BMLEN; b++) {
811 if (ath9k_regd_is_bit_set(b, channelBM)) {
812 fband = &freqs[b];
813 if (rd5GHz.regDmnEnum == MKK1
814 || rd5GHz.regDmnEnum == MKK2) {
815 if (ath9k_regd_japan_check(ah,
816 b,
817 &rd5GHz))
818 continue;
819 }
820
821 ath9k_regd_add_reg_classid(regclassids,
822 maxregids,
823 nregids,
824 fband->
825 regClassId);
826
827 if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) {
828 chanSep = 40;
829 if (fband->lowChannel == 5280)
830 low_adj += 20;
831
832 if (fband->lowChannel == 5170)
833 continue;
834 } else
835 chanSep = fband->channelSep;
836
837 for (c = fband->lowChannel + low_adj;
838 ((c <= (fband->highChannel + hi_adj)) &&
839 (c >= (fband->lowChannel + low_adj)));
840 c += chanSep) {
841 if (next >= maxchans) {
842 DPRINTF(ah->ah_sc,
843 ATH_DBG_REGULATORY,
844 "%s: too many channels "
845 "for channel table\n",
846 __func__);
847 goto done;
848 }
849 if (ath9k_regd_add_channel(ah,
850 c, c_lo, c_hi,
851 maxChan, ctl,
852 next,
853 rd5GHz,
854 fband, rd, cm,
855 ichans,
856 enableExtendedChannels))
857 next++;
858 }
859 if (IS_HT40_MODE(cm->mode) &&
860 (fband->lowChannel == 5280)) {
861 low_adj -= 20;
862 }
863 }
864 }
865 }
866done:
867 if (next != 0) {
868 int i;
869
870 if (next > ARRAY_SIZE(ah->ah_channels)) {
871 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
872 "%s: too many channels %u; truncating to %u\n",
873 __func__, next,
874 (int) ARRAY_SIZE(ah->ah_channels));
875 next = ARRAY_SIZE(ah->ah_channels);
876 }
877#ifdef ATH_NF_PER_CHAN
878 ath9k_regd_init_rf_buffer(ichans, next);
879#endif
880 ath9k_regd_sort(ichans, next,
881 sizeof(struct ath9k_channel),
882 ath9k_regd_chansort);
883
884 ah->ah_nchan = next;
885
886 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n");
887 for (i = 0; i < next; i++) {
888 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
889 "chan: %d flags: 0x%x\n",
890 ah->ah_channels[i].channel,
891 ah->ah_channels[i].channelFlags);
892 }
893 }
894 *nchans = next;
895
896 ah->ah_countryCode = ah->ah_countryCode;
897
898 ah->ah_currentRDInUse = regdmn;
899 ah->ah_currentRD5G = rd5GHz.regDmnEnum;
900 ah->ah_currentRD2G = rd2GHz.regDmnEnum;
901 if (country == NULL) {
902 ah->ah_iso[0] = 0;
903 ah->ah_iso[1] = 0;
904 } else {
905 ah->ah_iso[0] = country->isoName[0];
906 ah->ah_iso[1] = country->isoName[1];
907 }
908
909 return next != 0;
910}
911
912struct ath9k_channel*
913ath9k_regd_check_channel(struct ath_hal *ah,
914 const struct ath9k_channel *c)
915{
916 struct ath9k_channel *base, *cc;
917
918 int flags = c->channelFlags & CHAN_FLAGS;
919 int n, lim;
920
921 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
922 "%s: channel %u/0x%x (0x%x) requested\n", __func__,
923 c->channel, c->channelFlags, flags);
924
925 cc = ah->ah_curchan;
926 if (cc != NULL && cc->channel == c->channel &&
927 (cc->channelFlags & CHAN_FLAGS) == flags) {
928 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
929 (cc->privFlags & CHANNEL_DFS))
930 return NULL;
931 else
932 return cc;
933 }
934
935 base = ah->ah_channels;
936 n = ah->ah_nchan;
937
938 for (lim = n; lim != 0; lim >>= 1) {
939 int d;
940 cc = &base[lim >> 1];
941 d = c->channel - cc->channel;
942 if (d == 0) {
943 if ((cc->channelFlags & CHAN_FLAGS) == flags) {
944 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
945 (cc->privFlags & CHANNEL_DFS))
946 return NULL;
947 else
948 return cc;
949 }
950 d = flags - (cc->channelFlags & CHAN_FLAGS);
951 }
952 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
953 "%s: channel %u/0x%x d %d\n", __func__,
954 cc->channel, cc->channelFlags, d);
955 if (d > 0) {
956 base = cc + 1;
957 lim--;
958 }
959 }
960 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: no match for %u/0x%x\n",
961 __func__, c->channel, c->channelFlags);
962 return NULL;
963}
964
965u32
966ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
967 struct ath9k_channel *chan)
968{
969 struct ath9k_channel *ichan = NULL;
970
971 ichan = ath9k_regd_check_channel(ah, chan);
972 if (!ichan)
973 return 0;
974
975 return ichan->antennaMax;
976}
977
978u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
979{
980 u32 ctl = NO_CTL;
981 struct ath9k_channel *ichan;
982
983 if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
984 if (IS_CHAN_B(chan))
985 ctl = SD_NO_CTL | CTL_11B;
986 else if (IS_CHAN_G(chan))
987 ctl = SD_NO_CTL | CTL_11G;
988 else
989 ctl = SD_NO_CTL | CTL_11A;
990 } else {
991 ichan = ath9k_regd_check_channel(ah, chan);
992 if (ichan != NULL) {
993 /* FIXME */
994 if (IS_CHAN_A(ichan))
995 ctl = ichan->conformanceTestLimit[0];
996 else if (IS_CHAN_B(ichan))
997 ctl = ichan->conformanceTestLimit[1];
998 else if (IS_CHAN_G(ichan))
999 ctl = ichan->conformanceTestLimit[2];
1000
1001 if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B)
1002 ctl = (ctl & ~0xf) | CTL_11G;
1003 }
1004 }
1005 return ctl;
1006}
1007
1008void ath9k_regd_get_current_country(struct ath_hal *ah,
1009 struct ath9k_country_entry *ctry)
1010{
1011 u16 rd = ath9k_regd_get_eepromRD(ah);
1012
1013 ctry->isMultidomain = false;
1014 if (rd == CTRY_DEFAULT)
1015 ctry->isMultidomain = true;
1016 else if (!(rd & COUNTRY_ERD_FLAG))
1017 ctry->isMultidomain = isWwrSKU(ah);
1018
1019 ctry->countryCode = ah->ah_countryCode;
1020 ctry->regDmnEnum = ah->ah_currentRD;
1021 ctry->regDmn5G = ah->ah_currentRD5G;
1022 ctry->regDmn2G = ah->ah_currentRD2G;
1023 ctry->iso[0] = ah->ah_iso[0];
1024 ctry->iso[1] = ah->ah_iso[1];
1025 ctry->iso[2] = ah->ah_iso[2];
1026}
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
new file mode 100644
index 000000000000..0ecd344fbd98
--- /dev/null
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -0,0 +1,412 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef REGD_H
18#define REGD_H
19
20#include "ath9k.h"
21
22#define BMLEN 2
23#define BMZERO {(u64) 0, (u64) 0}
24
25#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
26 {((((_fa >= 0) && (_fa < 64)) ? \
27 (((u64) 1) << _fa) : (u64) 0) | \
28 (((_fb >= 0) && (_fb < 64)) ? \
29 (((u64) 1) << _fb) : (u64) 0) | \
30 (((_fc >= 0) && (_fc < 64)) ? \
31 (((u64) 1) << _fc) : (u64) 0) | \
32 (((_fd >= 0) && (_fd < 64)) ? \
33 (((u64) 1) << _fd) : (u64) 0) | \
34 (((_fe >= 0) && (_fe < 64)) ? \
35 (((u64) 1) << _fe) : (u64) 0) | \
36 (((_ff >= 0) && (_ff < 64)) ? \
37 (((u64) 1) << _ff) : (u64) 0) | \
38 (((_fg >= 0) && (_fg < 64)) ? \
39 (((u64) 1) << _fg) : (u64) 0) | \
40 (((_fh >= 0) && (_fh < 64)) ? \
41 (((u64) 1) << _fh) : (u64) 0) | \
42 (((_fi >= 0) && (_fi < 64)) ? \
43 (((u64) 1) << _fi) : (u64) 0) | \
44 (((_fj >= 0) && (_fj < 64)) ? \
45 (((u64) 1) << _fj) : (u64) 0) | \
46 (((_fk >= 0) && (_fk < 64)) ? \
47 (((u64) 1) << _fk) : (u64) 0) | \
48 (((_fl >= 0) && (_fl < 64)) ? \
49 (((u64) 1) << _fl) : (u64) 0) | \
50 ((((_fa > 63) && (_fa < 128)) ? \
51 (((u64) 1) << (_fa - 64)) : (u64) 0) | \
52 (((_fb > 63) && (_fb < 128)) ? \
53 (((u64) 1) << (_fb - 64)) : (u64) 0) | \
54 (((_fc > 63) && (_fc < 128)) ? \
55 (((u64) 1) << (_fc - 64)) : (u64) 0) | \
56 (((_fd > 63) && (_fd < 128)) ? \
57 (((u64) 1) << (_fd - 64)) : (u64) 0) | \
58 (((_fe > 63) && (_fe < 128)) ? \
59 (((u64) 1) << (_fe - 64)) : (u64) 0) | \
60 (((_ff > 63) && (_ff < 128)) ? \
61 (((u64) 1) << (_ff - 64)) : (u64) 0) | \
62 (((_fg > 63) && (_fg < 128)) ? \
63 (((u64) 1) << (_fg - 64)) : (u64) 0) | \
64 (((_fh > 63) && (_fh < 128)) ? \
65 (((u64) 1) << (_fh - 64)) : (u64) 0) | \
66 (((_fi > 63) && (_fi < 128)) ? \
67 (((u64) 1) << (_fi - 64)) : (u64) 0) | \
68 (((_fj > 63) && (_fj < 128)) ? \
69 (((u64) 1) << (_fj - 64)) : (u64) 0) | \
70 (((_fk > 63) && (_fk < 128)) ? \
71 (((u64) 1) << (_fk - 64)) : (u64) 0) | \
72 (((_fl > 63) && (_fl < 128)) ? \
73 (((u64) 1) << (_fl - 64)) : (u64) 0)))}
74
75#define DEF_REGDMN FCC1_FCCA
76#define DEF_DMN_5 FCC1
77#define DEF_DMN_2 FCCA
78#define COUNTRY_ERD_FLAG 0x8000
79#define WORLDWIDE_ROAMING_FLAG 0x4000
80#define SUPER_DOMAIN_MASK 0x0fff
81#define COUNTRY_CODE_MASK 0x3fff
82#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT)
83#define CHANNEL_14 (2484)
84#define IS_11G_CH14(_ch,_cf) \
85 (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
86
87#define NO_PSCAN 0x0ULL
88#define PSCAN_FCC 0x0000000000000001ULL
89#define PSCAN_FCC_T 0x0000000000000002ULL
90#define PSCAN_ETSI 0x0000000000000004ULL
91#define PSCAN_MKK1 0x0000000000000008ULL
92#define PSCAN_MKK2 0x0000000000000010ULL
93#define PSCAN_MKKA 0x0000000000000020ULL
94#define PSCAN_MKKA_G 0x0000000000000040ULL
95#define PSCAN_ETSIA 0x0000000000000080ULL
96#define PSCAN_ETSIB 0x0000000000000100ULL
97#define PSCAN_ETSIC 0x0000000000000200ULL
98#define PSCAN_WWR 0x0000000000000400ULL
99#define PSCAN_MKKA1 0x0000000000000800ULL
100#define PSCAN_MKKA1_G 0x0000000000001000ULL
101#define PSCAN_MKKA2 0x0000000000002000ULL
102#define PSCAN_MKKA2_G 0x0000000000004000ULL
103#define PSCAN_MKK3 0x0000000000008000ULL
104#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
105#define IS_ECM_CHAN 0x8000000000000000ULL
106
107#define isWwrSKU(_ah) \
108 (((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
109 WORLD_SKU_PREFIX) || \
110 (ath9k_regd_get_eepromRD(_ah) == WORLD))
111
112#define isWwrSKU_NoMidband(_ah) \
113 ((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
114 (ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
115 (ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
116
117#define isUNII1OddChan(ch) \
118 ((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
119
120#define IS_HT40_MODE(_mode) \
121 (((_mode == ATH9K_MODE_11NA_HT40PLUS || \
122 _mode == ATH9K_MODE_11NG_HT40PLUS || \
123 _mode == ATH9K_MODE_11NA_HT40MINUS || \
124 _mode == ATH9K_MODE_11NG_HT40MINUS) ? true : false))
125
126#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
127
128#define swap(_a, _b, _size) { \
129 u8 *s = _b; \
130 int i = _size; \
131 do { \
132 u8 tmp = *_a; \
133 *_a++ = *s; \
134 *s++ = tmp; \
135 } while (--i); \
136 _a -= _size; \
137}
138
139
140#define HALF_MAXCHANBW 10
141
142#define MULTI_DOMAIN_MASK 0xFF00
143
144#define WORLD_SKU_MASK 0x00F0
145#define WORLD_SKU_PREFIX 0x0060
146
147#define CHANNEL_HALF_BW 10
148#define CHANNEL_QUARTER_BW 5
149
150typedef int ath_hal_cmp_t(const void *, const void *);
151
152struct reg_dmn_pair_mapping {
153 u16 regDmnEnum;
154 u16 regDmn5GHz;
155 u16 regDmn2GHz;
156 u32 flags5GHz;
157 u32 flags2GHz;
158 u64 pscanMask;
159 u16 singleCC;
160};
161
162struct ccmap {
163 char isoName[3];
164 u16 countryCode;
165};
166
167struct country_code_to_enum_rd {
168 u16 countryCode;
169 u16 regDmnEnum;
170 const char *isoName;
171 const char *name;
172 bool allow11g;
173 bool allow11aTurbo;
174 bool allow11gTurbo;
175 bool allow11ng20;
176 bool allow11ng40;
177 bool allow11na20;
178 bool allow11na40;
179 u16 outdoorChanStart;
180};
181
182struct RegDmnFreqBand {
183 u16 lowChannel;
184 u16 highChannel;
185 u8 powerDfs;
186 u8 antennaMax;
187 u8 channelBW;
188 u8 channelSep;
189 u64 useDfs;
190 u64 usePassScan;
191 u8 regClassId;
192};
193
194struct regDomain {
195 u16 regDmnEnum;
196 u8 conformanceTestLimit;
197 u64 dfsMask;
198 u64 pscan;
199 u32 flags;
200 u64 chan11a[BMLEN];
201 u64 chan11a_turbo[BMLEN];
202 u64 chan11a_dyn_turbo[BMLEN];
203 u64 chan11b[BMLEN];
204 u64 chan11g[BMLEN];
205 u64 chan11g_turbo[BMLEN];
206};
207
208struct cmode {
209 u32 mode;
210 u32 flags;
211};
212
213#define YES true
214#define NO false
215
216struct japan_bandcheck {
217 u16 freqbandbit;
218 u32 eepromflagtocheck;
219};
220
221struct common_mode_power {
222 u16 lchan;
223 u16 hchan;
224 u8 pwrlvl;
225};
226
227enum CountryCode {
228 CTRY_ALBANIA = 8,
229 CTRY_ALGERIA = 12,
230 CTRY_ARGENTINA = 32,
231 CTRY_ARMENIA = 51,
232 CTRY_AUSTRALIA = 36,
233 CTRY_AUSTRIA = 40,
234 CTRY_AZERBAIJAN = 31,
235 CTRY_BAHRAIN = 48,
236 CTRY_BELARUS = 112,
237 CTRY_BELGIUM = 56,
238 CTRY_BELIZE = 84,
239 CTRY_BOLIVIA = 68,
240 CTRY_BOSNIA_HERZ = 70,
241 CTRY_BRAZIL = 76,
242 CTRY_BRUNEI_DARUSSALAM = 96,
243 CTRY_BULGARIA = 100,
244 CTRY_CANADA = 124,
245 CTRY_CHILE = 152,
246 CTRY_CHINA = 156,
247 CTRY_COLOMBIA = 170,
248 CTRY_COSTA_RICA = 188,
249 CTRY_CROATIA = 191,
250 CTRY_CYPRUS = 196,
251 CTRY_CZECH = 203,
252 CTRY_DENMARK = 208,
253 CTRY_DOMINICAN_REPUBLIC = 214,
254 CTRY_ECUADOR = 218,
255 CTRY_EGYPT = 818,
256 CTRY_EL_SALVADOR = 222,
257 CTRY_ESTONIA = 233,
258 CTRY_FAEROE_ISLANDS = 234,
259 CTRY_FINLAND = 246,
260 CTRY_FRANCE = 250,
261 CTRY_GEORGIA = 268,
262 CTRY_GERMANY = 276,
263 CTRY_GREECE = 300,
264 CTRY_GUATEMALA = 320,
265 CTRY_HONDURAS = 340,
266 CTRY_HONG_KONG = 344,
267 CTRY_HUNGARY = 348,
268 CTRY_ICELAND = 352,
269 CTRY_INDIA = 356,
270 CTRY_INDONESIA = 360,
271 CTRY_IRAN = 364,
272 CTRY_IRAQ = 368,
273 CTRY_IRELAND = 372,
274 CTRY_ISRAEL = 376,
275 CTRY_ITALY = 380,
276 CTRY_JAMAICA = 388,
277 CTRY_JAPAN = 392,
278 CTRY_JORDAN = 400,
279 CTRY_KAZAKHSTAN = 398,
280 CTRY_KENYA = 404,
281 CTRY_KOREA_NORTH = 408,
282 CTRY_KOREA_ROC = 410,
283 CTRY_KOREA_ROC2 = 411,
284 CTRY_KOREA_ROC3 = 412,
285 CTRY_KUWAIT = 414,
286 CTRY_LATVIA = 428,
287 CTRY_LEBANON = 422,
288 CTRY_LIBYA = 434,
289 CTRY_LIECHTENSTEIN = 438,
290 CTRY_LITHUANIA = 440,
291 CTRY_LUXEMBOURG = 442,
292 CTRY_MACAU = 446,
293 CTRY_MACEDONIA = 807,
294 CTRY_MALAYSIA = 458,
295 CTRY_MALTA = 470,
296 CTRY_MEXICO = 484,
297 CTRY_MONACO = 492,
298 CTRY_MOROCCO = 504,
299 CTRY_NEPAL = 524,
300 CTRY_NETHERLANDS = 528,
301 CTRY_NETHERLANDS_ANTILLES = 530,
302 CTRY_NEW_ZEALAND = 554,
303 CTRY_NICARAGUA = 558,
304 CTRY_NORWAY = 578,
305 CTRY_OMAN = 512,
306 CTRY_PAKISTAN = 586,
307 CTRY_PANAMA = 591,
308 CTRY_PAPUA_NEW_GUINEA = 598,
309 CTRY_PARAGUAY = 600,
310 CTRY_PERU = 604,
311 CTRY_PHILIPPINES = 608,
312 CTRY_POLAND = 616,
313 CTRY_PORTUGAL = 620,
314 CTRY_PUERTO_RICO = 630,
315 CTRY_QATAR = 634,
316 CTRY_ROMANIA = 642,
317 CTRY_RUSSIA = 643,
318 CTRY_SAUDI_ARABIA = 682,
319 CTRY_SERBIA_MONTENEGRO = 891,
320 CTRY_SINGAPORE = 702,
321 CTRY_SLOVAKIA = 703,
322 CTRY_SLOVENIA = 705,
323 CTRY_SOUTH_AFRICA = 710,
324 CTRY_SPAIN = 724,
325 CTRY_SRI_LANKA = 144,
326 CTRY_SWEDEN = 752,
327 CTRY_SWITZERLAND = 756,
328 CTRY_SYRIA = 760,
329 CTRY_TAIWAN = 158,
330 CTRY_THAILAND = 764,
331 CTRY_TRINIDAD_Y_TOBAGO = 780,
332 CTRY_TUNISIA = 788,
333 CTRY_TURKEY = 792,
334 CTRY_UAE = 784,
335 CTRY_UKRAINE = 804,
336 CTRY_UNITED_KINGDOM = 826,
337 CTRY_UNITED_STATES = 840,
338 CTRY_UNITED_STATES_FCC49 = 842,
339 CTRY_URUGUAY = 858,
340 CTRY_UZBEKISTAN = 860,
341 CTRY_VENEZUELA = 862,
342 CTRY_VIET_NAM = 704,
343 CTRY_YEMEN = 887,
344 CTRY_ZIMBABWE = 716,
345 CTRY_JAPAN1 = 393,
346 CTRY_JAPAN2 = 394,
347 CTRY_JAPAN3 = 395,
348 CTRY_JAPAN4 = 396,
349 CTRY_JAPAN5 = 397,
350 CTRY_JAPAN6 = 4006,
351 CTRY_JAPAN7 = 4007,
352 CTRY_JAPAN8 = 4008,
353 CTRY_JAPAN9 = 4009,
354 CTRY_JAPAN10 = 4010,
355 CTRY_JAPAN11 = 4011,
356 CTRY_JAPAN12 = 4012,
357 CTRY_JAPAN13 = 4013,
358 CTRY_JAPAN14 = 4014,
359 CTRY_JAPAN15 = 4015,
360 CTRY_JAPAN16 = 4016,
361 CTRY_JAPAN17 = 4017,
362 CTRY_JAPAN18 = 4018,
363 CTRY_JAPAN19 = 4019,
364 CTRY_JAPAN20 = 4020,
365 CTRY_JAPAN21 = 4021,
366 CTRY_JAPAN22 = 4022,
367 CTRY_JAPAN23 = 4023,
368 CTRY_JAPAN24 = 4024,
369 CTRY_JAPAN25 = 4025,
370 CTRY_JAPAN26 = 4026,
371 CTRY_JAPAN27 = 4027,
372 CTRY_JAPAN28 = 4028,
373 CTRY_JAPAN29 = 4029,
374 CTRY_JAPAN30 = 4030,
375 CTRY_JAPAN31 = 4031,
376 CTRY_JAPAN32 = 4032,
377 CTRY_JAPAN33 = 4033,
378 CTRY_JAPAN34 = 4034,
379 CTRY_JAPAN35 = 4035,
380 CTRY_JAPAN36 = 4036,
381 CTRY_JAPAN37 = 4037,
382 CTRY_JAPAN38 = 4038,
383 CTRY_JAPAN39 = 4039,
384 CTRY_JAPAN40 = 4040,
385 CTRY_JAPAN41 = 4041,
386 CTRY_JAPAN42 = 4042,
387 CTRY_JAPAN43 = 4043,
388 CTRY_JAPAN44 = 4044,
389 CTRY_JAPAN45 = 4045,
390 CTRY_JAPAN46 = 4046,
391 CTRY_JAPAN47 = 4047,
392 CTRY_JAPAN48 = 4048,
393 CTRY_JAPAN49 = 4049,
394 CTRY_JAPAN50 = 4050,
395 CTRY_JAPAN51 = 4051,
396 CTRY_JAPAN52 = 4052,
397 CTRY_JAPAN53 = 4053,
398 CTRY_JAPAN54 = 4054,
399 CTRY_JAPAN55 = 4055,
400 CTRY_JAPAN56 = 4056,
401 CTRY_JAPAN57 = 4057,
402 CTRY_JAPAN58 = 4058,
403 CTRY_JAPAN59 = 4059,
404 CTRY_AUSTRALIA2 = 5000,
405 CTRY_CANADA2 = 5001,
406 CTRY_BELGIUM2 = 5002
407};
408
409void ath9k_regd_get_current_country(struct ath_hal *ah,
410 struct ath9k_country_entry *ctry);
411
412#endif
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
new file mode 100644
index 000000000000..9112c030b1e8
--- /dev/null
+++ b/drivers/net/wireless/ath9k/regd_common.h
@@ -0,0 +1,1915 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef REGD_COMMON_H
18#define REGD_COMMON_H
19
20enum EnumRd {
21 NO_ENUMRD = 0x00,
22 NULL1_WORLD = 0x03,
23 NULL1_ETSIB = 0x07,
24 NULL1_ETSIC = 0x08,
25 FCC1_FCCA = 0x10,
26 FCC1_WORLD = 0x11,
27 FCC4_FCCA = 0x12,
28 FCC5_FCCA = 0x13,
29 FCC6_FCCA = 0x14,
30
31 FCC2_FCCA = 0x20,
32 FCC2_WORLD = 0x21,
33 FCC2_ETSIC = 0x22,
34 FCC6_WORLD = 0x23,
35 FRANCE_RES = 0x31,
36 FCC3_FCCA = 0x3A,
37 FCC3_WORLD = 0x3B,
38
39 ETSI1_WORLD = 0x37,
40 ETSI3_ETSIA = 0x32,
41 ETSI2_WORLD = 0x35,
42 ETSI3_WORLD = 0x36,
43 ETSI4_WORLD = 0x30,
44 ETSI4_ETSIC = 0x38,
45 ETSI5_WORLD = 0x39,
46 ETSI6_WORLD = 0x34,
47 ETSI_RESERVED = 0x33,
48
49 MKK1_MKKA = 0x40,
50 MKK1_MKKB = 0x41,
51 APL4_WORLD = 0x42,
52 MKK2_MKKA = 0x43,
53 APL_RESERVED = 0x44,
54 APL2_WORLD = 0x45,
55 APL2_APLC = 0x46,
56 APL3_WORLD = 0x47,
57 MKK1_FCCA = 0x48,
58 APL2_APLD = 0x49,
59 MKK1_MKKA1 = 0x4A,
60 MKK1_MKKA2 = 0x4B,
61 MKK1_MKKC = 0x4C,
62
63 APL3_FCCA = 0x50,
64 APL1_WORLD = 0x52,
65 APL1_FCCA = 0x53,
66 APL1_APLA = 0x54,
67 APL1_ETSIC = 0x55,
68 APL2_ETSIC = 0x56,
69 APL5_WORLD = 0x58,
70 APL6_WORLD = 0x5B,
71 APL7_FCCA = 0x5C,
72 APL8_WORLD = 0x5D,
73 APL9_WORLD = 0x5E,
74
75 WOR0_WORLD = 0x60,
76 WOR1_WORLD = 0x61,
77 WOR2_WORLD = 0x62,
78 WOR3_WORLD = 0x63,
79 WOR4_WORLD = 0x64,
80 WOR5_ETSIC = 0x65,
81
82 WOR01_WORLD = 0x66,
83 WOR02_WORLD = 0x67,
84 EU1_WORLD = 0x68,
85
86 WOR9_WORLD = 0x69,
87 WORA_WORLD = 0x6A,
88 WORB_WORLD = 0x6B,
89
90 MKK3_MKKB = 0x80,
91 MKK3_MKKA2 = 0x81,
92 MKK3_MKKC = 0x82,
93
94 MKK4_MKKB = 0x83,
95 MKK4_MKKA2 = 0x84,
96 MKK4_MKKC = 0x85,
97
98 MKK5_MKKB = 0x86,
99 MKK5_MKKA2 = 0x87,
100 MKK5_MKKC = 0x88,
101
102 MKK6_MKKB = 0x89,
103 MKK6_MKKA2 = 0x8A,
104 MKK6_MKKC = 0x8B,
105
106 MKK7_MKKB = 0x8C,
107 MKK7_MKKA2 = 0x8D,
108 MKK7_MKKC = 0x8E,
109
110 MKK8_MKKB = 0x8F,
111 MKK8_MKKA2 = 0x90,
112 MKK8_MKKC = 0x91,
113
114 MKK14_MKKA1 = 0x92,
115 MKK15_MKKA1 = 0x93,
116
117 MKK10_FCCA = 0xD0,
118 MKK10_MKKA1 = 0xD1,
119 MKK10_MKKC = 0xD2,
120 MKK10_MKKA2 = 0xD3,
121
122 MKK11_MKKA = 0xD4,
123 MKK11_FCCA = 0xD5,
124 MKK11_MKKA1 = 0xD6,
125 MKK11_MKKC = 0xD7,
126 MKK11_MKKA2 = 0xD8,
127
128 MKK12_MKKA = 0xD9,
129 MKK12_FCCA = 0xDA,
130 MKK12_MKKA1 = 0xDB,
131 MKK12_MKKC = 0xDC,
132 MKK12_MKKA2 = 0xDD,
133
134 MKK13_MKKB = 0xDE,
135
136 MKK3_MKKA = 0xF0,
137 MKK3_MKKA1 = 0xF1,
138 MKK3_FCCA = 0xF2,
139 MKK4_MKKA = 0xF3,
140 MKK4_MKKA1 = 0xF4,
141 MKK4_FCCA = 0xF5,
142 MKK9_MKKA = 0xF6,
143 MKK10_MKKA = 0xF7,
144 MKK6_MKKA1 = 0xF8,
145 MKK6_FCCA = 0xF9,
146 MKK7_MKKA1 = 0xFA,
147 MKK7_FCCA = 0xFB,
148 MKK9_FCCA = 0xFC,
149 MKK9_MKKA1 = 0xFD,
150 MKK9_MKKC = 0xFE,
151 MKK9_MKKA2 = 0xFF,
152
153 APL1 = 0x0150,
154 APL2 = 0x0250,
155 APL3 = 0x0350,
156 APL4 = 0x0450,
157 APL5 = 0x0550,
158 APL6 = 0x0650,
159 APL7 = 0x0750,
160 APL8 = 0x0850,
161 APL9 = 0x0950,
162 APL10 = 0x1050,
163
164 ETSI1 = 0x0130,
165 ETSI2 = 0x0230,
166 ETSI3 = 0x0330,
167 ETSI4 = 0x0430,
168 ETSI5 = 0x0530,
169 ETSI6 = 0x0630,
170 ETSIA = 0x0A30,
171 ETSIB = 0x0B30,
172 ETSIC = 0x0C30,
173
174 FCC1 = 0x0110,
175 FCC2 = 0x0120,
176 FCC3 = 0x0160,
177 FCC4 = 0x0165,
178 FCC5 = 0x0510,
179 FCC6 = 0x0610,
180 FCCA = 0x0A10,
181
182 APLD = 0x0D50,
183
184 MKK1 = 0x0140,
185 MKK2 = 0x0240,
186 MKK3 = 0x0340,
187 MKK4 = 0x0440,
188 MKK5 = 0x0540,
189 MKK6 = 0x0640,
190 MKK7 = 0x0740,
191 MKK8 = 0x0840,
192 MKK9 = 0x0940,
193 MKK10 = 0x0B40,
194 MKK11 = 0x1140,
195 MKK12 = 0x1240,
196 MKK13 = 0x0C40,
197 MKK14 = 0x1440,
198 MKK15 = 0x1540,
199 MKKA = 0x0A40,
200 MKKC = 0x0A50,
201
202 NULL1 = 0x0198,
203 WORLD = 0x0199,
204 DEBUG_REG_DMN = 0x01ff,
205};
206
207enum {
208 FCC = 0x10,
209 MKK = 0x40,
210 ETSI = 0x30,
211};
212
213enum {
214 NO_REQ = 0x00000000,
215 DISALLOW_ADHOC_11A = 0x00000001,
216 DISALLOW_ADHOC_11A_TURB = 0x00000002,
217 NEED_NFC = 0x00000004,
218
219 ADHOC_PER_11D = 0x00000008,
220 ADHOC_NO_11A = 0x00000010,
221
222 PUBLIC_SAFETY_DOMAIN = 0x00000020,
223 LIMIT_FRAME_4MS = 0x00000040,
224
225 NO_HOSTAP = 0x00000080,
226
227 REQ_MASK = 0x000000FF,
228};
229
230#define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \
231 (!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
232#define REG_DOMAIN_5GHZ_MASK REQ_MASK
233
234static struct reg_dmn_pair_mapping regDomainPairs[] = {
235 {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ,
236 PSCAN_DEFER, 0},
237 {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
238 {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
239 {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
240
241 {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
242 {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
243 {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
244 {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
245 {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
246 {FCC4_FCCA, FCC4, FCCA,
247 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
248 0},
249 {FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
250 {FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
251 {FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
252
253 {ETSI1_WORLD, ETSI1, WORLD,
254 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
255 0},
256 {ETSI2_WORLD, ETSI2, WORLD,
257 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
258 0},
259 {ETSI3_WORLD, ETSI3, WORLD,
260 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
261 0},
262 {ETSI4_WORLD, ETSI4, WORLD,
263 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
264 0},
265 {ETSI5_WORLD, ETSI5, WORLD,
266 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
267 0},
268 {ETSI6_WORLD, ETSI6, WORLD,
269 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
270 0},
271
272 {ETSI3_ETSIA, ETSI3, WORLD,
273 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
274 0},
275 {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
276
277 {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
278 {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
279 {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
280 {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
281 {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
282 {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
283 {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
284 {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
285 {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
286 {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
287
288 {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
289 {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
290 {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
291 {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER,},
292
293 {MKK1_MKKA, MKK1, MKKA,
294 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
295 PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN},
296 {MKK1_MKKB, MKK1, MKKA,
297 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
298 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G,
299 CTRY_JAPAN1},
300 {MKK1_FCCA, MKK1, FCCA,
301 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
302 PSCAN_MKK1, CTRY_JAPAN2},
303 {MKK1_MKKA1, MKK1, MKKA,
304 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
305 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4},
306 {MKK1_MKKA2, MKK1, MKKA,
307 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
308 PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5},
309 {MKK1_MKKC, MKK1, MKKC,
310 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
311 PSCAN_MKK1, CTRY_JAPAN6},
312
313 {MKK2_MKKA, MKK2, MKKA,
314 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
315 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G,
316 CTRY_JAPAN3},
317
318 {MKK3_MKKA, MKK3, MKKA,
319 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
320 PSCAN_MKKA, CTRY_JAPAN25},
321 {MKK3_MKKB, MKK3, MKKA,
322 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
323 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G,
324 CTRY_JAPAN7},
325 {MKK3_MKKA1, MKK3, MKKA,
326 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
327 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26},
328 {MKK3_MKKA2, MKK3, MKKA,
329 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
330 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8},
331 {MKK3_MKKC, MKK3, MKKC,
332 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
333 NO_PSCAN, CTRY_JAPAN9},
334 {MKK3_FCCA, MKK3, FCCA,
335 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
336 NO_PSCAN, CTRY_JAPAN27},
337
338 {MKK4_MKKA, MKK4, MKKA,
339 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
340 PSCAN_MKK3, CTRY_JAPAN36},
341 {MKK4_MKKB, MKK4, MKKA,
342 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
343 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
344 CTRY_JAPAN10},
345 {MKK4_MKKA1, MKK4, MKKA,
346 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
347 PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28},
348 {MKK4_MKKA2, MKK4, MKKA,
349 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
350 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11},
351 {MKK4_MKKC, MKK4, MKKC,
352 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
353 PSCAN_MKK3, CTRY_JAPAN12},
354 {MKK4_FCCA, MKK4, FCCA,
355 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
356 PSCAN_MKK3, CTRY_JAPAN29},
357
358 {MKK5_MKKB, MKK5, MKKA,
359 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
360 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
361 CTRY_JAPAN13},
362 {MKK5_MKKA2, MKK5, MKKA,
363 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
364 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14},
365 {MKK5_MKKC, MKK5, MKKC,
366 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
367 PSCAN_MKK3, CTRY_JAPAN15},
368
369 {MKK6_MKKB, MKK6, MKKA,
370 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
371 PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16},
372 {MKK6_MKKA1, MKK6, MKKA,
373 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
374 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30},
375 {MKK6_MKKA2, MKK6, MKKA,
376 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
377 PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17},
378 {MKK6_MKKC, MKK6, MKKC,
379 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
380 PSCAN_MKK1, CTRY_JAPAN18},
381 {MKK6_FCCA, MKK6, FCCA,
382 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
383 NO_PSCAN, CTRY_JAPAN31},
384
385 {MKK7_MKKB, MKK7, MKKA,
386 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
387 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
388 CTRY_JAPAN19},
389 {MKK7_MKKA1, MKK7, MKKA,
390 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
391 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32},
392 {MKK7_MKKA2, MKK7, MKKA,
393 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
394 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
395 CTRY_JAPAN20},
396 {MKK7_MKKC, MKK7, MKKC,
397 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
398 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21},
399 {MKK7_FCCA, MKK7, FCCA,
400 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
401 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33},
402
403 {MKK8_MKKB, MKK8, MKKA,
404 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
405 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
406 CTRY_JAPAN22},
407 {MKK8_MKKA2, MKK8, MKKA,
408 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
409 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
410 CTRY_JAPAN23},
411 {MKK8_MKKC, MKK8, MKKC,
412 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
413 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24},
414
415 {MKK9_MKKA, MKK9, MKKA,
416 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
417 LIMIT_FRAME_4MS, NEED_NFC,
418 PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
419 CTRY_JAPAN34},
420 {MKK9_FCCA, MKK9, FCCA,
421 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
422 NO_PSCAN, CTRY_JAPAN37},
423 {MKK9_MKKA1, MKK9, MKKA,
424 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
425 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38},
426 {MKK9_MKKA2, MKK9, MKKA,
427 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
428 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40},
429 {MKK9_MKKC, MKK9, MKKC,
430 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
431 NO_PSCAN, CTRY_JAPAN39},
432
433 {MKK10_MKKA, MKK10, MKKA,
434 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
435 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35},
436 {MKK10_FCCA, MKK10, FCCA,
437 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
438 NO_PSCAN, CTRY_JAPAN41},
439 {MKK10_MKKA1, MKK10, MKKA,
440 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
441 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42},
442 {MKK10_MKKA2, MKK10, MKKA,
443 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
444 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44},
445 {MKK10_MKKC, MKK10, MKKC,
446 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
447 NO_PSCAN, CTRY_JAPAN43},
448
449 {MKK11_MKKA, MKK11, MKKA,
450 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
451 PSCAN_MKK3, CTRY_JAPAN45},
452 {MKK11_FCCA, MKK11, FCCA,
453 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
454 PSCAN_MKK3, CTRY_JAPAN46},
455 {MKK11_MKKA1, MKK11, MKKA,
456 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
457 PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47},
458 {MKK11_MKKA2, MKK11, MKKA,
459 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
460 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49},
461 {MKK11_MKKC, MKK11, MKKC,
462 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
463 PSCAN_MKK3, CTRY_JAPAN48},
464
465 {MKK12_MKKA, MKK12, MKKA,
466 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
467 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50},
468 {MKK12_FCCA, MKK12, FCCA,
469 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
470 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51},
471 {MKK12_MKKA1, MKK12, MKKA,
472 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
473 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G,
474 CTRY_JAPAN52},
475 {MKK12_MKKA2, MKK12, MKKA,
476 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
477 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
478 CTRY_JAPAN54},
479 {MKK12_MKKC, MKK12, MKKC,
480 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
481 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53},
482
483 {MKK13_MKKB, MKK13, MKKA,
484 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
485 LIMIT_FRAME_4MS, NEED_NFC,
486 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
487 CTRY_JAPAN57},
488
489 {MKK14_MKKA1, MKK14, MKKA,
490 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
491 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58},
492 {MKK15_MKKA1, MKK15, MKKA,
493 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
494 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59},
495
496 {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
497 0},
498 {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD,
499 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
500 0},
501 {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB,
502 NO_REQ, PSCAN_DEFER, 0},
503 {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
504 0},
505 {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD,
506 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
507 0},
508 {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC,
509 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
510 0},
511 {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ,
512 PSCAN_DEFER, 0},
513 {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ,
514 PSCAN_DEFER, 0},
515 {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
516 {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD,
517 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
518 0},
519 {WORA_WORLD, WORA_WORLD, WORA_WORLD,
520 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
521 0},
522 {WORB_WORLD, WORB_WORLD, WORB_WORLD,
523 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
524 0},
525};
526
527#define NO_INTERSECT_REQ 0xFFFFFFFF
528#define NO_UNION_REQ 0
529
530static struct country_code_to_enum_rd allCountries[] = {
531 {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES,
532 YES, YES, 7000},
533 {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES,
534 YES, YES, YES, YES, 7000},
535 {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO,
536 NO, NO, 7000},
537 {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO,
538 NO, NO, 7000},
539 {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES,
540 NO, YES, NO, 7000},
541 {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES,
542 YES, NO, NO, 7000},
543 {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES,
544 YES, YES, YES, 7000},
545 {CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES,
546 YES, YES, YES, YES, 7000},
547 {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES,
548 YES, YES, YES, 7000},
549 {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES,
550 YES, YES, YES, YES, 7000},
551 {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES,
552 YES, NO, 7000},
553 {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES,
554 YES, YES, YES, 7000},
555 {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES,
556 YES, YES, YES, 7000},
557 {CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES,
558 YES, YES, YES, 7000},
559 {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES,
560 YES, YES, 7000},
561 {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES,
562 YES, YES, 7000},
563 {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO,
564 YES, YES, YES, YES, NO, 7000},
565 {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO,
566 YES, NO, 7000},
567 {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM",
568 YES, YES, YES, YES, YES, YES, YES, 7000},
569 {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES,
570 YES, YES, YES, 7000},
571 {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES,
572 YES, YES, 7000},
573 {CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES,
574 YES, YES, 7000},
575 {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES,
576 YES, YES, 7000},
577 {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES,
578 YES, YES, 7000},
579 {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES,
580 YES, YES, NO, 7000},
581 {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES,
582 YES, YES, YES, NO, 7000},
583 {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES,
584 YES, YES, NO, 7000},
585 {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES,
586 YES, YES, 7000},
587 {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES,
588 YES, YES, YES, YES, 7000},
589 {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES,
590 YES, YES, YES, 7000},
591 {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC",
592 YES, YES, YES, YES, YES, YES, YES, 7000},
593 {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES,
594 YES, NO, 7000},
595 {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES,
596 YES, NO, 7000},
597 {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES,
598 YES, YES, YES, NO, 7000},
599 {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES,
600 YES, YES, YES, 7000},
601 {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES,
602 YES, YES, YES, 7000},
603 {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES,
604 YES, YES, 7000},
605 {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES,
606 YES, YES, YES, 7000},
607 {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES,
608 YES, YES, YES, 7000},
609 {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES,
610 YES, YES, 7000},
611 {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES,
612 YES, YES, YES, 7000},
613 {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES,
614 YES, NO, NO, 7000},
615 {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES,
616 YES, YES, YES, 7000},
617 {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES,
618 YES, YES, YES, 7000},
619 {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES,
620 YES, YES, YES, 7000},
621 {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES,
622 YES, NO, 7000},
623 {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES,
624 YES, YES, NO, 7000},
625 {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES,
626 YES, 7000},
627 {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES,
628 YES, YES, YES, 7000},
629 {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES,
630 NO, NO, 7000},
631 {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES,
632 YES, YES, 7000},
633 {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES,
634 YES, YES, YES, 7000},
635
636 {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES,
637 YES, 7000},
638 {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES,
639 YES, YES, 7000},
640 {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES,
641 YES, YES, 7000},
642 {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES,
643 YES, YES, 7000},
644 {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES,
645 YES, YES, 7000},
646 {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES,
647 YES, YES, 7000},
648 {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES,
649 YES, YES, 7000},
650
651 {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES,
652 YES, YES, 7000},
653 {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES,
654 YES, YES, 7000},
655 {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES,
656 YES, YES, 7000},
657
658 {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES,
659 YES, YES, 7000},
660 {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES,
661 YES, YES, 7000},
662 {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES,
663 YES, YES, 7000},
664
665 {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES,
666 YES, YES, 7000},
667 {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES,
668 YES, YES, 7000},
669 {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES,
670 YES, YES, 7000},
671
672 {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES,
673 YES, YES, 7000},
674 {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES,
675 YES, YES, 7000},
676 {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES,
677 YES, YES, 7000},
678
679 {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES,
680 YES, YES, 7000},
681 {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES,
682 YES, YES, 7000},
683 {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES,
684 YES, YES, 7000},
685
686 {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES,
687 YES, YES, 7000},
688 {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES,
689 YES, YES, 7000},
690 {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES,
691 YES, YES, 7000},
692
693 {CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES,
694 YES, YES, 7000},
695 {CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES,
696 YES, YES, 7000},
697 {CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES,
698 YES, YES, 7000},
699 {CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES,
700 YES, YES, 7000},
701 {CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES,
702 YES, YES, 7000},
703 {CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES,
704 YES, YES, 7000},
705 {CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES,
706 YES, YES, 7000},
707 {CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES,
708 YES, YES, 7000},
709 {CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES,
710 YES, YES, 7000},
711 {CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES,
712 YES, YES, 7000},
713 {CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES,
714 YES, YES, 7000},
715 {CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES,
716 YES, YES, 7000},
717 {CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES,
718 YES, YES, 7000},
719 {CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES,
720 YES, YES, 7000},
721 {CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES,
722 YES, YES, 7000},
723 {CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES,
724 YES, YES, 7000},
725 {CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES,
726 YES, YES, 7000},
727 {CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES,
728 YES, YES, 7000},
729 {CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES,
730 YES, YES, 7000},
731 {CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES,
732 YES, YES, 7000},
733 {CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES,
734 YES, YES, 7000},
735 {CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES,
736 YES, YES, 7000},
737 {CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES,
738 YES, YES, 7000},
739 {CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES,
740 YES, YES, 7000},
741 {CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES,
742 YES, YES, 7000},
743 {CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES,
744 YES, YES, 7000},
745 {CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES,
746 YES, YES, 7000},
747 {CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES,
748 YES, YES, 7000},
749 {CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES,
750 YES, YES, 7000},
751 {CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES,
752 YES, YES, 7000},
753
754 {CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES,
755 YES, YES, 7000},
756 {CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES,
757 YES, YES, 7000},
758 {CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES,
759 YES, YES, 7000},
760
761 {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES,
762 YES, NO, 7000},
763 {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES,
764 YES, YES, NO, NO, 7000},
765 {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO,
766 YES, YES, YES, YES, 7000},
767 {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO,
768 YES, NO, YES, NO, 7000},
769 {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO,
770 YES, NO, YES, NO, 7000},
771 {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO,
772 YES, NO, YES, NO, 7000},
773 {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES,
774 NO, NO, 7000},
775 {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES,
776 YES, YES, 7000},
777 {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES,
778 YES, NO, NO, 7000},
779 {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO,
780 YES, YES, YES, YES, YES, 7000},
781 {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES,
782 YES, YES, YES, 7000},
783 {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES,
784 YES, YES, YES, YES, 7000},
785 {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES,
786 YES, YES, 7000},
787 {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES,
788 YES, NO, NO, 7000},
789 {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO,
790 YES, NO, 7000},
791 {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES,
792 YES, YES, 7000},
793 {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES,
794 YES, YES, 7000},
795 {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES,
796 YES, YES, 7000},
797 {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES,
798 YES, NO, NO, 7000},
799 {CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES,
800 YES, YES, 7000},
801 {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES,
802 YES, YES, YES, YES, 7000},
803 {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN",
804 "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000},
805 {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES,
806 YES, YES, YES, NO, 7000},
807 {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES,
808 YES, YES, 7000},
809 {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES,
810 NO, 7000},
811 {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES,
812 YES, NO, NO, 7000},
813 {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES,
814 YES, YES, 7000},
815 {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES,
816 YES, YES, YES, YES, YES, YES, 7000},
817 {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES,
818 NO, 7000},
819 {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES,
820 YES, YES, YES, YES, 7000},
821 {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES,
822 YES, YES, 7000},
823 {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES,
824 YES, YES, YES, 7000},
825 {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES,
826 YES, YES, YES, YES, 7000},
827 {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES,
828 NO, NO, 7000},
829 {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES,
830 YES, NO, NO, 7000},
831 {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES,
832 NO, NO, 7000},
833 {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO,
834 YES, YES, YES, NO, NO, 7000},
835 {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO",
836 YES, NO, YES, YES, YES, YES, YES, 7000},
837 {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES,
838 YES, YES, YES, 7000},
839 {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES,
840 YES, YES, YES, YES, 7000},
841 {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES,
842 YES, YES, YES, 7000},
843 {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES,
844 YES, YES, YES, NO, 7000},
845 {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES,
846 YES, YES, 7000},
847 {CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES,
848 YES, YES, NO, 7000},
849 {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES,
850 YES, YES, 7000},
851 {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES,
852 YES, YES, YES, YES, 7000},
853 {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES,
854 NO, NO, 7000},
855 {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES,
856 YES, YES, 7000},
857 {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES,
858 YES, NO, NO, 7000},
859 {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO",
860 YES, NO, YES, YES, YES, YES, NO, 7000},
861 {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES,
862 YES, YES, NO, 7000},
863 {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES,
864 YES, NO, 7000},
865 {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES,
866 YES, NO, NO, 7000},
867 {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES,
868 YES, YES, NO, NO, 7000},
869 {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO,
870 YES, YES, YES, YES, YES, 7000},
871 {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES,
872 YES, YES, YES, YES, YES, 5825},
873 {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS",
874 "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES,
875 YES, 7000},
876 {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES,
877 YES, NO, 7000},
878 {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES,
879 YES, YES, YES, YES, 7000},
880 {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES,
881 YES, YES, NO, 7000},
882 {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES,
883 YES, NO, NO, 7000},
884 {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES,
885 NO, NO, 7000},
886 {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES,
887 YES, NO, NO, 7000}
888};
889
890enum {
891 NO_DFS = 0x0000000000000000ULL,
892 DFS_FCC3 = 0x0000000000000001ULL,
893 DFS_ETSI = 0x0000000000000002ULL,
894 DFS_MKK4 = 0x0000000000000004ULL,
895};
896
897enum {
898 F1_4915_4925,
899 F1_4935_4945,
900 F1_4920_4980,
901 F1_4942_4987,
902 F1_4945_4985,
903 F1_4950_4980,
904 F1_5035_5040,
905 F1_5040_5080,
906 F1_5055_5055,
907
908 F1_5120_5240,
909
910 F1_5170_5230,
911 F2_5170_5230,
912
913 F1_5180_5240,
914 F2_5180_5240,
915 F3_5180_5240,
916 F4_5180_5240,
917 F5_5180_5240,
918 F6_5180_5240,
919 F7_5180_5240,
920 F8_5180_5240,
921
922 F1_5180_5320,
923
924 F1_5240_5280,
925
926 F1_5260_5280,
927
928 F1_5260_5320,
929 F2_5260_5320,
930 F3_5260_5320,
931 F4_5260_5320,
932 F5_5260_5320,
933 F6_5260_5320,
934
935 F1_5260_5700,
936
937 F1_5280_5320,
938
939 F1_5500_5580,
940
941 F1_5500_5620,
942
943 F1_5500_5700,
944 F2_5500_5700,
945 F3_5500_5700,
946 F4_5500_5700,
947 F5_5500_5700,
948
949 F1_5660_5700,
950
951 F1_5745_5805,
952 F2_5745_5805,
953 F3_5745_5805,
954
955 F1_5745_5825,
956 F2_5745_5825,
957 F3_5745_5825,
958 F4_5745_5825,
959 F5_5745_5825,
960 F6_5745_5825,
961
962 W1_4920_4980,
963 W1_5040_5080,
964 W1_5170_5230,
965 W1_5180_5240,
966 W1_5260_5320,
967 W1_5745_5825,
968 W1_5500_5700,
969 A_DEMO_ALL_CHANNELS
970};
971
972static struct RegDmnFreqBand regDmn5GhzFreq[] = {
973 {4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
974 {4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
975 {4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7},
976 {4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0},
977 {4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0},
978 {4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0},
979 {5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
980 {5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2},
981 {5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
982
983 {5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
984
985 {5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
986 {5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
987
988 {5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
989 {5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1},
990 {5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
991 {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
992 {5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
993 {5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0},
994 {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0},
995 {5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
996
997 {5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
998
999 {5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0},
1000
1001 {5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1002 PSCAN_FCC | PSCAN_ETSI, 0},
1003
1004 {5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1005 PSCAN_FCC | PSCAN_ETSI, 0},
1006
1007 {5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
1008 PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0},
1009
1010
1011 {5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI,
1012 PSCAN_FCC | PSCAN_ETSI, 2},
1013 {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2},
1014 {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
1015 {5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1016
1017 {5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0},
1018
1019 {5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
1020
1021 {5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
1022
1023 {5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
1024
1025 {5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4},
1026 {5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1027 PSCAN_FCC | PSCAN_ETSI, 0},
1028 {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1029 PSCAN_FCC | PSCAN_ETSI, 0},
1030 {5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
1031 PSCAN_MKK3 | PSCAN_FCC, 0},
1032 {5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
1033
1034 {5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
1035
1036 {5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1037 {5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1038 {5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
1039 {5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1040 {5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1041 {5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1042 {5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1043 {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3},
1044 {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1045
1046
1047 {4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1048 {5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1049 {5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1050 {5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1051 {5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
1052 {5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1053 {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
1054 {4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1055};
1056
1057enum {
1058 T1_5130_5650,
1059 T1_5150_5670,
1060
1061 T1_5200_5200,
1062 T2_5200_5200,
1063 T3_5200_5200,
1064 T4_5200_5200,
1065 T5_5200_5200,
1066 T6_5200_5200,
1067 T7_5200_5200,
1068 T8_5200_5200,
1069
1070 T1_5200_5280,
1071 T2_5200_5280,
1072 T3_5200_5280,
1073 T4_5200_5280,
1074 T5_5200_5280,
1075 T6_5200_5280,
1076
1077 T1_5200_5240,
1078 T1_5210_5210,
1079 T2_5210_5210,
1080 T3_5210_5210,
1081 T4_5210_5210,
1082 T5_5210_5210,
1083 T6_5210_5210,
1084 T7_5210_5210,
1085 T8_5210_5210,
1086 T9_5210_5210,
1087 T10_5210_5210,
1088 T1_5240_5240,
1089
1090 T1_5210_5250,
1091 T1_5210_5290,
1092 T2_5210_5290,
1093 T3_5210_5290,
1094
1095 T1_5280_5280,
1096 T2_5280_5280,
1097 T1_5290_5290,
1098 T2_5290_5290,
1099 T3_5290_5290,
1100 T1_5250_5290,
1101 T2_5250_5290,
1102 T3_5250_5290,
1103 T4_5250_5290,
1104
1105 T1_5540_5660,
1106 T2_5540_5660,
1107 T3_5540_5660,
1108 T1_5760_5800,
1109 T2_5760_5800,
1110 T3_5760_5800,
1111 T4_5760_5800,
1112 T5_5760_5800,
1113 T6_5760_5800,
1114 T7_5760_5800,
1115
1116 T1_5765_5805,
1117 T2_5765_5805,
1118 T3_5765_5805,
1119 T4_5765_5805,
1120 T5_5765_5805,
1121 T6_5765_5805,
1122 T7_5765_5805,
1123 T8_5765_5805,
1124 T9_5765_5805,
1125
1126 WT1_5210_5250,
1127 WT1_5290_5290,
1128 WT1_5540_5660,
1129 WT1_5760_5800,
1130};
1131
1132enum {
1133 F1_2312_2372,
1134 F2_2312_2372,
1135
1136 F1_2412_2472,
1137 F2_2412_2472,
1138 F3_2412_2472,
1139
1140 F1_2412_2462,
1141 F2_2412_2462,
1142
1143 F1_2432_2442,
1144
1145 F1_2457_2472,
1146
1147 F1_2467_2472,
1148
1149 F1_2484_2484,
1150 F2_2484_2484,
1151
1152 F1_2512_2732,
1153
1154 W1_2312_2372,
1155 W1_2412_2412,
1156 W1_2417_2432,
1157 W1_2437_2442,
1158 W1_2447_2457,
1159 W1_2462_2462,
1160 W1_2467_2467,
1161 W2_2467_2467,
1162 W1_2472_2472,
1163 W2_2472_2472,
1164 W1_2484_2484,
1165 W2_2484_2484,
1166};
1167
1168static struct RegDmnFreqBand regDmn2GhzFreq[] = {
1169 {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1170 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1171
1172 {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1173 {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
1174 {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1175
1176 {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1177 {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
1178
1179 {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1180
1181 {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1182
1183 {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
1184
1185 {2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1186 {2484, 2484, 20, 0, 20, 5, NO_DFS,
1187 PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
1188
1189 {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1190
1191 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1192 {2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1193 {2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1194 {2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1195 {2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1196 {2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1197 {2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1198 {2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1199 {2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1200 {2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1201 {2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1202 {2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1203};
1204
1205enum {
1206 G1_2312_2372,
1207 G2_2312_2372,
1208
1209 G1_2412_2472,
1210 G2_2412_2472,
1211 G3_2412_2472,
1212
1213 G1_2412_2462,
1214 G2_2412_2462,
1215
1216 G1_2432_2442,
1217
1218 G1_2457_2472,
1219
1220 G1_2512_2732,
1221
1222 G1_2467_2472,
1223
1224 WG1_2312_2372,
1225 WG1_2412_2462,
1226 WG1_2467_2472,
1227 WG2_2467_2472,
1228 G_DEMO_ALL_CHANNELS
1229};
1230
1231static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = {
1232 {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1233 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1234
1235 {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1236 {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
1237 {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1238
1239 {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1240 {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
1241
1242 {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1243
1244 {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1245
1246 {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1247
1248 {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
1249
1250 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1251 {2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1252 {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1253 {2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1254 {2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1255};
1256
1257enum {
1258 T1_2312_2372,
1259 T1_2437_2437,
1260 T2_2437_2437,
1261 T3_2437_2437,
1262 T1_2512_2732
1263};
1264
1265static struct regDomain regDomains[] = {
1266
1267 {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
1268 BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1269 -1),
1270 BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1271 -1),
1272 BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1,
1273 -1, -1, -1, -1, -1, -1),
1274 BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1,
1275 -1, -1, -1, -1, -1, -1),
1276 BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1277 -1),
1278 BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1,
1279 -1, -1, -1, -1)},
1280
1281 {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1282 BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1283 BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1284 BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1285 BMZERO,
1286 BMZERO,
1287 BMZERO},
1288
1289 {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1290 BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1291 BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1292 BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1293 BMZERO,
1294 BMZERO,
1295 BMZERO},
1296
1297 {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1298 BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1299 -1),
1300 BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1301 -1),
1302 BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1303 BMZERO,
1304 BMZERO,
1305 BMZERO},
1306
1307 {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1308 BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1309 -1),
1310 BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1311 -1),
1312 BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1313 -1),
1314 BMZERO,
1315 BMZERO,
1316 BMZERO},
1317
1318 {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1319 BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1320 BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1321 BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1322 BMZERO,
1323 BMZERO,
1324 BMZERO},
1325
1326 {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ,
1327 BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1,
1328 -1, -1, -1, -1),
1329 BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1,
1330 -1, -1, -1, -1),
1331 BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1332 -1),
1333 BMZERO,
1334 BMZERO,
1335 BMZERO},
1336
1337 {APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ,
1338 BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
1339 -1, -1, -1, -1),
1340 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1341 -1),
1342 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1343 -1),
1344 BMZERO,
1345 BMZERO,
1346 BMZERO},
1347
1348 {APL8, ETSI, NO_DFS, NO_PSCAN,
1349 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1350 BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1351 -1),
1352 BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1353 -1),
1354 BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1355 -1),
1356 BMZERO,
1357 BMZERO,
1358 BMZERO},
1359
1360 {APL9, ETSI, DFS_ETSI, PSCAN_ETSI,
1361 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1362 BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1,
1363 -1, -1, -1, -1),
1364 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1365 -1),
1366 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1367 -1),
1368 BMZERO,
1369 BMZERO,
1370 BMZERO},
1371
1372 {APL10, ETSI, DFS_ETSI, PSCAN_ETSI,
1373 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1374 BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
1375 -1, -1, -1, -1),
1376 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1377 -1),
1378 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1379 -1),
1380 BMZERO,
1381 BMZERO,
1382 BMZERO},
1383
1384 {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI,
1385 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1386 BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1,
1387 -1, -1, -1, -1),
1388 BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1389 BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1390 -1),
1391 BMZERO,
1392 BMZERO,
1393 BMZERO},
1394
1395 {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI,
1396 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1397 BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1398 BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1399 BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1400 BMZERO,
1401 BMZERO,
1402 BMZERO},
1403
1404 {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI,
1405 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1406 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1407 -1),
1408 BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1409 BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1410 BMZERO,
1411 BMZERO,
1412 BMZERO},
1413
1414 {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI,
1415 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1416 BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1417 -1),
1418 BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1419 BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1420 BMZERO,
1421 BMZERO,
1422 BMZERO},
1423
1424 {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI,
1425 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1426 BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1427 BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1428 BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1429 BMZERO,
1430 BMZERO,
1431 BMZERO},
1432
1433 {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI,
1434 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1435 BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1,
1436 -1, -1, -1, -1),
1437 BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1438 BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1439 BMZERO,
1440 BMZERO,
1441 BMZERO},
1442
1443 {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1444 BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1,
1445 -1, -1, -1, -1),
1446 BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1,
1447 -1, -1, -1, -1),
1448 BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1,
1449 -1, -1, -1, -1),
1450 BMZERO,
1451 BMZERO,
1452 BMZERO},
1453
1454 {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1455 BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1,
1456 -1, -1, -1, -1),
1457 BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
1458 -1, -1, -1, -1),
1459 BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
1460 -1, -1, -1, -1, -1, -1),
1461 BMZERO,
1462 BMZERO,
1463 BMZERO},
1464
1465 {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
1466 BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1,
1467 -1, -1, -1, -1, -1, -1),
1468 BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1469 -1),
1470 BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1471 -1),
1472 BMZERO,
1473 BMZERO,
1474 BMZERO},
1475
1476 {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
1477 BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1,
1478 -1, -1, -1, -1),
1479 BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1,
1480 -1, -1, -1, -1),
1481 BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1,
1482 -1, -1, -1, -1),
1483 BMZERO,
1484 BMZERO,
1485 BMZERO},
1486
1487 {FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1488 BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1489 -1),
1490 BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1491 -1),
1492 BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1493 -1),
1494 BMZERO,
1495 BMZERO,
1496 BMZERO},
1497
1498 {FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ,
1499 BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700,
1500 F6_5745_5825, -1, -1, -1, -1, -1, -1, -1),
1501 BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
1502 -1, -1, -1, -1),
1503 BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
1504 -1, -1, -1, -1, -1, -1),
1505 BMZERO,
1506 BMZERO,
1507 BMZERO},
1508
1509 {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1510 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
1511 -1, -1, -1, -1, -1, -1),
1512 BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1513 BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1514 BMZERO,
1515 BMZERO,
1516 BMZERO},
1517
1518 {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
1519 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1520 F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
1521 F2_5260_5320, F4_5500_5700, -1, -1),
1522 BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1523 BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1524 BMZERO,
1525 BMZERO,
1526 BMZERO},
1527
1528
1529 {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1530 BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1531 BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1532 BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1533 BMZERO,
1534 BMZERO,
1535 BMZERO},
1536
1537
1538 {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1539 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1540 -1),
1541 BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1542 BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1543 BMZERO,
1544 BMZERO,
1545 BMZERO},
1546
1547
1548 {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1549 BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1,
1550 -1, -1, -1, -1),
1551 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1552 BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1553 -1),
1554 BMZERO,
1555 BMZERO,
1556 BMZERO},
1557
1558
1559 {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1560 BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1561 -1),
1562 BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1563 BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1564 BMZERO,
1565 BMZERO,
1566 BMZERO},
1567
1568
1569 {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1570 DISALLOW_ADHOC_11A_TURB,
1571 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1,
1572 -1, -1, -1, -1),
1573 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1574 BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1575 BMZERO,
1576 BMZERO,
1577 BMZERO},
1578
1579
1580 {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1581 DISALLOW_ADHOC_11A_TURB,
1582 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
1583 -1, -1, -1, -1, -1, -1),
1584 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1585 BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1586 -1),
1587 BMZERO,
1588 BMZERO,
1589 BMZERO},
1590
1591
1592 {MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3,
1593 DISALLOW_ADHOC_11A_TURB,
1594 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1595 F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
1596 BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1597 BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1598 BMZERO,
1599 BMZERO,
1600 BMZERO},
1601
1602
1603 {MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3,
1604 DISALLOW_ADHOC_11A_TURB,
1605 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1606 F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1,
1607 -1, -1),
1608 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1609 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1610 BMZERO,
1611 BMZERO,
1612 BMZERO},
1613
1614
1615 {MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1616 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1617 F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320,
1618 F4_5500_5700, -1, -1, -1),
1619 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1620 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1621 BMZERO,
1622 BMZERO,
1623 BMZERO},
1624
1625
1626 {MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1627 DISALLOW_ADHOC_11A_TURB,
1628 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1629 F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
1630 F2_5260_5320, F4_5500_5700, -1, -1),
1631 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1632 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1633 BMZERO,
1634 BMZERO,
1635 BMZERO},
1636
1637
1638 {MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1639 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1640 BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
1641 -1, -1, -1, -1, -1, -1),
1642 BMZERO,
1643 BMZERO,
1644 BMZERO,
1645 BMZERO,
1646 BMZERO},
1647
1648
1649 {MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1650 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1651 F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1,
1652 -1, -1),
1653 BMZERO,
1654 BMZERO,
1655 BMZERO,
1656 BMZERO,
1657 BMZERO},
1658
1659
1660 {MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1661 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1662 F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240,
1663 F2_5260_5320, -1, -1, -1),
1664 BMZERO,
1665 BMZERO,
1666 BMZERO,
1667 BMZERO,
1668 BMZERO},
1669
1670
1671 {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
1672 BMZERO,
1673 BMZERO,
1674 BMZERO,
1675 BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1676 -1),
1677 BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1678 -1),
1679 BMZERO},
1680
1681 {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA,
1682 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1683 BMZERO,
1684 BMZERO,
1685 BMZERO,
1686 BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1687 BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1688 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1689
1690 {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB,
1691 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1692 BMZERO,
1693 BMZERO,
1694 BMZERO,
1695 BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1696 BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1697 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1698
1699 {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC,
1700 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1701 BMZERO,
1702 BMZERO,
1703 BMZERO,
1704 BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1705 BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1706 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1707
1708 {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1709 BMZERO,
1710 BMZERO,
1711 BMZERO,
1712 BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1713 BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1714 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1715
1716 {MKKA, MKK, NO_DFS,
1717 PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G |
1718 PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
1719 BMZERO,
1720 BMZERO,
1721 BMZERO,
1722 BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1,
1723 -1, -1, -1, -1),
1724 BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1725 -1),
1726 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1727
1728 {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
1729 BMZERO,
1730 BMZERO,
1731 BMZERO,
1732 BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1733 BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1734 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1735
1736 {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
1737 BMZERO,
1738 BMZERO,
1739 BMZERO,
1740 BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1741 BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1742 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1743
1744 {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1745 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1746 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1747 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1748 -1, -1, -1, -1, -1),
1749 BMZERO,
1750 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1751 W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
1752 -1, -1),
1753 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1754 -1, -1),
1755 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1756
1757 {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
1758 ADHOC_PER_11D,
1759 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1760 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1761 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1762 -1, -1, -1, -1, -1),
1763 BMZERO,
1764 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
1765 W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1766 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1767 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1768
1769 {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
1770 ADHOC_PER_11D,
1771 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1772 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1773 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1774 -1, -1, -1, -1, -1),
1775 BMZERO,
1776 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1777 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1778 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1779 -1, -1),
1780 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1781
1782 {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1783 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1784 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1785 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1786 -1, -1, -1, -1, -1),
1787 BMZERO,
1788 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472,
1789 W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
1790 BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1791 -1, -1),
1792 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1793
1794 {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1795 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1796 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1797 BMZERO,
1798 BMZERO,
1799 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1800 W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
1801 -1, -1),
1802 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1803 -1, -1),
1804 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1805
1806 {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1807 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1808 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1809 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1810 -1, -1, -1, -1, -1),
1811 BMZERO,
1812 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1813 W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
1814 -1, -1),
1815 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1816 -1, -1),
1817 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1818
1819 {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1820 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1,
1821 -1, -1, -1, -1, -1, -1),
1822 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1823 -1, -1, -1, -1, -1),
1824 BMZERO,
1825 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1826 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1827 BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1828 -1, -1),
1829 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1830
1831 {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1832 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
1833 -1, -1, -1, -1),
1834 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1835 -1, -1, -1, -1, -1),
1836 BMZERO,
1837 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
1838 W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1839 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1840 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1841
1842 {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1843 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
1844 -1, -1, -1, -1),
1845 BMZERO,
1846 BMZERO,
1847 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1848 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1849 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1850 -1, -1),
1851 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1852
1853 {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1854 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
1855 -1, -1, -1, -1, -1, -1),
1856 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1857 -1, -1, -1, -1, -1),
1858 BMZERO,
1859 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
1860 W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1861 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1862 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1863
1864 {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1865 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
1866 -1, -1, -1, -1, -1, -1),
1867 BMZERO,
1868 BMZERO,
1869 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1870 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1871 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1872 -1, -1),
1873 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1874
1875 {WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1876 BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1,
1877 -1, -1, -1, -1),
1878 BMZERO,
1879 BMZERO,
1880 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1881 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1882 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1883 -1, -1),
1884 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1885
1886 {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
1887 BMZERO,
1888 BMZERO,
1889 BMZERO,
1890 BMZERO,
1891 BMZERO,
1892 BMZERO}
1893};
1894
1895static const struct cmode modes[] = {
1896 {ATH9K_MODE_11A, CHANNEL_A},
1897 {ATH9K_MODE_11B, CHANNEL_B},
1898 {ATH9K_MODE_11G, CHANNEL_G},
1899 {ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20},
1900 {ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
1901 {ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
1902 {ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20},
1903 {ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
1904 {ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
1905};
1906
1907static struct japan_bandcheck j_bandcheck[] = {
1908 {F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD},
1909 {F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN},
1910 {F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2},
1911 {F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND}
1912};
1913
1914
1915#endif
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
new file mode 100644
index 000000000000..157f830ee6b8
--- /dev/null
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -0,0 +1,2871 @@
1/*
2 * Copyright (c) 2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/*
18 * Implementation of transmit path.
19 */
20
21#include "core.h"
22
23#define BITS_PER_BYTE 8
24#define OFDM_PLCP_BITS 22
25#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f)
26#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
27#define L_STF 8
28#define L_LTF 8
29#define L_SIG 4
30#define HT_SIG 8
31#define HT_STF 4
32#define HT_LTF(_ns) (4 * (_ns))
33#define SYMBOL_TIME(_ns) ((_ns) << 2) /* ns * 4 us */
34#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5) /* ns * 3.6 us */
35#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
36#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
37
38#define OFDM_SIFS_TIME 16
39
40static u32 bits_per_symbol[][2] = {
41 /* 20MHz 40MHz */
42 { 26, 54 }, /* 0: BPSK */
43 { 52, 108 }, /* 1: QPSK 1/2 */
44 { 78, 162 }, /* 2: QPSK 3/4 */
45 { 104, 216 }, /* 3: 16-QAM 1/2 */
46 { 156, 324 }, /* 4: 16-QAM 3/4 */
47 { 208, 432 }, /* 5: 64-QAM 2/3 */
48 { 234, 486 }, /* 6: 64-QAM 3/4 */
49 { 260, 540 }, /* 7: 64-QAM 5/6 */
50 { 52, 108 }, /* 8: BPSK */
51 { 104, 216 }, /* 9: QPSK 1/2 */
52 { 156, 324 }, /* 10: QPSK 3/4 */
53 { 208, 432 }, /* 11: 16-QAM 1/2 */
54 { 312, 648 }, /* 12: 16-QAM 3/4 */
55 { 416, 864 }, /* 13: 64-QAM 2/3 */
56 { 468, 972 }, /* 14: 64-QAM 3/4 */
57 { 520, 1080 }, /* 15: 64-QAM 5/6 */
58};
59
60#define IS_HT_RATE(_rate) ((_rate) & 0x80)
61
62/*
63 * Insert a chain of ath_buf (descriptors) on a multicast txq
64 * but do NOT start tx DMA on this queue.
65 * NB: must be called with txq lock held
66 */
67
68static void ath_tx_mcastqaddbuf(struct ath_softc *sc,
69 struct ath_txq *txq,
70 struct list_head *head)
71{
72 struct ath_hal *ah = sc->sc_ah;
73 struct ath_buf *bf;
74
75 if (list_empty(head))
76 return;
77
78 /*
79 * Insert the frame on the outbound list and
80 * pass it on to the hardware.
81 */
82 bf = list_first_entry(head, struct ath_buf, list);
83
84 /*
85 * The CAB queue is started from the SWBA handler since
86 * frames only go out on DTIM and to avoid possible races.
87 */
88 ath9k_hw_set_interrupts(ah, 0);
89
90 /*
91 * If there is anything in the mcastq, we want to set
92 * the "more data" bit in the last item in the queue to
93 * indicate that there is "more data". It makes sense to add
94 * it here since you are *always* going to have
95 * more data when adding to this queue, no matter where
96 * you call from.
97 */
98
99 if (txq->axq_depth) {
100 struct ath_buf *lbf;
101 struct ieee80211_hdr *hdr;
102
103 /*
104 * Add the "more data flag" to the last frame
105 */
106
107 lbf = list_entry(txq->axq_q.prev, struct ath_buf, list);
108 hdr = (struct ieee80211_hdr *)
109 ((struct sk_buff *)(lbf->bf_mpdu))->data;
110 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
111 }
112
113 /*
114 * Now, concat the frame onto the queue
115 */
116 list_splice_tail_init(head, &txq->axq_q);
117 txq->axq_depth++;
118 txq->axq_totalqueued++;
119 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
120
121 DPRINTF(sc, ATH_DBG_QUEUE,
122 "%s: txq depth = %d\n", __func__, txq->axq_depth);
123 if (txq->axq_link != NULL) {
124 *txq->axq_link = bf->bf_daddr;
125 DPRINTF(sc, ATH_DBG_XMIT,
126 "%s: link[%u](%p)=%llx (%p)\n",
127 __func__,
128 txq->axq_qnum, txq->axq_link,
129 ito64(bf->bf_daddr), bf->bf_desc);
130 }
131 txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
132 ath9k_hw_set_interrupts(ah, sc->sc_imask);
133}
134
135/*
136 * Insert a chain of ath_buf (descriptors) on a txq and
137 * assume the descriptors are already chained together by caller.
138 * NB: must be called with txq lock held
139 */
140
141static void ath_tx_txqaddbuf(struct ath_softc *sc,
142 struct ath_txq *txq, struct list_head *head)
143{
144 struct ath_hal *ah = sc->sc_ah;
145 struct ath_buf *bf;
146 /*
147 * Insert the frame on the outbound list and
148 * pass it on to the hardware.
149 */
150
151 if (list_empty(head))
152 return;
153
154 bf = list_first_entry(head, struct ath_buf, list);
155
156 list_splice_tail_init(head, &txq->axq_q);
157 txq->axq_depth++;
158 txq->axq_totalqueued++;
159 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
160
161 DPRINTF(sc, ATH_DBG_QUEUE,
162 "%s: txq depth = %d\n", __func__, txq->axq_depth);
163
164 if (txq->axq_link == NULL) {
165 ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
166 DPRINTF(sc, ATH_DBG_XMIT,
167 "%s: TXDP[%u] = %llx (%p)\n",
168 __func__, txq->axq_qnum,
169 ito64(bf->bf_daddr), bf->bf_desc);
170 } else {
171 *txq->axq_link = bf->bf_daddr;
172 DPRINTF(sc, ATH_DBG_XMIT, "%s: link[%u] (%p)=%llx (%p)\n",
173 __func__,
174 txq->axq_qnum, txq->axq_link,
175 ito64(bf->bf_daddr), bf->bf_desc);
176 }
177 txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
178 ath9k_hw_txstart(ah, txq->axq_qnum);
179}
180
181/* Get transmit rate index using rate in Kbps */
182
183static int ath_tx_findindex(const struct ath9k_rate_table *rt, int rate)
184{
185 int i;
186 int ndx = 0;
187
188 for (i = 0; i < rt->rateCount; i++) {
189 if (rt->info[i].rateKbps == rate) {
190 ndx = i;
191 break;
192 }
193 }
194
195 return ndx;
196}
197
198/* Check if it's okay to send out aggregates */
199
200static int ath_aggr_query(struct ath_softc *sc,
201 struct ath_node *an, u8 tidno)
202{
203 struct ath_atx_tid *tid;
204 tid = ATH_AN_2_TID(an, tidno);
205
206 if (tid->addba_exchangecomplete || tid->addba_exchangeinprogress)
207 return 1;
208 else
209 return 0;
210}
211
212static enum ath9k_pkt_type get_hal_packet_type(struct ieee80211_hdr *hdr)
213{
214 enum ath9k_pkt_type htype;
215 __le16 fc;
216
217 fc = hdr->frame_control;
218
219 /* Calculate Atheros packet type from IEEE80211 packet header */
220
221 if (ieee80211_is_beacon(fc))
222 htype = ATH9K_PKT_TYPE_BEACON;
223 else if (ieee80211_is_probe_resp(fc))
224 htype = ATH9K_PKT_TYPE_PROBE_RESP;
225 else if (ieee80211_is_atim(fc))
226 htype = ATH9K_PKT_TYPE_ATIM;
227 else if (ieee80211_is_pspoll(fc))
228 htype = ATH9K_PKT_TYPE_PSPOLL;
229 else
230 htype = ATH9K_PKT_TYPE_NORMAL;
231
232 return htype;
233}
234
235static void fill_min_rates(struct sk_buff *skb, struct ath_tx_control *txctl)
236{
237 struct ieee80211_hdr *hdr;
238 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
239 struct ath_tx_info_priv *tx_info_priv;
240 __le16 fc;
241
242 hdr = (struct ieee80211_hdr *)skb->data;
243 fc = hdr->frame_control;
244 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
245
246 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
247 txctl->use_minrate = 1;
248 txctl->min_rate = tx_info_priv->min_rate;
249 } else if (ieee80211_is_data(fc)) {
250 if (ieee80211_is_nullfunc(fc) ||
251 /* Port Access Entity (IEEE 802.1X) */
252 (skb->protocol == cpu_to_be16(0x888E))) {
253 txctl->use_minrate = 1;
254 txctl->min_rate = tx_info_priv->min_rate;
255 }
256 if (is_multicast_ether_addr(hdr->addr1))
257 txctl->mcast_rate = tx_info_priv->min_rate;
258 }
259
260}
261
262/* This function will setup additional txctl information, mostly rate stuff */
263/* FIXME: seqno, ps */
264static int ath_tx_prepare(struct ath_softc *sc,
265 struct sk_buff *skb,
266 struct ath_tx_control *txctl)
267{
268 struct ieee80211_hw *hw = sc->hw;
269 struct ieee80211_hdr *hdr;
270 struct ath_rc_series *rcs;
271 struct ath_txq *txq = NULL;
272 const struct ath9k_rate_table *rt;
273 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
274 struct ath_tx_info_priv *tx_info_priv;
275 int hdrlen;
276 u8 rix, antenna;
277 __le16 fc;
278 u8 *qc;
279
280 memset(txctl, 0, sizeof(struct ath_tx_control));
281
282 txctl->dev = sc;
283 hdr = (struct ieee80211_hdr *)skb->data;
284 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
285 fc = hdr->frame_control;
286
287 rt = sc->sc_currates;
288 BUG_ON(!rt);
289
290 /* Fill misc fields */
291
292 spin_lock_bh(&sc->node_lock);
293 txctl->an = ath_node_get(sc, hdr->addr1);
294 /* create a temp node, if the node is not there already */
295 if (!txctl->an)
296 txctl->an = ath_node_attach(sc, hdr->addr1, 0);
297 spin_unlock_bh(&sc->node_lock);
298
299 if (ieee80211_is_data_qos(fc)) {
300 qc = ieee80211_get_qos_ctl(hdr);
301 txctl->tidno = qc[0] & 0xf;
302 }
303
304 txctl->if_id = 0;
305 txctl->nextfraglen = 0;
306 txctl->frmlen = skb->len + FCS_LEN - (hdrlen & 3);
307 txctl->txpower = MAX_RATE_POWER; /* FIXME */
308
309 /* Fill Key related fields */
310
311 txctl->keytype = ATH9K_KEY_TYPE_CLEAR;
312 txctl->keyix = ATH9K_TXKEYIX_INVALID;
313
314 if (tx_info->control.hw_key) {
315 txctl->keyix = tx_info->control.hw_key->hw_key_idx;
316 txctl->frmlen += tx_info->control.icv_len;
317
318 if (sc->sc_keytype == ATH9K_CIPHER_WEP)
319 txctl->keytype = ATH9K_KEY_TYPE_WEP;
320 else if (sc->sc_keytype == ATH9K_CIPHER_TKIP)
321 txctl->keytype = ATH9K_KEY_TYPE_TKIP;
322 else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM)
323 txctl->keytype = ATH9K_KEY_TYPE_AES;
324 }
325
326 /* Fill packet type */
327
328 txctl->atype = get_hal_packet_type(hdr);
329
330 /* Fill qnum */
331
332 txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
333 txq = &sc->sc_txq[txctl->qnum];
334 spin_lock_bh(&txq->axq_lock);
335
336 /* Try to avoid running out of descriptors */
337 if (txq->axq_depth >= (ATH_TXBUF - 20)) {
338 DPRINTF(sc, ATH_DBG_FATAL,
339 "%s: TX queue: %d is full, depth: %d\n",
340 __func__,
341 txctl->qnum,
342 txq->axq_depth);
343 ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
344 txq->stopped = 1;
345 spin_unlock_bh(&txq->axq_lock);
346 return -1;
347 }
348
349 spin_unlock_bh(&txq->axq_lock);
350
351 /* Fill rate */
352
353 fill_min_rates(skb, txctl);
354
355 /* Fill flags */
356
357 txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
358
359 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
360 tx_info->flags |= ATH9K_TXDESC_NOACK;
361 if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
362 tx_info->flags |= ATH9K_TXDESC_RTSENA;
363
364 /*
365 * Setup for rate calculations.
366 */
367 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
368 rcs = tx_info_priv->rcs;
369
370 if (ieee80211_is_data(fc) && !txctl->use_minrate) {
371
372 /* Enable HT only for DATA frames and not for EAPOL */
373 txctl->ht = (hw->conf.ht_conf.ht_supported &&
374 (tx_info->flags & IEEE80211_TX_CTL_AMPDU));
375
376 if (is_multicast_ether_addr(hdr->addr1)) {
377 rcs[0].rix = (u8)
378 ath_tx_findindex(rt, txctl->mcast_rate);
379
380 /*
381 * mcast packets are not re-tried.
382 */
383 rcs[0].tries = 1;
384 }
385 /* For HT capable stations, we save tidno for later use.
386 * We also override seqno set by upper layer with the one
387 * in tx aggregation state.
388 *
389 * First, the fragmentation stat is determined.
390 * If fragmentation is on, the sequence number is
391 * not overridden, since it has been
392 * incremented by the fragmentation routine.
393 */
394 if (likely(!(txctl->flags & ATH9K_TXDESC_FRAG_IS_ON)) &&
395 txctl->ht && sc->sc_txaggr) {
396 struct ath_atx_tid *tid;
397
398 tid = ATH_AN_2_TID(txctl->an, txctl->tidno);
399
400 hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
401 IEEE80211_SEQ_SEQ_SHIFT);
402 txctl->seqno = tid->seq_next;
403 INCR(tid->seq_next, IEEE80211_SEQ_MAX);
404 }
405 } else {
406 /* for management and control frames,
407 * or for NULL and EAPOL frames */
408 if (txctl->min_rate)
409 rcs[0].rix = ath_rate_findrateix(sc, txctl->min_rate);
410 else
411 rcs[0].rix = 0;
412 rcs[0].tries = ATH_MGT_TXMAXTRY;
413 }
414 rix = rcs[0].rix;
415
416 /*
417 * Calculate duration. This logically belongs in the 802.11
418 * layer but it lacks sufficient information to calculate it.
419 */
420 if ((txctl->flags & ATH9K_TXDESC_NOACK) == 0 && !ieee80211_is_ctl(fc)) {
421 u16 dur;
422 /*
423 * XXX not right with fragmentation.
424 */
425 if (sc->sc_flags & ATH_PREAMBLE_SHORT)
426 dur = rt->info[rix].spAckDuration;
427 else
428 dur = rt->info[rix].lpAckDuration;
429
430 if (le16_to_cpu(hdr->frame_control) &
431 IEEE80211_FCTL_MOREFRAGS) {
432 dur += dur; /* Add additional 'SIFS + ACK' */
433
434 /*
435 ** Compute size of next fragment in order to compute
436 ** durations needed to update NAV.
437 ** The last fragment uses the ACK duration only.
438 ** Add time for next fragment.
439 */
440 dur += ath9k_hw_computetxtime(sc->sc_ah, rt,
441 txctl->nextfraglen,
442 rix, sc->sc_flags & ATH_PREAMBLE_SHORT);
443 }
444
445 if (ieee80211_has_morefrags(fc) ||
446 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
447 /*
448 ** Force hardware to use computed duration for next
449 ** fragment by disabling multi-rate retry, which
450 ** updates duration based on the multi-rate
451 ** duration table.
452 */
453 rcs[1].tries = rcs[2].tries = rcs[3].tries = 0;
454 rcs[1].rix = rcs[2].rix = rcs[3].rix = 0;
455 /* reset tries but keep rate index */
456 rcs[0].tries = ATH_TXMAXTRY;
457 }
458
459 hdr->duration_id = cpu_to_le16(dur);
460 }
461
462 /*
463 * Determine if a tx interrupt should be generated for
464 * this descriptor. We take a tx interrupt to reap
465 * descriptors when the h/w hits an EOL condition or
466 * when the descriptor is specifically marked to generate
467 * an interrupt. We periodically mark descriptors in this
468 * way to insure timely replenishing of the supply needed
469 * for sending frames. Defering interrupts reduces system
470 * load and potentially allows more concurrent work to be
471 * done but if done to aggressively can cause senders to
472 * backup.
473 *
474 * NB: use >= to deal with sc_txintrperiod changing
475 * dynamically through sysctl.
476 */
477 spin_lock_bh(&txq->axq_lock);
478 if ((++txq->axq_intrcnt >= sc->sc_txintrperiod)) {
479 txctl->flags |= ATH9K_TXDESC_INTREQ;
480 txq->axq_intrcnt = 0;
481 }
482 spin_unlock_bh(&txq->axq_lock);
483
484 if (is_multicast_ether_addr(hdr->addr1)) {
485 antenna = sc->sc_mcastantenna + 1;
486 sc->sc_mcastantenna = (sc->sc_mcastantenna + 1) & 0x1;
487 } else
488 antenna = sc->sc_txantenna;
489
490#ifdef USE_LEGACY_HAL
491 txctl->antenna = antenna;
492#endif
493 return 0;
494}
495
496/* To complete a chain of buffers associated a frame */
497
498static void ath_tx_complete_buf(struct ath_softc *sc,
499 struct ath_buf *bf,
500 struct list_head *bf_q,
501 int txok, int sendbar)
502{
503 struct sk_buff *skb = bf->bf_mpdu;
504 struct ath_xmit_status tx_status;
505 dma_addr_t *pa;
506
507 /*
508 * Set retry information.
509 * NB: Don't use the information in the descriptor, because the frame
510 * could be software retried.
511 */
512 tx_status.retries = bf->bf_retries;
513 tx_status.flags = 0;
514
515 if (sendbar)
516 tx_status.flags = ATH_TX_BAR;
517
518 if (!txok) {
519 tx_status.flags |= ATH_TX_ERROR;
520
521 if (bf->bf_isxretried)
522 tx_status.flags |= ATH_TX_XRETRY;
523 }
524 /* Unmap this frame */
525 pa = get_dma_mem_context(bf, bf_dmacontext);
526 pci_unmap_single(sc->pdev,
527 *pa,
528 skb->len,
529 PCI_DMA_TODEVICE);
530 /* complete this frame */
531 ath_tx_complete(sc, skb, &tx_status, bf->bf_node);
532
533 /*
534 * Return the list of ath_buf of this mpdu to free queue
535 */
536 spin_lock_bh(&sc->sc_txbuflock);
537 list_splice_tail_init(bf_q, &sc->sc_txbuf);
538 spin_unlock_bh(&sc->sc_txbuflock);
539}
540
541/*
542 * queue up a dest/ac pair for tx scheduling
543 * NB: must be called with txq lock held
544 */
545
546static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
547{
548 struct ath_atx_ac *ac = tid->ac;
549
550 /*
551 * if tid is paused, hold off
552 */
553 if (tid->paused)
554 return;
555
556 /*
557 * add tid to ac atmost once
558 */
559 if (tid->sched)
560 return;
561
562 tid->sched = true;
563 list_add_tail(&tid->list, &ac->tid_q);
564
565 /*
566 * add node ac to txq atmost once
567 */
568 if (ac->sched)
569 return;
570
571 ac->sched = true;
572 list_add_tail(&ac->list, &txq->axq_acq);
573}
574
575/* pause a tid */
576
577static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
578{
579 struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
580
581 spin_lock_bh(&txq->axq_lock);
582
583 tid->paused++;
584
585 spin_unlock_bh(&txq->axq_lock);
586}
587
588/* resume a tid and schedule aggregate */
589
590void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
591{
592 struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
593
594 ASSERT(tid->paused > 0);
595 spin_lock_bh(&txq->axq_lock);
596
597 tid->paused--;
598
599 if (tid->paused > 0)
600 goto unlock;
601
602 if (list_empty(&tid->buf_q))
603 goto unlock;
604
605 /*
606 * Add this TID to scheduler and try to send out aggregates
607 */
608 ath_tx_queue_tid(txq, tid);
609 ath_txq_schedule(sc, txq);
610unlock:
611 spin_unlock_bh(&txq->axq_lock);
612}
613
614/* Compute the number of bad frames */
615
616static int ath_tx_num_badfrms(struct ath_softc *sc,
617 struct ath_buf *bf, int txok)
618{
619 struct ath_node *an = bf->bf_node;
620 int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
621 struct ath_buf *bf_last = bf->bf_lastbf;
622 struct ath_desc *ds = bf_last->bf_desc;
623 u16 seq_st = 0;
624 u32 ba[WME_BA_BMP_SIZE >> 5];
625 int ba_index;
626 int nbad = 0;
627 int isaggr = 0;
628
629 if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
630 return 0;
631
632 isaggr = bf->bf_isaggr;
633 if (isaggr) {
634 seq_st = ATH_DS_BA_SEQ(ds);
635 memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
636 }
637
638 while (bf) {
639 ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
640 if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
641 nbad++;
642
643 bf = bf->bf_next;
644 }
645
646 return nbad;
647}
648
649static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
650{
651 struct sk_buff *skb;
652 struct ieee80211_hdr *hdr;
653
654 bf->bf_isretried = 1;
655 bf->bf_retries++;
656
657 skb = bf->bf_mpdu;
658 hdr = (struct ieee80211_hdr *)skb->data;
659 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
660}
661
662/* Update block ack window */
663
664static void ath_tx_update_baw(struct ath_softc *sc,
665 struct ath_atx_tid *tid, int seqno)
666{
667 int index, cindex;
668
669 index = ATH_BA_INDEX(tid->seq_start, seqno);
670 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
671
672 tid->tx_buf[cindex] = NULL;
673
674 while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
675 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
676 INCR(tid->baw_head, ATH_TID_MAX_BUFS);
677 }
678}
679
680/*
681 * ath_pkt_dur - compute packet duration (NB: not NAV)
682 *
683 * rix - rate index
684 * pktlen - total bytes (delims + data + fcs + pads + pad delims)
685 * width - 0 for 20 MHz, 1 for 40 MHz
686 * half_gi - to use 4us v/s 3.6 us for symbol time
687 */
688
689static u32 ath_pkt_duration(struct ath_softc *sc,
690 u8 rix,
691 struct ath_buf *bf,
692 int width,
693 int half_gi,
694 bool shortPreamble)
695{
696 const struct ath9k_rate_table *rt = sc->sc_currates;
697 u32 nbits, nsymbits, duration, nsymbols;
698 u8 rc;
699 int streams, pktlen;
700
701 pktlen = bf->bf_isaggr ? bf->bf_al : bf->bf_frmlen;
702 rc = rt->info[rix].rateCode;
703
704 /*
705 * for legacy rates, use old function to compute packet duration
706 */
707 if (!IS_HT_RATE(rc))
708 return ath9k_hw_computetxtime(sc->sc_ah,
709 rt,
710 pktlen,
711 rix,
712 shortPreamble);
713 /*
714 * find number of symbols: PLCP + data
715 */
716 nbits = (pktlen << 3) + OFDM_PLCP_BITS;
717 nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
718 nsymbols = (nbits + nsymbits - 1) / nsymbits;
719
720 if (!half_gi)
721 duration = SYMBOL_TIME(nsymbols);
722 else
723 duration = SYMBOL_TIME_HALFGI(nsymbols);
724
725 /*
726 * addup duration for legacy/ht training and signal fields
727 */
728 streams = HT_RC_2_STREAMS(rc);
729 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
730 return duration;
731}
732
733/* Rate module function to set rate related fields in tx descriptor */
734
735static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
736{
737 struct ath_hal *ah = sc->sc_ah;
738 const struct ath9k_rate_table *rt;
739 struct ath_desc *ds = bf->bf_desc;
740 struct ath_desc *lastds = bf->bf_lastbf->bf_desc;
741 struct ath9k_11n_rate_series series[4];
742 int i, flags, rtsctsena = 0, dynamic_mimops = 0;
743 u32 ctsduration = 0;
744 u8 rix = 0, cix, ctsrate = 0;
745 u32 aggr_limit_with_rts = sc->sc_rtsaggrlimit;
746 struct ath_node *an = (struct ath_node *) bf->bf_node;
747
748 /*
749 * get the cix for the lowest valid rix.
750 */
751 rt = sc->sc_currates;
752 for (i = 4; i--;) {
753 if (bf->bf_rcs[i].tries) {
754 rix = bf->bf_rcs[i].rix;
755 break;
756 }
757 }
758 flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA));
759 cix = rt->info[rix].controlRate;
760
761 /*
762 * If 802.11g protection is enabled, determine whether
763 * to use RTS/CTS or just CTS. Note that this is only
764 * done for OFDM/HT unicast frames.
765 */
766 if (sc->sc_protmode != PROT_M_NONE &&
767 (rt->info[rix].phy == PHY_OFDM ||
768 rt->info[rix].phy == PHY_HT) &&
769 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
770 if (sc->sc_protmode == PROT_M_RTSCTS)
771 flags = ATH9K_TXDESC_RTSENA;
772 else if (sc->sc_protmode == PROT_M_CTSONLY)
773 flags = ATH9K_TXDESC_CTSENA;
774
775 cix = rt->info[sc->sc_protrix].controlRate;
776 rtsctsena = 1;
777 }
778
779 /* For 11n, the default behavior is to enable RTS for
780 * hw retried frames. We enable the global flag here and
781 * let rate series flags determine which rates will actually
782 * use RTS.
783 */
784 if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf->bf_isdata) {
785 BUG_ON(!an);
786 /*
787 * 802.11g protection not needed, use our default behavior
788 */
789 if (!rtsctsena)
790 flags = ATH9K_TXDESC_RTSENA;
791 /*
792 * For dynamic MIMO PS, RTS needs to precede the first aggregate
793 * and the second aggregate should have any protection at all.
794 */
795 if (an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) {
796 if (!bf->bf_aggrburst) {
797 flags = ATH9K_TXDESC_RTSENA;
798 dynamic_mimops = 1;
799 } else {
800 flags = 0;
801 }
802 }
803 }
804
805 /*
806 * Set protection if aggregate protection on
807 */
808 if (sc->sc_config.ath_aggr_prot &&
809 (!bf->bf_isaggr || (bf->bf_isaggr && bf->bf_al < 8192))) {
810 flags = ATH9K_TXDESC_RTSENA;
811 cix = rt->info[sc->sc_protrix].controlRate;
812 rtsctsena = 1;
813 }
814
815 /*
816 * For AR5416 - RTS cannot be followed by a frame larger than 8K.
817 */
818 if (bf->bf_isaggr && (bf->bf_al > aggr_limit_with_rts)) {
819 /*
820 * Ensure that in the case of SM Dynamic power save
821 * while we are bursting the second aggregate the
822 * RTS is cleared.
823 */
824 flags &= ~(ATH9K_TXDESC_RTSENA);
825 }
826
827 /*
828 * CTS transmit rate is derived from the transmit rate
829 * by looking in the h/w rate table. We must also factor
830 * in whether or not a short preamble is to be used.
831 */
832 /* NB: cix is set above where RTS/CTS is enabled */
833 BUG_ON(cix == 0xff);
834 ctsrate = rt->info[cix].rateCode |
835 (bf->bf_shpreamble ? rt->info[cix].shortPreamble : 0);
836
837 /*
838 * Setup HAL rate series
839 */
840 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
841
842 for (i = 0; i < 4; i++) {
843 if (!bf->bf_rcs[i].tries)
844 continue;
845
846 rix = bf->bf_rcs[i].rix;
847
848 series[i].Rate = rt->info[rix].rateCode |
849 (bf->bf_shpreamble ? rt->info[rix].shortPreamble : 0);
850
851 series[i].Tries = bf->bf_rcs[i].tries;
852
853 series[i].RateFlags = (
854 (bf->bf_rcs[i].flags & ATH_RC_RTSCTS_FLAG) ?
855 ATH9K_RATESERIES_RTS_CTS : 0) |
856 ((bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) ?
857 ATH9K_RATESERIES_2040 : 0) |
858 ((bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG) ?
859 ATH9K_RATESERIES_HALFGI : 0);
860
861 series[i].PktDuration = ath_pkt_duration(
862 sc, rix, bf,
863 (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0,
864 (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG),
865 bf->bf_shpreamble);
866
867 if ((an->an_smmode == ATH_SM_PWRSAV_STATIC) &&
868 (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG) == 0) {
869 /*
870 * When sending to an HT node that has enabled static
871 * SM/MIMO power save, send at single stream rates but
872 * use maximum allowed transmit chains per user,
873 * hardware, regulatory, or country limits for
874 * better range.
875 */
876 series[i].ChSel = sc->sc_tx_chainmask;
877 } else {
878 if (bf->bf_ht)
879 series[i].ChSel =
880 ath_chainmask_sel_logic(sc, an);
881 else
882 series[i].ChSel = sc->sc_tx_chainmask;
883 }
884
885 if (rtsctsena)
886 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
887
888 /*
889 * Set RTS for all rates if node is in dynamic powersave
890 * mode and we are using dual stream rates.
891 */
892 if (dynamic_mimops && (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG))
893 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
894 }
895
896 /*
897 * For non-HT devices, calculate RTS/CTS duration in software
898 * and disable multi-rate retry.
899 */
900 if (flags && !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)) {
901 /*
902 * Compute the transmit duration based on the frame
903 * size and the size of an ACK frame. We call into the
904 * HAL to do the computation since it depends on the
905 * characteristics of the actual PHY being used.
906 *
907 * NB: CTS is assumed the same size as an ACK so we can
908 * use the precalculated ACK durations.
909 */
910 if (flags & ATH9K_TXDESC_RTSENA) { /* SIFS + CTS */
911 ctsduration += bf->bf_shpreamble ?
912 rt->info[cix].spAckDuration :
913 rt->info[cix].lpAckDuration;
914 }
915
916 ctsduration += series[0].PktDuration;
917
918 if ((bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { /* SIFS + ACK */
919 ctsduration += bf->bf_shpreamble ?
920 rt->info[rix].spAckDuration :
921 rt->info[rix].lpAckDuration;
922 }
923
924 /*
925 * Disable multi-rate retry when using RTS/CTS by clearing
926 * series 1, 2 and 3.
927 */
928 memzero(&series[1], sizeof(struct ath9k_11n_rate_series) * 3);
929 }
930
931 /*
932 * set dur_update_en for l-sig computation except for PS-Poll frames
933 */
934 ath9k_hw_set11n_ratescenario(ah, ds, lastds,
935 !bf->bf_ispspoll,
936 ctsrate,
937 ctsduration,
938 series, 4, flags);
939 if (sc->sc_config.ath_aggr_prot && flags)
940 ath9k_hw_set11n_burstduration(ah, ds, 8192);
941}
942
943/*
944 * Function to send a normal HT (non-AMPDU) frame
945 * NB: must be called with txq lock held
946 */
947
948static int ath_tx_send_normal(struct ath_softc *sc,
949 struct ath_txq *txq,
950 struct ath_atx_tid *tid,
951 struct list_head *bf_head)
952{
953 struct ath_buf *bf;
954 struct sk_buff *skb;
955 struct ieee80211_tx_info *tx_info;
956 struct ath_tx_info_priv *tx_info_priv;
957
958 BUG_ON(list_empty(bf_head));
959
960 bf = list_first_entry(bf_head, struct ath_buf, list);
961 bf->bf_isampdu = 0; /* regular HT frame */
962
963 skb = (struct sk_buff *)bf->bf_mpdu;
964 tx_info = IEEE80211_SKB_CB(skb);
965 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
966 memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
967
968 /* update starting sequence number for subsequent ADDBA request */
969 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
970
971 /* Queue to h/w without aggregation */
972 bf->bf_nframes = 1;
973 bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
974 ath_buf_set_rate(sc, bf);
975 ath_tx_txqaddbuf(sc, txq, bf_head);
976
977 return 0;
978}
979
980/* flush tid's software queue and send frames as non-ampdu's */
981
982static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
983{
984 struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
985 struct ath_buf *bf;
986 struct list_head bf_head;
987 INIT_LIST_HEAD(&bf_head);
988
989 ASSERT(tid->paused > 0);
990 spin_lock_bh(&txq->axq_lock);
991
992 tid->paused--;
993
994 if (tid->paused > 0) {
995 spin_unlock_bh(&txq->axq_lock);
996 return;
997 }
998
999 while (!list_empty(&tid->buf_q)) {
1000 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
1001 ASSERT(!bf->bf_isretried);
1002 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1003 ath_tx_send_normal(sc, txq, tid, &bf_head);
1004 }
1005
1006 spin_unlock_bh(&txq->axq_lock);
1007}
1008
1009/* Completion routine of an aggregate */
1010
1011static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1012 struct ath_txq *txq,
1013 struct ath_buf *bf,
1014 struct list_head *bf_q,
1015 int txok)
1016{
1017 struct ath_node *an = bf->bf_node;
1018 struct ath_atx_tid *tid = ATH_AN_2_TID(an, bf->bf_tidno);
1019 struct ath_buf *bf_last = bf->bf_lastbf;
1020 struct ath_desc *ds = bf_last->bf_desc;
1021 struct ath_buf *bf_next, *bf_lastq = NULL;
1022 struct list_head bf_head, bf_pending;
1023 u16 seq_st = 0;
1024 u32 ba[WME_BA_BMP_SIZE >> 5];
1025 int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
1026 int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
1027
1028 isaggr = bf->bf_isaggr;
1029 if (isaggr) {
1030 if (txok) {
1031 if (ATH_DS_TX_BA(ds)) {
1032 /*
1033 * extract starting sequence and
1034 * block-ack bitmap
1035 */
1036 seq_st = ATH_DS_BA_SEQ(ds);
1037 memcpy(ba,
1038 ATH_DS_BA_BITMAP(ds),
1039 WME_BA_BMP_SIZE >> 3);
1040 } else {
1041 memzero(ba, WME_BA_BMP_SIZE >> 3);
1042
1043 /*
1044 * AR5416 can become deaf/mute when BA
1045 * issue happens. Chip needs to be reset.
1046 * But AP code may have sychronization issues
1047 * when perform internal reset in this routine.
1048 * Only enable reset in STA mode for now.
1049 */
1050 if (sc->sc_opmode == ATH9K_M_STA)
1051 needreset = 1;
1052 }
1053 } else {
1054 memzero(ba, WME_BA_BMP_SIZE >> 3);
1055 }
1056 }
1057
1058 INIT_LIST_HEAD(&bf_pending);
1059 INIT_LIST_HEAD(&bf_head);
1060
1061 while (bf) {
1062 txfail = txpending = 0;
1063 bf_next = bf->bf_next;
1064
1065 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
1066 /* transmit completion, subframe is
1067 * acked by block ack */
1068 } else if (!isaggr && txok) {
1069 /* transmit completion */
1070 } else {
1071
1072 if (!tid->cleanup_inprogress && !isnodegone &&
1073 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
1074 if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
1075 ath_tx_set_retry(sc, bf);
1076 txpending = 1;
1077 } else {
1078 bf->bf_isxretried = 1;
1079 txfail = 1;
1080 sendbar = 1;
1081 }
1082 } else {
1083 /*
1084 * cleanup in progress, just fail
1085 * the un-acked sub-frames
1086 */
1087 txfail = 1;
1088 }
1089 }
1090 /*
1091 * Remove ath_buf's of this sub-frame from aggregate queue.
1092 */
1093 if (bf_next == NULL) { /* last subframe in the aggregate */
1094 ASSERT(bf->bf_lastfrm == bf_last);
1095
1096 /*
1097 * The last descriptor of the last sub frame could be
1098 * a holding descriptor for h/w. If that's the case,
1099 * bf->bf_lastfrm won't be in the bf_q.
1100 * Make sure we handle bf_q properly here.
1101 */
1102
1103 if (!list_empty(bf_q)) {
1104 bf_lastq = list_entry(bf_q->prev,
1105 struct ath_buf, list);
1106 list_cut_position(&bf_head,
1107 bf_q, &bf_lastq->list);
1108 } else {
1109 /*
1110 * XXX: if the last subframe only has one
1111 * descriptor which is also being used as
1112 * a holding descriptor. Then the ath_buf
1113 * is not in the bf_q at all.
1114 */
1115 INIT_LIST_HEAD(&bf_head);
1116 }
1117 } else {
1118 ASSERT(!list_empty(bf_q));
1119 list_cut_position(&bf_head,
1120 bf_q, &bf->bf_lastfrm->list);
1121 }
1122
1123 if (!txpending) {
1124 /*
1125 * complete the acked-ones/xretried ones; update
1126 * block-ack window
1127 */
1128 spin_lock_bh(&txq->axq_lock);
1129 ath_tx_update_baw(sc, tid, bf->bf_seqno);
1130 spin_unlock_bh(&txq->axq_lock);
1131
1132 /* complete this sub-frame */
1133 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
1134 } else {
1135 /*
1136 * retry the un-acked ones
1137 */
1138 /*
1139 * XXX: if the last descriptor is holding descriptor,
1140 * in order to requeue the frame to software queue, we
1141 * need to allocate a new descriptor and
1142 * copy the content of holding descriptor to it.
1143 */
1144 if (bf->bf_next == NULL &&
1145 bf_last->bf_status & ATH_BUFSTATUS_STALE) {
1146 struct ath_buf *tbf;
1147
1148 /* allocate new descriptor */
1149 spin_lock_bh(&sc->sc_txbuflock);
1150 ASSERT(!list_empty((&sc->sc_txbuf)));
1151 tbf = list_first_entry(&sc->sc_txbuf,
1152 struct ath_buf, list);
1153 list_del(&tbf->list);
1154 spin_unlock_bh(&sc->sc_txbuflock);
1155
1156 ATH_TXBUF_RESET(tbf);
1157
1158 /* copy descriptor content */
1159 tbf->bf_mpdu = bf_last->bf_mpdu;
1160 tbf->bf_node = bf_last->bf_node;
1161 tbf->bf_buf_addr = bf_last->bf_buf_addr;
1162 *(tbf->bf_desc) = *(bf_last->bf_desc);
1163
1164 /* link it to the frame */
1165 if (bf_lastq) {
1166 bf_lastq->bf_desc->ds_link =
1167 tbf->bf_daddr;
1168 bf->bf_lastfrm = tbf;
1169 ath9k_hw_cleartxdesc(sc->sc_ah,
1170 bf->bf_lastfrm->bf_desc);
1171 } else {
1172 tbf->bf_state = bf_last->bf_state;
1173 tbf->bf_lastfrm = tbf;
1174 ath9k_hw_cleartxdesc(sc->sc_ah,
1175 tbf->bf_lastfrm->bf_desc);
1176
1177 /* copy the DMA context */
1178 copy_dma_mem_context(
1179 get_dma_mem_context(tbf,
1180 bf_dmacontext),
1181 get_dma_mem_context(bf_last,
1182 bf_dmacontext));
1183 }
1184 list_add_tail(&tbf->list, &bf_head);
1185 } else {
1186 /*
1187 * Clear descriptor status words for
1188 * software retry
1189 */
1190 ath9k_hw_cleartxdesc(sc->sc_ah,
1191 bf->bf_lastfrm->bf_desc);
1192 }
1193
1194 /*
1195 * Put this buffer to the temporary pending
1196 * queue to retain ordering
1197 */
1198 list_splice_tail_init(&bf_head, &bf_pending);
1199 }
1200
1201 bf = bf_next;
1202 }
1203
1204 /*
1205 * node is already gone. no more assocication
1206 * with the node. the node might have been freed
1207 * any node acces can result in panic.note tid
1208 * is part of the node.
1209 */
1210 if (isnodegone)
1211 return;
1212
1213 if (tid->cleanup_inprogress) {
1214 /* check to see if we're done with cleaning the h/w queue */
1215 spin_lock_bh(&txq->axq_lock);
1216
1217 if (tid->baw_head == tid->baw_tail) {
1218 tid->addba_exchangecomplete = 0;
1219 tid->addba_exchangeattempts = 0;
1220 spin_unlock_bh(&txq->axq_lock);
1221
1222 tid->cleanup_inprogress = false;
1223
1224 /* send buffered frames as singles */
1225 ath_tx_flush_tid(sc, tid);
1226 } else
1227 spin_unlock_bh(&txq->axq_lock);
1228
1229 return;
1230 }
1231
1232 /*
1233 * prepend un-acked frames to the beginning of the pending frame queue
1234 */
1235 if (!list_empty(&bf_pending)) {
1236 spin_lock_bh(&txq->axq_lock);
1237 /* Note: we _prepend_, we _do_not_ at to
1238 * the end of the queue ! */
1239 list_splice(&bf_pending, &tid->buf_q);
1240 ath_tx_queue_tid(txq, tid);
1241 spin_unlock_bh(&txq->axq_lock);
1242 }
1243
1244 if (needreset)
1245 ath_internal_reset(sc);
1246
1247 return;
1248}
1249
1250/* Process completed xmit descriptors from the specified queue */
1251
1252static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1253{
1254 struct ath_hal *ah = sc->sc_ah;
1255 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1256 struct list_head bf_head;
1257 struct ath_desc *ds, *tmp_ds;
1258 struct sk_buff *skb;
1259 struct ieee80211_tx_info *tx_info;
1260 struct ath_tx_info_priv *tx_info_priv;
1261 int nacked, txok, nbad = 0, isrifs = 0;
1262 int status;
1263
1264 DPRINTF(sc, ATH_DBG_QUEUE,
1265 "%s: tx queue %d (%x), link %p\n", __func__,
1266 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
1267 txq->axq_link);
1268
1269 nacked = 0;
1270 for (;;) {
1271 spin_lock_bh(&txq->axq_lock);
1272 txq->axq_intrcnt = 0; /* reset periodic desc intr count */
1273 if (list_empty(&txq->axq_q)) {
1274 txq->axq_link = NULL;
1275 txq->axq_linkbuf = NULL;
1276 spin_unlock_bh(&txq->axq_lock);
1277 break;
1278 }
1279 bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
1280
1281 /*
1282 * There is a race condition that a BH gets scheduled
1283 * after sw writes TxE and before hw re-load the last
1284 * descriptor to get the newly chained one.
1285 * Software must keep the last DONE descriptor as a
1286 * holding descriptor - software does so by marking
1287 * it with the STALE flag.
1288 */
1289 bf_held = NULL;
1290 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
1291 bf_held = bf;
1292 if (list_is_last(&bf_held->list, &txq->axq_q)) {
1293 /* FIXME:
1294 * The holding descriptor is the last
1295 * descriptor in queue. It's safe to remove
1296 * the last holding descriptor in BH context.
1297 */
1298 spin_unlock_bh(&txq->axq_lock);
1299 break;
1300 } else {
1301 /* Lets work with the next buffer now */
1302 bf = list_entry(bf_held->list.next,
1303 struct ath_buf, list);
1304 }
1305 }
1306
1307 lastbf = bf->bf_lastbf;
1308 ds = lastbf->bf_desc; /* NB: last decriptor */
1309
1310 status = ath9k_hw_txprocdesc(ah, ds);
1311 if (status == -EINPROGRESS) {
1312 spin_unlock_bh(&txq->axq_lock);
1313 break;
1314 }
1315 if (bf->bf_desc == txq->axq_lastdsWithCTS)
1316 txq->axq_lastdsWithCTS = NULL;
1317 if (ds == txq->axq_gatingds)
1318 txq->axq_gatingds = NULL;
1319
1320 /*
1321 * Remove ath_buf's of the same transmit unit from txq,
1322 * however leave the last descriptor back as the holding
1323 * descriptor for hw.
1324 */
1325 lastbf->bf_status |= ATH_BUFSTATUS_STALE;
1326 INIT_LIST_HEAD(&bf_head);
1327
1328 if (!list_is_singular(&lastbf->list))
1329 list_cut_position(&bf_head,
1330 &txq->axq_q, lastbf->list.prev);
1331
1332 txq->axq_depth--;
1333
1334 if (bf->bf_isaggr)
1335 txq->axq_aggr_depth--;
1336
1337 txok = (ds->ds_txstat.ts_status == 0);
1338
1339 spin_unlock_bh(&txq->axq_lock);
1340
1341 if (bf_held) {
1342 list_del(&bf_held->list);
1343 spin_lock_bh(&sc->sc_txbuflock);
1344 list_add_tail(&bf_held->list, &sc->sc_txbuf);
1345 spin_unlock_bh(&sc->sc_txbuflock);
1346 }
1347
1348 if (!bf->bf_isampdu) {
1349 /*
1350 * This frame is sent out as a single frame.
1351 * Use hardware retry status for this frame.
1352 */
1353 bf->bf_retries = ds->ds_txstat.ts_longretry;
1354 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
1355 bf->bf_isxretried = 1;
1356 nbad = 0;
1357 } else {
1358 nbad = ath_tx_num_badfrms(sc, bf, txok);
1359 }
1360 skb = bf->bf_mpdu;
1361 tx_info = IEEE80211_SKB_CB(skb);
1362 tx_info_priv = (struct ath_tx_info_priv *)
1363 tx_info->driver_data[0];
1364 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1365 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1366 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
1367 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
1368 if (ds->ds_txstat.ts_status == 0)
1369 nacked++;
1370
1371 if (bf->bf_isdata) {
1372 if (isrifs)
1373 tmp_ds = bf->bf_rifslast->bf_desc;
1374 else
1375 tmp_ds = ds;
1376 memcpy(&tx_info_priv->tx,
1377 &tmp_ds->ds_txstat,
1378 sizeof(tx_info_priv->tx));
1379 tx_info_priv->n_frames = bf->bf_nframes;
1380 tx_info_priv->n_bad_frames = nbad;
1381 }
1382 }
1383
1384 /*
1385 * Complete this transmit unit
1386 */
1387 if (bf->bf_isampdu)
1388 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok);
1389 else
1390 ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
1391
1392 /* Wake up mac80211 queue */
1393
1394 spin_lock_bh(&txq->axq_lock);
1395 if (txq->stopped && ath_txq_depth(sc, txq->axq_qnum) <=
1396 (ATH_TXBUF - 20)) {
1397 int qnum;
1398 qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
1399 if (qnum != -1) {
1400 ieee80211_wake_queue(sc->hw, qnum);
1401 txq->stopped = 0;
1402 }
1403
1404 }
1405
1406 /*
1407 * schedule any pending packets if aggregation is enabled
1408 */
1409 if (sc->sc_txaggr)
1410 ath_txq_schedule(sc, txq);
1411 spin_unlock_bh(&txq->axq_lock);
1412 }
1413 return nacked;
1414}
1415
1416static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
1417{
1418 struct ath_hal *ah = sc->sc_ah;
1419
1420 (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
1421 DPRINTF(sc, ATH_DBG_XMIT, "%s: tx queue [%u] %x, link %p\n",
1422 __func__, txq->axq_qnum,
1423 ath9k_hw_gettxbuf(ah, txq->axq_qnum), txq->axq_link);
1424}
1425
1426/* Drain only the data queues */
1427
1428static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
1429{
1430 struct ath_hal *ah = sc->sc_ah;
1431 int i;
1432 int npend = 0;
1433 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
1434
1435 /* XXX return value */
1436 if (!sc->sc_invalid) {
1437 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1438 if (ATH_TXQ_SETUP(sc, i)) {
1439 ath_tx_stopdma(sc, &sc->sc_txq[i]);
1440
1441 /* The TxDMA may not really be stopped.
1442 * Double check the hal tx pending count */
1443 npend += ath9k_hw_numtxpending(ah,
1444 sc->sc_txq[i].axq_qnum);
1445 }
1446 }
1447 }
1448
1449 if (npend) {
1450 int status;
1451
1452 /* TxDMA not stopped, reset the hal */
1453 DPRINTF(sc, ATH_DBG_XMIT,
1454 "%s: Unable to stop TxDMA. Reset HAL!\n", __func__);
1455
1456 spin_lock_bh(&sc->sc_resetlock);
1457 if (!ath9k_hw_reset(ah, sc->sc_opmode,
1458 &sc->sc_curchan, ht_macmode,
1459 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
1460 sc->sc_ht_extprotspacing, true, &status)) {
1461
1462 DPRINTF(sc, ATH_DBG_FATAL,
1463 "%s: unable to reset hardware; hal status %u\n",
1464 __func__,
1465 status);
1466 }
1467 spin_unlock_bh(&sc->sc_resetlock);
1468 }
1469
1470 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1471 if (ATH_TXQ_SETUP(sc, i))
1472 ath_tx_draintxq(sc, &sc->sc_txq[i], retry_tx);
1473 }
1474}
1475
1476/* Add a sub-frame to block ack window */
1477
1478static void ath_tx_addto_baw(struct ath_softc *sc,
1479 struct ath_atx_tid *tid,
1480 struct ath_buf *bf)
1481{
1482 int index, cindex;
1483
1484 if (bf->bf_isretried)
1485 return;
1486
1487 index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
1488 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
1489
1490 ASSERT(tid->tx_buf[cindex] == NULL);
1491 tid->tx_buf[cindex] = bf;
1492
1493 if (index >= ((tid->baw_tail - tid->baw_head) &
1494 (ATH_TID_MAX_BUFS - 1))) {
1495 tid->baw_tail = cindex;
1496 INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
1497 }
1498}
1499
1500/*
1501 * Function to send an A-MPDU
1502 * NB: must be called with txq lock held
1503 */
1504
1505static int ath_tx_send_ampdu(struct ath_softc *sc,
1506 struct ath_txq *txq,
1507 struct ath_atx_tid *tid,
1508 struct list_head *bf_head,
1509 struct ath_tx_control *txctl)
1510{
1511 struct ath_buf *bf;
1512 struct sk_buff *skb;
1513 struct ieee80211_tx_info *tx_info;
1514 struct ath_tx_info_priv *tx_info_priv;
1515
1516 BUG_ON(list_empty(bf_head));
1517
1518 bf = list_first_entry(bf_head, struct ath_buf, list);
1519 bf->bf_isampdu = 1;
1520 bf->bf_seqno = txctl->seqno; /* save seqno and tidno in buffer */
1521 bf->bf_tidno = txctl->tidno;
1522
1523 /*
1524 * Do not queue to h/w when any of the following conditions is true:
1525 * - there are pending frames in software queue
1526 * - the TID is currently paused for ADDBA/BAR request
1527 * - seqno is not within block-ack window
1528 * - h/w queue depth exceeds low water mark
1529 */
1530 if (!list_empty(&tid->buf_q) || tid->paused ||
1531 !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
1532 txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
1533 /*
1534 * Add this frame to software queue for scheduling later
1535 * for aggregation.
1536 */
1537 list_splice_tail_init(bf_head, &tid->buf_q);
1538 ath_tx_queue_tid(txq, tid);
1539 return 0;
1540 }
1541
1542 skb = (struct sk_buff *)bf->bf_mpdu;
1543 tx_info = IEEE80211_SKB_CB(skb);
1544 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
1545 memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
1546
1547 /* Add sub-frame to BAW */
1548 ath_tx_addto_baw(sc, tid, bf);
1549
1550 /* Queue to h/w without aggregation */
1551 bf->bf_nframes = 1;
1552 bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
1553 ath_buf_set_rate(sc, bf);
1554 ath_tx_txqaddbuf(sc, txq, bf_head);
1555 return 0;
1556}
1557
1558/*
1559 * looks up the rate
1560 * returns aggr limit based on lowest of the rates
1561 */
1562
1563static u32 ath_lookup_rate(struct ath_softc *sc,
1564 struct ath_buf *bf)
1565{
1566 const struct ath9k_rate_table *rt = sc->sc_currates;
1567 struct sk_buff *skb;
1568 struct ieee80211_tx_info *tx_info;
1569 struct ath_tx_info_priv *tx_info_priv;
1570 u32 max_4ms_framelen, frame_length;
1571 u16 aggr_limit, legacy = 0, maxampdu;
1572 int i;
1573
1574
1575 skb = (struct sk_buff *)bf->bf_mpdu;
1576 tx_info = IEEE80211_SKB_CB(skb);
1577 tx_info_priv = (struct ath_tx_info_priv *)
1578 tx_info->driver_data[0];
1579 memcpy(bf->bf_rcs,
1580 tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
1581
1582 /*
1583 * Find the lowest frame length among the rate series that will have a
1584 * 4ms transmit duration.
1585 * TODO - TXOP limit needs to be considered.
1586 */
1587 max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
1588
1589 for (i = 0; i < 4; i++) {
1590 if (bf->bf_rcs[i].tries) {
1591 frame_length = bf->bf_rcs[i].max_4ms_framelen;
1592
1593 if (rt->info[bf->bf_rcs[i].rix].phy != PHY_HT) {
1594 legacy = 1;
1595 break;
1596 }
1597
1598 max_4ms_framelen = min(max_4ms_framelen, frame_length);
1599 }
1600 }
1601
1602 /*
1603 * limit aggregate size by the minimum rate if rate selected is
1604 * not a probe rate, if rate selected is a probe rate then
1605 * avoid aggregation of this packet.
1606 */
1607 if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
1608 return 0;
1609
1610 aggr_limit = min(max_4ms_framelen,
1611 (u32)ATH_AMPDU_LIMIT_DEFAULT);
1612
1613 /*
1614 * h/w can accept aggregates upto 16 bit lengths (65535).
1615 * The IE, however can hold upto 65536, which shows up here
1616 * as zero. Ignore 65536 since we are constrained by hw.
1617 */
1618 maxampdu = sc->sc_ht_info.maxampdu;
1619 if (maxampdu)
1620 aggr_limit = min(aggr_limit, maxampdu);
1621
1622 return aggr_limit;
1623}
1624
1625/*
1626 * returns the number of delimiters to be added to
1627 * meet the minimum required mpdudensity.
1628 * caller should make sure that the rate is HT rate .
1629 */
1630
1631static int ath_compute_num_delims(struct ath_softc *sc,
1632 struct ath_buf *bf,
1633 u16 frmlen)
1634{
1635 const struct ath9k_rate_table *rt = sc->sc_currates;
1636 u32 nsymbits, nsymbols, mpdudensity;
1637 u16 minlen;
1638 u8 rc, flags, rix;
1639 int width, half_gi, ndelim, mindelim;
1640
1641 /* Select standard number of delimiters based on frame length alone */
1642 ndelim = ATH_AGGR_GET_NDELIM(frmlen);
1643
1644 /*
1645 * If encryption enabled, hardware requires some more padding between
1646 * subframes.
1647 * TODO - this could be improved to be dependent on the rate.
1648 * The hardware can keep up at lower rates, but not higher rates
1649 */
1650 if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
1651 ndelim += ATH_AGGR_ENCRYPTDELIM;
1652
1653 /*
1654 * Convert desired mpdu density from microeconds to bytes based
1655 * on highest rate in rate series (i.e. first rate) to determine
1656 * required minimum length for subframe. Take into account
1657 * whether high rate is 20 or 40Mhz and half or full GI.
1658 */
1659 mpdudensity = sc->sc_ht_info.mpdudensity;
1660
1661 /*
1662 * If there is no mpdu density restriction, no further calculation
1663 * is needed.
1664 */
1665 if (mpdudensity == 0)
1666 return ndelim;
1667
1668 rix = bf->bf_rcs[0].rix;
1669 flags = bf->bf_rcs[0].flags;
1670 rc = rt->info[rix].rateCode;
1671 width = (flags & ATH_RC_CW40_FLAG) ? 1 : 0;
1672 half_gi = (flags & ATH_RC_SGI_FLAG) ? 1 : 0;
1673
1674 if (half_gi)
1675 nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
1676 else
1677 nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
1678
1679 if (nsymbols == 0)
1680 nsymbols = 1;
1681
1682 nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
1683 minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
1684
1685 /* Is frame shorter than required minimum length? */
1686 if (frmlen < minlen) {
1687 /* Get the minimum number of delimiters required. */
1688 mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
1689 ndelim = max(mindelim, ndelim);
1690 }
1691
1692 return ndelim;
1693}
1694
1695/*
1696 * For aggregation from software buffer queue.
1697 * NB: must be called with txq lock held
1698 */
1699
1700static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
1701 struct ath_atx_tid *tid,
1702 struct list_head *bf_q,
1703 struct ath_buf **bf_last,
1704 struct aggr_rifs_param *param,
1705 int *prev_frames)
1706{
1707#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
1708 struct ath_buf *bf, *tbf, *bf_first, *bf_prev = NULL;
1709 struct list_head bf_head;
1710 int rl = 0, nframes = 0, ndelim;
1711 u16 aggr_limit = 0, al = 0, bpad = 0,
1712 al_delta, h_baw = tid->baw_size / 2;
1713 enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
1714 int prev_al = 0, is_ds_rate = 0;
1715 INIT_LIST_HEAD(&bf_head);
1716
1717 BUG_ON(list_empty(&tid->buf_q));
1718
1719 bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
1720
1721 do {
1722 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
1723
1724 /*
1725 * do not step over block-ack window
1726 */
1727 if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
1728 status = ATH_AGGR_BAW_CLOSED;
1729 break;
1730 }
1731
1732 if (!rl) {
1733 aggr_limit = ath_lookup_rate(sc, bf);
1734 rl = 1;
1735 /*
1736 * Is rate dual stream
1737 */
1738 is_ds_rate =
1739 (bf->bf_rcs[0].flags & ATH_RC_DS_FLAG) ? 1 : 0;
1740 }
1741
1742 /*
1743 * do not exceed aggregation limit
1744 */
1745 al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
1746
1747 if (nframes && (aggr_limit <
1748 (al + bpad + al_delta + prev_al))) {
1749 status = ATH_AGGR_LIMITED;
1750 break;
1751 }
1752
1753 /*
1754 * do not exceed subframe limit
1755 */
1756 if ((nframes + *prev_frames) >=
1757 min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
1758 status = ATH_AGGR_LIMITED;
1759 break;
1760 }
1761
1762 /*
1763 * add padding for previous frame to aggregation length
1764 */
1765 al += bpad + al_delta;
1766
1767 /*
1768 * Get the delimiters needed to meet the MPDU
1769 * density for this node.
1770 */
1771 ndelim = ath_compute_num_delims(sc, bf_first, bf->bf_frmlen);
1772
1773 bpad = PADBYTES(al_delta) + (ndelim << 2);
1774
1775 bf->bf_next = NULL;
1776 bf->bf_lastfrm->bf_desc->ds_link = 0;
1777
1778 /*
1779 * this packet is part of an aggregate
1780 * - remove all descriptors belonging to this frame from
1781 * software queue
1782 * - add it to block ack window
1783 * - set up descriptors for aggregation
1784 */
1785 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1786 ath_tx_addto_baw(sc, tid, bf);
1787
1788 list_for_each_entry(tbf, &bf_head, list) {
1789 ath9k_hw_set11n_aggr_middle(sc->sc_ah,
1790 tbf->bf_desc, ndelim);
1791 }
1792
1793 /*
1794 * link buffers of this frame to the aggregate
1795 */
1796 list_splice_tail_init(&bf_head, bf_q);
1797 nframes++;
1798
1799 if (bf_prev) {
1800 bf_prev->bf_next = bf;
1801 bf_prev->bf_lastfrm->bf_desc->ds_link = bf->bf_daddr;
1802 }
1803 bf_prev = bf;
1804
1805#ifdef AGGR_NOSHORT
1806 /*
1807 * terminate aggregation on a small packet boundary
1808 */
1809 if (bf->bf_frmlen < ATH_AGGR_MINPLEN) {
1810 status = ATH_AGGR_SHORTPKT;
1811 break;
1812 }
1813#endif
1814 } while (!list_empty(&tid->buf_q));
1815
1816 bf_first->bf_al = al;
1817 bf_first->bf_nframes = nframes;
1818 *bf_last = bf_prev;
1819 return status;
1820#undef PADBYTES
1821}
1822
1823/*
1824 * process pending frames possibly doing a-mpdu aggregation
1825 * NB: must be called with txq lock held
1826 */
1827
1828static void ath_tx_sched_aggr(struct ath_softc *sc,
1829 struct ath_txq *txq, struct ath_atx_tid *tid)
1830{
1831 struct ath_buf *bf, *tbf, *bf_last, *bf_lastaggr = NULL;
1832 enum ATH_AGGR_STATUS status;
1833 struct list_head bf_q;
1834 struct aggr_rifs_param param = {0, 0, 0, 0, NULL};
1835 int prev_frames = 0;
1836
1837 do {
1838 if (list_empty(&tid->buf_q))
1839 return;
1840
1841 INIT_LIST_HEAD(&bf_q);
1842
1843 status = ath_tx_form_aggr(sc, tid, &bf_q, &bf_lastaggr, &param,
1844 &prev_frames);
1845
1846 /*
1847 * no frames picked up to be aggregated; block-ack
1848 * window is not open
1849 */
1850 if (list_empty(&bf_q))
1851 break;
1852
1853 bf = list_first_entry(&bf_q, struct ath_buf, list);
1854 bf_last = list_entry(bf_q.prev, struct ath_buf, list);
1855 bf->bf_lastbf = bf_last;
1856
1857 /*
1858 * if only one frame, send as non-aggregate
1859 */
1860 if (bf->bf_nframes == 1) {
1861 ASSERT(bf->bf_lastfrm == bf_last);
1862
1863 bf->bf_isaggr = 0;
1864 /*
1865 * clear aggr bits for every descriptor
1866 * XXX TODO: is there a way to optimize it?
1867 */
1868 list_for_each_entry(tbf, &bf_q, list) {
1869 ath9k_hw_clr11n_aggr(sc->sc_ah, tbf->bf_desc);
1870 }
1871
1872 ath_buf_set_rate(sc, bf);
1873 ath_tx_txqaddbuf(sc, txq, &bf_q);
1874 continue;
1875 }
1876
1877 /*
1878 * setup first desc with rate and aggr info
1879 */
1880 bf->bf_isaggr = 1;
1881 ath_buf_set_rate(sc, bf);
1882 ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
1883
1884 /*
1885 * anchor last frame of aggregate correctly
1886 */
1887 ASSERT(bf_lastaggr);
1888 ASSERT(bf_lastaggr->bf_lastfrm == bf_last);
1889 tbf = bf_lastaggr;
1890 ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
1891
1892 /* XXX: We don't enter into this loop, consider removing this */
1893 while (!list_empty(&bf_q) && !list_is_last(&tbf->list, &bf_q)) {
1894 tbf = list_entry(tbf->list.next, struct ath_buf, list);
1895 ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
1896 }
1897
1898 txq->axq_aggr_depth++;
1899
1900 /*
1901 * Normal aggregate, queue to hardware
1902 */
1903 ath_tx_txqaddbuf(sc, txq, &bf_q);
1904
1905 } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
1906 status != ATH_AGGR_BAW_CLOSED);
1907}
1908
1909/* Called with txq lock held */
1910
1911static void ath_tid_drain(struct ath_softc *sc,
1912 struct ath_txq *txq,
1913 struct ath_atx_tid *tid,
1914 bool bh_flag)
1915{
1916 struct ath_buf *bf;
1917 struct list_head bf_head;
1918 INIT_LIST_HEAD(&bf_head);
1919
1920 for (;;) {
1921 if (list_empty(&tid->buf_q))
1922 break;
1923 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
1924
1925 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1926
1927 /* update baw for software retried frame */
1928 if (bf->bf_isretried)
1929 ath_tx_update_baw(sc, tid, bf->bf_seqno);
1930
1931 /*
1932 * do not indicate packets while holding txq spinlock.
1933 * unlock is intentional here
1934 */
1935 if (likely(bh_flag))
1936 spin_unlock_bh(&txq->axq_lock);
1937 else
1938 spin_unlock(&txq->axq_lock);
1939
1940 /* complete this sub-frame */
1941 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
1942
1943 if (likely(bh_flag))
1944 spin_lock_bh(&txq->axq_lock);
1945 else
1946 spin_lock(&txq->axq_lock);
1947 }
1948
1949 /*
1950 * TODO: For frame(s) that are in the retry state, we will reuse the
1951 * sequence number(s) without setting the retry bit. The
1952 * alternative is to give up on these and BAR the receiver's window
1953 * forward.
1954 */
1955 tid->seq_next = tid->seq_start;
1956 tid->baw_tail = tid->baw_head;
1957}
1958
1959/*
1960 * Drain all pending buffers
1961 * NB: must be called with txq lock held
1962 */
1963
1964static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
1965 struct ath_txq *txq,
1966 bool bh_flag)
1967{
1968 struct ath_atx_ac *ac, *ac_tmp;
1969 struct ath_atx_tid *tid, *tid_tmp;
1970
1971 list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
1972 list_del(&ac->list);
1973 ac->sched = false;
1974 list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
1975 list_del(&tid->list);
1976 tid->sched = false;
1977 ath_tid_drain(sc, txq, tid, bh_flag);
1978 }
1979 }
1980}
1981
1982static int ath_tx_start_dma(struct ath_softc *sc,
1983 struct sk_buff *skb,
1984 struct scatterlist *sg,
1985 u32 n_sg,
1986 struct ath_tx_control *txctl)
1987{
1988 struct ath_node *an = txctl->an;
1989 struct ath_buf *bf = NULL;
1990 struct list_head bf_head;
1991 struct ath_desc *ds;
1992 struct ath_hal *ah = sc->sc_ah;
1993 struct ath_txq *txq = &sc->sc_txq[txctl->qnum];
1994 struct ath_tx_info_priv *tx_info_priv;
1995 struct ath_rc_series *rcs;
1996 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1997 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1998 __le16 fc = hdr->frame_control;
1999
2000 /* For each sglist entry, allocate an ath_buf for DMA */
2001 INIT_LIST_HEAD(&bf_head);
2002 spin_lock_bh(&sc->sc_txbuflock);
2003 if (unlikely(list_empty(&sc->sc_txbuf))) {
2004 spin_unlock_bh(&sc->sc_txbuflock);
2005 return -ENOMEM;
2006 }
2007
2008 bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list);
2009 list_del(&bf->list);
2010 spin_unlock_bh(&sc->sc_txbuflock);
2011
2012 list_add_tail(&bf->list, &bf_head);
2013
2014 /* set up this buffer */
2015 ATH_TXBUF_RESET(bf);
2016 bf->bf_frmlen = txctl->frmlen;
2017 bf->bf_isdata = ieee80211_is_data(fc);
2018 bf->bf_isbar = ieee80211_is_back_req(fc);
2019 bf->bf_ispspoll = ieee80211_is_pspoll(fc);
2020 bf->bf_flags = txctl->flags;
2021 bf->bf_shpreamble = sc->sc_flags & ATH_PREAMBLE_SHORT;
2022 bf->bf_keytype = txctl->keytype;
2023 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
2024 rcs = tx_info_priv->rcs;
2025 bf->bf_rcs[0] = rcs[0];
2026 bf->bf_rcs[1] = rcs[1];
2027 bf->bf_rcs[2] = rcs[2];
2028 bf->bf_rcs[3] = rcs[3];
2029 bf->bf_node = an;
2030 bf->bf_mpdu = skb;
2031 bf->bf_buf_addr = sg_dma_address(sg);
2032
2033 /* setup descriptor */
2034 ds = bf->bf_desc;
2035 ds->ds_link = 0;
2036 ds->ds_data = bf->bf_buf_addr;
2037
2038 /*
2039 * Save the DMA context in the first ath_buf
2040 */
2041 copy_dma_mem_context(get_dma_mem_context(bf, bf_dmacontext),
2042 get_dma_mem_context(txctl, dmacontext));
2043
2044 /*
2045 * Formulate first tx descriptor with tx controls.
2046 */
2047 ath9k_hw_set11n_txdesc(ah,
2048 ds,
2049 bf->bf_frmlen, /* frame length */
2050 txctl->atype, /* Atheros packet type */
2051 min(txctl->txpower, (u16)60), /* txpower */
2052 txctl->keyix, /* key cache index */
2053 txctl->keytype, /* key type */
2054 txctl->flags); /* flags */
2055 ath9k_hw_filltxdesc(ah,
2056 ds,
2057 sg_dma_len(sg), /* segment length */
2058 true, /* first segment */
2059 (n_sg == 1) ? true : false, /* last segment */
2060 ds); /* first descriptor */
2061
2062 bf->bf_lastfrm = bf;
2063 bf->bf_ht = txctl->ht;
2064
2065 spin_lock_bh(&txq->axq_lock);
2066
2067 if (txctl->ht && sc->sc_txaggr) {
2068 struct ath_atx_tid *tid = ATH_AN_2_TID(an, txctl->tidno);
2069 if (ath_aggr_query(sc, an, txctl->tidno)) {
2070 /*
2071 * Try aggregation if it's a unicast data frame
2072 * and the destination is HT capable.
2073 */
2074 ath_tx_send_ampdu(sc, txq, tid, &bf_head, txctl);
2075 } else {
2076 /*
2077 * Send this frame as regular when ADDBA exchange
2078 * is neither complete nor pending.
2079 */
2080 ath_tx_send_normal(sc, txq, tid, &bf_head);
2081 }
2082 } else {
2083 bf->bf_lastbf = bf;
2084 bf->bf_nframes = 1;
2085 ath_buf_set_rate(sc, bf);
2086
2087 if (ieee80211_is_back_req(fc)) {
2088 /* This is required for resuming tid
2089 * during BAR completion */
2090 bf->bf_tidno = txctl->tidno;
2091 }
2092
2093 if (is_multicast_ether_addr(hdr->addr1)) {
2094 struct ath_vap *avp = sc->sc_vaps[txctl->if_id];
2095
2096 /*
2097 * When servicing one or more stations in power-save
2098 * mode (or) if there is some mcast data waiting on
2099 * mcast queue (to prevent out of order delivery of
2100 * mcast,bcast packets) multicast frames must be
2101 * buffered until after the beacon. We use the private
2102 * mcast queue for that.
2103 */
2104 /* XXX? more bit in 802.11 frame header */
2105 spin_lock_bh(&avp->av_mcastq.axq_lock);
2106 if (txctl->ps || avp->av_mcastq.axq_depth)
2107 ath_tx_mcastqaddbuf(sc,
2108 &avp->av_mcastq, &bf_head);
2109 else
2110 ath_tx_txqaddbuf(sc, txq, &bf_head);
2111 spin_unlock_bh(&avp->av_mcastq.axq_lock);
2112 } else
2113 ath_tx_txqaddbuf(sc, txq, &bf_head);
2114 }
2115 spin_unlock_bh(&txq->axq_lock);
2116 return 0;
2117}
2118
2119static void xmit_map_sg(struct ath_softc *sc,
2120 struct sk_buff *skb,
2121 dma_addr_t *pa,
2122 struct ath_tx_control *txctl)
2123{
2124 struct ath_xmit_status tx_status;
2125 struct ath_atx_tid *tid;
2126 struct scatterlist sg;
2127
2128 *pa = pci_map_single(sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
2129
2130 /* setup S/G list */
2131 memset(&sg, 0, sizeof(struct scatterlist));
2132 sg_dma_address(&sg) = *pa;
2133 sg_dma_len(&sg) = skb->len;
2134
2135 if (ath_tx_start_dma(sc, skb, &sg, 1, txctl) != 0) {
2136 /*
2137 * We have to do drop frame here.
2138 */
2139 pci_unmap_single(sc->pdev, *pa, skb->len, PCI_DMA_TODEVICE);
2140
2141 tx_status.retries = 0;
2142 tx_status.flags = ATH_TX_ERROR;
2143
2144 if (txctl->ht && sc->sc_txaggr) {
2145 /* Reclaim the seqno. */
2146 tid = ATH_AN_2_TID((struct ath_node *)
2147 txctl->an, txctl->tidno);
2148 DECR(tid->seq_next, IEEE80211_SEQ_MAX);
2149 }
2150 ath_tx_complete(sc, skb, &tx_status, txctl->an);
2151 }
2152}
2153
2154/* Initialize TX queue and h/w */
2155
2156int ath_tx_init(struct ath_softc *sc, int nbufs)
2157{
2158 int error = 0;
2159
2160 do {
2161 spin_lock_init(&sc->sc_txbuflock);
2162
2163 /* Setup tx descriptors */
2164 error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
2165 "tx", nbufs * ATH_FRAG_PER_MSDU, ATH_TXDESC);
2166 if (error != 0) {
2167 DPRINTF(sc, ATH_DBG_FATAL,
2168 "%s: failed to allocate tx descriptors: %d\n",
2169 __func__, error);
2170 break;
2171 }
2172
2173 /* XXX allocate beacon state together with vap */
2174 error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
2175 "beacon", ATH_BCBUF, 1);
2176 if (error != 0) {
2177 DPRINTF(sc, ATH_DBG_FATAL,
2178 "%s: failed to allocate "
2179 "beacon descripotrs: %d\n",
2180 __func__, error);
2181 break;
2182 }
2183
2184 } while (0);
2185
2186 if (error != 0)
2187 ath_tx_cleanup(sc);
2188
2189 return error;
2190}
2191
2192/* Reclaim all tx queue resources */
2193
2194int ath_tx_cleanup(struct ath_softc *sc)
2195{
2196 /* cleanup beacon descriptors */
2197 if (sc->sc_bdma.dd_desc_len != 0)
2198 ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf);
2199
2200 /* cleanup tx descriptors */
2201 if (sc->sc_txdma.dd_desc_len != 0)
2202 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);
2203
2204 return 0;
2205}
2206
2207/* Setup a h/w transmit queue */
2208
2209struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
2210{
2211 struct ath_hal *ah = sc->sc_ah;
2212 struct ath9k_tx_queue_info qi;
2213 int qnum;
2214
2215 memzero(&qi, sizeof(qi));
2216 qi.tqi_subtype = subtype;
2217 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
2218 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
2219 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
2220 qi.tqi_physCompBuf = 0;
2221
2222 /*
2223 * Enable interrupts only for EOL and DESC conditions.
2224 * We mark tx descriptors to receive a DESC interrupt
2225 * when a tx queue gets deep; otherwise waiting for the
2226 * EOL to reap descriptors. Note that this is done to
2227 * reduce interrupt load and this only defers reaping
2228 * descriptors, never transmitting frames. Aside from
2229 * reducing interrupts this also permits more concurrency.
2230 * The only potential downside is if the tx queue backs
2231 * up in which case the top half of the kernel may backup
2232 * due to a lack of tx descriptors.
2233 *
2234 * The UAPSD queue is an exception, since we take a desc-
2235 * based intr on the EOSP frames.
2236 */
2237 if (qtype == ATH9K_TX_QUEUE_UAPSD)
2238 qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
2239 else
2240 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
2241 TXQ_FLAG_TXDESCINT_ENABLE;
2242 qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
2243 if (qnum == -1) {
2244 /*
2245 * NB: don't print a message, this happens
2246 * normally on parts with too few tx queues
2247 */
2248 return NULL;
2249 }
2250 if (qnum >= ARRAY_SIZE(sc->sc_txq)) {
2251 DPRINTF(sc, ATH_DBG_FATAL,
2252 "%s: hal qnum %u out of range, max %u!\n",
2253 __func__, qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq));
2254 ath9k_hw_releasetxqueue(ah, qnum);
2255 return NULL;
2256 }
2257 if (!ATH_TXQ_SETUP(sc, qnum)) {
2258 struct ath_txq *txq = &sc->sc_txq[qnum];
2259
2260 txq->axq_qnum = qnum;
2261 txq->axq_link = NULL;
2262 INIT_LIST_HEAD(&txq->axq_q);
2263 INIT_LIST_HEAD(&txq->axq_acq);
2264 spin_lock_init(&txq->axq_lock);
2265 txq->axq_depth = 0;
2266 txq->axq_aggr_depth = 0;
2267 txq->axq_totalqueued = 0;
2268 txq->axq_intrcnt = 0;
2269 txq->axq_linkbuf = NULL;
2270 sc->sc_txqsetup |= 1<<qnum;
2271 }
2272 return &sc->sc_txq[qnum];
2273}
2274
2275/* Reclaim resources for a setup queue */
2276
2277void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
2278{
2279 ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
2280 sc->sc_txqsetup &= ~(1<<txq->axq_qnum);
2281}
2282
2283/*
2284 * Setup a hardware data transmit queue for the specified
2285 * access control. The hal may not support all requested
2286 * queues in which case it will return a reference to a
2287 * previously setup queue. We record the mapping from ac's
2288 * to h/w queues for use by ath_tx_start and also track
2289 * the set of h/w queues being used to optimize work in the
2290 * transmit interrupt handler and related routines.
2291 */
2292
2293int ath_tx_setup(struct ath_softc *sc, int haltype)
2294{
2295 struct ath_txq *txq;
2296
2297 if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
2298 DPRINTF(sc, ATH_DBG_FATAL,
2299 "%s: HAL AC %u out of range, max %zu!\n",
2300 __func__, haltype, ARRAY_SIZE(sc->sc_haltype2q));
2301 return 0;
2302 }
2303 txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
2304 if (txq != NULL) {
2305 sc->sc_haltype2q[haltype] = txq->axq_qnum;
2306 return 1;
2307 } else
2308 return 0;
2309}
2310
2311int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
2312{
2313 int qnum;
2314
2315 switch (qtype) {
2316 case ATH9K_TX_QUEUE_DATA:
2317 if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
2318 DPRINTF(sc, ATH_DBG_FATAL,
2319 "%s: HAL AC %u out of range, max %zu!\n",
2320 __func__,
2321 haltype, ARRAY_SIZE(sc->sc_haltype2q));
2322 return -1;
2323 }
2324 qnum = sc->sc_haltype2q[haltype];
2325 break;
2326 case ATH9K_TX_QUEUE_BEACON:
2327 qnum = sc->sc_bhalq;
2328 break;
2329 case ATH9K_TX_QUEUE_CAB:
2330 qnum = sc->sc_cabq->axq_qnum;
2331 break;
2332 default:
2333 qnum = -1;
2334 }
2335 return qnum;
2336}
2337
2338/* Update parameters for a transmit queue */
2339
2340int ath_txq_update(struct ath_softc *sc, int qnum,
2341 struct ath9k_tx_queue_info *qinfo)
2342{
2343 struct ath_hal *ah = sc->sc_ah;
2344 int error = 0;
2345 struct ath9k_tx_queue_info qi;
2346
2347 if (qnum == sc->sc_bhalq) {
2348 /*
2349 * XXX: for beacon queue, we just save the parameter.
2350 * It will be picked up by ath_beaconq_config when
2351 * it's necessary.
2352 */
2353 sc->sc_beacon_qi = *qinfo;
2354 return 0;
2355 }
2356
2357 ASSERT(sc->sc_txq[qnum].axq_qnum == qnum);
2358
2359 ath9k_hw_get_txq_props(ah, qnum, &qi);
2360 qi.tqi_aifs = qinfo->tqi_aifs;
2361 qi.tqi_cwmin = qinfo->tqi_cwmin;
2362 qi.tqi_cwmax = qinfo->tqi_cwmax;
2363 qi.tqi_burstTime = qinfo->tqi_burstTime;
2364 qi.tqi_readyTime = qinfo->tqi_readyTime;
2365
2366 if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
2367 DPRINTF(sc, ATH_DBG_FATAL,
2368 "%s: unable to update hardware queue %u!\n",
2369 __func__, qnum);
2370 error = -EIO;
2371 } else {
2372 ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
2373 }
2374
2375 return error;
2376}
2377
2378int ath_cabq_update(struct ath_softc *sc)
2379{
2380 struct ath9k_tx_queue_info qi;
2381 int qnum = sc->sc_cabq->axq_qnum;
2382 struct ath_beacon_config conf;
2383
2384 ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
2385 /*
2386 * Ensure the readytime % is within the bounds.
2387 */
2388 if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
2389 sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
2390 else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
2391 sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
2392
2393 ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf);
2394 qi.tqi_readyTime =
2395 (conf.beacon_interval * sc->sc_config.cabqReadytime) / 100;
2396 ath_txq_update(sc, qnum, &qi);
2397
2398 return 0;
2399}
2400
2401int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb)
2402{
2403 struct ath_tx_control txctl;
2404 int error = 0;
2405
2406 error = ath_tx_prepare(sc, skb, &txctl);
2407 if (error == 0)
2408 /*
2409 * Start DMA mapping.
2410 * ath_tx_start_dma() will be called either synchronously
2411 * or asynchrounsly once DMA is complete.
2412 */
2413 xmit_map_sg(sc, skb,
2414 get_dma_mem_context(&txctl, dmacontext),
2415 &txctl);
2416 else
2417 ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);
2418
2419 /* failed packets will be dropped by the caller */
2420 return error;
2421}
2422
2423/* Deferred processing of transmit interrupt */
2424
2425void ath_tx_tasklet(struct ath_softc *sc)
2426{
2427 u64 tsf = ath9k_hw_gettsf64(sc->sc_ah);
2428 int i, nacked = 0;
2429 u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
2430
2431 ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
2432
2433 /*
2434 * Process each active queue.
2435 */
2436 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2437 if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
2438 nacked += ath_tx_processq(sc, &sc->sc_txq[i]);
2439 }
2440 if (nacked)
2441 sc->sc_lastrx = tsf;
2442}
2443
2444void ath_tx_draintxq(struct ath_softc *sc,
2445 struct ath_txq *txq, bool retry_tx)
2446{
2447 struct ath_buf *bf, *lastbf;
2448 struct list_head bf_head;
2449
2450 INIT_LIST_HEAD(&bf_head);
2451
2452 /*
2453 * NB: this assumes output has been stopped and
2454 * we do not need to block ath_tx_tasklet
2455 */
2456 for (;;) {
2457 spin_lock_bh(&txq->axq_lock);
2458
2459 if (list_empty(&txq->axq_q)) {
2460 txq->axq_link = NULL;
2461 txq->axq_linkbuf = NULL;
2462 spin_unlock_bh(&txq->axq_lock);
2463 break;
2464 }
2465
2466 bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
2467
2468 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
2469 list_del(&bf->list);
2470 spin_unlock_bh(&txq->axq_lock);
2471
2472 spin_lock_bh(&sc->sc_txbuflock);
2473 list_add_tail(&bf->list, &sc->sc_txbuf);
2474 spin_unlock_bh(&sc->sc_txbuflock);
2475 continue;
2476 }
2477
2478 lastbf = bf->bf_lastbf;
2479 if (!retry_tx)
2480 lastbf->bf_desc->ds_txstat.ts_flags =
2481 ATH9K_TX_SW_ABORTED;
2482
2483 /* remove ath_buf's of the same mpdu from txq */
2484 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
2485 txq->axq_depth--;
2486
2487 spin_unlock_bh(&txq->axq_lock);
2488
2489 if (bf->bf_isampdu)
2490 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0);
2491 else
2492 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
2493 }
2494
2495 /* flush any pending frames if aggregation is enabled */
2496 if (sc->sc_txaggr) {
2497 if (!retry_tx) {
2498 spin_lock_bh(&txq->axq_lock);
2499 ath_txq_drain_pending_buffers(sc, txq,
2500 ATH9K_BH_STATUS_CHANGE);
2501 spin_unlock_bh(&txq->axq_lock);
2502 }
2503 }
2504}
2505
2506/* Drain the transmit queues and reclaim resources */
2507
2508void ath_draintxq(struct ath_softc *sc, bool retry_tx)
2509{
2510 /* stop beacon queue. The beacon will be freed when
2511 * we go to INIT state */
2512 if (!sc->sc_invalid) {
2513 (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
2514 DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__,
2515 ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq));
2516 }
2517
2518 ath_drain_txdataq(sc, retry_tx);
2519}
2520
2521u32 ath_txq_depth(struct ath_softc *sc, int qnum)
2522{
2523 return sc->sc_txq[qnum].axq_depth;
2524}
2525
2526u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
2527{
2528 return sc->sc_txq[qnum].axq_aggr_depth;
2529}
2530
2531/* Check if an ADDBA is required. A valid node must be passed. */
2532enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
2533 struct ath_node *an,
2534 u8 tidno)
2535{
2536 struct ath_atx_tid *txtid;
2537 DECLARE_MAC_BUF(mac);
2538
2539 if (!sc->sc_txaggr)
2540 return AGGR_NOT_REQUIRED;
2541
2542 /* ADDBA exchange must be completed before sending aggregates */
2543 txtid = ATH_AN_2_TID(an, tidno);
2544
2545 if (txtid->addba_exchangecomplete)
2546 return AGGR_EXCHANGE_DONE;
2547
2548 if (txtid->cleanup_inprogress)
2549 return AGGR_CLEANUP_PROGRESS;
2550
2551 if (txtid->addba_exchangeinprogress)
2552 return AGGR_EXCHANGE_PROGRESS;
2553
2554 if (!txtid->addba_exchangecomplete) {
2555 if (!txtid->addba_exchangeinprogress &&
2556 (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
2557 txtid->addba_exchangeattempts++;
2558 return AGGR_REQUIRED;
2559 }
2560 }
2561
2562 return AGGR_NOT_REQUIRED;
2563}
2564
2565/* Start TX aggregation */
2566
2567int ath_tx_aggr_start(struct ath_softc *sc,
2568 const u8 *addr,
2569 u16 tid,
2570 u16 *ssn)
2571{
2572 struct ath_atx_tid *txtid;
2573 struct ath_node *an;
2574
2575 spin_lock_bh(&sc->node_lock);
2576 an = ath_node_find(sc, (u8 *) addr);
2577 spin_unlock_bh(&sc->node_lock);
2578
2579 if (!an) {
2580 DPRINTF(sc, ATH_DBG_AGGR,
2581 "%s: Node not found to initialize "
2582 "TX aggregation\n", __func__);
2583 return -1;
2584 }
2585
2586 if (sc->sc_txaggr) {
2587 txtid = ATH_AN_2_TID(an, tid);
2588 txtid->addba_exchangeinprogress = 1;
2589 ath_tx_pause_tid(sc, txtid);
2590 }
2591
2592 return 0;
2593}
2594
2595/* Stop tx aggregation */
2596
2597int ath_tx_aggr_stop(struct ath_softc *sc,
2598 const u8 *addr,
2599 u16 tid)
2600{
2601 struct ath_node *an;
2602
2603 spin_lock_bh(&sc->node_lock);
2604 an = ath_node_find(sc, (u8 *) addr);
2605 spin_unlock_bh(&sc->node_lock);
2606
2607 if (!an) {
2608 DPRINTF(sc, ATH_DBG_AGGR,
2609 "%s: TX aggr stop for non-existent node\n", __func__);
2610 return -1;
2611 }
2612
2613 ath_tx_aggr_teardown(sc, an, tid);
2614 return 0;
2615}
2616
2617/*
2618 * Performs transmit side cleanup when TID changes from aggregated to
2619 * unaggregated.
2620 * - Pause the TID and mark cleanup in progress
2621 * - Discard all retry frames from the s/w queue.
2622 */
2623
2624void ath_tx_aggr_teardown(struct ath_softc *sc,
2625 struct ath_node *an, u8 tid)
2626{
2627 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
2628 struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum];
2629 struct ath_buf *bf;
2630 struct list_head bf_head;
2631 INIT_LIST_HEAD(&bf_head);
2632
2633 DPRINTF(sc, ATH_DBG_AGGR, "%s: teardown TX aggregation\n", __func__);
2634
2635 if (txtid->cleanup_inprogress) /* cleanup is in progress */
2636 return;
2637
2638 if (!txtid->addba_exchangecomplete) {
2639 txtid->addba_exchangeattempts = 0;
2640 return;
2641 }
2642
2643 /* TID must be paused first */
2644 ath_tx_pause_tid(sc, txtid);
2645
2646 /* drop all software retried frames and mark this TID */
2647 spin_lock_bh(&txq->axq_lock);
2648 while (!list_empty(&txtid->buf_q)) {
2649 bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
2650 if (!bf->bf_isretried) {
2651 /*
2652 * NB: it's based on the assumption that
2653 * software retried frame will always stay
2654 * at the head of software queue.
2655 */
2656 break;
2657 }
2658 list_cut_position(&bf_head,
2659 &txtid->buf_q, &bf->bf_lastfrm->list);
2660 ath_tx_update_baw(sc, txtid, bf->bf_seqno);
2661
2662 /* complete this sub-frame */
2663 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
2664 }
2665
2666 if (txtid->baw_head != txtid->baw_tail) {
2667 spin_unlock_bh(&txq->axq_lock);
2668 txtid->cleanup_inprogress = true;
2669 } else {
2670 txtid->addba_exchangecomplete = 0;
2671 txtid->addba_exchangeattempts = 0;
2672 spin_unlock_bh(&txq->axq_lock);
2673 ath_tx_flush_tid(sc, txtid);
2674 }
2675}
2676
2677/*
2678 * Tx scheduling logic
2679 * NB: must be called with txq lock held
2680 */
2681
2682void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
2683{
2684 struct ath_atx_ac *ac;
2685 struct ath_atx_tid *tid;
2686
2687 /* nothing to schedule */
2688 if (list_empty(&txq->axq_acq))
2689 return;
2690 /*
2691 * get the first node/ac pair on the queue
2692 */
2693 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
2694 list_del(&ac->list);
2695 ac->sched = false;
2696
2697 /*
2698 * process a single tid per destination
2699 */
2700 do {
2701 /* nothing to schedule */
2702 if (list_empty(&ac->tid_q))
2703 return;
2704
2705 tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
2706 list_del(&tid->list);
2707 tid->sched = false;
2708
2709 if (tid->paused) /* check next tid to keep h/w busy */
2710 continue;
2711
2712 if (!(tid->an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) ||
2713 ((txq->axq_depth % 2) == 0)) {
2714 ath_tx_sched_aggr(sc, txq, tid);
2715 }
2716
2717 /*
2718 * add tid to round-robin queue if more frames
2719 * are pending for the tid
2720 */
2721 if (!list_empty(&tid->buf_q))
2722 ath_tx_queue_tid(txq, tid);
2723
2724 /* only schedule one TID at a time */
2725 break;
2726 } while (!list_empty(&ac->tid_q));
2727
2728 /*
2729 * schedule AC if more TIDs need processing
2730 */
2731 if (!list_empty(&ac->tid_q)) {
2732 /*
2733 * add dest ac to txq if not already added
2734 */
2735 if (!ac->sched) {
2736 ac->sched = true;
2737 list_add_tail(&ac->list, &txq->axq_acq);
2738 }
2739 }
2740}
2741
2742/* Initialize per-node transmit state */
2743
2744void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2745{
2746 if (sc->sc_txaggr) {
2747 struct ath_atx_tid *tid;
2748 struct ath_atx_ac *ac;
2749 int tidno, acno;
2750
2751 sc->sc_ht_info.maxampdu = ATH_AMPDU_LIMIT_DEFAULT;
2752
2753 /*
2754 * Init per tid tx state
2755 */
2756 for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
2757 tidno < WME_NUM_TID;
2758 tidno++, tid++) {
2759 tid->an = an;
2760 tid->tidno = tidno;
2761 tid->seq_start = tid->seq_next = 0;
2762 tid->baw_size = WME_MAX_BA;
2763 tid->baw_head = tid->baw_tail = 0;
2764 tid->sched = false;
2765 tid->paused = false;
2766 tid->cleanup_inprogress = false;
2767 INIT_LIST_HEAD(&tid->buf_q);
2768
2769 acno = TID_TO_WME_AC(tidno);
2770 tid->ac = &an->an_aggr.tx.ac[acno];
2771
2772 /* ADDBA state */
2773 tid->addba_exchangecomplete = 0;
2774 tid->addba_exchangeinprogress = 0;
2775 tid->addba_exchangeattempts = 0;
2776 }
2777
2778 /*
2779 * Init per ac tx state
2780 */
2781 for (acno = 0, ac = &an->an_aggr.tx.ac[acno];
2782 acno < WME_NUM_AC; acno++, ac++) {
2783 ac->sched = false;
2784 INIT_LIST_HEAD(&ac->tid_q);
2785
2786 switch (acno) {
2787 case WME_AC_BE:
2788 ac->qnum = ath_tx_get_qnum(sc,
2789 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
2790 break;
2791 case WME_AC_BK:
2792 ac->qnum = ath_tx_get_qnum(sc,
2793 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
2794 break;
2795 case WME_AC_VI:
2796 ac->qnum = ath_tx_get_qnum(sc,
2797 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
2798 break;
2799 case WME_AC_VO:
2800 ac->qnum = ath_tx_get_qnum(sc,
2801 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
2802 break;
2803 }
2804 }
2805 }
2806}
2807
2808/* Cleanupthe pending buffers for the node. */
2809
2810void ath_tx_node_cleanup(struct ath_softc *sc,
2811 struct ath_node *an, bool bh_flag)
2812{
2813 int i;
2814 struct ath_atx_ac *ac, *ac_tmp;
2815 struct ath_atx_tid *tid, *tid_tmp;
2816 struct ath_txq *txq;
2817 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2818 if (ATH_TXQ_SETUP(sc, i)) {
2819 txq = &sc->sc_txq[i];
2820
2821 if (likely(bh_flag))
2822 spin_lock_bh(&txq->axq_lock);
2823 else
2824 spin_lock(&txq->axq_lock);
2825
2826 list_for_each_entry_safe(ac,
2827 ac_tmp, &txq->axq_acq, list) {
2828 tid = list_first_entry(&ac->tid_q,
2829 struct ath_atx_tid, list);
2830 if (tid && tid->an != an)
2831 continue;
2832 list_del(&ac->list);
2833 ac->sched = false;
2834
2835 list_for_each_entry_safe(tid,
2836 tid_tmp, &ac->tid_q, list) {
2837 list_del(&tid->list);
2838 tid->sched = false;
2839 ath_tid_drain(sc, txq, tid, bh_flag);
2840 tid->addba_exchangecomplete = 0;
2841 tid->addba_exchangeattempts = 0;
2842 tid->cleanup_inprogress = false;
2843 }
2844 }
2845
2846 if (likely(bh_flag))
2847 spin_unlock_bh(&txq->axq_lock);
2848 else
2849 spin_unlock(&txq->axq_lock);
2850 }
2851 }
2852}
2853
2854/* Cleanup per node transmit state */
2855
2856void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an)
2857{
2858 if (sc->sc_txaggr) {
2859 struct ath_atx_tid *tid;
2860 int tidno, i;
2861
2862 /* Init per tid rx state */
2863 for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
2864 tidno < WME_NUM_TID;
2865 tidno++, tid++) {
2866
2867 for (i = 0; i < ATH_TID_MAX_BUFS; i++)
2868 ASSERT(tid->tx_buf[i] == NULL);
2869 }
2870 }
2871}
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 3bf3a869361f..7205a936ec74 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -33,7 +33,6 @@
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <linux/if_arp.h> 34#include <linux/if_arp.h>
35#include <linux/etherdevice.h> 35#include <linux/etherdevice.h>
36#include <linux/version.h>
37#include <linux/firmware.h> 36#include <linux/firmware.h>
38#include <linux/wireless.h> 37#include <linux/wireless.h>
39#include <linux/workqueue.h> 38#include <linux/workqueue.h>
@@ -4615,7 +4614,9 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
4615 if (bus->bustype == SSB_BUSTYPE_PCI) { 4614 if (bus->bustype == SSB_BUSTYPE_PCI) {
4616 pdev = bus->host_pci; 4615 pdev = bus->host_pci;
4617 if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) || 4616 if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
4617 IS_PDEV(pdev, BROADCOM, 0x4320, DELL, 0x0003) ||
4618 IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) || 4618 IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
4619 IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) ||
4619 IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013)) 4620 IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013))
4620 bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST; 4621 bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
4621 } 4622 }
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index c6f886ec08a3..19a401c4a0dc 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -157,7 +157,6 @@ that only one external action is invoked at a time.
157#include <linux/stringify.h> 157#include <linux/stringify.h>
158#include <linux/tcp.h> 158#include <linux/tcp.h>
159#include <linux/types.h> 159#include <linux/types.h>
160#include <linux/version.h>
161#include <linux/time.h> 160#include <linux/time.h>
162#include <linux/firmware.h> 161#include <linux/firmware.h>
163#include <linux/acpi.h> 162#include <linux/acpi.h>
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 36e8d2f6e7b4..dcce3542d5a7 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -31,7 +31,6 @@
31******************************************************************************/ 31******************************************************************************/
32 32
33#include "ipw2200.h" 33#include "ipw2200.h"
34#include <linux/version.h>
35 34
36 35
37#ifndef KBUILD_EXTMOD 36#ifndef KBUILD_EXTMOD
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index b3931f6135a4..3f51f3635344 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -26,7 +26,6 @@
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/version.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
32#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 22bb26985c2e..e2581229d8b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -26,7 +26,6 @@
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/version.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
32#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
@@ -967,7 +966,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
967 966
968 s = iwl4965_get_sub_band(priv, channel); 967 s = iwl4965_get_sub_band(priv, channel);
969 if (s >= EEPROM_TX_POWER_BANDS) { 968 if (s >= EEPROM_TX_POWER_BANDS) {
970 IWL_ERROR("Tx Power can not find channel %d ", channel); 969 IWL_ERROR("Tx Power can not find channel %d\n", channel);
971 return -1; 970 return -1;
972 } 971 }
973 972
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index f3d139b663e6..cbc01a00eaf4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -25,7 +25,6 @@
25 25
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/version.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/pci.h> 29#include <linux/pci.h>
31#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b8407d5704a1..061ffba9c884 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -29,7 +29,6 @@
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/pci.h> 33#include <linux/pci.h>
35#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
@@ -2719,7 +2718,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2719{ 2718{
2720 struct iwl_priv *priv = hw->priv; 2719 struct iwl_priv *priv = hw->priv;
2721 2720
2722 IWL_DEBUG_MAC80211("enter\n"); 2721 IWL_DEBUG_MACDUMP("enter\n");
2723 2722
2724 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { 2723 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
2725 IWL_DEBUG_MAC80211("leave - monitor\n"); 2724 IWL_DEBUG_MAC80211("leave - monitor\n");
@@ -2733,7 +2732,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2733 if (iwl_tx_skb(priv, skb)) 2732 if (iwl_tx_skb(priv, skb))
2734 dev_kfree_skb_any(skb); 2733 dev_kfree_skb_any(skb);
2735 2734
2736 IWL_DEBUG_MAC80211("leave\n"); 2735 IWL_DEBUG_MACDUMP("leave\n");
2737 return 0; 2736 return 0;
2738} 2737}
2739 2738
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 9bd61809129f..c72f72579bea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -28,7 +28,6 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/version.h>
32#include <net/mac80211.h> 31#include <net/mac80211.h>
33 32
34struct iwl_priv; /* FIXME: remove */ 33struct iwl_priv; /* FIXME: remove */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index b4ffd33ef98c..d2daa174df22 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -114,7 +114,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
114#define IWL_DL_MAC80211 (1 << 1) 114#define IWL_DL_MAC80211 (1 << 1)
115#define IWL_DL_HOST_COMMAND (1 << 2) 115#define IWL_DL_HOST_COMMAND (1 << 2)
116#define IWL_DL_STATE (1 << 3) 116#define IWL_DL_STATE (1 << 3)
117 117#define IWL_DL_MACDUMP (1 << 4)
118#define IWL_DL_RADIO (1 << 7) 118#define IWL_DL_RADIO (1 << 7)
119#define IWL_DL_POWER (1 << 8) 119#define IWL_DL_POWER (1 << 8)
120#define IWL_DL_TEMP (1 << 9) 120#define IWL_DL_TEMP (1 << 9)
@@ -154,6 +154,7 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
154#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a) 154#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
155 155
156#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a) 156#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
157#define IWL_DEBUG_MACDUMP(f, a...) IWL_DEBUG(IWL_DL_MACDUMP, f, ## a)
157#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a) 158#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
158#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a) 159#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
159#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a) 160#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index bce53830b301..37155755efc5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -63,7 +63,6 @@
63 63
64#include <linux/kernel.h> 64#include <linux/kernel.h>
65#include <linux/module.h> 65#include <linux/module.h>
66#include <linux/version.h>
67#include <linux/init.h> 66#include <linux/init.h>
68 67
69#include <net/mac80211.h> 68#include <net/mac80211.h>
@@ -146,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
146{ 145{
147 u32 gp = iwl_read32(priv, CSR_EEPROM_GP); 146 u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
148 if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { 147 if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
149 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); 148 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
150 return -ENOENT; 149 return -ENOENT;
151 } 150 }
152 return 0; 151 return 0;
@@ -227,7 +226,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
227 226
228 ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); 227 ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
229 if (ret < 0) { 228 if (ret < 0) {
230 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); 229 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
231 ret = -ENOENT; 230 ret = -ENOENT;
232 goto err; 231 goto err;
233 } 232 }
@@ -254,7 +253,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
254 } 253 }
255 254
256 if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) { 255 if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
257 IWL_ERROR("Time out reading EEPROM[%d]", addr); 256 IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
258 ret = -ETIMEDOUT; 257 ret = -ETIMEDOUT;
259 goto done; 258 goto done;
260 } 259 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 6512834bb916..2eb03eea1908 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -28,7 +28,6 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/version.h>
32#include <net/mac80211.h> 31#include <net/mac80211.h>
33 32
34#include "iwl-dev.h" /* FIXME: remove */ 33#include "iwl-dev.h" /* FIXME: remove */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 028e3053c0ca..a099c9e30e55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -29,7 +29,6 @@
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/init.h> 32#include <linux/init.h>
34 33
35#include <net/mac80211.h> 34#include <net/mac80211.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 60a6e0106036..6283a3a707f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -207,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
207 case WLAN_HT_CAP_MIMO_PS_DISABLED: 207 case WLAN_HT_CAP_MIMO_PS_DISABLED:
208 break; 208 break;
209 default: 209 default:
210 IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode); 210 IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
211 break; 211 break;
212 } 212 }
213 213
@@ -969,7 +969,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
969 return priv->hw_params.bcast_sta_id; 969 return priv->hw_params.bcast_sta_id;
970 970
971 default: 971 default:
972 IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); 972 IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
973 return priv->hw_params.bcast_sta_id; 973 return priv->hw_params.bcast_sta_id;
974 } 974 }
975} 975}
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index aa98c76d8195..d82823b5c8ab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -493,7 +493,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
493 /* Alloc keep-warm buffer */ 493 /* Alloc keep-warm buffer */
494 ret = iwl_kw_alloc(priv); 494 ret = iwl_kw_alloc(priv);
495 if (ret) { 495 if (ret) {
496 IWL_ERROR("Keep Warm allocation failed"); 496 IWL_ERROR("Keep Warm allocation failed\n");
497 goto error_kw; 497 goto error_kw;
498 } 498 }
499 spin_lock_irqsave(&priv->lock, flags); 499 spin_lock_irqsave(&priv->lock, flags);
@@ -764,20 +764,19 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
764 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 764 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
765 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 765 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
766 struct iwl_tfd_frame *tfd; 766 struct iwl_tfd_frame *tfd;
767 u32 *control_flags; 767 struct iwl_tx_queue *txq;
768 int txq_id = skb_get_queue_mapping(skb); 768 struct iwl_queue *q;
769 struct iwl_tx_queue *txq = NULL; 769 struct iwl_cmd *out_cmd;
770 struct iwl_queue *q = NULL; 770 struct iwl_tx_cmd *tx_cmd;
771 int swq_id, txq_id;
771 dma_addr_t phys_addr; 772 dma_addr_t phys_addr;
772 dma_addr_t txcmd_phys; 773 dma_addr_t txcmd_phys;
773 dma_addr_t scratch_phys; 774 dma_addr_t scratch_phys;
774 struct iwl_cmd *out_cmd = NULL;
775 struct iwl_tx_cmd *tx_cmd;
776 u16 len, idx, len_org; 775 u16 len, idx, len_org;
777 u16 seq_number = 0; 776 u16 seq_number = 0;
778 u8 id, hdr_len, unicast;
779 u8 sta_id;
780 __le16 fc; 777 __le16 fc;
778 u8 hdr_len, unicast;
779 u8 sta_id;
781 u8 wait_write_ptr = 0; 780 u8 wait_write_ptr = 0;
782 u8 tid = 0; 781 u8 tid = 0;
783 u8 *qc = NULL; 782 u8 *qc = NULL;
@@ -802,7 +801,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
802 } 801 }
803 802
804 unicast = !is_multicast_ether_addr(hdr->addr1); 803 unicast = !is_multicast_ether_addr(hdr->addr1);
805 id = 0;
806 804
807 fc = hdr->frame_control; 805 fc = hdr->frame_control;
808 806
@@ -840,14 +838,16 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
840 838
841 IWL_DEBUG_TX("station Id %d\n", sta_id); 839 IWL_DEBUG_TX("station Id %d\n", sta_id);
842 840
841 swq_id = skb_get_queue_mapping(skb);
842 txq_id = swq_id;
843 if (ieee80211_is_data_qos(fc)) { 843 if (ieee80211_is_data_qos(fc)) {
844 qc = ieee80211_get_qos_ctl(hdr); 844 qc = ieee80211_get_qos_ctl(hdr);
845 tid = qc[0] & 0xf; 845 tid = qc[0] & 0xf;
846 seq_number = priv->stations[sta_id].tid[tid].seq_number & 846 seq_number = priv->stations[sta_id].tid[tid].seq_number;
847 IEEE80211_SCTL_SEQ; 847 seq_number &= IEEE80211_SCTL_SEQ;
848 hdr->seq_ctrl = cpu_to_le16(seq_number) | 848 hdr->seq_ctrl = hdr->seq_ctrl &
849 (hdr->seq_ctrl & 849 __constant_cpu_to_le16(IEEE80211_SCTL_FRAG);
850 __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); 850 hdr->seq_ctrl |= cpu_to_le16(seq_number);
851 seq_number += 0x10; 851 seq_number += 0x10;
852 /* aggregation is on for this <sta,tid> */ 852 /* aggregation is on for this <sta,tid> */
853 if (info->flags & IEEE80211_TX_CTL_AMPDU) 853 if (info->flags & IEEE80211_TX_CTL_AMPDU)
@@ -864,7 +864,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
864 /* Set up first empty TFD within this queue's circular TFD buffer */ 864 /* Set up first empty TFD within this queue's circular TFD buffer */
865 tfd = &txq->bd[q->write_ptr]; 865 tfd = &txq->bd[q->write_ptr];
866 memset(tfd, 0, sizeof(*tfd)); 866 memset(tfd, 0, sizeof(*tfd));
867 control_flags = (u32 *) tfd;
868 idx = get_cmd_index(q, q->write_ptr, 0); 867 idx = get_cmd_index(q, q->write_ptr, 0);
869 868
870 /* Set up driver data for this TFD */ 869 /* Set up driver data for this TFD */
@@ -983,8 +982,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
983 iwl_txq_update_write_ptr(priv, txq); 982 iwl_txq_update_write_ptr(priv, txq);
984 spin_unlock_irqrestore(&priv->lock, flags); 983 spin_unlock_irqrestore(&priv->lock, flags);
985 } else { 984 } else {
986 ieee80211_stop_queue(priv->hw, 985 ieee80211_stop_queue(priv->hw, swq_id);
987 skb_get_queue_mapping(skb));
988 } 986 }
989 } 987 }
990 988
@@ -1013,13 +1011,12 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1013 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; 1011 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
1014 struct iwl_queue *q = &txq->q; 1012 struct iwl_queue *q = &txq->q;
1015 struct iwl_tfd_frame *tfd; 1013 struct iwl_tfd_frame *tfd;
1016 u32 *control_flags;
1017 struct iwl_cmd *out_cmd; 1014 struct iwl_cmd *out_cmd;
1018 u32 idx;
1019 u16 fix_size;
1020 dma_addr_t phys_addr; 1015 dma_addr_t phys_addr;
1021 int len, ret;
1022 unsigned long flags; 1016 unsigned long flags;
1017 int len, ret;
1018 u32 idx;
1019 u16 fix_size;
1023 1020
1024 cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); 1021 cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
1025 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); 1022 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
@@ -1045,7 +1042,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1045 tfd = &txq->bd[q->write_ptr]; 1042 tfd = &txq->bd[q->write_ptr];
1046 memset(tfd, 0, sizeof(*tfd)); 1043 memset(tfd, 0, sizeof(*tfd));
1047 1044
1048 control_flags = (u32 *) tfd;
1049 1045
1050 idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); 1046 idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
1051 out_cmd = txq->cmd[idx]; 1047 out_cmd = txq->cmd[idx];
@@ -1467,7 +1463,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1467 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); 1463 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
1468 1464
1469 if (scd_flow >= priv->hw_params.max_txq_num) { 1465 if (scd_flow >= priv->hw_params.max_txq_num) {
1470 IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); 1466 IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
1471 return; 1467 return;
1472 } 1468 }
1473 1469
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 444847ab1b5a..b775d5bab668 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -29,7 +29,6 @@
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/pci.h> 33#include <linux/pci.h>
35#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
@@ -1558,7 +1557,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
1558 BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE); 1557 BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
1559 1558
1560 if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { 1559 if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
1561 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); 1560 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
1562 return -ENOENT; 1561 return -ENOENT;
1563 } 1562 }
1564 1563
@@ -1583,7 +1582,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
1583 } 1582 }
1584 1583
1585 if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) { 1584 if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
1586 IWL_ERROR("Time out reading EEPROM[%d]", addr); 1585 IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
1587 return -ETIMEDOUT; 1586 return -ETIMEDOUT;
1588 } 1587 }
1589 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); 1588 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
@@ -2507,7 +2506,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
2507 return priv->hw_setting.bcast_sta_id; 2506 return priv->hw_setting.bcast_sta_id;
2508 2507
2509 default: 2508 default:
2510 IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); 2509 IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
2511 return priv->hw_setting.bcast_sta_id; 2510 return priv->hw_setting.bcast_sta_id;
2512 } 2511 }
2513} 2512}
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index b047306bf386..1ebcafe7ca5f 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -1998,13 +1998,6 @@ __orinoco_set_multicast_list(struct net_device *dev)
1998 else 1998 else
1999 priv->mc_count = mc_count; 1999 priv->mc_count = mc_count;
2000 } 2000 }
2001
2002 /* Since we can set the promiscuous flag when it wasn't asked
2003 for, make sure the net_device knows about it. */
2004 if (priv->promiscuous)
2005 dev->flags |= IFF_PROMISC;
2006 else
2007 dev->flags &= ~IFF_PROMISC;
2008} 2001}
2009 2002
2010/* This must be called from user context, without locks held - use 2003/* This must be called from user context, without locks held - use
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index cac9a515b82d..4801a363507b 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -52,6 +52,7 @@ struct p54_common {
52 int (*open)(struct ieee80211_hw *dev); 52 int (*open)(struct ieee80211_hw *dev);
53 void (*stop)(struct ieee80211_hw *dev); 53 void (*stop)(struct ieee80211_hw *dev);
54 int mode; 54 int mode;
55 u16 seqno;
55 struct mutex conf_mutex; 56 struct mutex conf_mutex;
56 u8 mac_addr[ETH_ALEN]; 57 u8 mac_addr[ETH_ALEN];
57 u8 bssid[ETH_ALEN]; 58 u8 bssid[ETH_ALEN];
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 4da89ea9b561..29be3dc8ee09 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -413,12 +413,12 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
413 last_addr = range->end_addr; 413 last_addr = range->end_addr;
414 __skb_unlink(entry, &priv->tx_queue); 414 __skb_unlink(entry, &priv->tx_queue);
415 memset(&info->status, 0, sizeof(info->status)); 415 memset(&info->status, 0, sizeof(info->status));
416 priv->tx_stats[skb_get_queue_mapping(skb)].len--;
417 entry_hdr = (struct p54_control_hdr *) entry->data; 416 entry_hdr = (struct p54_control_hdr *) entry->data;
418 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; 417 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
419 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) 418 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
420 pad = entry_data->align[0]; 419 pad = entry_data->align[0];
421 420
421 priv->tx_stats[entry_data->hw_queue - 4].len--;
422 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { 422 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
423 if (!(payload->status & 0x01)) 423 if (!(payload->status & 0x01))
424 info->flags |= IEEE80211_TX_STAT_ACK; 424 info->flags |= IEEE80211_TX_STAT_ACK;
@@ -553,9 +553,11 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
553 struct ieee80211_tx_queue_stats *current_queue; 553 struct ieee80211_tx_queue_stats *current_queue;
554 struct p54_common *priv = dev->priv; 554 struct p54_common *priv = dev->priv;
555 struct p54_control_hdr *hdr; 555 struct p54_control_hdr *hdr;
556 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
556 struct p54_tx_control_allocdata *txhdr; 557 struct p54_tx_control_allocdata *txhdr;
557 size_t padding, len; 558 size_t padding, len;
558 u8 rate; 559 u8 rate;
560 u8 cts_rate = 0x20;
559 561
560 current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)]; 562 current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)];
561 if (unlikely(current_queue->len > current_queue->limit)) 563 if (unlikely(current_queue->len > current_queue->limit))
@@ -580,31 +582,44 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
580 hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1); 582 hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
581 hdr->retry1 = hdr->retry2 = info->control.retry_limit; 583 hdr->retry1 = hdr->retry2 = info->control.retry_limit;
582 584
583 memset(txhdr->wep_key, 0x0, 16);
584 txhdr->padding = 0;
585 txhdr->padding2 = 0;
586
587 /* TODO: add support for alternate retry TX rates */ 585 /* TODO: add support for alternate retry TX rates */
588 rate = ieee80211_get_tx_rate(dev, info)->hw_value; 586 rate = ieee80211_get_tx_rate(dev, info)->hw_value;
589 if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) 587 if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) {
590 rate |= 0x10; 588 rate |= 0x10;
591 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) 589 cts_rate |= 0x10;
590 }
591 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
592 rate |= 0x40; 592 rate |= 0x40;
593 else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) 593 cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
594 } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
594 rate |= 0x20; 595 rate |= 0x20;
596 cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
597 }
595 memset(txhdr->rateset, rate, 8); 598 memset(txhdr->rateset, rate, 8);
596 txhdr->wep_key_present = 0; 599 txhdr->key_type = 0;
597 txhdr->wep_key_len = 0; 600 txhdr->key_len = 0;
598 txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4); 601 txhdr->hw_queue = skb_get_queue_mapping(skb) + 4;
599 txhdr->magic4 = 0; 602 txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
600 txhdr->antenna = (info->antenna_sel_tx == 0) ?
601 2 : info->antenna_sel_tx - 1; 603 2 : info->antenna_sel_tx - 1;
602 txhdr->output_power = 0x7f; // HW Maximum 604 txhdr->output_power = 0x7f; // HW Maximum
603 txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 605 txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
604 0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23)); 606 0 : cts_rate;
605 if (padding) 607 if (padding)
606 txhdr->align[0] = padding; 608 txhdr->align[0] = padding;
607 609
610 /* FIXME: The sequence that follows is needed for this driver to
611 * work with mac80211 since "mac80211: fix TX sequence numbers".
612 * As with the temporary code in rt2x00, changes will be needed
613 * to get proper sequence numbers on beacons. In addition, this
614 * patch places the sequence number in the hardware state, which
615 * limits us to a single virtual state.
616 */
617 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
618 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
619 priv->seqno += 0x10;
620 ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
621 ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
622 }
608 /* modifies skb->cb and with it info, so must be last! */ 623 /* modifies skb->cb and with it info, so must be last! */
609 p54_assign_address(dev, skb, hdr, skb->len); 624 p54_assign_address(dev, skb, hdr, skb->len);
610 625
@@ -803,8 +818,8 @@ static void p54_set_vdcf(struct ieee80211_hw *dev)
803 818
804 if (dev->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) { 819 if (dev->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
805 vdcf->slottime = 9; 820 vdcf->slottime = 9;
806 vdcf->magic1 = 0x00; 821 vdcf->magic1 = 0x10;
807 vdcf->magic2 = 0x10; 822 vdcf->magic2 = 0x00;
808 } else { 823 } else {
809 vdcf->slottime = 20; 824 vdcf->slottime = 20;
810 vdcf->magic1 = 0x0a; 825 vdcf->magic1 = 0x0a;
@@ -822,10 +837,21 @@ static int p54_start(struct ieee80211_hw *dev)
822 struct p54_common *priv = dev->priv; 837 struct p54_common *priv = dev->priv;
823 int err; 838 int err;
824 839
840 if (!priv->cached_vdcf) {
841 priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf)+
842 priv->tx_hdr_len + sizeof(struct p54_control_hdr),
843 GFP_KERNEL);
844
845 if (!priv->cached_vdcf)
846 return -ENOMEM;
847 }
848
825 err = priv->open(dev); 849 err = priv->open(dev);
826 if (!err) 850 if (!err)
827 priv->mode = IEEE80211_IF_TYPE_MNTR; 851 priv->mode = IEEE80211_IF_TYPE_MNTR;
828 852
853 p54_init_vdcf(dev);
854
829 return err; 855 return err;
830} 856}
831 857
@@ -1005,15 +1031,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1005 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 + 1031 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
1006 sizeof(struct p54_tx_control_allocdata); 1032 sizeof(struct p54_tx_control_allocdata);
1007 1033
1008 priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) +
1009 priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
1010
1011 if (!priv->cached_vdcf) {
1012 ieee80211_free_hw(dev);
1013 return NULL;
1014 }
1015
1016 p54_init_vdcf(dev);
1017 mutex_init(&priv->conf_mutex); 1034 mutex_init(&priv->conf_mutex);
1018 1035
1019 return dev; 1036 return dev;
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 2245fcce92dc..8db6c0e8e540 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -183,16 +183,16 @@ struct p54_frame_sent_hdr {
183 183
184struct p54_tx_control_allocdata { 184struct p54_tx_control_allocdata {
185 u8 rateset[8]; 185 u8 rateset[8];
186 u16 padding; 186 u8 unalloc0[2];
187 u8 wep_key_present; 187 u8 key_type;
188 u8 wep_key_len; 188 u8 key_len;
189 u8 wep_key[16]; 189 u8 key[16];
190 __le32 frame_type; 190 u8 hw_queue;
191 u32 padding2; 191 u8 unalloc1[9];
192 __le16 magic4; 192 u8 tx_antenna;
193 u8 antenna;
194 u8 output_power; 193 u8 output_power;
195 __le32 magic5; 194 u8 cts_rate;
195 u8 unalloc2[3];
196 u8 align[0]; 196 u8 align[0];
197} __attribute__ ((packed)); 197} __attribute__ ((packed));
198 198
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 815c095ef797..cbaca23a9453 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -109,7 +109,17 @@ static void p54u_rx_cb(struct urb *urb)
109 urb->context = skb; 109 urb->context = skb;
110 skb_queue_tail(&priv->rx_queue, skb); 110 skb_queue_tail(&priv->rx_queue, skb);
111 } else { 111 } else {
112 if (!priv->hw_type)
113 skb_push(skb, sizeof(struct net2280_tx_hdr));
114
115 skb_reset_tail_pointer(skb);
112 skb_trim(skb, 0); 116 skb_trim(skb, 0);
117 if (urb->transfer_buffer != skb_tail_pointer(skb)) {
118 /* this should not happen */
119 WARN_ON(1);
120 urb->transfer_buffer = skb_tail_pointer(skb);
121 }
122
113 skb_queue_tail(&priv->rx_queue, skb); 123 skb_queue_tail(&priv->rx_queue, skb);
114 } 124 }
115 125
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index bd422fd6a894..d06507388635 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -203,23 +203,43 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
203 !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 203 !test_bit(DEVICE_STARTED, &rt2x00dev->flags))
204 return -ENODEV; 204 return -ENODEV;
205 205
206 /* 206 switch (conf->type) {
207 * We don't support mixed combinations of sta and ap virtual 207 case IEEE80211_IF_TYPE_AP:
208 * interfaces. We can only add this interface when the rival 208 /*
209 * interface count is 0. 209 * We don't support mixed combinations of
210 */ 210 * sta and ap interfaces.
211 if ((conf->type == IEEE80211_IF_TYPE_AP && rt2x00dev->intf_sta_count) || 211 */
212 (conf->type != IEEE80211_IF_TYPE_AP && rt2x00dev->intf_ap_count)) 212 if (rt2x00dev->intf_sta_count)
213 return -ENOBUFS; 213 return -ENOBUFS;
214 214
215 /* 215 /*
216 * Check if we exceeded the maximum amount of supported interfaces. 216 * Check if we exceeded the maximum amount
217 */ 217 * of supported interfaces.
218 if ((conf->type == IEEE80211_IF_TYPE_AP && 218 */
219 rt2x00dev->intf_ap_count >= rt2x00dev->ops->max_ap_intf) || 219 if (rt2x00dev->intf_ap_count >= rt2x00dev->ops->max_ap_intf)
220 (conf->type != IEEE80211_IF_TYPE_AP && 220 return -ENOBUFS;
221 rt2x00dev->intf_sta_count >= rt2x00dev->ops->max_sta_intf)) 221
222 return -ENOBUFS; 222 break;
223 case IEEE80211_IF_TYPE_STA:
224 case IEEE80211_IF_TYPE_IBSS:
225 /*
226 * We don't support mixed combinations of
227 * sta and ap interfaces.
228 */
229 if (rt2x00dev->intf_ap_count)
230 return -ENOBUFS;
231
232 /*
233 * Check if we exceeded the maximum amount
234 * of supported interfaces.
235 */
236 if (rt2x00dev->intf_sta_count >= rt2x00dev->ops->max_sta_intf)
237 return -ENOBUFS;
238
239 break;
240 default:
241 return -EINVAL;
242 }
223 243
224 /* 244 /*
225 * Loop through all beacon queues to find a free 245 * Loop through all beacon queues to find a free
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index a4a8c57004db..ff78e52ce43c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -173,10 +173,10 @@ struct rxdone_entry_desc {
173 * frame transmission failed due to excessive retries. 173 * frame transmission failed due to excessive retries.
174 */ 174 */
175enum txdone_entry_desc_flags { 175enum txdone_entry_desc_flags {
176 TXDONE_UNKNOWN = 1 << 0, 176 TXDONE_UNKNOWN,
177 TXDONE_SUCCESS = 1 << 1, 177 TXDONE_SUCCESS,
178 TXDONE_FAILURE = 1 << 2, 178 TXDONE_FAILURE,
179 TXDONE_EXCESSIVE_RETRY = 1 << 3, 179 TXDONE_EXCESSIVE_RETRY,
180}; 180};
181 181
182/** 182/**
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 8d76bb2e0312..2050227ea530 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -181,6 +181,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
181 * (Only indirectly by looking at the failed TX counters 181 * (Only indirectly by looking at the failed TX counters
182 * in the register). 182 * in the register).
183 */ 183 */
184 txdesc.flags = 0;
184 if (!urb->status) 185 if (!urb->status)
185 __set_bit(TXDONE_UNKNOWN, &txdesc.flags); 186 __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
186 else 187 else
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 57376fb993ed..ca5deb6244e6 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -40,6 +40,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
40 /* Netgear */ 40 /* Netgear */
41 {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, 41 {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
42 {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, 42 {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
43 {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B},
43 /* HP */ 44 /* HP */
44 {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, 45 {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
45 /* Sitecom */ 46 /* Sitecom */
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 49ae97003952..136220b5ca81 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -1409,9 +1409,6 @@ static void wavelan_set_multicast_list(struct net_device * dev)
1409 lp->mc_count = 0; 1409 lp->mc_count = 0;
1410 1410
1411 wv_82586_reconfig(dev); 1411 wv_82586_reconfig(dev);
1412
1413 /* Tell the kernel that we are doing a really bad job. */
1414 dev->flags |= IFF_PROMISC;
1415 } 1412 }
1416 } else 1413 } else
1417 /* Are there multicast addresses to send? */ 1414 /* Are there multicast addresses to send? */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index b584c0ecc62d..00a3559e5aa4 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -1412,9 +1412,6 @@ wavelan_set_multicast_list(struct net_device * dev)
1412 lp->mc_count = 0; 1412 lp->mc_count = 0;
1413 1413
1414 wv_82593_reconfig(dev); 1414 wv_82593_reconfig(dev);
1415
1416 /* Tell the kernel that we are doing a really bad job... */
1417 dev->flags |= IFF_PROMISC;
1418 } 1415 }
1419 } 1416 }
1420 else 1417 else
@@ -1433,9 +1430,6 @@ wavelan_set_multicast_list(struct net_device * dev)
1433 lp->mc_count = 0; 1430 lp->mc_count = 0;
1434 1431
1435 wv_82593_reconfig(dev); 1432 wv_82593_reconfig(dev);
1436
1437 /* Tell the kernel that we are doing a really bad job... */
1438 dev->flags |= IFF_ALLMULTI;
1439 } 1433 }
1440 } 1434 }
1441 else 1435 else
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 902bbe788215..c749bdba214c 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -329,7 +329,7 @@ static int xennet_open(struct net_device *dev)
329 } 329 }
330 spin_unlock_bh(&np->rx_lock); 330 spin_unlock_bh(&np->rx_lock);
331 331
332 xennet_maybe_wake_tx(dev); 332 netif_start_queue(dev);
333 333
334 return 0; 334 return 0;
335} 335}
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 93e37f0666ab..e17ef54f0efc 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
382int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags) 382int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
383{ 383{
384 acpi_status status; 384 acpi_status status;
385 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev)); 385 acpi_handle chandle, handle;
386 struct pci_dev *pdev = dev; 386 struct pci_dev *pdev = dev;
387 struct pci_bus *parent; 387 struct pci_bus *parent;
388 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 388 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -399,10 +399,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
399 * Per PCI firmware specification, we should run the ACPI _OSC 399 * Per PCI firmware specification, we should run the ACPI _OSC
400 * method to get control of hotplug hardware before using it. If 400 * method to get control of hotplug hardware before using it. If
401 * an _OSC is missing, we look for an OSHP to do the same thing. 401 * an _OSC is missing, we look for an OSHP to do the same thing.
402 * To handle different BIOS behavior, we look for _OSC and OSHP 402 * To handle different BIOS behavior, we look for _OSC on a root
403 * within the scope of the hotplug controller and its parents, 403 * bridge preferentially (according to PCI fw spec). Later for
404 * OSHP within the scope of the hotplug controller and its parents,
404 * upto the host bridge under which this controller exists. 405 * upto the host bridge under which this controller exists.
405 */ 406 */
407 handle = acpi_find_root_bridge_handle(pdev);
408 if (handle) {
409 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
410 dbg("Trying to get hotplug control for %s\n",
411 (char *)string.pointer);
412 status = pci_osc_control_set(handle, flags);
413 if (ACPI_SUCCESS(status))
414 goto got_one;
415 kfree(string.pointer);
416 string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
417 }
418
419 pdev = dev;
420 handle = DEVICE_ACPI_HANDLE(&dev->dev);
406 while (!handle) { 421 while (!handle) {
407 /* 422 /*
408 * This hotplug controller was not listed in the ACPI name 423 * This hotplug controller was not listed in the ACPI name
@@ -427,15 +442,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
427 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 442 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
428 dbg("Trying to get hotplug control for %s \n", 443 dbg("Trying to get hotplug control for %s \n",
429 (char *)string.pointer); 444 (char *)string.pointer);
430 status = pci_osc_control_set(handle, flags); 445 status = acpi_run_oshp(handle);
431 if (status == AE_NOT_FOUND) 446 if (ACPI_SUCCESS(status))
432 status = acpi_run_oshp(handle); 447 goto got_one;
433 if (ACPI_SUCCESS(status)) {
434 dbg("Gained control for hotplug HW for pci %s (%s)\n",
435 pci_name(dev), (char *)string.pointer);
436 kfree(string.pointer);
437 return 0;
438 }
439 if (acpi_root_bridge(handle)) 448 if (acpi_root_bridge(handle))
440 break; 449 break;
441 chandle = handle; 450 chandle = handle;
@@ -449,6 +458,11 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
449 458
450 kfree(string.pointer); 459 kfree(string.pointer);
451 return -ENODEV; 460 return -ENODEV;
461got_one:
462 dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev),
463 (char *)string.pointer);
464 kfree(string.pointer);
465 return 0;
452} 466}
453EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); 467EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware);
454 468
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 18354817173c..4a10b5624f72 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -308,9 +308,8 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
308 entry->msi_attrib.masked); 308 entry->msi_attrib.masked);
309 309
310 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); 310 pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
311 control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); 311 control &= ~PCI_MSI_FLAGS_QSIZE;
312 if (entry->msi_attrib.maskbit || !entry->msi_attrib.masked) 312 control |= PCI_MSI_FLAGS_ENABLE;
313 control |= PCI_MSI_FLAGS_ENABLE;
314 pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); 313 pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
315} 314}
316 315
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0a3d856833fc..c9884bba22de 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1060,7 +1060,7 @@ bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
1060 * The caller must verify that the device is capable of generating PME# before 1060 * The caller must verify that the device is capable of generating PME# before
1061 * calling this function with @enable equal to 'true'. 1061 * calling this function with @enable equal to 'true'.
1062 */ 1062 */
1063static void pci_pme_active(struct pci_dev *dev, bool enable) 1063void pci_pme_active(struct pci_dev *dev, bool enable)
1064{ 1064{
1065 u16 pmcsr; 1065 u16 pmcsr;
1066 1066
@@ -1941,6 +1941,7 @@ EXPORT_SYMBOL(pci_set_power_state);
1941EXPORT_SYMBOL(pci_save_state); 1941EXPORT_SYMBOL(pci_save_state);
1942EXPORT_SYMBOL(pci_restore_state); 1942EXPORT_SYMBOL(pci_restore_state);
1943EXPORT_SYMBOL(pci_pme_capable); 1943EXPORT_SYMBOL(pci_pme_capable);
1944EXPORT_SYMBOL(pci_pme_active);
1944EXPORT_SYMBOL(pci_enable_wake); 1945EXPORT_SYMBOL(pci_enable_wake);
1945EXPORT_SYMBOL(pci_target_state); 1946EXPORT_SYMBOL(pci_target_state);
1946EXPORT_SYMBOL(pci_prepare_to_sleep); 1947EXPORT_SYMBOL(pci_prepare_to_sleep);
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 30f581b8791f..6dd7b13e9808 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -36,12 +36,7 @@ int aer_osc_setup(struct pcie_device *pciedev)
36 if (acpi_pci_disabled) 36 if (acpi_pci_disabled)
37 return -1; 37 return -1;
38 38
39 /* Find root host bridge */ 39 handle = acpi_find_root_bridge_handle(pdev);
40 while (pdev->bus->self)
41 pdev = pdev->bus->self;
42 handle = acpi_get_pci_rootbridge_handle(
43 pci_domain_nr(pdev->bus), pdev->bus->number);
44
45 if (handle) { 40 if (handle) {
46 pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); 41 pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT);
47 status = pci_osc_control_set(handle, 42 status = pci_osc_control_set(handle,
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 7098dfb07449..cce2f4cb1fbf 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -52,27 +52,49 @@ EXPORT_SYMBOL(no_pci_devices);
52 * Some platforms allow access to legacy I/O port and ISA memory space on 52 * Some platforms allow access to legacy I/O port and ISA memory space on
53 * a per-bus basis. This routine creates the files and ties them into 53 * a per-bus basis. This routine creates the files and ties them into
54 * their associated read, write and mmap files from pci-sysfs.c 54 * their associated read, write and mmap files from pci-sysfs.c
55 *
56 * On error unwind, but don't propogate the error to the caller
57 * as it is ok to set up the PCI bus without these files.
55 */ 58 */
56static void pci_create_legacy_files(struct pci_bus *b) 59static void pci_create_legacy_files(struct pci_bus *b)
57{ 60{
61 int error;
62
58 b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, 63 b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
59 GFP_ATOMIC); 64 GFP_ATOMIC);
60 if (b->legacy_io) { 65 if (!b->legacy_io)
61 b->legacy_io->attr.name = "legacy_io"; 66 goto kzalloc_err;
62 b->legacy_io->size = 0xffff; 67
63 b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; 68 b->legacy_io->attr.name = "legacy_io";
64 b->legacy_io->read = pci_read_legacy_io; 69 b->legacy_io->size = 0xffff;
65 b->legacy_io->write = pci_write_legacy_io; 70 b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
66 device_create_bin_file(&b->dev, b->legacy_io); 71 b->legacy_io->read = pci_read_legacy_io;
67 72 b->legacy_io->write = pci_write_legacy_io;
68 /* Allocated above after the legacy_io struct */ 73 error = device_create_bin_file(&b->dev, b->legacy_io);
69 b->legacy_mem = b->legacy_io + 1; 74 if (error)
70 b->legacy_mem->attr.name = "legacy_mem"; 75 goto legacy_io_err;
71 b->legacy_mem->size = 1024*1024; 76
72 b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; 77 /* Allocated above after the legacy_io struct */
73 b->legacy_mem->mmap = pci_mmap_legacy_mem; 78 b->legacy_mem = b->legacy_io + 1;
74 device_create_bin_file(&b->dev, b->legacy_mem); 79 b->legacy_mem->attr.name = "legacy_mem";
75 } 80 b->legacy_mem->size = 1024*1024;
81 b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
82 b->legacy_mem->mmap = pci_mmap_legacy_mem;
83 error = device_create_bin_file(&b->dev, b->legacy_mem);
84 if (error)
85 goto legacy_mem_err;
86
87 return;
88
89legacy_mem_err:
90 device_remove_bin_file(&b->dev, b->legacy_io);
91legacy_io_err:
92 kfree(b->legacy_io);
93 b->legacy_io = NULL;
94kzalloc_err:
95 printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
96 "and ISA memory resources to sysfs\n");
97 return;
76} 98}
77 99
78void pci_remove_legacy_files(struct pci_bus *b) 100void pci_remove_legacy_files(struct pci_bus *b)
@@ -361,6 +383,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
361 res->start = base; 383 res->start = base;
362 if (!res->end) 384 if (!res->end)
363 res->end = limit + 0xfff; 385 res->end = limit + 0xfff;
386 printk(KERN_INFO "PCI: bridge %s io port: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
364 } 387 }
365 388
366 res = child->resource[1]; 389 res = child->resource[1];
@@ -372,6 +395,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
372 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; 395 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
373 res->start = base; 396 res->start = base;
374 res->end = limit + 0xfffff; 397 res->end = limit + 0xfffff;
398 printk(KERN_INFO "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
375 } 399 }
376 400
377 res = child->resource[2]; 401 res = child->resource[2];
@@ -407,6 +431,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
407 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; 431 res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
408 res->start = base; 432 res->start = base;
409 res->end = limit + 0xfffff; 433 res->end = limit + 0xfffff;
434 printk(KERN_INFO "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64)?"64":"32",res->start, res->end);
410 } 435 }
411} 436}
412 437
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 0fb365074288..9236e7f869c8 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1756,9 +1756,14 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_c
1756 */ 1756 */
1757static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev) 1757static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev)
1758{ 1758{
1759 /* Only disable the VPD capability for 5706, 5708, and 5709 rev. A */ 1759 /*
1760 * Only disable the VPD capability for 5706, 5706S, 5708,
1761 * 5708S and 5709 rev. A
1762 */
1760 if ((dev->device == PCI_DEVICE_ID_NX2_5706) || 1763 if ((dev->device == PCI_DEVICE_ID_NX2_5706) ||
1764 (dev->device == PCI_DEVICE_ID_NX2_5706S) ||
1761 (dev->device == PCI_DEVICE_ID_NX2_5708) || 1765 (dev->device == PCI_DEVICE_ID_NX2_5708) ||
1766 (dev->device == PCI_DEVICE_ID_NX2_5708S) ||
1762 ((dev->device == PCI_DEVICE_ID_NX2_5709) && 1767 ((dev->device == PCI_DEVICE_ID_NX2_5709) &&
1763 (dev->revision & 0xf0) == 0x0)) { 1768 (dev->revision & 0xf0) == 0x0)) {
1764 if (dev->vpd) 1769 if (dev->vpd)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 827c0a520e2b..82634a2f1b1d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -530,6 +530,36 @@ void __ref pci_bus_assign_resources(struct pci_bus *bus)
530} 530}
531EXPORT_SYMBOL(pci_bus_assign_resources); 531EXPORT_SYMBOL(pci_bus_assign_resources);
532 532
533static void pci_bus_dump_res(struct pci_bus *bus)
534{
535 int i;
536
537 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
538 struct resource *res = bus->resource[i];
539 if (!res)
540 continue;
541
542 printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", bus->number, i, (res->flags & IORESOURCE_IO)? "io port":"mmio", res->start, res->end);
543 }
544}
545
546static void pci_bus_dump_resources(struct pci_bus *bus)
547{
548 struct pci_bus *b;
549 struct pci_dev *dev;
550
551
552 pci_bus_dump_res(bus);
553
554 list_for_each_entry(dev, &bus->devices, bus_list) {
555 b = dev->subordinate;
556 if (!b)
557 continue;
558
559 pci_bus_dump_resources(b);
560 }
561}
562
533void __init 563void __init
534pci_assign_unassigned_resources(void) 564pci_assign_unassigned_resources(void)
535{ 565{
@@ -545,4 +575,9 @@ pci_assign_unassigned_resources(void)
545 pci_bus_assign_resources(bus); 575 pci_bus_assign_resources(bus);
546 pci_enable_bridges(bus); 576 pci_enable_bridges(bus);
547 } 577 }
578
579 /* dump the resource on buses */
580 list_for_each_entry(bus, &pci_root_buses, node) {
581 pci_bus_dump_resources(bus);
582 }
548} 583}
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 684968558c19..a0ffb8ebfe00 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -18,13 +18,13 @@
18 18
19#include <pcmcia/ss.h> 19#include <pcmcia/ss.h>
20 20
21#include <asm/hardware.h> 21#include <mach/hardware.h>
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/sizes.h> 23#include <asm/sizes.h>
24#include <asm/gpio.h> 24#include <asm/gpio.h>
25 25
26#include <asm/arch/board.h> 26#include <mach/board.h>
27#include <asm/arch/at91rm9200_mc.h> 27#include <mach/at91rm9200_mc.h>
28 28
29 29
30/* 30/*
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 569b746b5731..f3736398900e 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -19,12 +19,12 @@
19 19
20#include <pcmcia/ss.h> 20#include <pcmcia/ss.h>
21 21
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/sizes.h> 24#include <asm/sizes.h>
25 25
26#include <asm/arch/mux.h> 26#include <mach/mux.h>
27#include <asm/arch/tc.h> 27#include <mach/tc.h>
28 28
29 29
30/* NOTE: don't expect this to support many I/O cards. The 16xx chips have 30/* NOTE: don't expect this to support many I/O cards. The 16xx chips have
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index ccfdf1969a7f..1b07af5a2ed3 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -24,12 +24,12 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26 26
27#include <asm/hardware.h> 27#include <mach/hardware.h>
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/irq.h> 29#include <asm/irq.h>
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/arch/pxa-regs.h> 31#include <mach/pxa-regs.h>
32#include <asm/arch/pxa2xx-regs.h> 32#include <mach/pxa2xx-regs.h>
33 33
34#include <pcmcia/cs_types.h> 34#include <pcmcia/cs_types.h>
35#include <pcmcia/ss.h> 35#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index bb95db7d2b76..bcff5cfed051 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -16,7 +16,7 @@
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17 17
18#include <asm/mach-types.h> 18#include <asm/mach-types.h>
19#include <asm/arch/pxa-regs.h> 19#include <mach/pxa-regs.h>
20 20
21#include "soc_common.h" 21#include "soc_common.h"
22 22
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index 881ec8a8e389..37ec55df086e 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -21,11 +21,11 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23 23
24#include <asm/hardware.h> 24#include <mach/hardware.h>
25#include <asm/hardware/sa1111.h> 25#include <asm/hardware/sa1111.h>
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27#include <asm/arch/pxa-regs.h> 27#include <mach/pxa-regs.h>
28#include <asm/arch/lubbock.h> 28#include <mach/lubbock.h>
29 29
30#include "sa1111_generic.h" 30#include "sa1111_generic.h"
31 31
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 92d1cc33808c..877001db4916 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -21,12 +21,12 @@
21 21
22#include <pcmcia/ss.h> 22#include <pcmcia/ss.h>
23 23
24#include <asm/hardware.h> 24#include <mach/hardware.h>
25#include <asm/mach-types.h> 25#include <asm/mach-types.h>
26#include <asm/irq.h> 26#include <asm/irq.h>
27 27
28#include <asm/arch/pxa-regs.h> 28#include <mach/pxa-regs.h>
29#include <asm/arch/mainstone.h> 29#include <mach/mainstone.h>
30 30
31#include "soc_common.h" 31#include "soc_common.h"
32 32
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
index 4abde190c1f5..e07b5c51ec5b 100644
--- a/drivers/pcmcia/pxa2xx_palmtx.c
+++ b/drivers/pcmcia/pxa2xx_palmtx.c
@@ -16,19 +16,64 @@
16 16
17#include <asm/mach-types.h> 17#include <asm/mach-types.h>
18 18
19#include <asm/arch/gpio.h> 19#include <mach/gpio.h>
20#include <asm/arch/palmtx.h> 20#include <mach/palmtx.h>
21 21
22#include "soc_common.h" 22#include "soc_common.h"
23 23
24static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 24static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
25{ 25{
26 skt->irq = IRQ_GPIO(GPIO_NR_PALMTX_PCMCIA_READY); 26 int ret;
27
28 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1");
29 if (ret)
30 goto err1;
31 ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0);
32 if (ret)
33 goto err2;
34
35 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2");
36 if (ret)
37 goto err2;
38 ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0);
39 if (ret)
40 goto err3;
41
42 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST");
43 if (ret)
44 goto err3;
45 ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1);
46 if (ret)
47 goto err4;
48
49 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY");
50 if (ret)
51 goto err4;
52 ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY);
53 if (ret)
54 goto err5;
55
56 skt->irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
27 return 0; 57 return 0;
58
59err5:
60 gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
61err4:
62 gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
63err3:
64 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
65err2:
66 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
67err1:
68 return ret;
28} 69}
29 70
30static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 71static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
31{ 72{
73 gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
74 gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
75 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
76 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
32} 77}
33 78
34static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 79static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
@@ -109,7 +154,7 @@ static void __exit palmtx_pcmcia_exit(void)
109 platform_device_unregister(palmtx_pcmcia_device); 154 platform_device_unregister(palmtx_pcmcia_device);
110} 155}
111 156
112fs_initcall(palmtx_pcmcia_init); 157module_init(palmtx_pcmcia_init);
113module_exit(palmtx_pcmcia_exit); 158module_exit(palmtx_pcmcia_exit);
114 159
115MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); 160MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index d71f93d45833..1cd02f5a23a0 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -19,7 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20 20
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/hardware/scoop.h> 24#include <asm/hardware/scoop.h>
25 25
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index ce133ce81c10..f424146a2bc9 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -11,11 +11,11 @@
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/init.h> 12#include <linux/init.h>
13 13
14#include <asm/hardware.h> 14#include <mach/hardware.h>
15#include <asm/mach-types.h> 15#include <asm/mach-types.h>
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/signal.h> 17#include <asm/signal.h>
18#include <asm/arch/assabet.h> 18#include <mach/assabet.h>
19 19
20#include "sa1100_generic.h" 20#include "sa1100_generic.h"
21 21
diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c
index 607c3f326eca..1ca9737ea79e 100644
--- a/drivers/pcmcia/sa1100_badge4.c
+++ b/drivers/pcmcia/sa1100_badge4.c
@@ -18,9 +18,9 @@
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/init.h> 19#include <linux/init.h>
20 20
21#include <asm/hardware.h> 21#include <mach/hardware.h>
22#include <asm/mach-types.h> 22#include <asm/mach-types.h>
23#include <asm/arch/badge4.h> 23#include <mach/badge4.h>
24#include <asm/hardware/sa1111.h> 24#include <asm/hardware/sa1111.h>
25 25
26#include "sa1111_generic.h" 26#include "sa1111_generic.h"
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index 7c3951a2675d..63e6bc431a0d 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -11,10 +11,10 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13 13
14#include <asm/hardware.h> 14#include <mach/hardware.h>
15#include <asm/mach-types.h> 15#include <asm/mach-types.h>
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/arch/cerf.h> 17#include <mach/cerf.h>
18#include "sa1100_generic.h" 18#include "sa1100_generic.h"
19 19
20#define CERF_SOCKET 1 20#define CERF_SOCKET 1
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index e5491879acd9..6de4e1b41d60 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -11,10 +11,10 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13 13
14#include <asm/hardware.h> 14#include <mach/hardware.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include <asm/mach-types.h> 16#include <asm/mach-types.h>
17#include <asm/arch/h3600.h> 17#include <mach/h3600.h>
18 18
19#include "sa1100_generic.h" 19#include "sa1100_generic.h"
20 20
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
index 2167e6714d2d..57ca085473d5 100644
--- a/drivers/pcmcia/sa1100_jornada720.c
+++ b/drivers/pcmcia/sa1100_jornada720.c
@@ -10,7 +10,7 @@
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/init.h> 11#include <linux/init.h>
12 12
13#include <asm/hardware.h> 13#include <mach/hardware.h>
14#include <asm/hardware/sa1111.h> 14#include <asm/hardware/sa1111.h>
15#include <asm/mach-types.h> 15#include <asm/mach-types.h>
16 16
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
index 687492fcd5b4..4c41e86ccff9 100644
--- a/drivers/pcmcia/sa1100_neponset.c
+++ b/drivers/pcmcia/sa1100_neponset.c
@@ -9,9 +9,9 @@
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/init.h> 10#include <linux/init.h>
11 11
12#include <asm/hardware.h> 12#include <mach/hardware.h>
13#include <asm/mach-types.h> 13#include <asm/mach-types.h>
14#include <asm/arch/neponset.h> 14#include <mach/neponset.h>
15#include <asm/hardware/sa1111.h> 15#include <asm/hardware/sa1111.h>
16 16
17#include "sa1111_generic.h" 17#include "sa1111_generic.h"
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 494912fccc0d..46d8c1977c2a 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -9,9 +9,9 @@
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/init.h> 10#include <linux/init.h>
11 11
12#include <asm/hardware.h> 12#include <mach/hardware.h>
13#include <asm/mach-types.h> 13#include <asm/mach-types.h>
14#include <asm/arch/shannon.h> 14#include <mach/shannon.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include "sa1100_generic.h" 16#include "sa1100_generic.h"
17 17
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 42567de894b9..33a08ae09fdf 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -9,10 +9,10 @@
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/init.h> 10#include <linux/init.h>
11 11
12#include <asm/hardware.h> 12#include <mach/hardware.h>
13#include <asm/mach-types.h> 13#include <asm/mach-types.h>
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <asm/arch/simpad.h> 15#include <mach/simpad.h>
16#include "sa1100_generic.h" 16#include "sa1100_generic.h"
17 17
18extern long get_cs3_shadow(void); 18extern long get_cs3_shadow(void);
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 658cddfbcf29..6924d0ea8d32 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -14,7 +14,7 @@
14 14
15#include <pcmcia/ss.h> 15#include <pcmcia/ss.h>
16 16
17#include <asm/hardware.h> 17#include <mach/hardware.h>
18#include <asm/hardware/sa1111.h> 18#include <asm/hardware/sa1111.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/irq.h> 20#include <asm/irq.h>
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 31a7abc55b23..7cb1273202cc 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -37,7 +37,7 @@
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39 39
40#include <asm/hardware.h> 40#include <mach/hardware.h>
41#include <asm/io.h> 41#include <asm/io.h>
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/system.h> 43#include <asm/system.h>
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 8c21446996f2..c48f3f69bdaf 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -43,7 +43,7 @@
43#include <linux/spinlock.h> 43#include <linux/spinlock.h>
44#include <linux/cpufreq.h> 44#include <linux/cpufreq.h>
45 45
46#include <asm/hardware.h> 46#include <mach/hardware.h>
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/system.h> 48#include <asm/system.h>
49 49
@@ -51,7 +51,7 @@
51 51
52/* FIXME: platform dependent resource declaration has to move out of this file */ 52/* FIXME: platform dependent resource declaration has to move out of this file */
53#ifdef CONFIG_ARCH_PXA 53#ifdef CONFIG_ARCH_PXA
54#include <asm/arch/pxa-regs.h> 54#include <mach/pxa-regs.h>
55#endif 55#endif
56 56
57#ifdef DEBUG 57#ifdef DEBUG
diff --git a/drivers/power/palmtx_battery.c b/drivers/power/palmtx_battery.c
index 244bb273a637..7035bfa41c62 100644
--- a/drivers/power/palmtx_battery.c
+++ b/drivers/power/palmtx_battery.c
@@ -22,7 +22,7 @@
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23 23
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/arch/palmtx.h> 25#include <mach/palmtx.h>
26 26
27static DEFINE_MUTEX(bat_lock); 27static DEFINE_MUTEX(bat_lock);
28static struct work_struct bat_work; 28static struct work_struct bat_work;
diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
index bf664fbd6610..2eab35aab311 100644
--- a/drivers/power/tosa_battery.c
+++ b/drivers/power/tosa_battery.c
@@ -19,7 +19,7 @@
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20 20
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/arch/tosa.h> 22#include <mach/tosa.h>
23 23
24static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ 24static DEFINE_MUTEX(bat_lock); /* protects gpio pins */
25static struct work_struct bat_work; 25static struct work_struct bat_work;
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index cd32d05db773..4e888cc8be5b 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -29,7 +29,7 @@
29#include <linux/completion.h> 29#include <linux/completion.h>
30 30
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32#include <asm/arch/at91_rtc.h> 32#include <mach/at91_rtc.h>
33 33
34 34
35#define AT91_RTC_FREQ 1 35#define AT91_RTC_FREQ 1
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index f0246ef413a4..2133f37906f2 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -19,8 +19,8 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/ioctl.h> 20#include <linux/ioctl.h>
21 21
22#include <asm/arch/board.h> 22#include <mach/board.h>
23#include <asm/arch/at91_rtt.h> 23#include <mach/at91_rtt.h>
24 24
25 25
26/* 26/*
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 856cc1af40df..35dcc06eb3e2 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/rtc.h> 15#include <linux/rtc.h>
16#include <linux/smp_lock.h>
17#include "rtc-core.h" 16#include "rtc-core.h"
18 17
19static dev_t rtc_devt; 18static dev_t rtc_devt;
@@ -27,11 +26,8 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
27 struct rtc_device, char_dev); 26 struct rtc_device, char_dev);
28 const struct rtc_class_ops *ops = rtc->ops; 27 const struct rtc_class_ops *ops = rtc->ops;
29 28
30 lock_kernel(); 29 if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
31 if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) { 30 return -EBUSY;
32 err = -EBUSY;
33 goto out;
34 }
35 31
36 file->private_data = rtc; 32 file->private_data = rtc;
37 33
@@ -41,13 +37,11 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
41 rtc->irq_data = 0; 37 rtc->irq_data = 0;
42 spin_unlock_irq(&rtc->irq_lock); 38 spin_unlock_irq(&rtc->irq_lock);
43 39
44 goto out; 40 return 0;
45 } 41 }
46 42
47 /* something has gone wrong */ 43 /* something has gone wrong */
48 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); 44 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
49out:
50 unlock_kernel();
51 return err; 45 return err;
52} 46}
53 47
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 1e99325270df..36e4ac0bd69c 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -12,7 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/rtc.h> 13#include <linux/rtc.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <asm/hardware.h> 15#include <mach/hardware.h>
16 16
17#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x)) 17#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x))
18#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000) 18#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000)
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index fbb90b1e4098..a81adab6e515 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -482,7 +482,7 @@ isl1208_sysfs_register(struct device *dev)
482static int 482static int
483isl1208_sysfs_unregister(struct device *dev) 483isl1208_sysfs_unregister(struct device *dev)
484{ 484{
485 device_remove_file(dev, &dev_attr_atrim); 485 device_remove_file(dev, &dev_attr_dtrim);
486 device_remove_file(dev, &dev_attr_atrim); 486 device_remove_file(dev, &dev_attr_atrim);
487 device_remove_file(dev, &dev_attr_usr); 487 device_remove_file(dev, &dev_attr_usr);
488 488
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 54b1ebb01502..e7d19b6c265a 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -22,7 +22,7 @@
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/log2.h> 23#include <linux/log2.h>
24 24
25#include <asm/hardware.h> 25#include <mach/hardware.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/io.h> 27#include <asm/io.h>
28#include <asm/irq.h> 28#include <asm/irq.h>
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index f47294c60148..66a9bb85bbe8 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -31,11 +31,11 @@
31#include <linux/pm.h> 31#include <linux/pm.h>
32#include <linux/bitops.h> 32#include <linux/bitops.h>
33 33
34#include <asm/hardware.h> 34#include <mach/hardware.h>
35#include <asm/irq.h> 35#include <asm/irq.h>
36 36
37#ifdef CONFIG_ARCH_PXA 37#ifdef CONFIG_ARCH_PXA
38#include <asm/arch/pxa-regs.h> 38#include <mach/pxa-regs.h>
39#endif 39#endif
40 40
41#define TIMER_FREQ CLOCK_TICK_RATE 41#define TIMER_FREQ CLOCK_TICK_RATE
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
index 73a86d09bba8..9c129248466c 100644
--- a/drivers/sbus/sbus.c
+++ b/drivers/sbus/sbus.c
@@ -7,13 +7,13 @@
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/of_device.h>
10 11
11#include <asm/system.h> 12#include <asm/system.h>
12#include <asm/sbus.h> 13#include <asm/sbus.h>
13#include <asm/dma.h> 14#include <asm/dma.h>
14#include <asm/oplib.h> 15#include <asm/oplib.h>
15#include <asm/prom.h> 16#include <asm/prom.h>
16#include <asm/of_device.h>
17#include <asm/bpp.h> 17#include <asm/bpp.h>
18#include <asm/irq.h> 18#include <asm/irq.h>
19 19
diff --git a/drivers/scsi/arm/acornscsi-io.S b/drivers/scsi/arm/acornscsi-io.S
index 5cebe3105260..22171b2110a8 100644
--- a/drivers/scsi/arm/acornscsi-io.S
+++ b/drivers/scsi/arm/acornscsi-io.S
@@ -8,7 +8,7 @@
8#include <linux/linkage.h> 8#include <linux/linkage.h>
9 9
10#include <asm/assembler.h> 10#include <asm/assembler.h>
11#include <asm/hardware.h> 11#include <mach/hardware.h>
12 12
13#if defined(__APCS_32__) 13#if defined(__APCS_32__)
14#define LOADREGS(t,r,l...) ldm##t r, l 14#define LOADREGS(t,r,l...) ldm##t r, l
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index fcdd73f25625..994da56fffed 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -680,7 +680,7 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
680 680
681} 681}
682 682
683const struct scsi_dh_devlist alua_dev_list[] = { 683static const struct scsi_dh_devlist alua_dev_list[] = {
684 {"HP", "MSA VOLUME" }, 684 {"HP", "MSA VOLUME" },
685 {"HP", "HSV101" }, 685 {"HP", "HSV101" },
686 {"HP", "HSV111" }, 686 {"HP", "HSV111" },
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index aa46b131b20e..b9d23e9e9a44 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -562,7 +562,7 @@ done:
562 return result; 562 return result;
563} 563}
564 564
565const struct scsi_dh_devlist clariion_dev_list[] = { 565static const struct scsi_dh_devlist clariion_dev_list[] = {
566 {"DGC", "RAID"}, 566 {"DGC", "RAID"},
567 {"DGC", "DISK"}, 567 {"DGC", "DISK"},
568 {"DGC", "VRAID"}, 568 {"DGC", "VRAID"},
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 9c7a1f8ebb72..a6a4ef3ad51c 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -282,7 +282,7 @@ static int hp_sw_activate(struct scsi_device *sdev)
282 return ret; 282 return ret;
283} 283}
284 284
285const struct scsi_dh_devlist hp_sw_dh_data_list[] = { 285static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
286 {"COMPAQ", "MSA1000 VOLUME"}, 286 {"COMPAQ", "MSA1000 VOLUME"},
287 {"COMPAQ", "HSV110"}, 287 {"COMPAQ", "HSV110"},
288 {"HP", "HSV100"}, 288 {"HP", "HSV100"},
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 518da832ad26..2dee69da35cf 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -575,7 +575,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
575 return SCSI_RETURN_NOT_HANDLED; 575 return SCSI_RETURN_NOT_HANDLED;
576} 576}
577 577
578const struct scsi_dh_devlist rdac_dev_list[] = { 578static const struct scsi_dh_devlist rdac_dev_list[] = {
579 {"IBM", "1722"}, 579 {"IBM", "1722"},
580 {"IBM", "1724"}, 580 {"IBM", "1724"},
581 {"IBM", "1726"}, 581 {"IBM", "1726"},
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 6558a4037806..f31c6698419c 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -19,7 +19,7 @@
19#include <asm/irq.h> 19#include <asm/irq.h>
20#include <asm/mach-types.h> 20#include <asm/mach-types.h>
21#include <asm/hardware/dec21285.h> 21#include <asm/hardware/dec21285.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23 23
24#define BAUD_BASE (mem_fclk_21285/64) 24#define BAUD_BASE (mem_fclk_21285/64)
25 25
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 3b4a14e355c1..77cb34270fc1 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -449,6 +449,7 @@ config SERIAL_CLPS711X_CONSOLE
449config SERIAL_SAMSUNG 449config SERIAL_SAMSUNG
450 tristate "Samsung SoC serial support" 450 tristate "Samsung SoC serial support"
451 depends on ARM && PLAT_S3C24XX 451 depends on ARM && PLAT_S3C24XX
452 select SERIAL_CORE
452 help 453 help
453 Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, 454 Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
454 providing /dev/ttySAC0, 1 and 2 (note, some machines may not 455 providing /dev/ttySAC0, 1 and 2 (note, some machines may not
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 1fee12c1f4f8..3a6da80b081c 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -42,11 +42,11 @@
42#include <asm/io.h> 42#include <asm/io.h>
43 43
44#include <asm/mach/serial_at91.h> 44#include <asm/mach/serial_at91.h>
45#include <asm/arch/board.h> 45#include <mach/board.h>
46 46
47#ifdef CONFIG_ARM 47#ifdef CONFIG_ARM
48#include <asm/arch/cpu.h> 48#include <mach/cpu.h>
49#include <asm/arch/gpio.h> 49#include <mach/gpio.h>
50#endif 50#endif
51 51
52#define PDC_BUFFER_SIZE 512 52#define PDC_BUFFER_SIZE 512
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index fc1fa9267c59..459f3420a429 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -39,7 +39,7 @@
39#include <linux/serial_core.h> 39#include <linux/serial_core.h>
40#include <linux/serial.h> 40#include <linux/serial.h>
41 41
42#include <asm/hardware.h> 42#include <mach/hardware.h>
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/irq.h> 44#include <asm/irq.h>
45#include <asm/hardware/clps7111.h> 45#include <asm/hardware/clps7111.h>
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index e0da4dc7bbf6..6a29f9330a73 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -44,8 +44,8 @@
44 44
45#include <asm/io.h> 45#include <asm/io.h>
46#include <asm/irq.h> 46#include <asm/irq.h>
47#include <asm/hardware.h> 47#include <mach/hardware.h>
48#include <asm/arch/imx-uart.h> 48#include <mach/imx-uart.h>
49 49
50/* Register definitions */ 50/* Register definitions */
51#define URXD0 0x0 /* Receiver Register */ 51#define URXD0 0x0 /* Receiver Register */
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 9f8ccb735c19..3f489329e8d3 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -35,8 +35,8 @@
35 35
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/hardware.h> 38#include <mach/hardware.h>
39#include <asm/arch/netx-regs.h> 39#include <mach/netx-regs.h>
40 40
41/* We've been assigned a range on the "Low-density serial ports" major */ 41/* We've been assigned a range on the "Low-density serial ports" major */
42#define SERIAL_NX_MAJOR 204 42#define SERIAL_NX_MAJOR 204
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index b9a93f326fb8..f7a0d37c4221 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -45,9 +45,9 @@
45#include <linux/clk.h> 45#include <linux/clk.h>
46 46
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/hardware.h> 48#include <mach/hardware.h>
49#include <asm/irq.h> 49#include <asm/irq.h>
50#include <asm/arch/pxa-regs.h> 50#include <mach/pxa-regs.h>
51 51
52 52
53struct uart_pxa_port { 53struct uart_pxa_port {
diff --git a/drivers/serial/s3c2400.c b/drivers/serial/s3c2400.c
index a1102053e553..c8b4266ac35f 100644
--- a/drivers/serial/s3c2400.c
+++ b/drivers/serial/s3c2400.c
@@ -17,10 +17,10 @@
17 17
18#include <asm/irq.h> 18#include <asm/irq.h>
19 19
20#include <asm/hardware.h> 20#include <mach/hardware.h>
21 21
22#include <asm/plat-s3c/regs-serial.h> 22#include <asm/plat-s3c/regs-serial.h>
23#include <asm/arch/regs-gpio.h> 23#include <mach/regs-gpio.h>
24 24
25#include "samsung.h" 25#include "samsung.h"
26 26
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index c5f03f41686f..40a2531b5541 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -19,10 +19,10 @@
19#include <linux/serial.h> 19#include <linux/serial.h>
20 20
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23 23
24#include <asm/plat-s3c/regs-serial.h> 24#include <asm/plat-s3c/regs-serial.h>
25#include <asm/arch/regs-gpio.h> 25#include <mach/regs-gpio.h>
26 26
27#include "samsung.h" 27#include "samsung.h"
28 28
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
index ce0c220e3e92..d0170319c729 100644
--- a/drivers/serial/s3c2412.c
+++ b/drivers/serial/s3c2412.c
@@ -19,10 +19,10 @@
19#include <linux/serial.h> 19#include <linux/serial.h>
20 20
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23 23
24#include <asm/plat-s3c/regs-serial.h> 24#include <asm/plat-s3c/regs-serial.h>
25#include <asm/arch/regs-gpio.h> 25#include <mach/regs-gpio.h>
26 26
27#include "samsung.h" 27#include "samsung.h"
28 28
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c
index 38f954bd39c6..d4a2b17b2498 100644
--- a/drivers/serial/s3c2440.c
+++ b/drivers/serial/s3c2440.c
@@ -19,10 +19,10 @@
19#include <linux/serial.h> 19#include <linux/serial.h>
20 20
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23 23
24#include <asm/plat-s3c/regs-serial.h> 24#include <asm/plat-s3c/regs-serial.h>
25#include <asm/arch/regs-gpio.h> 25#include <mach/regs-gpio.h>
26 26
27#include "samsung.h" 27#include "samsung.h"
28 28
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index a5e76cc18073..b24a25ea6bc5 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -39,7 +39,7 @@
39 39
40#include <asm/io.h> 40#include <asm/io.h>
41#include <asm/irq.h> 41#include <asm/irq.h>
42#include <asm/hardware.h> 42#include <mach/hardware.h>
43#include <asm/mach/serial_sa1100.h> 43#include <asm/mach/serial_sa1100.h>
44 44
45/* We've been assigned a range on the "Low-density serial ports" major */ 45/* We've been assigned a range on the "Low-density serial ports" major */
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index d852f83f8900..5a88b3f9fe9b 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -45,10 +45,10 @@
45 45
46#include <asm/irq.h> 46#include <asm/irq.h>
47 47
48#include <asm/hardware.h> 48#include <mach/hardware.h>
49 49
50#include <asm/plat-s3c/regs-serial.h> 50#include <asm/plat-s3c/regs-serial.h>
51#include <asm/arch/regs-gpio.h> 51#include <mach/regs-gpio.h>
52 52
53#include "samsung.h" 53#include "samsung.h"
54 54
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 0edbc5dd378b..b9cbfc87f616 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -26,8 +26,8 @@
26#include <asm/irq.h> 26#include <asm/irq.h>
27#include <asm/mach/irq.h> 27#include <asm/mach/irq.h>
28 28
29#include <asm/arch/regs-uart.h> 29#include <mach/regs-uart.h>
30#include <asm/arch/regs-irq.h> 30#include <mach/regs-irq.h>
31 31
32#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 32#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
33#define SUPPORT_SYSRQ 33#define SUPPORT_SYSRQ
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index aeeec5588afd..e41766d08035 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -17,11 +17,11 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/of_device.h>
20 21
21#include <asm/hypervisor.h> 22#include <asm/hypervisor.h>
22#include <asm/spitfire.h> 23#include <asm/spitfire.h>
23#include <asm/prom.h> 24#include <asm/prom.h>
24#include <asm/of_device.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26 26
27#if defined(CONFIG_MAGIC_SYSRQ) 27#if defined(CONFIG_MAGIC_SYSRQ)
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 15ee497e1c78..29b4458abf74 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -32,11 +32,11 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/of_device.h>
35 36
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/irq.h> 38#include <asm/irq.h>
38#include <asm/prom.h> 39#include <asm/prom.h>
39#include <asm/of_device.h>
40 40
41#if defined(CONFIG_SERIAL_SUNSAB_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 41#if defined(CONFIG_SERIAL_SUNSAB_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
42#define SUPPORT_SYSRQ 42#define SUPPORT_SYSRQ
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index e24e68235088..a378464f9292 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -35,11 +35,11 @@
35#include <linux/serial_reg.h> 35#include <linux/serial_reg.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/of_device.h>
38 39
39#include <asm/io.h> 40#include <asm/io.h>
40#include <asm/irq.h> 41#include <asm/irq.h>
41#include <asm/prom.h> 42#include <asm/prom.h>
42#include <asm/of_device.h>
43 43
44#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 44#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
45#define SUPPORT_SYSRQ 45#define SUPPORT_SYSRQ
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 0f3d69b86d67..3cb4c8aee13f 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -32,11 +32,11 @@
32#include <linux/serio.h> 32#include <linux/serio.h>
33#endif 33#endif
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/of_device.h>
35 36
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/irq.h> 38#include <asm/irq.h>
38#include <asm/prom.h> 39#include <asm/prom.h>
39#include <asm/of_device.h>
40 40
41#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 41#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
42#define SUPPORT_SYSRQ 42#define SUPPORT_SYSRQ
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 95190c619c10..02f9320f3efc 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -20,9 +20,9 @@
20#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
21 21
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/arch/board.h> 23#include <mach/board.h>
24#include <asm/arch/gpio.h> 24#include <mach/gpio.h>
25#include <asm/arch/cpu.h> 25#include <mach/cpu.h>
26 26
27#include "atmel_spi.h" 27#include "atmel_spi.h"
28 28
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index f6f987bb71ca..9d2186fd74aa 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -35,8 +35,8 @@
35 35
36#include <linux/spi/spi.h> 36#include <linux/spi/spi.h>
37 37
38#include <asm/arch/dma.h> 38#include <mach/dma.h>
39#include <asm/arch/clock.h> 39#include <mach/clock.h>
40 40
41 41
42#define OMAP2_MCSPI_MAX_FREQ 48000000 42#define OMAP2_MCSPI_MAX_FREQ 48000000
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index d9ae111c27ae..5515eb97d7c5 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -47,12 +47,12 @@
47 47
48#include <asm/system.h> 48#include <asm/system.h>
49#include <asm/irq.h> 49#include <asm/irq.h>
50#include <asm/hardware.h> 50#include <mach/hardware.h>
51#include <asm/io.h> 51#include <asm/io.h>
52#include <asm/mach-types.h> 52#include <asm/mach-types.h>
53 53
54#include <asm/arch/mux.h> 54#include <mach/mux.h>
55#include <asm/arch/omap730.h> /* OMAP730_IO_CONF registers */ 55#include <mach/omap730.h> /* OMAP730_IO_CONF registers */
56 56
57 57
58/* FIXME address is now a platform device resource, 58/* FIXME address is now a platform device resource,
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 067299d6d192..34c7c9875681 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -31,15 +31,14 @@
31 31
32#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/irq.h> 33#include <asm/irq.h>
34#include <asm/hardware.h>
35#include <asm/delay.h> 34#include <asm/delay.h>
36#include <asm/dma.h> 35#include <asm/dma.h>
37 36
38#include <asm/arch/hardware.h> 37#include <mach/hardware.h>
39#include <asm/arch/pxa-regs.h> 38#include <mach/pxa-regs.h>
40#include <asm/arch/regs-ssp.h> 39#include <mach/regs-ssp.h>
41#include <asm/arch/ssp.h> 40#include <mach/ssp.h>
42#include <asm/arch/pxa2xx_spi.h> 41#include <mach/pxa2xx_spi.h>
43 42
44MODULE_AUTHOR("Stephen Street"); 43MODULE_AUTHOR("Stephen Street");
45MODULE_DESCRIPTION("PXA2xx SSP SPI Controller"); 44MODULE_DESCRIPTION("PXA2xx SSP SPI Controller");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 964124b60db2..75e86865234c 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -226,10 +226,11 @@ EXPORT_SYMBOL_GPL(spi_alloc_device);
226 * Companion function to spi_alloc_device. Devices allocated with 226 * Companion function to spi_alloc_device. Devices allocated with
227 * spi_alloc_device can be added onto the spi bus with this function. 227 * spi_alloc_device can be added onto the spi bus with this function.
228 * 228 *
229 * Returns 0 on success; non-zero on failure 229 * Returns 0 on success; negative errno on failure
230 */ 230 */
231int spi_add_device(struct spi_device *spi) 231int spi_add_device(struct spi_device *spi)
232{ 232{
233 static DEFINE_MUTEX(spi_add_lock);
233 struct device *dev = spi->master->dev.parent; 234 struct device *dev = spi->master->dev.parent;
234 int status; 235 int status;
235 236
@@ -246,26 +247,43 @@ int spi_add_device(struct spi_device *spi)
246 "%s.%u", spi->master->dev.bus_id, 247 "%s.%u", spi->master->dev.bus_id,
247 spi->chip_select); 248 spi->chip_select);
248 249
249 /* drivers may modify this initial i/o setup */ 250
251 /* We need to make sure there's no other device with this
252 * chipselect **BEFORE** we call setup(), else we'll trash
253 * its configuration. Lock against concurrent add() calls.
254 */
255 mutex_lock(&spi_add_lock);
256
257 if (bus_find_device_by_name(&spi_bus_type, NULL, spi->dev.bus_id)
258 != NULL) {
259 dev_err(dev, "chipselect %d already in use\n",
260 spi->chip_select);
261 status = -EBUSY;
262 goto done;
263 }
264
265 /* Drivers may modify this initial i/o setup, but will
266 * normally rely on the device being setup. Devices
267 * using SPI_CS_HIGH can't coexist well otherwise...
268 */
250 status = spi->master->setup(spi); 269 status = spi->master->setup(spi);
251 if (status < 0) { 270 if (status < 0) {
252 dev_err(dev, "can't %s %s, status %d\n", 271 dev_err(dev, "can't %s %s, status %d\n",
253 "setup", spi->dev.bus_id, status); 272 "setup", spi->dev.bus_id, status);
254 return status; 273 goto done;
255 } 274 }
256 275
257 /* driver core catches callers that misbehave by defining 276 /* Device may be bound to an active driver when this returns */
258 * devices that already exist.
259 */
260 status = device_add(&spi->dev); 277 status = device_add(&spi->dev);
261 if (status < 0) { 278 if (status < 0)
262 dev_err(dev, "can't %s %s, status %d\n", 279 dev_err(dev, "can't %s %s, status %d\n",
263 "add", spi->dev.bus_id, status); 280 "add", spi->dev.bus_id, status);
264 return status; 281 else
265 } 282 dev_dbg(dev, "registered child %s\n", spi->dev.bus_id);
266 283
267 dev_dbg(dev, "registered child %s\n", spi->dev.bus_id); 284done:
268 return 0; 285 mutex_unlock(&spi_add_lock);
286 return status;
269} 287}
270EXPORT_SYMBOL_GPL(spi_add_device); 288EXPORT_SYMBOL_GPL(spi_add_device);
271 289
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 6fb77fcc4971..61ba147e384d 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -33,12 +33,11 @@
33 33
34#include <asm/io.h> 34#include <asm/io.h>
35#include <asm/irq.h> 35#include <asm/irq.h>
36#include <asm/hardware.h>
37#include <asm/delay.h> 36#include <asm/delay.h>
38 37
39#include <asm/arch/hardware.h> 38#include <mach/hardware.h>
40#include <asm/arch/imx-dma.h> 39#include <mach/imx-dma.h>
41#include <asm/arch/spi_imx.h> 40#include <mach/spi_imx.h>
42 41
43/*-------------------------------------------------------------------------*/ 42/*-------------------------------------------------------------------------*/
44/* SPI Registers offsets from peripheral base address */ 43/* SPI Registers offsets from peripheral base address */
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 21661c7959c8..98abc73c1a1d 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -25,11 +25,11 @@
25 25
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/dma.h> 27#include <asm/dma.h>
28#include <asm/hardware.h> 28#include <mach/hardware.h>
29 29
30#include <asm/arch/regs-gpio.h> 30#include <mach/regs-gpio.h>
31#include <asm/plat-s3c24xx/regs-spi.h> 31#include <asm/plat-s3c24xx/regs-spi.h>
32#include <asm/arch/spi.h> 32#include <mach/spi.h>
33 33
34struct s3c24xx_spi { 34struct s3c24xx_spi {
35 /* bitbang has to be first */ 35 /* bitbang has to be first */
diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c
index e33f6145c560..cc1f647f579b 100644
--- a/drivers/spi/spi_s3c24xx_gpio.c
+++ b/drivers/spi/spi_s3c24xx_gpio.c
@@ -21,9 +21,9 @@
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/spi/spi_bitbang.h> 22#include <linux/spi/spi_bitbang.h>
23 23
24#include <asm/arch/regs-gpio.h> 24#include <mach/regs-gpio.h>
25#include <asm/arch/spi-gpio.h> 25#include <mach/spi-gpio.h>
26#include <asm/hardware.h> 26#include <mach/hardware.h>
27 27
28struct s3c2410_spigpio { 28struct s3c2410_spigpio {
29 struct spi_bitbang bitbang; 29 struct spi_bitbang bitbang;
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index d831a2beff39..87ab2443e66d 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1165,15 +1165,19 @@ EXPORT_SYMBOL(ssb_dma_translation);
1165 1165
1166int ssb_dma_set_mask(struct ssb_device *dev, u64 mask) 1166int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
1167{ 1167{
1168#ifdef CONFIG_SSB_PCIHOST
1168 int err; 1169 int err;
1170#endif
1169 1171
1170 switch (dev->bus->bustype) { 1172 switch (dev->bus->bustype) {
1171 case SSB_BUSTYPE_PCI: 1173 case SSB_BUSTYPE_PCI:
1174#ifdef CONFIG_SSB_PCIHOST
1172 err = pci_set_dma_mask(dev->bus->host_pci, mask); 1175 err = pci_set_dma_mask(dev->bus->host_pci, mask);
1173 if (err) 1176 if (err)
1174 return err; 1177 return err;
1175 err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask); 1178 err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
1176 return err; 1179 return err;
1180#endif
1177 case SSB_BUSTYPE_SSB: 1181 case SSB_BUSTYPE_SSB:
1178 return dma_set_mask(dev->dev, mask); 1182 return dma_set_mask(dev->dev, mask);
1179 default: 1183 default:
@@ -1188,6 +1192,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
1188{ 1192{
1189 switch (dev->bus->bustype) { 1193 switch (dev->bus->bustype) {
1190 case SSB_BUSTYPE_PCI: 1194 case SSB_BUSTYPE_PCI:
1195#ifdef CONFIG_SSB_PCIHOST
1191 if (gfp_flags & GFP_DMA) { 1196 if (gfp_flags & GFP_DMA) {
1192 /* Workaround: The PCI API does not support passing 1197 /* Workaround: The PCI API does not support passing
1193 * a GFP flag. */ 1198 * a GFP flag. */
@@ -1195,6 +1200,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
1195 size, dma_handle, gfp_flags); 1200 size, dma_handle, gfp_flags);
1196 } 1201 }
1197 return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle); 1202 return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
1203#endif
1198 case SSB_BUSTYPE_SSB: 1204 case SSB_BUSTYPE_SSB:
1199 return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags); 1205 return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
1200 default: 1206 default:
@@ -1210,6 +1216,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
1210{ 1216{
1211 switch (dev->bus->bustype) { 1217 switch (dev->bus->bustype) {
1212 case SSB_BUSTYPE_PCI: 1218 case SSB_BUSTYPE_PCI:
1219#ifdef CONFIG_SSB_PCIHOST
1213 if (gfp_flags & GFP_DMA) { 1220 if (gfp_flags & GFP_DMA) {
1214 /* Workaround: The PCI API does not support passing 1221 /* Workaround: The PCI API does not support passing
1215 * a GFP flag. */ 1222 * a GFP flag. */
@@ -1220,6 +1227,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
1220 pci_free_consistent(dev->bus->host_pci, size, 1227 pci_free_consistent(dev->bus->host_pci, size,
1221 vaddr, dma_handle); 1228 vaddr, dma_handle);
1222 return; 1229 return;
1230#endif
1223 case SSB_BUSTYPE_SSB: 1231 case SSB_BUSTYPE_SSB:
1224 dma_free_coherent(dev->dev, size, vaddr, dma_handle); 1232 dma_free_coherent(dev->dev, size, vaddr, dma_handle);
1225 return; 1233 return;
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 755823cdf62a..bcefbddeba50 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -95,16 +95,18 @@ config USB
95 95
96source "drivers/usb/core/Kconfig" 96source "drivers/usb/core/Kconfig"
97 97
98source "drivers/usb/mon/Kconfig"
99
98source "drivers/usb/host/Kconfig" 100source "drivers/usb/host/Kconfig"
99 101
102source "drivers/usb/musb/Kconfig"
103
100source "drivers/usb/class/Kconfig" 104source "drivers/usb/class/Kconfig"
101 105
102source "drivers/usb/storage/Kconfig" 106source "drivers/usb/storage/Kconfig"
103 107
104source "drivers/usb/image/Kconfig" 108source "drivers/usb/image/Kconfig"
105 109
106source "drivers/usb/mon/Kconfig"
107
108comment "USB port drivers" 110comment "USB port drivers"
109 depends on USB 111 depends on USB
110 112
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 507a9bd0d77c..9aea43a8c4ad 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -602,7 +602,7 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ
602 offd = le32_to_cpu(buf[offb++]); 602 offd = le32_to_cpu(buf[offb++]);
603 if (offd >= size) { 603 if (offd >= size) {
604 if (printk_ratelimit()) 604 if (printk_ratelimit())
605 usb_err(instance->usbatm, "wrong index #%x in response to cm #%x\n", 605 usb_err(instance->usbatm, "wrong index %#x in response to cm %#x\n",
606 offd, cm); 606 offd, cm);
607 ret = -EIO; 607 ret = -EIO;
608 goto cleanup; 608 goto cleanup;
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 0725b1871f23..efc4373ededb 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -51,6 +51,7 @@
51 */ 51 */
52 52
53#undef DEBUG 53#undef DEBUG
54#undef VERBOSE_DEBUG
54 55
55#include <linux/kernel.h> 56#include <linux/kernel.h>
56#include <linux/errno.h> 57#include <linux/errno.h>
@@ -70,6 +71,9 @@
70 71
71#include "cdc-acm.h" 72#include "cdc-acm.h"
72 73
74
75#define ACM_CLOSE_TIMEOUT 15 /* seconds to let writes drain */
76
73/* 77/*
74 * Version Information 78 * Version Information
75 */ 79 */
@@ -85,6 +89,12 @@ static DEFINE_MUTEX(open_mutex);
85 89
86#define ACM_READY(acm) (acm && acm->dev && acm->used) 90#define ACM_READY(acm) (acm && acm->dev && acm->used)
87 91
92#ifdef VERBOSE_DEBUG
93#define verbose 1
94#else
95#define verbose 0
96#endif
97
88/* 98/*
89 * Functions for ACM control messages. 99 * Functions for ACM control messages.
90 */ 100 */
@@ -136,19 +146,17 @@ static int acm_wb_alloc(struct acm *acm)
136static int acm_wb_is_avail(struct acm *acm) 146static int acm_wb_is_avail(struct acm *acm)
137{ 147{
138 int i, n; 148 int i, n;
149 unsigned long flags;
139 150
140 n = ACM_NW; 151 n = ACM_NW;
152 spin_lock_irqsave(&acm->write_lock, flags);
141 for (i = 0; i < ACM_NW; i++) { 153 for (i = 0; i < ACM_NW; i++) {
142 n -= acm->wb[i].use; 154 n -= acm->wb[i].use;
143 } 155 }
156 spin_unlock_irqrestore(&acm->write_lock, flags);
144 return n; 157 return n;
145} 158}
146 159
147static inline int acm_wb_is_used(struct acm *acm, int wbn)
148{
149 return acm->wb[wbn].use;
150}
151
152/* 160/*
153 * Finish write. 161 * Finish write.
154 */ 162 */
@@ -157,7 +165,6 @@ static void acm_write_done(struct acm *acm, struct acm_wb *wb)
157 unsigned long flags; 165 unsigned long flags;
158 166
159 spin_lock_irqsave(&acm->write_lock, flags); 167 spin_lock_irqsave(&acm->write_lock, flags);
160 acm->write_ready = 1;
161 wb->use = 0; 168 wb->use = 0;
162 acm->transmitting--; 169 acm->transmitting--;
163 spin_unlock_irqrestore(&acm->write_lock, flags); 170 spin_unlock_irqrestore(&acm->write_lock, flags);
@@ -190,40 +197,25 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb)
190static int acm_write_start(struct acm *acm, int wbn) 197static int acm_write_start(struct acm *acm, int wbn)
191{ 198{
192 unsigned long flags; 199 unsigned long flags;
193 struct acm_wb *wb; 200 struct acm_wb *wb = &acm->wb[wbn];
194 int rc; 201 int rc;
195 202
196 spin_lock_irqsave(&acm->write_lock, flags); 203 spin_lock_irqsave(&acm->write_lock, flags);
197 if (!acm->dev) { 204 if (!acm->dev) {
205 wb->use = 0;
198 spin_unlock_irqrestore(&acm->write_lock, flags); 206 spin_unlock_irqrestore(&acm->write_lock, flags);
199 return -ENODEV; 207 return -ENODEV;
200 } 208 }
201 209
202 if (!acm->write_ready) {
203 spin_unlock_irqrestore(&acm->write_lock, flags);
204 return 0; /* A white lie */
205 }
206
207 wb = &acm->wb[wbn];
208 if(acm_wb_is_avail(acm) <= 1)
209 acm->write_ready = 0;
210
211 dbg("%s susp_count: %d", __func__, acm->susp_count); 210 dbg("%s susp_count: %d", __func__, acm->susp_count);
212 if (acm->susp_count) { 211 if (acm->susp_count) {
213 acm->old_ready = acm->write_ready;
214 acm->delayed_wb = wb; 212 acm->delayed_wb = wb;
215 acm->write_ready = 0;
216 schedule_work(&acm->waker); 213 schedule_work(&acm->waker);
217 spin_unlock_irqrestore(&acm->write_lock, flags); 214 spin_unlock_irqrestore(&acm->write_lock, flags);
218 return 0; /* A white lie */ 215 return 0; /* A white lie */
219 } 216 }
220 usb_mark_last_busy(acm->dev); 217 usb_mark_last_busy(acm->dev);
221 218
222 if (!acm_wb_is_used(acm, wbn)) {
223 spin_unlock_irqrestore(&acm->write_lock, flags);
224 return 0;
225 }
226
227 rc = acm_start_wb(acm, wb); 219 rc = acm_start_wb(acm, wb);
228 spin_unlock_irqrestore(&acm->write_lock, flags); 220 spin_unlock_irqrestore(&acm->write_lock, flags);
229 221
@@ -488,22 +480,28 @@ urbs:
488/* data interface wrote those outgoing bytes */ 480/* data interface wrote those outgoing bytes */
489static void acm_write_bulk(struct urb *urb) 481static void acm_write_bulk(struct urb *urb)
490{ 482{
491 struct acm *acm;
492 struct acm_wb *wb = urb->context; 483 struct acm_wb *wb = urb->context;
484 struct acm *acm = wb->instance;
493 485
494 dbg("Entering acm_write_bulk with status %d", urb->status); 486 if (verbose || urb->status
487 || (urb->actual_length != urb->transfer_buffer_length))
488 dev_dbg(&acm->data->dev, "tx %d/%d bytes -- > %d\n",
489 urb->actual_length,
490 urb->transfer_buffer_length,
491 urb->status);
495 492
496 acm = wb->instance;
497 acm_write_done(acm, wb); 493 acm_write_done(acm, wb);
498 if (ACM_READY(acm)) 494 if (ACM_READY(acm))
499 schedule_work(&acm->work); 495 schedule_work(&acm->work);
496 else
497 wake_up_interruptible(&acm->drain_wait);
500} 498}
501 499
502static void acm_softint(struct work_struct *work) 500static void acm_softint(struct work_struct *work)
503{ 501{
504 struct acm *acm = container_of(work, struct acm, work); 502 struct acm *acm = container_of(work, struct acm, work);
505 dbg("Entering acm_softint."); 503
506 504 dev_vdbg(&acm->data->dev, "tx work\n");
507 if (!ACM_READY(acm)) 505 if (!ACM_READY(acm))
508 return; 506 return;
509 tty_wakeup(acm->tty); 507 tty_wakeup(acm->tty);
@@ -512,7 +510,6 @@ static void acm_softint(struct work_struct *work)
512static void acm_waker(struct work_struct *waker) 510static void acm_waker(struct work_struct *waker)
513{ 511{
514 struct acm *acm = container_of(waker, struct acm, waker); 512 struct acm *acm = container_of(waker, struct acm, waker);
515 long flags;
516 int rv; 513 int rv;
517 514
518 rv = usb_autopm_get_interface(acm->control); 515 rv = usb_autopm_get_interface(acm->control);
@@ -524,9 +521,6 @@ static void acm_waker(struct work_struct *waker)
524 acm_start_wb(acm, acm->delayed_wb); 521 acm_start_wb(acm, acm->delayed_wb);
525 acm->delayed_wb = NULL; 522 acm->delayed_wb = NULL;
526 } 523 }
527 spin_lock_irqsave(&acm->write_lock, flags);
528 acm->write_ready = acm->old_ready;
529 spin_unlock_irqrestore(&acm->write_lock, flags);
530 usb_autopm_put_interface(acm->control); 524 usb_autopm_put_interface(acm->control);
531} 525}
532 526
@@ -628,6 +622,8 @@ static void acm_tty_unregister(struct acm *acm)
628 kfree(acm); 622 kfree(acm);
629} 623}
630 624
625static int acm_tty_chars_in_buffer(struct tty_struct *tty);
626
631static void acm_tty_close(struct tty_struct *tty, struct file *filp) 627static void acm_tty_close(struct tty_struct *tty, struct file *filp)
632{ 628{
633 struct acm *acm = tty->driver_data; 629 struct acm *acm = tty->driver_data;
@@ -642,6 +638,13 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
642 if (acm->dev) { 638 if (acm->dev) {
643 usb_autopm_get_interface(acm->control); 639 usb_autopm_get_interface(acm->control);
644 acm_set_control(acm, acm->ctrlout = 0); 640 acm_set_control(acm, acm->ctrlout = 0);
641
642 /* try letting the last writes drain naturally */
643 wait_event_interruptible_timeout(acm->drain_wait,
644 (ACM_NW == acm_wb_is_avail(acm))
645 || !acm->dev,
646 ACM_CLOSE_TIMEOUT * HZ);
647
645 usb_kill_urb(acm->ctrlurb); 648 usb_kill_urb(acm->ctrlurb);
646 for (i = 0; i < ACM_NW; i++) 649 for (i = 0; i < ACM_NW; i++)
647 usb_kill_urb(acm->wb[i].urb); 650 usb_kill_urb(acm->wb[i].urb);
@@ -697,7 +700,7 @@ static int acm_tty_write_room(struct tty_struct *tty)
697 * Do not let the line discipline to know that we have a reserve, 700 * Do not let the line discipline to know that we have a reserve,
698 * or it might get too enthusiastic. 701 * or it might get too enthusiastic.
699 */ 702 */
700 return (acm->write_ready && acm_wb_is_avail(acm)) ? acm->writesize : 0; 703 return acm_wb_is_avail(acm) ? acm->writesize : 0;
701} 704}
702 705
703static int acm_tty_chars_in_buffer(struct tty_struct *tty) 706static int acm_tty_chars_in_buffer(struct tty_struct *tty)
@@ -1072,11 +1075,11 @@ skip_normal_probe:
1072 acm->urb_task.data = (unsigned long) acm; 1075 acm->urb_task.data = (unsigned long) acm;
1073 INIT_WORK(&acm->work, acm_softint); 1076 INIT_WORK(&acm->work, acm_softint);
1074 INIT_WORK(&acm->waker, acm_waker); 1077 INIT_WORK(&acm->waker, acm_waker);
1078 init_waitqueue_head(&acm->drain_wait);
1075 spin_lock_init(&acm->throttle_lock); 1079 spin_lock_init(&acm->throttle_lock);
1076 spin_lock_init(&acm->write_lock); 1080 spin_lock_init(&acm->write_lock);
1077 spin_lock_init(&acm->read_lock); 1081 spin_lock_init(&acm->read_lock);
1078 mutex_init(&acm->mutex); 1082 mutex_init(&acm->mutex);
1079 acm->write_ready = 1;
1080 acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); 1083 acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
1081 1084
1082 buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 1085 buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
@@ -1108,9 +1111,11 @@ skip_normal_probe:
1108 rcv->instance = acm; 1111 rcv->instance = acm;
1109 } 1112 }
1110 for (i = 0; i < num_rx_buf; i++) { 1113 for (i = 0; i < num_rx_buf; i++) {
1111 struct acm_rb *buf = &(acm->rb[i]); 1114 struct acm_rb *rb = &(acm->rb[i]);
1112 1115
1113 if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { 1116 rb->base = usb_buffer_alloc(acm->dev, readsize,
1117 GFP_KERNEL, &rb->dma);
1118 if (!rb->base) {
1114 dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); 1119 dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
1115 goto alloc_fail7; 1120 goto alloc_fail7;
1116 } 1121 }
@@ -1172,6 +1177,7 @@ skip_countries:
1172 acm_set_line(acm, &acm->line); 1177 acm_set_line(acm, &acm->line);
1173 1178
1174 usb_driver_claim_interface(&acm_driver, data_interface, acm); 1179 usb_driver_claim_interface(&acm_driver, data_interface, acm);
1180 usb_set_intfdata(data_interface, acm);
1175 1181
1176 usb_get_intf(control_interface); 1182 usb_get_intf(control_interface);
1177 tty_register_device(acm_tty_driver, minor, &control_interface->dev); 1183 tty_register_device(acm_tty_driver, minor, &control_interface->dev);
@@ -1221,11 +1227,11 @@ static void acm_disconnect(struct usb_interface *intf)
1221 struct acm *acm = usb_get_intfdata(intf); 1227 struct acm *acm = usb_get_intfdata(intf);
1222 struct usb_device *usb_dev = interface_to_usbdev(intf); 1228 struct usb_device *usb_dev = interface_to_usbdev(intf);
1223 1229
1224 mutex_lock(&open_mutex); 1230 /* sibling interface is already cleaning up */
1225 if (!acm || !acm->dev) { 1231 if (!acm)
1226 mutex_unlock(&open_mutex);
1227 return; 1232 return;
1228 } 1233
1234 mutex_lock(&open_mutex);
1229 if (acm->country_codes){ 1235 if (acm->country_codes){
1230 device_remove_file(&acm->control->dev, 1236 device_remove_file(&acm->control->dev,
1231 &dev_attr_wCountryCodes); 1237 &dev_attr_wCountryCodes);
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 85c3aaaab7c5..1f95e7aa1b66 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -106,8 +106,6 @@ struct acm {
106 struct list_head spare_read_bufs; 106 struct list_head spare_read_bufs;
107 struct list_head filled_read_bufs; 107 struct list_head filled_read_bufs;
108 int write_used; /* number of non-empty write buffers */ 108 int write_used; /* number of non-empty write buffers */
109 int write_ready; /* write urb is not running */
110 int old_ready;
111 int processing; 109 int processing;
112 int transmitting; 110 int transmitting;
113 spinlock_t write_lock; 111 spinlock_t write_lock;
@@ -115,6 +113,7 @@ struct acm {
115 struct usb_cdc_line_coding line; /* bits, stop, parity */ 113 struct usb_cdc_line_coding line; /* bits, stop, parity */
116 struct work_struct work; /* work queue entry for line discipline waking up */ 114 struct work_struct work; /* work queue entry for line discipline waking up */
117 struct work_struct waker; 115 struct work_struct waker;
116 wait_queue_head_t drain_wait; /* close processing */
118 struct tasklet_struct urb_task; /* rx processing */ 117 struct tasklet_struct urb_task; /* rx processing */
119 spinlock_t throttle_lock; /* synchronize throtteling and read callback */ 118 spinlock_t throttle_lock; /* synchronize throtteling and read callback */
120 unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */ 119 unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index ddb54e14a5c5..2be37fe466f2 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -774,7 +774,6 @@ void usb_deregister(struct usb_driver *driver)
774} 774}
775EXPORT_SYMBOL_GPL(usb_deregister); 775EXPORT_SYMBOL_GPL(usb_deregister);
776 776
777
778/* Forced unbinding of a USB interface driver, either because 777/* Forced unbinding of a USB interface driver, either because
779 * it doesn't support pre_reset/post_reset/reset_resume or 778 * it doesn't support pre_reset/post_reset/reset_resume or
780 * because it doesn't support suspend/resume. 779 * because it doesn't support suspend/resume.
@@ -821,6 +820,8 @@ void usb_rebind_intf(struct usb_interface *intf)
821 dev_warn(&intf->dev, "rebind failed: %d\n", rc); 820 dev_warn(&intf->dev, "rebind failed: %d\n", rc);
822} 821}
823 822
823#ifdef CONFIG_PM
824
824#define DO_UNBIND 0 825#define DO_UNBIND 0
825#define DO_REBIND 1 826#define DO_REBIND 1
826 827
@@ -872,8 +873,6 @@ static void do_unbind_rebind(struct usb_device *udev, int action)
872 } 873 }
873} 874}
874 875
875#ifdef CONFIG_PM
876
877/* Caller has locked udev's pm_mutex */ 876/* Caller has locked udev's pm_mutex */
878static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) 877static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
879{ 878{
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 586d6f1376cf..286b4431a097 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1091,8 +1091,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
1091 continue; 1091 continue;
1092 dev_dbg(&dev->dev, "unregistering interface %s\n", 1092 dev_dbg(&dev->dev, "unregistering interface %s\n",
1093 dev_name(&interface->dev)); 1093 dev_name(&interface->dev));
1094 device_del(&interface->dev);
1095 usb_remove_sysfs_intf_files(interface); 1094 usb_remove_sysfs_intf_files(interface);
1095 device_del(&interface->dev);
1096 } 1096 }
1097 1097
1098 /* Now that the interfaces are unbound, nobody should 1098 /* Now that the interfaces are unbound, nobody should
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index c6a8c6b1116a..acc95b2ac6f8 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -284,6 +284,16 @@ config USB_LH7A40X
284 default USB_GADGET 284 default USB_GADGET
285 select USB_GADGET_SELECTED 285 select USB_GADGET_SELECTED
286 286
287# built in ../musb along with host support
288config USB_GADGET_MUSB_HDRC
289 boolean "Inventra HDRC USB Peripheral (TI, ...)"
290 depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
291 select USB_GADGET_DUALSPEED
292 select USB_GADGET_SELECTED
293 help
294 This OTG-capable silicon IP is used in dual designs including
295 the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
296
287config USB_GADGET_OMAP 297config USB_GADGET_OMAP
288 boolean "OMAP USB Device Controller" 298 boolean "OMAP USB Device Controller"
289 depends on ARCH_OMAP 299 depends on ARCH_OMAP
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index e2d8a5d86c40..a8a1de413321 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -40,16 +40,15 @@
40#include <linux/usb/gadget.h> 40#include <linux/usb/gadget.h>
41 41
42#include <asm/byteorder.h> 42#include <asm/byteorder.h>
43#include <asm/hardware.h> 43#include <mach/hardware.h>
44#include <asm/io.h> 44#include <asm/io.h>
45#include <asm/irq.h> 45#include <asm/irq.h>
46#include <asm/system.h> 46#include <asm/system.h>
47#include <asm/mach-types.h>
48#include <asm/gpio.h> 47#include <asm/gpio.h>
49 48
50#include <asm/arch/board.h> 49#include <mach/board.h>
51#include <asm/arch/cpu.h> 50#include <mach/cpu.h>
52#include <asm/arch/at91sam9261_matrix.h> 51#include <mach/at91sam9261_matrix.h>
53 52
54#include "at91_udc.h" 53#include "at91_udc.h"
55 54
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 07e5a0b5dcda..ae30ab1d264f 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -22,7 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23 23
24#include <asm/gpio.h> 24#include <asm/gpio.h>
25#include <asm/arch/board.h> 25#include <mach/board.h>
26 26
27#include "atmel_usba_udc.h" 27#include "atmel_usba_udc.h"
28 28
@@ -334,7 +334,7 @@ static void toggle_bias(int is_on)
334 334
335#elif defined(CONFIG_ARCH_AT91) 335#elif defined(CONFIG_ARCH_AT91)
336 336
337#include <asm/arch/at91_pmc.h> 337#include <mach/at91_pmc.h>
338 338
339static void toggle_bias(int is_on) 339static void toggle_bias(int is_on)
340{ 340{
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 21d1406af9ee..7600a0c78753 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -542,13 +542,14 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req,
542 req->req.context = dum; 542 req->req.context = dum;
543 req->req.complete = fifo_complete; 543 req->req.complete = fifo_complete;
544 544
545 list_add_tail(&req->queue, &ep->queue);
545 spin_unlock (&dum->lock); 546 spin_unlock (&dum->lock);
546 _req->actual = _req->length; 547 _req->actual = _req->length;
547 _req->status = 0; 548 _req->status = 0;
548 _req->complete (_ep, _req); 549 _req->complete (_ep, _req);
549 spin_lock (&dum->lock); 550 spin_lock (&dum->lock);
550 } 551 } else
551 list_add_tail (&req->queue, &ep->queue); 552 list_add_tail(&req->queue, &ep->queue);
552 spin_unlock_irqrestore (&dum->lock, flags); 553 spin_unlock_irqrestore (&dum->lock, flags);
553 554
554 /* real hardware would likely enable transfers here, in case 555 /* real hardware would likely enable transfers here, in case
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index d8faccf27895..5ee1590b8e9c 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -47,18 +47,37 @@ struct f_acm {
47 u8 ctrl_id, data_id; 47 u8 ctrl_id, data_id;
48 u8 port_num; 48 u8 port_num;
49 49
50 struct usb_descriptor_header **fs_function; 50 u8 pending;
51
52 /* lock is mostly for pending and notify_req ... they get accessed
53 * by callbacks both from tty (open/close/break) under its spinlock,
54 * and notify_req.complete() which can't use that lock.
55 */
56 spinlock_t lock;
57
51 struct acm_ep_descs fs; 58 struct acm_ep_descs fs;
52 struct usb_descriptor_header **hs_function;
53 struct acm_ep_descs hs; 59 struct acm_ep_descs hs;
54 60
55 struct usb_ep *notify; 61 struct usb_ep *notify;
56 struct usb_endpoint_descriptor *notify_desc; 62 struct usb_endpoint_descriptor *notify_desc;
63 struct usb_request *notify_req;
57 64
58 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ 65 struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */
66
67 /* SetControlLineState request -- CDC 1.1 section 6.2.14 (INPUT) */
59 u16 port_handshake_bits; 68 u16 port_handshake_bits;
60#define RS232_RTS (1 << 1) /* unused with full duplex */ 69#define ACM_CTRL_RTS (1 << 1) /* unused with full duplex */
61#define RS232_DTR (1 << 0) /* host is ready for data r/w */ 70#define ACM_CTRL_DTR (1 << 0) /* host is ready for data r/w */
71
72 /* SerialState notification -- CDC 1.1 section 6.3.5 (OUTPUT) */
73 u16 serial_state;
74#define ACM_CTRL_OVERRUN (1 << 6)
75#define ACM_CTRL_PARITY (1 << 5)
76#define ACM_CTRL_FRAMING (1 << 4)
77#define ACM_CTRL_RI (1 << 3)
78#define ACM_CTRL_BRK (1 << 2)
79#define ACM_CTRL_DSR (1 << 1)
80#define ACM_CTRL_DCD (1 << 0)
62}; 81};
63 82
64static inline struct f_acm *func_to_acm(struct usb_function *f) 83static inline struct f_acm *func_to_acm(struct usb_function *f)
@@ -66,12 +85,17 @@ static inline struct f_acm *func_to_acm(struct usb_function *f)
66 return container_of(f, struct f_acm, port.func); 85 return container_of(f, struct f_acm, port.func);
67} 86}
68 87
88static inline struct f_acm *port_to_acm(struct gserial *p)
89{
90 return container_of(p, struct f_acm, port);
91}
92
69/*-------------------------------------------------------------------------*/ 93/*-------------------------------------------------------------------------*/
70 94
71/* notification endpoint uses smallish and infrequent fixed-size messages */ 95/* notification endpoint uses smallish and infrequent fixed-size messages */
72 96
73#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */ 97#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */
74#define GS_NOTIFY_MAXPACKET 8 98#define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */
75 99
76/* interface and class descriptors: */ 100/* interface and class descriptors: */
77 101
@@ -117,7 +141,7 @@ static struct usb_cdc_acm_descriptor acm_descriptor __initdata = {
117 .bLength = sizeof(acm_descriptor), 141 .bLength = sizeof(acm_descriptor),
118 .bDescriptorType = USB_DT_CS_INTERFACE, 142 .bDescriptorType = USB_DT_CS_INTERFACE,
119 .bDescriptorSubType = USB_CDC_ACM_TYPE, 143 .bDescriptorSubType = USB_CDC_ACM_TYPE,
120 .bmCapabilities = (1 << 1), 144 .bmCapabilities = USB_CDC_CAP_LINE,
121}; 145};
122 146
123static struct usb_cdc_union_desc acm_union_desc __initdata = { 147static struct usb_cdc_union_desc acm_union_desc __initdata = {
@@ -277,6 +301,11 @@ static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
277 301
278 /* composite driver infrastructure handles everything except 302 /* composite driver infrastructure handles everything except
279 * CDC class messages; interface activation uses set_alt(). 303 * CDC class messages; interface activation uses set_alt().
304 *
305 * Note CDC spec table 4 lists the ACM request profile. It requires
306 * encapsulated command support ... we don't handle any, and respond
307 * to them by stalling. Options include get/set/clear comm features
308 * (not that useful) and SEND_BREAK.
280 */ 309 */
281 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { 310 switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
282 311
@@ -312,7 +341,7 @@ static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
312 value = 0; 341 value = 0;
313 342
314 /* FIXME we should not allow data to flow until the 343 /* FIXME we should not allow data to flow until the
315 * host sets the RS232_DTR bit; and when it clears 344 * host sets the ACM_CTRL_DTR bit; and when it clears
316 * that bit, we should return to that no-flow state. 345 * that bit, we should return to that no-flow state.
317 */ 346 */
318 acm->port_handshake_bits = w_value; 347 acm->port_handshake_bits = w_value;
@@ -350,9 +379,6 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
350 /* we know alt == 0, so this is an activation or a reset */ 379 /* we know alt == 0, so this is an activation or a reset */
351 380
352 if (intf == acm->ctrl_id) { 381 if (intf == acm->ctrl_id) {
353 /* REVISIT this may need more work when we start to
354 * send notifications ...
355 */
356 if (acm->notify->driver_data) { 382 if (acm->notify->driver_data) {
357 VDBG(cdev, "reset acm control interface %d\n", intf); 383 VDBG(cdev, "reset acm control interface %d\n", intf);
358 usb_ep_disable(acm->notify); 384 usb_ep_disable(acm->notify);
@@ -397,6 +423,128 @@ static void acm_disable(struct usb_function *f)
397 423
398/*-------------------------------------------------------------------------*/ 424/*-------------------------------------------------------------------------*/
399 425
426/**
427 * acm_cdc_notify - issue CDC notification to host
428 * @acm: wraps host to be notified
429 * @type: notification type
430 * @value: Refer to cdc specs, wValue field.
431 * @data: data to be sent
432 * @length: size of data
433 * Context: irqs blocked, acm->lock held, acm_notify_req non-null
434 *
435 * Returns zero on sucess or a negative errno.
436 *
437 * See section 6.3.5 of the CDC 1.1 specification for information
438 * about the only notification we issue: SerialState change.
439 */
440static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
441 void *data, unsigned length)
442{
443 struct usb_ep *ep = acm->notify;
444 struct usb_request *req;
445 struct usb_cdc_notification *notify;
446 const unsigned len = sizeof(*notify) + length;
447 void *buf;
448 int status;
449
450 req = acm->notify_req;
451 acm->notify_req = NULL;
452 acm->pending = false;
453
454 req->length = len;
455 notify = req->buf;
456 buf = notify + 1;
457
458 notify->bmRequestType = USB_DIR_IN | USB_TYPE_CLASS
459 | USB_RECIP_INTERFACE;
460 notify->bNotificationType = type;
461 notify->wValue = cpu_to_le16(value);
462 notify->wIndex = cpu_to_le16(acm->ctrl_id);
463 notify->wLength = cpu_to_le16(length);
464 memcpy(buf, data, length);
465
466 status = usb_ep_queue(ep, req, GFP_ATOMIC);
467 if (status < 0) {
468 ERROR(acm->port.func.config->cdev,
469 "acm ttyGS%d can't notify serial state, %d\n",
470 acm->port_num, status);
471 acm->notify_req = req;
472 }
473
474 return status;
475}
476
477static int acm_notify_serial_state(struct f_acm *acm)
478{
479 struct usb_composite_dev *cdev = acm->port.func.config->cdev;
480 int status;
481
482 spin_lock(&acm->lock);
483 if (acm->notify_req) {
484 DBG(cdev, "acm ttyGS%d serial state %04x\n",
485 acm->port_num, acm->serial_state);
486 status = acm_cdc_notify(acm, USB_CDC_NOTIFY_SERIAL_STATE,
487 0, &acm->serial_state, sizeof(acm->serial_state));
488 } else {
489 acm->pending = true;
490 status = 0;
491 }
492 spin_unlock(&acm->lock);
493 return status;
494}
495
496static void acm_cdc_notify_complete(struct usb_ep *ep, struct usb_request *req)
497{
498 struct f_acm *acm = req->context;
499 u8 doit = false;
500
501 /* on this call path we do NOT hold the port spinlock,
502 * which is why ACM needs its own spinlock
503 */
504 spin_lock(&acm->lock);
505 if (req->status != -ESHUTDOWN)
506 doit = acm->pending;
507 acm->notify_req = req;
508 spin_unlock(&acm->lock);
509
510 if (doit)
511 acm_notify_serial_state(acm);
512}
513
514/* connect == the TTY link is open */
515
516static void acm_connect(struct gserial *port)
517{
518 struct f_acm *acm = port_to_acm(port);
519
520 acm->serial_state |= ACM_CTRL_DSR | ACM_CTRL_DCD;
521 acm_notify_serial_state(acm);
522}
523
524static void acm_disconnect(struct gserial *port)
525{
526 struct f_acm *acm = port_to_acm(port);
527
528 acm->serial_state &= ~(ACM_CTRL_DSR | ACM_CTRL_DCD);
529 acm_notify_serial_state(acm);
530}
531
532static int acm_send_break(struct gserial *port, int duration)
533{
534 struct f_acm *acm = port_to_acm(port);
535 u16 state;
536
537 state = acm->serial_state;
538 state &= ~ACM_CTRL_BRK;
539 if (duration)
540 state |= ACM_CTRL_BRK;
541
542 acm->serial_state = state;
543 return acm_notify_serial_state(acm);
544}
545
546/*-------------------------------------------------------------------------*/
547
400/* ACM function driver setup/binding */ 548/* ACM function driver setup/binding */
401static int __init 549static int __init
402acm_bind(struct usb_configuration *c, struct usb_function *f) 550acm_bind(struct usb_configuration *c, struct usb_function *f)
@@ -445,8 +593,20 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
445 acm->notify = ep; 593 acm->notify = ep;
446 ep->driver_data = cdev; /* claim */ 594 ep->driver_data = cdev; /* claim */
447 595
596 /* allocate notification */
597 acm->notify_req = gs_alloc_req(ep,
598 sizeof(struct usb_cdc_notification) + 2,
599 GFP_KERNEL);
600 if (!acm->notify_req)
601 goto fail;
602
603 acm->notify_req->complete = acm_cdc_notify_complete;
604 acm->notify_req->context = acm;
605
448 /* copy descriptors, and track endpoint copies */ 606 /* copy descriptors, and track endpoint copies */
449 f->descriptors = usb_copy_descriptors(acm_fs_function); 607 f->descriptors = usb_copy_descriptors(acm_fs_function);
608 if (!f->descriptors)
609 goto fail;
450 610
451 acm->fs.in = usb_find_endpoint(acm_fs_function, 611 acm->fs.in = usb_find_endpoint(acm_fs_function,
452 f->descriptors, &acm_fs_in_desc); 612 f->descriptors, &acm_fs_in_desc);
@@ -478,8 +638,6 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
478 f->hs_descriptors, &acm_hs_notify_desc); 638 f->hs_descriptors, &acm_hs_notify_desc);
479 } 639 }
480 640
481 /* FIXME provide a callback for triggering notifications */
482
483 DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", 641 DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
484 acm->port_num, 642 acm->port_num,
485 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 643 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
@@ -488,6 +646,9 @@ acm_bind(struct usb_configuration *c, struct usb_function *f)
488 return 0; 646 return 0;
489 647
490fail: 648fail:
649 if (acm->notify_req)
650 gs_free_req(acm->notify, acm->notify_req);
651
491 /* we might as well release our claims on endpoints */ 652 /* we might as well release our claims on endpoints */
492 if (acm->notify) 653 if (acm->notify)
493 acm->notify->driver_data = NULL; 654 acm->notify->driver_data = NULL;
@@ -504,10 +665,13 @@ fail:
504static void 665static void
505acm_unbind(struct usb_configuration *c, struct usb_function *f) 666acm_unbind(struct usb_configuration *c, struct usb_function *f)
506{ 667{
668 struct f_acm *acm = func_to_acm(f);
669
507 if (gadget_is_dualspeed(c->cdev->gadget)) 670 if (gadget_is_dualspeed(c->cdev->gadget))
508 usb_free_descriptors(f->hs_descriptors); 671 usb_free_descriptors(f->hs_descriptors);
509 usb_free_descriptors(f->descriptors); 672 usb_free_descriptors(f->descriptors);
510 kfree(func_to_acm(f)); 673 gs_free_req(acm->notify, acm->notify_req);
674 kfree(acm);
511} 675}
512 676
513/* Some controllers can't support CDC ACM ... */ 677/* Some controllers can't support CDC ACM ... */
@@ -571,8 +735,14 @@ int __init acm_bind_config(struct usb_configuration *c, u8 port_num)
571 if (!acm) 735 if (!acm)
572 return -ENOMEM; 736 return -ENOMEM;
573 737
738 spin_lock_init(&acm->lock);
739
574 acm->port_num = port_num; 740 acm->port_num = port_num;
575 741
742 acm->port.connect = acm_connect;
743 acm->port.disconnect = acm_disconnect;
744 acm->port.send_break = acm_send_break;
745
576 acm->port.func.name = "acm"; 746 acm->port.func.name = "acm";
577 acm->port.func.strings = acm_strings; 747 acm->port.func.strings = acm_strings;
578 /* descriptors are per-instance copies */ 748 /* descriptors are per-instance copies */
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index 0822e9d7693a..a2b5c092bda0 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -63,9 +63,7 @@ struct f_ecm {
63 63
64 char ethaddr[14]; 64 char ethaddr[14];
65 65
66 struct usb_descriptor_header **fs_function;
67 struct ecm_ep_descs fs; 66 struct ecm_ep_descs fs;
68 struct usb_descriptor_header **hs_function;
69 struct ecm_ep_descs hs; 67 struct ecm_ep_descs hs;
70 68
71 struct usb_ep *notify; 69 struct usb_ep *notify;
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 61652f0f13fd..659b3d9671c4 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -85,9 +85,7 @@ struct f_rndis {
85 u8 ethaddr[ETH_ALEN]; 85 u8 ethaddr[ETH_ALEN];
86 int config; 86 int config;
87 87
88 struct usb_descriptor_header **fs_function;
89 struct rndis_ep_descs fs; 88 struct rndis_ep_descs fs;
90 struct usb_descriptor_header **hs_function;
91 struct rndis_ep_descs hs; 89 struct rndis_ep_descs hs;
92 90
93 struct usb_ep *notify; 91 struct usb_ep *notify;
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 1b6bde9aaed5..fe5674db344b 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -36,9 +36,7 @@ struct f_gser {
36 u8 data_id; 36 u8 data_id;
37 u8 port_num; 37 u8 port_num;
38 38
39 struct usb_descriptor_header **fs_function;
40 struct gser_descs fs; 39 struct gser_descs fs;
41 struct usb_descriptor_header **hs_function;
42 struct gser_descs hs; 40 struct gser_descs hs;
43}; 41};
44 42
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index afeab9a0523f..acb8d233aa1d 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -66,9 +66,7 @@ struct f_gether {
66 66
67 char ethaddr[14]; 67 char ethaddr[14];
68 68
69 struct usb_descriptor_header **fs_function;
70 struct geth_descs fs; 69 struct geth_descs fs;
71 struct usb_descriptor_header **hs_function;
72 struct geth_descs hs; 70 struct geth_descs hs;
73}; 71};
74 72
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 5246e8fef2b2..17d9905101b7 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -11,6 +11,10 @@
11 * Some are available on 2.4 kernels; several are available, but not 11 * Some are available on 2.4 kernels; several are available, but not
12 * yet pushed in the 2.6 mainline tree. 12 * yet pushed in the 2.6 mainline tree.
13 */ 13 */
14
15#ifndef __GADGET_CHIPS_H
16#define __GADGET_CHIPS_H
17
14#ifdef CONFIG_USB_GADGET_NET2280 18#ifdef CONFIG_USB_GADGET_NET2280
15#define gadget_is_net2280(g) !strcmp("net2280", (g)->name) 19#define gadget_is_net2280(g) !strcmp("net2280", (g)->name)
16#else 20#else
@@ -237,3 +241,5 @@ static inline bool gadget_supports_altsettings(struct usb_gadget *gadget)
237 /* Everything else is *presumably* fine ... */ 241 /* Everything else is *presumably* fine ... */
238 return true; 242 return true;
239} 243}
244
245#endif /* __GADGET_CHIPS_H */
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h
index 1ecfd6366b9a..ca861203a301 100644
--- a/drivers/usb/gadget/lh7a40x_udc.h
+++ b/drivers/usb/gadget/lh7a40x_udc.h
@@ -47,7 +47,7 @@
47#include <asm/irq.h> 47#include <asm/irq.h>
48#include <asm/system.h> 48#include <asm/system.h>
49#include <asm/unaligned.h> 49#include <asm/unaligned.h>
50#include <asm/hardware.h> 50#include <mach/hardware.h>
51 51
52#include <linux/usb/ch9.h> 52#include <linux/usb/ch9.h>
53#include <linux/usb/gadget.h> 53#include <linux/usb/gadget.h>
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 395bd1844482..574c53831a05 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -52,8 +52,9 @@
52#include <asm/unaligned.h> 52#include <asm/unaligned.h>
53#include <asm/mach-types.h> 53#include <asm/mach-types.h>
54 54
55#include <asm/arch/dma.h> 55#include <mach/dma.h>
56#include <asm/arch/usb.h> 56#include <mach/usb.h>
57#include <mach/control.h>
57 58
58#include "omap_udc.h" 59#include "omap_udc.h"
59 60
@@ -2310,10 +2311,10 @@ static int proc_otg_show(struct seq_file *s)
2310 u32 trans; 2311 u32 trans;
2311 char *ctrl_name; 2312 char *ctrl_name;
2312 2313
2313 tmp = OTG_REV_REG; 2314 tmp = omap_readl(OTG_REV);
2314 if (cpu_is_omap24xx()) { 2315 if (cpu_is_omap24xx()) {
2315 ctrl_name = "control_devconf"; 2316 ctrl_name = "control_devconf";
2316 trans = CONTROL_DEVCONF_REG; 2317 trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
2317 } else { 2318 } else {
2318 ctrl_name = "tranceiver_ctrl"; 2319 ctrl_name = "tranceiver_ctrl";
2319 trans = omap_readw(USB_TRANSCEIVER_CTRL); 2320 trans = omap_readw(USB_TRANSCEIVER_CTRL);
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index 7e6725d89976..da6e93c201d2 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -61,7 +61,7 @@
61 * This driver is PXA25x only. Grab the right register definitions. 61 * This driver is PXA25x only. Grab the right register definitions.
62 */ 62 */
63#ifdef CONFIG_ARCH_PXA 63#ifdef CONFIG_ARCH_PXA
64#include <asm/arch/pxa25x-udc.h> 64#include <mach/pxa25x-udc.h>
65#endif 65#endif
66 66
67#include <asm/mach/udc_pxa2xx.h> 67#include <asm/mach/udc_pxa2xx.h>
diff --git a/drivers/usb/gadget/pxa25x_udc.h b/drivers/usb/gadget/pxa25x_udc.h
index c8a13215e02c..1d51aa21e6eb 100644
--- a/drivers/usb/gadget/pxa25x_udc.h
+++ b/drivers/usb/gadget/pxa25x_udc.h
@@ -139,7 +139,7 @@ struct pxa25x_udc {
139/*-------------------------------------------------------------------------*/ 139/*-------------------------------------------------------------------------*/
140 140
141#ifdef CONFIG_ARCH_LUBBOCK 141#ifdef CONFIG_ARCH_LUBBOCK
142#include <asm/arch/lubbock.h> 142#include <mach/lubbock.h>
143/* lubbock can also report usb connect/disconnect irqs */ 143/* lubbock can also report usb connect/disconnect irqs */
144#endif 144#endif
145 145
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 9d447d8cfc0c..a28513ecbe5b 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -33,13 +33,13 @@
33#include <linux/irq.h> 33#include <linux/irq.h>
34 34
35#include <asm/byteorder.h> 35#include <asm/byteorder.h>
36#include <asm/hardware.h> 36#include <mach/hardware.h>
37 37
38#include <linux/usb.h> 38#include <linux/usb.h>
39#include <linux/usb/ch9.h> 39#include <linux/usb/ch9.h>
40#include <linux/usb/gadget.h> 40#include <linux/usb/gadget.h>
41#include <asm/arch/pxa2xx-regs.h> /* FIXME: for PSSR */ 41#include <mach/pxa2xx-regs.h> /* FIXME: for PSSR */
42#include <asm/arch/udc.h> 42#include <mach/udc.h>
43 43
44#include "pxa27x_udc.h" 44#include "pxa27x_udc.h"
45 45
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index 6b1ef488043b..538807384592 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -49,15 +49,14 @@
49#include <asm/irq.h> 49#include <asm/irq.h>
50#include <asm/system.h> 50#include <asm/system.h>
51#include <asm/unaligned.h> 51#include <asm/unaligned.h>
52#include <asm/arch/irqs.h> 52#include <mach/irqs.h>
53 53
54#include <asm/arch/hardware.h> 54#include <mach/hardware.h>
55#include <asm/arch/regs-gpio.h> 55#include <mach/regs-gpio.h>
56 56
57#include <asm/plat-s3c24xx/regs-udc.h> 57#include <asm/plat-s3c24xx/regs-udc.h>
58#include <asm/plat-s3c24xx/udc.h> 58#include <asm/plat-s3c24xx/udc.h>
59 59
60#include <asm/mach-types.h>
61 60
62#include "s3c2410_udc.h" 61#include "s3c2410_udc.h"
63 62
@@ -888,7 +887,7 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
888 } 887 }
889} 888}
890 889
891#include <asm/arch/regs-irq.h> 890#include <mach/regs-irq.h>
892 891
893/* 892/*
894 * s3c2410_udc_irq - interrupt handler 893 * s3c2410_udc_irq - interrupt handler
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index abf9505d3a75..53d59287f2bc 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -52,13 +52,16 @@
52 * is managed in userspace ... OBEX, PTP, and MTP have been mentioned. 52 * is managed in userspace ... OBEX, PTP, and MTP have been mentioned.
53 */ 53 */
54 54
55#define PREFIX "ttyGS"
56
55/* 57/*
56 * gserial is the lifecycle interface, used by USB functions 58 * gserial is the lifecycle interface, used by USB functions
57 * gs_port is the I/O nexus, used by the tty driver 59 * gs_port is the I/O nexus, used by the tty driver
58 * tty_struct links to the tty/filesystem framework 60 * tty_struct links to the tty/filesystem framework
59 * 61 *
60 * gserial <---> gs_port ... links will be null when the USB link is 62 * gserial <---> gs_port ... links will be null when the USB link is
61 * inactive; managed by gserial_{connect,disconnect}(). 63 * inactive; managed by gserial_{connect,disconnect}(). each gserial
64 * instance can wrap its own USB control protocol.
62 * gserial->ioport == usb_ep->driver_data ... gs_port 65 * gserial->ioport == usb_ep->driver_data ... gs_port
63 * gs_port->port_usb ... gserial 66 * gs_port->port_usb ... gserial
64 * 67 *
@@ -100,6 +103,8 @@ struct gs_port {
100 wait_queue_head_t close_wait; /* wait for last close */ 103 wait_queue_head_t close_wait; /* wait for last close */
101 104
102 struct list_head read_pool; 105 struct list_head read_pool;
106 struct list_head read_queue;
107 unsigned n_read;
103 struct tasklet_struct push; 108 struct tasklet_struct push;
104 109
105 struct list_head write_pool; 110 struct list_head write_pool;
@@ -177,7 +182,7 @@ static void gs_buf_clear(struct gs_buf *gb)
177/* 182/*
178 * gs_buf_data_avail 183 * gs_buf_data_avail
179 * 184 *
180 * Return the number of bytes of data available in the circular 185 * Return the number of bytes of data written into the circular
181 * buffer. 186 * buffer.
182 */ 187 */
183static unsigned gs_buf_data_avail(struct gs_buf *gb) 188static unsigned gs_buf_data_avail(struct gs_buf *gb)
@@ -278,7 +283,7 @@ gs_buf_get(struct gs_buf *gb, char *buf, unsigned count)
278 * Allocate a usb_request and its buffer. Returns a pointer to the 283 * Allocate a usb_request and its buffer. Returns a pointer to the
279 * usb_request or NULL if there is an error. 284 * usb_request or NULL if there is an error.
280 */ 285 */
281static struct usb_request * 286struct usb_request *
282gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags) 287gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
283{ 288{
284 struct usb_request *req; 289 struct usb_request *req;
@@ -302,7 +307,7 @@ gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
302 * 307 *
303 * Free a usb_request and its buffer. 308 * Free a usb_request and its buffer.
304 */ 309 */
305static void gs_free_req(struct usb_ep *ep, struct usb_request *req) 310void gs_free_req(struct usb_ep *ep, struct usb_request *req)
306{ 311{
307 kfree(req->buf); 312 kfree(req->buf);
308 usb_ep_free_request(ep, req); 313 usb_ep_free_request(ep, req);
@@ -367,11 +372,9 @@ __acquires(&port->port_lock)
367 req->length = len; 372 req->length = len;
368 list_del(&req->list); 373 list_del(&req->list);
369 374
370#ifdef VERBOSE_DEBUG 375 pr_vdebug(PREFIX "%d: tx len=%d, 0x%02x 0x%02x 0x%02x ...\n",
371 pr_debug("%s: %s, len=%d, 0x%02x 0x%02x 0x%02x ...\n", 376 port->port_num, len, *((u8 *)req->buf),
372 __func__, in->name, len, *((u8 *)req->buf),
373 *((u8 *)req->buf+1), *((u8 *)req->buf+2)); 377 *((u8 *)req->buf+1), *((u8 *)req->buf+2));
374#endif
375 378
376 /* Drop lock while we call out of driver; completions 379 /* Drop lock while we call out of driver; completions
377 * could be issued while we do so. Disconnection may 380 * could be issued while we do so. Disconnection may
@@ -401,56 +404,6 @@ __acquires(&port->port_lock)
401 return status; 404 return status;
402} 405}
403 406
404static void gs_rx_push(unsigned long _port)
405{
406 struct gs_port *port = (void *)_port;
407 struct tty_struct *tty = port->port_tty;
408
409 /* With low_latency, tty_flip_buffer_push() doesn't put its
410 * real work through a workqueue, so the ldisc has a better
411 * chance to keep up with peak USB data rates.
412 */
413 if (tty) {
414 tty_flip_buffer_push(tty);
415 wake_up_interruptible(&tty->read_wait);
416 }
417}
418
419/*
420 * gs_recv_packet
421 *
422 * Called for each USB packet received. Reads the packet
423 * header and stuffs the data in the appropriate tty buffer.
424 * Returns 0 if successful, or a negative error number.
425 *
426 * Called during USB completion routine, on interrupt time.
427 * With port_lock.
428 */
429static int gs_recv_packet(struct gs_port *port, char *packet, unsigned size)
430{
431 unsigned len;
432 struct tty_struct *tty;
433
434 /* I/O completions can continue for a while after close(), until the
435 * request queue empties. Just discard any data we receive, until
436 * something reopens this TTY ... as if there were no HW flow control.
437 */
438 tty = port->port_tty;
439 if (tty == NULL) {
440 pr_vdebug("%s: ttyGS%d, after close\n",
441 __func__, port->port_num);
442 return -EIO;
443 }
444
445 len = tty_insert_flip_string(tty, packet, size);
446 if (len > 0)
447 tasklet_schedule(&port->push);
448 if (len < size)
449 pr_debug("%s: ttyGS%d, drop %d bytes\n",
450 __func__, port->port_num, size - len);
451 return 0;
452}
453
454/* 407/*
455 * Context: caller owns port_lock, and port_usb is set 408 * Context: caller owns port_lock, and port_usb is set
456 */ 409 */
@@ -469,9 +422,9 @@ __acquires(&port->port_lock)
469 int status; 422 int status;
470 struct tty_struct *tty; 423 struct tty_struct *tty;
471 424
472 /* no more rx if closed or throttled */ 425 /* no more rx if closed */
473 tty = port->port_tty; 426 tty = port->port_tty;
474 if (!tty || test_bit(TTY_THROTTLED, &tty->flags)) 427 if (!tty)
475 break; 428 break;
476 429
477 req = list_entry(pool->next, struct usb_request, list); 430 req = list_entry(pool->next, struct usb_request, list);
@@ -500,36 +453,134 @@ __acquires(&port->port_lock)
500 return started; 453 return started;
501} 454}
502 455
503static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) 456/*
457 * RX tasklet takes data out of the RX queue and hands it up to the TTY
458 * layer until it refuses to take any more data (or is throttled back).
459 * Then it issues reads for any further data.
460 *
461 * If the RX queue becomes full enough that no usb_request is queued,
462 * the OUT endpoint may begin NAKing as soon as its FIFO fills up.
463 * So QUEUE_SIZE packets plus however many the FIFO holds (usually two)
464 * can be buffered before the TTY layer's buffers (currently 64 KB).
465 */
466static void gs_rx_push(unsigned long _port)
504{ 467{
505 int status; 468 struct gs_port *port = (void *)_port;
506 struct gs_port *port = ep->driver_data; 469 struct tty_struct *tty;
470 struct list_head *queue = &port->read_queue;
471 bool disconnect = false;
472 bool do_push = false;
507 473
508 spin_lock(&port->port_lock); 474 /* hand any queued data to the tty */
509 list_add(&req->list, &port->read_pool); 475 spin_lock_irq(&port->port_lock);
476 tty = port->port_tty;
477 while (!list_empty(queue)) {
478 struct usb_request *req;
510 479
511 switch (req->status) { 480 req = list_first_entry(queue, struct usb_request, list);
512 case 0:
513 /* normal completion */
514 status = gs_recv_packet(port, req->buf, req->actual);
515 if (status && status != -EIO)
516 pr_debug("%s: %s %s err %d\n",
517 __func__, "recv", ep->name, status);
518 gs_start_rx(port);
519 break;
520 481
521 case -ESHUTDOWN: 482 /* discard data if tty was closed */
522 /* disconnect */ 483 if (!tty)
523 pr_vdebug("%s: %s shutdown\n", __func__, ep->name); 484 goto recycle;
524 break;
525 485
526 default: 486 /* leave data queued if tty was rx throttled */
527 /* presumably a transient fault */ 487 if (test_bit(TTY_THROTTLED, &tty->flags))
528 pr_warning("%s: unexpected %s status %d\n", 488 break;
529 __func__, ep->name, req->status); 489
530 gs_start_rx(port); 490 switch (req->status) {
531 break; 491 case -ESHUTDOWN:
492 disconnect = true;
493 pr_vdebug(PREFIX "%d: shutdown\n", port->port_num);
494 break;
495
496 default:
497 /* presumably a transient fault */
498 pr_warning(PREFIX "%d: unexpected RX status %d\n",
499 port->port_num, req->status);
500 /* FALLTHROUGH */
501 case 0:
502 /* normal completion */
503 break;
504 }
505
506 /* push data to (open) tty */
507 if (req->actual) {
508 char *packet = req->buf;
509 unsigned size = req->actual;
510 unsigned n;
511 int count;
512
513 /* we may have pushed part of this packet already... */
514 n = port->n_read;
515 if (n) {
516 packet += n;
517 size -= n;
518 }
519
520 count = tty_insert_flip_string(tty, packet, size);
521 if (count)
522 do_push = true;
523 if (count != size) {
524 /* stop pushing; TTY layer can't handle more */
525 port->n_read += count;
526 pr_vdebug(PREFIX "%d: rx block %d/%d\n",
527 port->port_num,
528 count, req->actual);
529 break;
530 }
531 port->n_read = 0;
532 }
533recycle:
534 list_move(&req->list, &port->read_pool);
532 } 535 }
536
537 /* Push from tty to ldisc; this is immediate with low_latency, and
538 * may trigger callbacks to this driver ... so drop the spinlock.
539 */
540 if (tty && do_push) {
541 spin_unlock_irq(&port->port_lock);
542 tty_flip_buffer_push(tty);
543 wake_up_interruptible(&tty->read_wait);
544 spin_lock_irq(&port->port_lock);
545
546 /* tty may have been closed */
547 tty = port->port_tty;
548 }
549
550
551 /* We want our data queue to become empty ASAP, keeping data
552 * in the tty and ldisc (not here). If we couldn't push any
553 * this time around, there may be trouble unless there's an
554 * implicit tty_unthrottle() call on its way...
555 *
556 * REVISIT we should probably add a timer to keep the tasklet
557 * from starving ... but it's not clear that case ever happens.
558 */
559 if (!list_empty(queue) && tty) {
560 if (!test_bit(TTY_THROTTLED, &tty->flags)) {
561 if (do_push)
562 tasklet_schedule(&port->push);
563 else
564 pr_warning(PREFIX "%d: RX not scheduled?\n",
565 port->port_num);
566 }
567 }
568
569 /* If we're still connected, refill the USB RX queue. */
570 if (!disconnect && port->port_usb)
571 gs_start_rx(port);
572
573 spin_unlock_irq(&port->port_lock);
574}
575
576static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
577{
578 struct gs_port *port = ep->driver_data;
579
580 /* Queue all received data until the tty layer is ready for it. */
581 spin_lock(&port->port_lock);
582 list_add_tail(&req->list, &port->read_queue);
583 tasklet_schedule(&port->push);
533 spin_unlock(&port->port_lock); 584 spin_unlock(&port->port_lock);
534} 585}
535 586
@@ -625,6 +676,7 @@ static int gs_start_io(struct gs_port *port)
625 } 676 }
626 677
627 /* queue read requests */ 678 /* queue read requests */
679 port->n_read = 0;
628 started = gs_start_rx(port); 680 started = gs_start_rx(port);
629 681
630 /* unblock any pending writes into our circular buffer */ 682 /* unblock any pending writes into our circular buffer */
@@ -633,9 +685,10 @@ static int gs_start_io(struct gs_port *port)
633 } else { 685 } else {
634 gs_free_requests(ep, head); 686 gs_free_requests(ep, head);
635 gs_free_requests(port->port_usb->in, &port->write_pool); 687 gs_free_requests(port->port_usb->in, &port->write_pool);
688 status = -EIO;
636 } 689 }
637 690
638 return started ? 0 : status; 691 return status;
639} 692}
640 693
641/*-------------------------------------------------------------------------*/ 694/*-------------------------------------------------------------------------*/
@@ -736,10 +789,13 @@ static int gs_open(struct tty_struct *tty, struct file *file)
736 789
737 /* if connected, start the I/O stream */ 790 /* if connected, start the I/O stream */
738 if (port->port_usb) { 791 if (port->port_usb) {
792 struct gserial *gser = port->port_usb;
793
739 pr_debug("gs_open: start ttyGS%d\n", port->port_num); 794 pr_debug("gs_open: start ttyGS%d\n", port->port_num);
740 gs_start_io(port); 795 gs_start_io(port);
741 796
742 /* REVISIT for ACM, issue "network connected" event */ 797 if (gser->connect)
798 gser->connect(gser);
743 } 799 }
744 800
745 pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file); 801 pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file);
@@ -766,6 +822,7 @@ static int gs_writes_finished(struct gs_port *p)
766static void gs_close(struct tty_struct *tty, struct file *file) 822static void gs_close(struct tty_struct *tty, struct file *file)
767{ 823{
768 struct gs_port *port = tty->driver_data; 824 struct gs_port *port = tty->driver_data;
825 struct gserial *gser;
769 826
770 spin_lock_irq(&port->port_lock); 827 spin_lock_irq(&port->port_lock);
771 828
@@ -785,32 +842,31 @@ static void gs_close(struct tty_struct *tty, struct file *file)
785 port->openclose = true; 842 port->openclose = true;
786 port->open_count = 0; 843 port->open_count = 0;
787 844
788 if (port->port_usb) 845 gser = port->port_usb;
789 /* REVISIT for ACM, issue "network disconnected" event */; 846 if (gser && gser->disconnect)
847 gser->disconnect(gser);
790 848
791 /* wait for circular write buffer to drain, disconnect, or at 849 /* wait for circular write buffer to drain, disconnect, or at
792 * most GS_CLOSE_TIMEOUT seconds; then discard the rest 850 * most GS_CLOSE_TIMEOUT seconds; then discard the rest
793 */ 851 */
794 if (gs_buf_data_avail(&port->port_write_buf) > 0 852 if (gs_buf_data_avail(&port->port_write_buf) > 0 && gser) {
795 && port->port_usb) {
796 spin_unlock_irq(&port->port_lock); 853 spin_unlock_irq(&port->port_lock);
797 wait_event_interruptible_timeout(port->drain_wait, 854 wait_event_interruptible_timeout(port->drain_wait,
798 gs_writes_finished(port), 855 gs_writes_finished(port),
799 GS_CLOSE_TIMEOUT * HZ); 856 GS_CLOSE_TIMEOUT * HZ);
800 spin_lock_irq(&port->port_lock); 857 spin_lock_irq(&port->port_lock);
858 gser = port->port_usb;
801 } 859 }
802 860
803 /* Iff we're disconnected, there can be no I/O in flight so it's 861 /* Iff we're disconnected, there can be no I/O in flight so it's
804 * ok to free the circular buffer; else just scrub it. And don't 862 * ok to free the circular buffer; else just scrub it. And don't
805 * let the push tasklet fire again until we're re-opened. 863 * let the push tasklet fire again until we're re-opened.
806 */ 864 */
807 if (port->port_usb == NULL) 865 if (gser == NULL)
808 gs_buf_free(&port->port_write_buf); 866 gs_buf_free(&port->port_write_buf);
809 else 867 else
810 gs_buf_clear(&port->port_write_buf); 868 gs_buf_clear(&port->port_write_buf);
811 869
812 tasklet_kill(&port->push);
813
814 tty->driver_data = NULL; 870 tty->driver_data = NULL;
815 port->port_tty = NULL; 871 port->port_tty = NULL;
816 872
@@ -911,15 +967,35 @@ static void gs_unthrottle(struct tty_struct *tty)
911{ 967{
912 struct gs_port *port = tty->driver_data; 968 struct gs_port *port = tty->driver_data;
913 unsigned long flags; 969 unsigned long flags;
914 unsigned started = 0;
915 970
916 spin_lock_irqsave(&port->port_lock, flags); 971 spin_lock_irqsave(&port->port_lock, flags);
917 if (port->port_usb) 972 if (port->port_usb) {
918 started = gs_start_rx(port); 973 /* Kickstart read queue processing. We don't do xon/xoff,
974 * rts/cts, or other handshaking with the host, but if the
975 * read queue backs up enough we'll be NAKing OUT packets.
976 */
977 tasklet_schedule(&port->push);
978 pr_vdebug(PREFIX "%d: unthrottle\n", port->port_num);
979 }
919 spin_unlock_irqrestore(&port->port_lock, flags); 980 spin_unlock_irqrestore(&port->port_lock, flags);
981}
982
983static int gs_break_ctl(struct tty_struct *tty, int duration)
984{
985 struct gs_port *port = tty->driver_data;
986 int status = 0;
987 struct gserial *gser;
988
989 pr_vdebug("gs_break_ctl: ttyGS%d, send break (%d) \n",
990 port->port_num, duration);
920 991
921 pr_vdebug("gs_unthrottle: ttyGS%d, %d packets\n", 992 spin_lock_irq(&port->port_lock);
922 port->port_num, started); 993 gser = port->port_usb;
994 if (gser && gser->send_break)
995 status = gser->send_break(gser, duration);
996 spin_unlock_irq(&port->port_lock);
997
998 return status;
923} 999}
924 1000
925static const struct tty_operations gs_tty_ops = { 1001static const struct tty_operations gs_tty_ops = {
@@ -931,6 +1007,7 @@ static const struct tty_operations gs_tty_ops = {
931 .write_room = gs_write_room, 1007 .write_room = gs_write_room,
932 .chars_in_buffer = gs_chars_in_buffer, 1008 .chars_in_buffer = gs_chars_in_buffer,
933 .unthrottle = gs_unthrottle, 1009 .unthrottle = gs_unthrottle,
1010 .break_ctl = gs_break_ctl,
934}; 1011};
935 1012
936/*-------------------------------------------------------------------------*/ 1013/*-------------------------------------------------------------------------*/
@@ -953,6 +1030,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding)
953 tasklet_init(&port->push, gs_rx_push, (unsigned long) port); 1030 tasklet_init(&port->push, gs_rx_push, (unsigned long) port);
954 1031
955 INIT_LIST_HEAD(&port->read_pool); 1032 INIT_LIST_HEAD(&port->read_pool);
1033 INIT_LIST_HEAD(&port->read_queue);
956 INIT_LIST_HEAD(&port->write_pool); 1034 INIT_LIST_HEAD(&port->write_pool);
957 1035
958 port->port_num = port_num; 1036 port->port_num = port_num;
@@ -997,7 +1075,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count)
997 1075
998 gs_tty_driver->owner = THIS_MODULE; 1076 gs_tty_driver->owner = THIS_MODULE;
999 gs_tty_driver->driver_name = "g_serial"; 1077 gs_tty_driver->driver_name = "g_serial";
1000 gs_tty_driver->name = "ttyGS"; 1078 gs_tty_driver->name = PREFIX;
1001 /* uses dynamically assigned dev_t values */ 1079 /* uses dynamically assigned dev_t values */
1002 1080
1003 gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; 1081 gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
@@ -1104,6 +1182,8 @@ void gserial_cleanup(void)
1104 ports[i].port = NULL; 1182 ports[i].port = NULL;
1105 mutex_unlock(&ports[i].lock); 1183 mutex_unlock(&ports[i].lock);
1106 1184
1185 tasklet_kill(&port->push);
1186
1107 /* wait for old opens to finish */ 1187 /* wait for old opens to finish */
1108 wait_event(port->close_wait, gs_closed(port)); 1188 wait_event(port->close_wait, gs_closed(port));
1109 1189
@@ -1175,14 +1255,17 @@ int gserial_connect(struct gserial *gser, u8 port_num)
1175 1255
1176 /* REVISIT if waiting on "carrier detect", signal. */ 1256 /* REVISIT if waiting on "carrier detect", signal. */
1177 1257
1178 /* REVISIT for ACM, issue "network connection" status notification: 1258 /* if it's already open, start I/O ... and notify the serial
1179 * connected if open_count, else disconnected. 1259 * protocol about open/close status (connect/disconnect).
1180 */ 1260 */
1181
1182 /* if it's already open, start I/O */
1183 if (port->open_count) { 1261 if (port->open_count) {
1184 pr_debug("gserial_connect: start ttyGS%d\n", port->port_num); 1262 pr_debug("gserial_connect: start ttyGS%d\n", port->port_num);
1185 gs_start_io(port); 1263 gs_start_io(port);
1264 if (gser->connect)
1265 gser->connect(gser);
1266 } else {
1267 if (gser->disconnect)
1268 gser->disconnect(gser);
1186 } 1269 }
1187 1270
1188 spin_unlock_irqrestore(&port->port_lock, flags); 1271 spin_unlock_irqrestore(&port->port_lock, flags);
@@ -1241,6 +1324,7 @@ void gserial_disconnect(struct gserial *gser)
1241 if (port->open_count == 0 && !port->openclose) 1324 if (port->open_count == 0 && !port->openclose)
1242 gs_buf_free(&port->port_write_buf); 1325 gs_buf_free(&port->port_write_buf);
1243 gs_free_requests(gser->out, &port->read_pool); 1326 gs_free_requests(gser->out, &port->read_pool);
1327 gs_free_requests(gser->out, &port->read_queue);
1244 gs_free_requests(gser->in, &port->write_pool); 1328 gs_free_requests(gser->in, &port->write_pool);
1245 spin_unlock_irqrestore(&port->port_lock, flags); 1329 spin_unlock_irqrestore(&port->port_lock, flags);
1246} 1330}
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h
index 7b561138f90e..af3910d01aea 100644
--- a/drivers/usb/gadget/u_serial.h
+++ b/drivers/usb/gadget/u_serial.h
@@ -23,8 +23,7 @@
23 * style I/O using the USB peripheral endpoints listed here, including 23 * style I/O using the USB peripheral endpoints listed here, including
24 * hookups to sysfs and /dev for each logical "tty" device. 24 * hookups to sysfs and /dev for each logical "tty" device.
25 * 25 *
26 * REVISIT need TTY --> USB event flow too, so ACM can report open/close 26 * REVISIT at least ACM could support tiocmget() if needed.
27 * as carrier detect events. Model after ECM. There's more ACM state too.
28 * 27 *
29 * REVISIT someday, allow multiplexing several TTYs over these endpoints. 28 * REVISIT someday, allow multiplexing several TTYs over these endpoints.
30 */ 29 */
@@ -41,8 +40,17 @@ struct gserial {
41 40
42 /* REVISIT avoid this CDC-ACM support harder ... */ 41 /* REVISIT avoid this CDC-ACM support harder ... */
43 struct usb_cdc_line_coding port_line_coding; /* 9600-8-N-1 etc */ 42 struct usb_cdc_line_coding port_line_coding; /* 9600-8-N-1 etc */
43
44 /* notification callbacks */
45 void (*connect)(struct gserial *p);
46 void (*disconnect)(struct gserial *p);
47 int (*send_break)(struct gserial *p, int duration);
44}; 48};
45 49
50/* utilities to allocate/free request and buffer */
51struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags);
52void gs_free_req(struct usb_ep *, struct usb_request *req);
53
46/* port setup/teardown is handled by gadget driver */ 54/* port setup/teardown is handled by gadget driver */
47int gserial_setup(struct usb_gadget *g, unsigned n_ports); 55int gserial_setup(struct usb_gadget *g, unsigned n_ports);
48void gserial_cleanup(void); 56void gserial_cleanup(void);
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 5fbdc14e63b3..5416cf969005 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -12,7 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/mbus.h> 14#include <linux/mbus.h>
15#include <asm/plat-orion/ehci-orion.h> 15#include <plat/ehci-orion.h>
16 16
17#define rdl(off) __raw_readl(hcd->regs + (off)) 17#define rdl(off) __raw_readl(hcd->regs + (off))
18#define wrl(off, val) __raw_writel((val), hcd->regs + (off)) 18#define wrl(off, val) __raw_writel((val), hcd->regs + (off))
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 2622b6596d7c..3712b925b315 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -932,7 +932,7 @@ static struct ehci_qh *qh_append_tds (
932 932
933 list_del (&qtd->qtd_list); 933 list_del (&qtd->qtd_list);
934 list_add (&dummy->qtd_list, qtd_list); 934 list_add (&dummy->qtd_list, qtd_list);
935 __list_splice (qtd_list, qh->qtd_list.prev); 935 list_splice_tail(qtd_list, &qh->qtd_list);
936 936
937 ehci_qtd_init(ehci, qtd, qtd->qtd_dma); 937 ehci_qtd_init(ehci, qtd, qtd->qtd_dma);
938 qh->dummy = qtd; 938 qh->dummy = qtd;
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index c858f2adb929..d22a84f86a33 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -126,9 +126,8 @@ static void isp1760_writel(const unsigned int val, __u32 __iomem *regs)
126 * doesn't quite work because some people have to enforce 32-bit access 126 * doesn't quite work because some people have to enforce 32-bit access
127 */ 127 */
128static void priv_read_copy(struct isp1760_hcd *priv, u32 *src, 128static void priv_read_copy(struct isp1760_hcd *priv, u32 *src,
129 __u32 __iomem *dst, u32 offset, u32 len) 129 __u32 __iomem *dst, u32 len)
130{ 130{
131 struct usb_hcd *hcd = priv_to_hcd(priv);
132 u32 val; 131 u32 val;
133 u8 *buff8; 132 u8 *buff8;
134 133
@@ -136,11 +135,6 @@ static void priv_read_copy(struct isp1760_hcd *priv, u32 *src,
136 printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len); 135 printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len);
137 return; 136 return;
138 } 137 }
139 isp1760_writel(offset, hcd->regs + HC_MEMORY_REG);
140 /* XXX
141 * 90nsec delay, the spec says something how this could be avoided.
142 */
143 mdelay(1);
144 138
145 while (len >= 4) { 139 while (len >= 4) {
146 *src = __raw_readl(dst); 140 *src = __raw_readl(dst);
@@ -987,8 +981,20 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
987 printk(KERN_ERR "qh is 0\n"); 981 printk(KERN_ERR "qh is 0\n");
988 continue; 982 continue;
989 } 983 }
990 priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs, 984 isp1760_writel(atl_regs + ISP_BANK(0), usb_hcd->regs +
991 atl_regs, sizeof(ptd)); 985 HC_MEMORY_REG);
986 isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
987 HC_MEMORY_REG);
988 /*
989 * write bank1 address twice to ensure the 90ns delay (time
990 * between BANK0 write and the priv_read_copy() call is at
991 * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 92ns)
992 */
993 isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
994 HC_MEMORY_REG);
995
996 priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs +
997 ISP_BANK(0), sizeof(ptd));
992 998
993 dw1 = le32_to_cpu(ptd.dw1); 999 dw1 = le32_to_cpu(ptd.dw1);
994 dw2 = le32_to_cpu(ptd.dw2); 1000 dw2 = le32_to_cpu(ptd.dw2);
@@ -1091,7 +1097,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
1091 case IN_PID: 1097 case IN_PID:
1092 priv_read_copy(priv, 1098 priv_read_copy(priv,
1093 priv->atl_ints[queue_entry].data_buffer, 1099 priv->atl_ints[queue_entry].data_buffer,
1094 usb_hcd->regs + payload, payload, 1100 usb_hcd->regs + payload + ISP_BANK(1),
1095 length); 1101 length);
1096 1102
1097 case OUT_PID: 1103 case OUT_PID:
@@ -1122,11 +1128,11 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
1122 } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) { 1128 } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) {
1123 /* short BULK received */ 1129 /* short BULK received */
1124 1130
1125 printk(KERN_ERR "short bulk, %d instead %zu\n", length,
1126 qtd->length);
1127 if (urb->transfer_flags & URB_SHORT_NOT_OK) { 1131 if (urb->transfer_flags & URB_SHORT_NOT_OK) {
1128 urb->status = -EREMOTEIO; 1132 urb->status = -EREMOTEIO;
1129 printk(KERN_ERR "not okey\n"); 1133 isp1760_dbg(priv, "short bulk, %d instead %zu "
1134 "with URB_SHORT_NOT_OK flag.\n",
1135 length, qtd->length);
1130 } 1136 }
1131 1137
1132 if (urb->status == -EINPROGRESS) 1138 if (urb->status == -EINPROGRESS)
@@ -1206,8 +1212,20 @@ static void do_intl_int(struct usb_hcd *usb_hcd)
1206 continue; 1212 continue;
1207 } 1213 }
1208 1214
1209 priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs, 1215 isp1760_writel(int_regs + ISP_BANK(0), usb_hcd->regs +
1210 int_regs, sizeof(ptd)); 1216 HC_MEMORY_REG);
1217 isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
1218 HC_MEMORY_REG);
1219 /*
1220 * write bank1 address twice to ensure the 90ns delay (time
1221 * between BANK0 write and the priv_read_copy() call is at
1222 * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 92ns)
1223 */
1224 isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
1225 HC_MEMORY_REG);
1226
1227 priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs +
1228 ISP_BANK(0), sizeof(ptd));
1211 dw1 = le32_to_cpu(ptd.dw1); 1229 dw1 = le32_to_cpu(ptd.dw1);
1212 dw3 = le32_to_cpu(ptd.dw3); 1230 dw3 = le32_to_cpu(ptd.dw3);
1213 check_int_err_status(le32_to_cpu(ptd.dw4)); 1231 check_int_err_status(le32_to_cpu(ptd.dw4));
@@ -1242,7 +1260,7 @@ static void do_intl_int(struct usb_hcd *usb_hcd)
1242 case IN_PID: 1260 case IN_PID:
1243 priv_read_copy(priv, 1261 priv_read_copy(priv,
1244 priv->int_ints[queue_entry].data_buffer, 1262 priv->int_ints[queue_entry].data_buffer,
1245 usb_hcd->regs + payload , payload, 1263 usb_hcd->regs + payload + ISP_BANK(1),
1246 length); 1264 length);
1247 case OUT_PID: 1265 case OUT_PID:
1248 1266
@@ -1615,8 +1633,7 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
1615 return -EPIPE; 1633 return -EPIPE;
1616 } 1634 }
1617 1635
1618 isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe); 1636 return isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe);
1619 return 0;
1620} 1637}
1621 1638
1622static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, 1639static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h
index 6473dd86993c..4377277667d9 100644
--- a/drivers/usb/host/isp1760-hcd.h
+++ b/drivers/usb/host/isp1760-hcd.h
@@ -54,6 +54,8 @@ void deinit_kmem_cache(void);
54#define BUFFER_MAP 0x7 54#define BUFFER_MAP 0x7
55 55
56#define HC_MEMORY_REG 0x33c 56#define HC_MEMORY_REG 0x33c
57#define ISP_BANK(x) ((x) << 16)
58
57#define HC_PORT1_CTRL 0x374 59#define HC_PORT1_CTRL 0x374
58#define PORT1_POWER (3 << 3) 60#define PORT1_POWER (3 << 3)
59#define PORT1_INIT1 (1 << 7) 61#define PORT1_INIT1 (1 << 7)
@@ -119,6 +121,9 @@ struct inter_packet_info {
119typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh, 121typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
120 struct isp1760_qtd *qtd); 122 struct isp1760_qtd *qtd);
121 123
124#define isp1760_dbg(priv, fmt, args...) \
125 dev_dbg(priv_to_hcd(priv)->self.controller, fmt, ##args)
126
122#define isp1760_info(priv, fmt, args...) \ 127#define isp1760_info(priv, fmt, args...) \
123 dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args) 128 dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args)
124 129
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index a5d8e550d897..6db7a2889e66 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -15,12 +15,11 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17 17
18#include <asm/mach-types.h> 18#include <mach/hardware.h>
19#include <asm/hardware.h>
20#include <asm/gpio.h> 19#include <asm/gpio.h>
21 20
22#include <asm/arch/board.h> 21#include <mach/board.h>
23#include <asm/arch/cpu.h> 22#include <mach/cpu.h>
24 23
25#ifndef CONFIG_ARCH_AT91 24#ifndef CONFIG_ARCH_AT91
26#error "CONFIG_ARCH_AT91 must be defined." 25#error "CONFIG_ARCH_AT91 must be defined."
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index 5adaf36e47d0..cb0b506f8259 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -28,8 +28,7 @@
28#include <linux/signal.h> 28#include <linux/signal.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30 30
31#include <asm/mach-types.h> 31#include <mach/hardware.h>
32#include <asm/hardware.h>
33 32
34static struct clk *usb_host_clock; 33static struct clk *usb_host_clock;
35 34
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 26bc47941d01..89901962cbfd 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -86,6 +86,21 @@ static void ohci_stop (struct usb_hcd *hcd);
86static int ohci_restart (struct ohci_hcd *ohci); 86static int ohci_restart (struct ohci_hcd *ohci);
87#endif 87#endif
88 88
89#ifdef CONFIG_PCI
90static void quirk_amd_pll(int state);
91static void amd_iso_dev_put(void);
92#else
93static inline void quirk_amd_pll(int state)
94{
95 return;
96}
97static inline void amd_iso_dev_put(void)
98{
99 return;
100}
101#endif
102
103
89#include "ohci-hub.c" 104#include "ohci-hub.c"
90#include "ohci-dbg.c" 105#include "ohci-dbg.c"
91#include "ohci-mem.c" 106#include "ohci-mem.c"
@@ -483,6 +498,9 @@ static int ohci_init (struct ohci_hcd *ohci)
483 int ret; 498 int ret;
484 struct usb_hcd *hcd = ohci_to_hcd(ohci); 499 struct usb_hcd *hcd = ohci_to_hcd(ohci);
485 500
501 if (distrust_firmware)
502 ohci->flags |= OHCI_QUIRK_HUB_POWER;
503
486 disable (ohci); 504 disable (ohci);
487 ohci->regs = hcd->regs; 505 ohci->regs = hcd->regs;
488 506
@@ -689,7 +707,8 @@ retry:
689 temp |= RH_A_NOCP; 707 temp |= RH_A_NOCP;
690 temp &= ~(RH_A_POTPGT | RH_A_NPS); 708 temp &= ~(RH_A_POTPGT | RH_A_NPS);
691 ohci_writel (ohci, temp, &ohci->regs->roothub.a); 709 ohci_writel (ohci, temp, &ohci->regs->roothub.a);
692 } else if ((ohci->flags & OHCI_QUIRK_AMD756) || distrust_firmware) { 710 } else if ((ohci->flags & OHCI_QUIRK_AMD756) ||
711 (ohci->flags & OHCI_QUIRK_HUB_POWER)) {
693 /* hub power always on; required for AMD-756 and some 712 /* hub power always on; required for AMD-756 and some
694 * Mac platforms. ganged overcurrent reporting, if any. 713 * Mac platforms. ganged overcurrent reporting, if any.
695 */ 714 */
@@ -882,6 +901,8 @@ static void ohci_stop (struct usb_hcd *hcd)
882 901
883 if (quirk_zfmicro(ohci)) 902 if (quirk_zfmicro(ohci))
884 del_timer(&ohci->unlink_watchdog); 903 del_timer(&ohci->unlink_watchdog);
904 if (quirk_amdiso(ohci))
905 amd_iso_dev_put();
885 906
886 remove_debug_files (ohci); 907 remove_debug_files (ohci);
887 ohci_mem_cleanup (ohci); 908 ohci_mem_cleanup (ohci);
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index b56739221d11..439beb784f3e 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -483,6 +483,13 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
483 length++; 483 length++;
484 } 484 }
485 485
486 /* Some broken controllers never turn off RHCS in the interrupt
487 * status register. For their sake we won't re-enable RHSC
488 * interrupts if the flag is already set.
489 */
490 if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC)
491 changed = 1;
492
486 /* look at each port */ 493 /* look at each port */
487 for (i = 0; i < ohci->num_ports; i++) { 494 for (i = 0; i < ohci->num_ports; i++) {
488 u32 status = roothub_portstatus (ohci, i); 495 u32 status = roothub_portstatus (ohci, i);
@@ -572,8 +579,6 @@ static int ohci_start_port_reset (struct usb_hcd *hcd, unsigned port)
572 return 0; 579 return 0;
573} 580}
574 581
575static void start_hnp(struct ohci_hcd *ohci);
576
577#else 582#else
578 583
579#define ohci_start_port_reset NULL 584#define ohci_start_port_reset NULL
@@ -760,7 +765,7 @@ static int ohci_hub_control (
760#ifdef CONFIG_USB_OTG 765#ifdef CONFIG_USB_OTG
761 if (hcd->self.otg_port == (wIndex + 1) 766 if (hcd->self.otg_port == (wIndex + 1)
762 && hcd->self.b_hnp_enable) 767 && hcd->self.b_hnp_enable)
763 start_hnp(ohci); 768 ohci->start_hnp(ohci);
764 else 769 else
765#endif 770#endif
766 ohci_writel (ohci, RH_PS_PSS, 771 ohci_writel (ohci, RH_PS_PSS,
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 1ef5d482c145..9e31d440d115 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -19,7 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/signal.h> 20#include <linux/signal.h>
21 21
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23 23
24 24
25extern int usb_disabled(void); 25extern int usb_disabled(void);
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 6e5e5f81ac90..3d532b709670 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -19,15 +19,15 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/clk.h> 20#include <linux/clk.h>
21 21
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25 25
26#include <asm/arch/mux.h> 26#include <mach/mux.h>
27#include <asm/arch/irqs.h> 27#include <mach/irqs.h>
28#include <asm/arch/gpio.h> 28#include <mach/gpio.h>
29#include <asm/arch/fpga.h> 29#include <mach/fpga.h>
30#include <asm/arch/usb.h> 30#include <mach/usb.h>
31 31
32 32
33/* OMAP-1510 OHCI has its own MMU for DMA */ 33/* OMAP-1510 OHCI has its own MMU for DMA */
@@ -225,6 +225,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)
225 dev_err(hcd->self.controller, "can't find transceiver\n"); 225 dev_err(hcd->self.controller, "can't find transceiver\n");
226 return -ENODEV; 226 return -ENODEV;
227 } 227 }
228 ohci->start_hnp = start_hnp;
228 } 229 }
229#endif 230#endif
230 231
@@ -260,7 +261,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)
260 omap_cfg_reg(W4_USB_HIGHZ); 261 omap_cfg_reg(W4_USB_HIGHZ);
261 } 262 }
262 ohci_writel(ohci, rh, &ohci->regs->roothub.a); 263 ohci_writel(ohci, rh, &ohci->regs->roothub.a);
263 distrust_firmware = 0; 264 ohci->flags &= ~OHCI_QUIRK_HUB_POWER;
264 } else if (machine_is_nokia770()) { 265 } else if (machine_is_nokia770()) {
265 /* We require a self-powered hub, which should have 266 /* We require a self-powered hub, which should have
266 * plenty of power. */ 267 * plenty of power. */
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 4696cc912e16..083e8df0a817 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -18,6 +18,28 @@
18#error "This file is PCI bus glue. CONFIG_PCI must be defined." 18#error "This file is PCI bus glue. CONFIG_PCI must be defined."
19#endif 19#endif
20 20
21#include <linux/pci.h>
22#include <linux/io.h>
23
24
25/* constants used to work around PM-related transfer
26 * glitches in some AMD 700 series southbridges
27 */
28#define AB_REG_BAR 0xf0
29#define AB_INDX(addr) ((addr) + 0x00)
30#define AB_DATA(addr) ((addr) + 0x04)
31#define AX_INDXC 0X30
32#define AX_DATAC 0x34
33
34#define NB_PCIE_INDX_ADDR 0xe0
35#define NB_PCIE_INDX_DATA 0xe4
36#define PCIE_P_CNTL 0x10040
37#define BIF_NB 0x10002
38
39static struct pci_dev *amd_smbus_dev;
40static struct pci_dev *amd_hb_dev;
41static int amd_ohci_iso_count;
42
21/*-------------------------------------------------------------------------*/ 43/*-------------------------------------------------------------------------*/
22 44
23static int broken_suspend(struct usb_hcd *hcd) 45static int broken_suspend(struct usb_hcd *hcd)
@@ -143,6 +165,103 @@ static int ohci_quirk_nec(struct usb_hcd *hcd)
143 return 0; 165 return 0;
144} 166}
145 167
168static int ohci_quirk_amd700(struct usb_hcd *hcd)
169{
170 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
171 u8 rev = 0;
172
173 if (!amd_smbus_dev)
174 amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI,
175 PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL);
176 if (!amd_smbus_dev)
177 return 0;
178
179 pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
180 if ((rev > 0x3b) || (rev < 0x30)) {
181 pci_dev_put(amd_smbus_dev);
182 amd_smbus_dev = NULL;
183 return 0;
184 }
185
186 amd_ohci_iso_count++;
187
188 if (!amd_hb_dev)
189 amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL);
190
191 ohci->flags |= OHCI_QUIRK_AMD_ISO;
192 ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n");
193
194 return 0;
195}
196
197/*
198 * The hardware normally enables the A-link power management feature, which
199 * lets the system lower the power consumption in idle states.
200 *
201 * Assume the system is configured to have USB 1.1 ISO transfers going
202 * to or from a USB device. Without this quirk, that stream may stutter
203 * or have breaks occasionally. For transfers going to speakers, this
204 * makes a very audible mess...
205 *
206 * That audio playback corruption is due to the audio stream getting
207 * interrupted occasionally when the link goes in lower power state
208 * This USB quirk prevents the link going into that lower power state
209 * during audio playback or other ISO operations.
210 */
211static void quirk_amd_pll(int on)
212{
213 u32 addr;
214 u32 val;
215 u32 bit = (on > 0) ? 1 : 0;
216
217 pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr);
218
219 /* BIT names/meanings are NDA-protected, sorry ... */
220
221 outl(AX_INDXC, AB_INDX(addr));
222 outl(0x40, AB_DATA(addr));
223 outl(AX_DATAC, AB_INDX(addr));
224 val = inl(AB_DATA(addr));
225 val &= ~((1 << 3) | (1 << 4) | (1 << 9));
226 val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9);
227 outl(val, AB_DATA(addr));
228
229 if (amd_hb_dev) {
230 addr = PCIE_P_CNTL;
231 pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr);
232
233 pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val);
234 val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12));
235 val |= bit | (bit << 3) | (bit << 12);
236 val |= ((!bit) << 4) | ((!bit) << 9);
237 pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val);
238
239 addr = BIF_NB;
240 pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr);
241
242 pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val);
243 val &= ~(1 << 8);
244 val |= bit << 8;
245 pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val);
246 }
247}
248
249static void amd_iso_dev_put(void)
250{
251 amd_ohci_iso_count--;
252 if (amd_ohci_iso_count == 0) {
253 if (amd_smbus_dev) {
254 pci_dev_put(amd_smbus_dev);
255 amd_smbus_dev = NULL;
256 }
257 if (amd_hb_dev) {
258 pci_dev_put(amd_hb_dev);
259 amd_hb_dev = NULL;
260 }
261 }
262
263}
264
146/* List of quirks for OHCI */ 265/* List of quirks for OHCI */
147static const struct pci_device_id ohci_pci_quirks[] = { 266static const struct pci_device_id ohci_pci_quirks[] = {
148 { 267 {
@@ -181,6 +300,19 @@ static const struct pci_device_id ohci_pci_quirks[] = {
181 PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152), 300 PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152),
182 .driver_data = (unsigned long) broken_suspend, 301 .driver_data = (unsigned long) broken_suspend,
183 }, 302 },
303 {
304 PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4397),
305 .driver_data = (unsigned long)ohci_quirk_amd700,
306 },
307 {
308 PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4398),
309 .driver_data = (unsigned long)ohci_quirk_amd700,
310 },
311 {
312 PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
313 .driver_data = (unsigned long)ohci_quirk_amd700,
314 },
315
184 /* FIXME for some of the early AMD 760 southbridges, OHCI 316 /* FIXME for some of the early AMD 760 southbridges, OHCI
185 * won't work at all. blacklist them. 317 * won't work at all. blacklist them.
186 */ 318 */
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
index 6ad8f2fc57b9..b02cd0761977 100644
--- a/drivers/usb/host/ohci-pnx4008.c
+++ b/drivers/usb/host/ohci-pnx4008.c
@@ -21,13 +21,12 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/i2c.h> 22#include <linux/i2c.h>
23 23
24#include <asm/hardware.h> 24#include <mach/hardware.h>
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/mach-types.h>
27 26
28#include <asm/arch/platform.h> 27#include <mach/platform.h>
29#include <asm/arch/irqs.h> 28#include <mach/irqs.h>
30#include <asm/arch/gpio.h> 29#include <mach/gpio.h>
31 30
32#define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) 31#define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
33 32
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 127b15799024..8c9c4849db6e 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -24,11 +24,10 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/clk.h> 25#include <linux/clk.h>
26 26
27#include <asm/mach-types.h> 27#include <mach/hardware.h>
28#include <asm/hardware.h> 28#include <mach/pxa-regs.h>
29#include <asm/arch/pxa-regs.h> 29#include <mach/pxa2xx-regs.h> /* FIXME: for PSSR */
30#include <asm/arch/pxa2xx-regs.h> /* FIXME: for PSSR */ 30#include <mach/ohci.h>
31#include <asm/arch/ohci.h>
32 31
33#define PXA_UHC_MAX_PORTNUM 3 32#define PXA_UHC_MAX_PORTNUM 3
34 33
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 6a9b4c557953..c2d80f80448b 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -49,6 +49,9 @@ __acquires(ohci->lock)
49 switch (usb_pipetype (urb->pipe)) { 49 switch (usb_pipetype (urb->pipe)) {
50 case PIPE_ISOCHRONOUS: 50 case PIPE_ISOCHRONOUS:
51 ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; 51 ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
52 if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
53 && quirk_amdiso(ohci))
54 quirk_amd_pll(1);
52 break; 55 break;
53 case PIPE_INTERRUPT: 56 case PIPE_INTERRUPT:
54 ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; 57 ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
@@ -677,6 +680,9 @@ static void td_submit_urb (
677 data + urb->iso_frame_desc [cnt].offset, 680 data + urb->iso_frame_desc [cnt].offset,
678 urb->iso_frame_desc [cnt].length, urb, cnt); 681 urb->iso_frame_desc [cnt].length, urb, cnt);
679 } 682 }
683 if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
684 && quirk_amdiso(ohci))
685 quirk_amd_pll(0);
680 periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 686 periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
681 && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; 687 && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
682 break; 688 break;
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 3c7a740cfe0c..9e3dc4069e8b 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -22,8 +22,8 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24 24
25#include <asm/hardware.h> 25#include <mach/hardware.h>
26#include <asm/arch/usb-control.h> 26#include <mach/usb-control.h>
27 27
28#define valid_port(idx) ((idx) == 1 || (idx) == 2) 28#define valid_port(idx) ((idx) == 1 || (idx) == 2)
29 29
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index 2e9dceb9bb99..4626b002e670 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -13,10 +13,10 @@
13 * This file is licenced under the GPL. 13 * This file is licenced under the GPL.
14 */ 14 */
15 15
16#include <asm/hardware.h> 16#include <mach/hardware.h>
17#include <asm/mach-types.h> 17#include <asm/mach-types.h>
18#include <asm/arch/assabet.h> 18#include <mach/assabet.h>
19#include <asm/arch/badge4.h> 19#include <mach/badge4.h>
20#include <asm/hardware/sa1111.h> 20#include <asm/hardware/sa1111.h>
21 21
22#ifndef CONFIG_SA1111 22#ifndef CONFIG_SA1111
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index dc544ddc7849..faf622eafce7 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -371,6 +371,7 @@ struct ohci_hcd {
371 * other external transceivers should be software-transparent 371 * other external transceivers should be software-transparent
372 */ 372 */
373 struct otg_transceiver *transceiver; 373 struct otg_transceiver *transceiver;
374 void (*start_hnp)(struct ohci_hcd *ohci);
374 375
375 /* 376 /*
376 * memory management for queue data structures 377 * memory management for queue data structures
@@ -399,6 +400,8 @@ struct ohci_hcd {
399#define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ 400#define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/
400#define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ 401#define OHCI_QUIRK_NEC 0x40 /* lost interrupts */
401#define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ 402#define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */
403#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
404#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/
402 // there are also chip quirks/bugs in init logic 405 // there are also chip quirks/bugs in init logic
403 406
404 struct work_struct nec_work; /* Worker for NEC quirk */ 407 struct work_struct nec_work; /* Worker for NEC quirk */
@@ -426,6 +429,10 @@ static inline int quirk_zfmicro(struct ohci_hcd *ohci)
426{ 429{
427 return ohci->flags & OHCI_QUIRK_ZFMICRO; 430 return ohci->flags & OHCI_QUIRK_ZFMICRO;
428} 431}
432static inline int quirk_amdiso(struct ohci_hcd *ohci)
433{
434 return ohci->flags & OHCI_QUIRK_AMD_ISO;
435}
429#else 436#else
430static inline int quirk_nec(struct ohci_hcd *ohci) 437static inline int quirk_nec(struct ohci_hcd *ohci)
431{ 438{
@@ -435,6 +442,10 @@ static inline int quirk_zfmicro(struct ohci_hcd *ohci)
435{ 442{
436 return 0; 443 return 0;
437} 444}
445static inline int quirk_amdiso(struct ohci_hcd *ohci)
446{
447 return 0;
448}
438#endif 449#endif
439 450
440/* convert between an hcd pointer and the corresponding ohci_hcd */ 451/* convert between an hcd pointer and the corresponding ohci_hcd */
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index d5f02dddb120..ea7126f99cab 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -964,11 +964,34 @@ static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
964 disable_irq_nrdy(r8a66597, pipenum); 964 disable_irq_nrdy(r8a66597, pipenum);
965} 965}
966 966
967static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597)
968{
969 mod_timer(&r8a66597->rh_timer,
970 jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME));
971}
972
973static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port,
974 int connect)
975{
976 struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
977
978 rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
979 rh->scount = R8A66597_MAX_SAMPLING;
980 if (connect)
981 rh->port |= 1 << USB_PORT_FEAT_CONNECTION;
982 else
983 rh->port &= ~(1 << USB_PORT_FEAT_CONNECTION);
984 rh->port |= 1 << USB_PORT_FEAT_C_CONNECTION;
985
986 r8a66597_root_hub_start_polling(r8a66597);
987}
988
967/* this function must be called with interrupt disabled */ 989/* this function must be called with interrupt disabled */
968static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, 990static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port,
969 u16 syssts) 991 u16 syssts)
970{ 992{
971 if (syssts == SE0) { 993 if (syssts == SE0) {
994 r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port));
972 r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); 995 r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port));
973 return; 996 return;
974 } 997 }
@@ -1002,13 +1025,10 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port)
1002{ 1025{
1003 struct r8a66597_device *dev = r8a66597->root_hub[port].dev; 1026 struct r8a66597_device *dev = r8a66597->root_hub[port].dev;
1004 1027
1005 r8a66597->root_hub[port].port &= ~(1 << USB_PORT_FEAT_CONNECTION);
1006 r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_C_CONNECTION);
1007
1008 disable_r8a66597_pipe_all(r8a66597, dev); 1028 disable_r8a66597_pipe_all(r8a66597, dev);
1009 free_usb_address(r8a66597, dev); 1029 free_usb_address(r8a66597, dev);
1010 1030
1011 r8a66597_bset(r8a66597, ATTCHE, get_intenb_reg(port)); 1031 start_root_hub_sampling(r8a66597, port, 0);
1012} 1032}
1013 1033
1014/* this function must be called with interrupt disabled */ 1034/* this function must be called with interrupt disabled */
@@ -1551,23 +1571,6 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597)
1551 } 1571 }
1552} 1572}
1553 1573
1554static void r8a66597_root_hub_start_polling(struct r8a66597 *r8a66597)
1555{
1556 mod_timer(&r8a66597->rh_timer,
1557 jiffies + msecs_to_jiffies(R8A66597_RH_POLL_TIME));
1558}
1559
1560static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port)
1561{
1562 struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
1563
1564 rh->old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port)) & LNST;
1565 rh->scount = R8A66597_MAX_SAMPLING;
1566 r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION)
1567 | (1 << USB_PORT_FEAT_C_CONNECTION);
1568 r8a66597_root_hub_start_polling(r8a66597);
1569}
1570
1571static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) 1574static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
1572{ 1575{
1573 struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); 1576 struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd);
@@ -1594,7 +1597,7 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
1594 r8a66597_bclr(r8a66597, ATTCHE, INTENB2); 1597 r8a66597_bclr(r8a66597, ATTCHE, INTENB2);
1595 1598
1596 /* start usb bus sampling */ 1599 /* start usb bus sampling */
1597 start_root_hub_sampling(r8a66597, 1); 1600 start_root_hub_sampling(r8a66597, 1, 1);
1598 } 1601 }
1599 if (mask2 & DTCH) { 1602 if (mask2 & DTCH) {
1600 r8a66597_write(r8a66597, ~DTCH, INTSTS2); 1603 r8a66597_write(r8a66597, ~DTCH, INTSTS2);
@@ -1609,7 +1612,7 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd)
1609 r8a66597_bclr(r8a66597, ATTCHE, INTENB1); 1612 r8a66597_bclr(r8a66597, ATTCHE, INTENB1);
1610 1613
1611 /* start usb bus sampling */ 1614 /* start usb bus sampling */
1612 start_root_hub_sampling(r8a66597, 0); 1615 start_root_hub_sampling(r8a66597, 0, 1);
1613 } 1616 }
1614 if (mask1 & DTCH) { 1617 if (mask1 & DTCH) {
1615 r8a66597_write(r8a66597, ~DTCH, INTSTS1); 1618 r8a66597_write(r8a66597, ~DTCH, INTSTS1);
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 001789c9a11a..4ea50e0abcbb 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -42,16 +42,6 @@ config USB_ADUTUX
42 To compile this driver as a module, choose M here. The module 42 To compile this driver as a module, choose M here. The module
43 will be called adutux. 43 will be called adutux.
44 44
45config USB_AUERSWALD
46 tristate "USB Auerswald ISDN support"
47 depends on USB
48 help
49 Say Y here if you want to connect an Auerswald USB ISDN Device
50 to your computer's USB port.
51
52 To compile this driver as a module, choose M here: the
53 module will be called auerswald.
54
55config USB_RIO500 45config USB_RIO500
56 tristate "USB Diamond Rio500 support" 46 tristate "USB Diamond Rio500 support"
57 depends on USB 47 depends on USB
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index aba091cb5ec0..45b4e12afb08 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -5,7 +5,6 @@
5 5
6obj-$(CONFIG_USB_ADUTUX) += adutux.o 6obj-$(CONFIG_USB_ADUTUX) += adutux.o
7obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o 7obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
8obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
9obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o 8obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o
10obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o 9obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
11obj-$(CONFIG_USB_CYTHERM) += cytherm.o 10obj-$(CONFIG_USB_CYTHERM) += cytherm.o
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
deleted file mode 100644
index d2f61d5510e7..000000000000
--- a/drivers/usb/misc/auerswald.c
+++ /dev/null
@@ -1,2152 +0,0 @@
1/*****************************************************************************/
2/*
3 * auerswald.c -- Auerswald PBX/System Telephone usb driver.
4 *
5 * Copyright (C) 2001 Wolfgang Mües (wolfgang@iksw-muees.de)
6 *
7 * Very much code of this driver is borrowed from dabusb.c (Deti Fliegl)
8 * and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24 /*****************************************************************************/
25
26/* Standard Linux module include files */
27#include <asm/uaccess.h>
28#include <asm/byteorder.h>
29#include <linux/slab.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/wait.h>
33#include <linux/usb.h>
34#include <linux/mutex.h>
35
36/*-------------------------------------------------------------------*/
37/* Debug support */
38#ifdef DEBUG
39#define dump( adr, len) \
40do { \
41 unsigned int u; \
42 printk (KERN_DEBUG); \
43 for (u = 0; u < len; u++) \
44 printk (" %02X", adr[u] & 0xFF); \
45 printk ("\n"); \
46} while (0)
47#else
48#define dump( adr, len)
49#endif
50
51/*-------------------------------------------------------------------*/
52/* Version Information */
53#define DRIVER_VERSION "0.9.11"
54#define DRIVER_AUTHOR "Wolfgang Mües <wolfgang@iksw-muees.de>"
55#define DRIVER_DESC "Auerswald PBX/System Telephone usb driver"
56
57/*-------------------------------------------------------------------*/
58/* Private declarations for Auerswald USB driver */
59
60/* Auerswald Vendor ID */
61#define ID_AUERSWALD 0x09BF
62
63#define AUER_MINOR_BASE 112 /* auerswald driver minor number */
64
65/* we can have up to this number of device plugged in at once */
66#define AUER_MAX_DEVICES 16
67
68
69/* Number of read buffers for each device */
70#define AU_RBUFFERS 10
71
72/* Number of chain elements for each control chain */
73#define AUCH_ELEMENTS 20
74
75/* Number of retries in communication */
76#define AU_RETRIES 10
77
78/*-------------------------------------------------------------------*/
79/* vendor specific protocol */
80/* Header Byte */
81#define AUH_INDIRMASK 0x80 /* mask for direct/indirect bit */
82#define AUH_DIRECT 0x00 /* data is for USB device */
83#define AUH_INDIRECT 0x80 /* USB device is relay */
84
85#define AUH_SPLITMASK 0x40 /* mask for split bit */
86#define AUH_UNSPLIT 0x00 /* data block is full-size */
87#define AUH_SPLIT 0x40 /* data block is part of a larger one,
88 split-byte follows */
89
90#define AUH_TYPEMASK 0x3F /* mask for type of data transfer */
91#define AUH_TYPESIZE 0x40 /* different types */
92#define AUH_DCHANNEL 0x00 /* D channel data */
93#define AUH_B1CHANNEL 0x01 /* B1 channel transparent */
94#define AUH_B2CHANNEL 0x02 /* B2 channel transparent */
95/* 0x03..0x0F reserved for driver internal use */
96#define AUH_COMMAND 0x10 /* Command channel */
97#define AUH_BPROT 0x11 /* Configuration block protocol */
98#define AUH_DPROTANA 0x12 /* D channel protocol analyzer */
99#define AUH_TAPI 0x13 /* telephone api data (ATD) */
100/* 0x14..0x3F reserved for other protocols */
101#define AUH_UNASSIGNED 0xFF /* if char device has no assigned service */
102#define AUH_FIRSTUSERCH 0x11 /* first channel which is available for driver users */
103
104#define AUH_SIZE 1 /* Size of Header Byte */
105
106/* Split Byte. Only present if split bit in header byte set.*/
107#define AUS_STARTMASK 0x80 /* mask for first block of splitted frame */
108#define AUS_FIRST 0x80 /* first block */
109#define AUS_FOLLOW 0x00 /* following block */
110
111#define AUS_ENDMASK 0x40 /* mask for last block of splitted frame */
112#define AUS_END 0x40 /* last block */
113#define AUS_NOEND 0x00 /* not the last block */
114
115#define AUS_LENMASK 0x3F /* mask for block length information */
116
117/* Request types */
118#define AUT_RREQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Read Request */
119#define AUT_WREQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER) /* Write Request */
120
121/* Vendor Requests */
122#define AUV_GETINFO 0x00 /* GetDeviceInfo */
123#define AUV_WBLOCK 0x01 /* Write Block */
124#define AUV_RBLOCK 0x02 /* Read Block */
125#define AUV_CHANNELCTL 0x03 /* Channel Control */
126#define AUV_DUMMY 0x04 /* Dummy Out for retry */
127
128/* Device Info Types */
129#define AUDI_NUMBCH 0x0000 /* Number of supported B channels */
130#define AUDI_OUTFSIZE 0x0001 /* Size of OUT B channel fifos */
131#define AUDI_MBCTRANS 0x0002 /* max. Blocklength of control transfer */
132
133/* Interrupt endpoint definitions */
134#define AU_IRQENDP 1 /* Endpoint number */
135#define AU_IRQCMDID 16 /* Command-block ID */
136#define AU_BLOCKRDY 0 /* Command: Block data ready on ctl endpoint */
137#define AU_IRQMINSIZE 5 /* Nr. of bytes decoded in this driver */
138
139/* Device String Descriptors */
140#define AUSI_VENDOR 1 /* "Auerswald GmbH & Co. KG" */
141#define AUSI_DEVICE 2 /* Name of the Device */
142#define AUSI_SERIALNR 3 /* Serial Number */
143#define AUSI_MSN 4 /* "MSN ..." (first) Multiple Subscriber Number */
144
145#define AUSI_DLEN 100 /* Max. Length of Device Description */
146
147#define AUV_RETRY 0x101 /* First Firmware version which can do control retries */
148
149/*-------------------------------------------------------------------*/
150/* External data structures / Interface */
151typedef struct
152{
153 char __user *buf; /* return buffer for string contents */
154 unsigned int bsize; /* size of return buffer */
155} audevinfo_t,*paudevinfo_t;
156
157/* IO controls */
158#define IOCTL_AU_SLEN _IOR( 'U', 0xF0, int) /* return the max. string descriptor length */
159#define IOCTL_AU_DEVINFO _IOWR('U', 0xF1, audevinfo_t) /* get name of a specific device */
160#define IOCTL_AU_SERVREQ _IOW( 'U', 0xF2, int) /* request a service channel */
161#define IOCTL_AU_BUFLEN _IOR( 'U', 0xF3, int) /* return the max. buffer length for the device */
162#define IOCTL_AU_RXAVAIL _IOR( 'U', 0xF4, int) /* return != 0 if Receive Data available */
163#define IOCTL_AU_CONNECT _IOR( 'U', 0xF5, int) /* return != 0 if connected to a service channel */
164#define IOCTL_AU_TXREADY _IOR( 'U', 0xF6, int) /* return != 0 if Transmitt channel ready to send */
165/* 'U' 0xF7..0xFF reseved */
166
167/*-------------------------------------------------------------------*/
168/* Internal data structures */
169
170/* ..................................................................*/
171/* urb chain element */
172struct auerchain; /* forward for circular reference */
173typedef struct
174{
175 struct auerchain *chain; /* pointer to the chain to which this element belongs */
176 struct urb * urbp; /* pointer to attached urb */
177 void *context; /* saved URB context */
178 usb_complete_t complete; /* saved URB completion function */
179 struct list_head list; /* to include element into a list */
180} auerchainelement_t,*pauerchainelement_t;
181
182/* urb chain */
183typedef struct auerchain
184{
185 pauerchainelement_t active; /* element which is submitted to urb */
186 spinlock_t lock; /* protection agains interrupts */
187 struct list_head waiting_list; /* list of waiting elements */
188 struct list_head free_list; /* list of available elements */
189} auerchain_t,*pauerchain_t;
190
191/* urb blocking completion helper struct */
192typedef struct
193{
194 wait_queue_head_t wqh; /* wait for completion */
195 unsigned int done; /* completion flag */
196} auerchain_chs_t,*pauerchain_chs_t;
197
198/* ...................................................................*/
199/* buffer element */
200struct auerbufctl; /* forward */
201typedef struct
202{
203 char *bufp; /* reference to allocated data buffer */
204 unsigned int len; /* number of characters in data buffer */
205 unsigned int retries; /* for urb retries */
206 struct usb_ctrlrequest *dr; /* for setup data in control messages */
207 struct urb * urbp; /* USB urb */
208 struct auerbufctl *list; /* pointer to list */
209 struct list_head buff_list; /* reference to next buffer in list */
210} auerbuf_t,*pauerbuf_t;
211
212/* buffer list control block */
213typedef struct auerbufctl
214{
215 spinlock_t lock; /* protection in interrupt */
216 struct list_head free_buff_list;/* free buffers */
217 struct list_head rec_buff_list; /* buffers with receive data */
218} auerbufctl_t,*pauerbufctl_t;
219
220/* ...................................................................*/
221/* service context */
222struct auerscon; /* forward */
223typedef void (*auer_dispatch_t)(struct auerscon*, pauerbuf_t);
224typedef void (*auer_disconn_t) (struct auerscon*);
225typedef struct auerscon
226{
227 unsigned int id; /* protocol service id AUH_xxxx */
228 auer_dispatch_t dispatch; /* dispatch read buffer */
229 auer_disconn_t disconnect; /* disconnect from device, wake up all char readers */
230} auerscon_t,*pauerscon_t;
231
232/* ...................................................................*/
233/* USB device context */
234typedef struct
235{
236 struct mutex mutex; /* protection in user context */
237 char name[20]; /* name of the /dev/usb entry */
238 unsigned int dtindex; /* index in the device table */
239 struct usb_device * usbdev; /* USB device handle */
240 int open_count; /* count the number of open character channels */
241 char dev_desc[AUSI_DLEN];/* for storing a textual description */
242 unsigned int maxControlLength; /* max. Length of control paket (without header) */
243 struct urb * inturbp; /* interrupt urb */
244 char * intbufp; /* data buffer for interrupt urb */
245 unsigned int irqsize; /* size of interrupt endpoint 1 */
246 struct auerchain controlchain; /* for chaining of control messages */
247 auerbufctl_t bufctl; /* Buffer control for control transfers */
248 pauerscon_t services[AUH_TYPESIZE];/* context pointers for each service */
249 unsigned int version; /* Version of the device */
250 wait_queue_head_t bufferwait; /* wait for a control buffer */
251} auerswald_t,*pauerswald_t;
252
253/* ................................................................... */
254/* character device context */
255typedef struct
256{
257 struct mutex mutex; /* protection in user context */
258 pauerswald_t auerdev; /* context pointer of assigned device */
259 auerbufctl_t bufctl; /* controls the buffer chain */
260 auerscon_t scontext; /* service context */
261 wait_queue_head_t readwait; /* for synchronous reading */
262 struct mutex readmutex; /* protection against multiple reads */
263 pauerbuf_t readbuf; /* buffer held for partial reading */
264 unsigned int readoffset; /* current offset in readbuf */
265 unsigned int removed; /* is != 0 if device is removed */
266} auerchar_t,*pauerchar_t;
267
268
269/*-------------------------------------------------------------------*/
270/* Forwards */
271static void auerswald_ctrlread_complete (struct urb * urb);
272static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp);
273static struct usb_driver auerswald_driver;
274
275
276/*-------------------------------------------------------------------*/
277/* USB chain helper functions */
278/* -------------------------- */
279
280/* completion function for chained urbs */
281static void auerchain_complete (struct urb * urb)
282{
283 unsigned long flags;
284 int result;
285
286 /* get pointer to element and to chain */
287 pauerchainelement_t acep = urb->context;
288 pauerchain_t acp = acep->chain;
289
290 /* restore original entries in urb */
291 urb->context = acep->context;
292 urb->complete = acep->complete;
293
294 dbg ("auerchain_complete called");
295
296 /* call original completion function
297 NOTE: this function may lead to more urbs submitted into the chain.
298 (no chain lock at calling complete()!)
299 acp->active != NULL is protecting us against recursion.*/
300 urb->complete (urb);
301
302 /* detach element from chain data structure */
303 spin_lock_irqsave (&acp->lock, flags);
304 if (acp->active != acep) /* paranoia debug check */
305 dbg ("auerchain_complete: completion on non-active element called!");
306 else
307 acp->active = NULL;
308
309 /* add the used chain element to the list of free elements */
310 list_add_tail (&acep->list, &acp->free_list);
311 acep = NULL;
312
313 /* is there a new element waiting in the chain? */
314 if (!acp->active && !list_empty (&acp->waiting_list)) {
315 /* yes: get the entry */
316 struct list_head *tmp = acp->waiting_list.next;
317 list_del (tmp);
318 acep = list_entry (tmp, auerchainelement_t, list);
319 acp->active = acep;
320 }
321 spin_unlock_irqrestore (&acp->lock, flags);
322
323 /* submit the new urb */
324 if (acep) {
325 urb = acep->urbp;
326 dbg ("auerchain_complete: submitting next urb from chain");
327 urb->status = 0; /* needed! */
328 result = usb_submit_urb(urb, GFP_ATOMIC);
329
330 /* check for submit errors */
331 if (result) {
332 urb->status = result;
333 dbg("auerchain_complete: usb_submit_urb with error code %d", result);
334 /* and do error handling via *this* completion function (recursive) */
335 auerchain_complete( urb);
336 }
337 } else {
338 /* simple return without submitting a new urb.
339 The empty chain is detected with acp->active == NULL. */
340 };
341}
342
343
344/* submit function for chained urbs
345 this function may be called from completion context or from user space!
346 early = 1 -> submit in front of chain
347*/
348static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int early)
349{
350 int result;
351 unsigned long flags;
352 pauerchainelement_t acep = NULL;
353
354 dbg ("auerchain_submit_urb called");
355
356 /* try to get a chain element */
357 spin_lock_irqsave (&acp->lock, flags);
358 if (!list_empty (&acp->free_list)) {
359 /* yes: get the entry */
360 struct list_head *tmp = acp->free_list.next;
361 list_del (tmp);
362 acep = list_entry (tmp, auerchainelement_t, list);
363 }
364 spin_unlock_irqrestore (&acp->lock, flags);
365
366 /* if no chain element available: return with error */
367 if (!acep) {
368 return -ENOMEM;
369 }
370
371 /* fill in the new chain element values */
372 acep->chain = acp;
373 acep->context = urb->context;
374 acep->complete = urb->complete;
375 acep->urbp = urb;
376 INIT_LIST_HEAD (&acep->list);
377
378 /* modify urb */
379 urb->context = acep;
380 urb->complete = auerchain_complete;
381 urb->status = -EINPROGRESS; /* usb_submit_urb does this, too */
382
383 /* add element to chain - or start it immediately */
384 spin_lock_irqsave (&acp->lock, flags);
385 if (acp->active) {
386 /* there is traffic in the chain, simple add element to chain */
387 if (early) {
388 dbg ("adding new urb to head of chain");
389 list_add (&acep->list, &acp->waiting_list);
390 } else {
391 dbg ("adding new urb to end of chain");
392 list_add_tail (&acep->list, &acp->waiting_list);
393 }
394 acep = NULL;
395 } else {
396 /* the chain is empty. Prepare restart */
397 acp->active = acep;
398 }
399 /* Spin has to be removed before usb_submit_urb! */
400 spin_unlock_irqrestore (&acp->lock, flags);
401
402 /* Submit urb if immediate restart */
403 if (acep) {
404 dbg("submitting urb immediate");
405 urb->status = 0; /* needed! */
406 result = usb_submit_urb(urb, GFP_ATOMIC);
407 /* check for submit errors */
408 if (result) {
409 urb->status = result;
410 dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result);
411 /* and do error handling via completion function */
412 auerchain_complete( urb);
413 }
414 }
415
416 return 0;
417}
418
419/* submit function for chained urbs
420 this function may be called from completion context or from user space!
421*/
422static int auerchain_submit_urb (pauerchain_t acp, struct urb * urb)
423{
424 return auerchain_submit_urb_list (acp, urb, 0);
425}
426
427/* cancel an urb which is submitted to the chain
428 the result is 0 if the urb is cancelled, or -EINPROGRESS if
429 the function is successfully started.
430*/
431static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb)
432{
433 unsigned long flags;
434 struct urb * urbp;
435 pauerchainelement_t acep;
436 struct list_head *tmp;
437
438 dbg ("auerchain_unlink_urb called");
439
440 /* search the chain of waiting elements */
441 spin_lock_irqsave (&acp->lock, flags);
442 list_for_each (tmp, &acp->waiting_list) {
443 acep = list_entry (tmp, auerchainelement_t, list);
444 if (acep->urbp == urb) {
445 list_del (tmp);
446 urb->context = acep->context;
447 urb->complete = acep->complete;
448 list_add_tail (&acep->list, &acp->free_list);
449 spin_unlock_irqrestore (&acp->lock, flags);
450 dbg ("unlink waiting urb");
451 urb->status = -ENOENT;
452 urb->complete (urb);
453 return 0;
454 }
455 }
456 /* not found. */
457 spin_unlock_irqrestore (&acp->lock, flags);
458
459 /* get the active urb */
460 acep = acp->active;
461 if (acep) {
462 urbp = acep->urbp;
463
464 /* check if we have to cancel the active urb */
465 if (urbp == urb) {
466 /* note that there is a race condition between the check above
467 and the unlink() call because of no lock. This race is harmless,
468 because the usb module will detect the unlink() after completion.
469 We can't use the acp->lock here because the completion function
470 wants to grab it.
471 */
472 dbg ("unlink active urb");
473 return usb_unlink_urb (urbp);
474 }
475 }
476
477 /* not found anyway
478 ... is some kind of success
479 */
480 dbg ("urb to unlink not found in chain");
481 return 0;
482}
483
484/* cancel all urbs which are in the chain.
485 this function must not be called from interrupt or completion handler.
486*/
487static void auerchain_unlink_all (pauerchain_t acp)
488{
489 unsigned long flags;
490 struct urb * urbp;
491 pauerchainelement_t acep;
492
493 dbg ("auerchain_unlink_all called");
494
495 /* clear the chain of waiting elements */
496 spin_lock_irqsave (&acp->lock, flags);
497 while (!list_empty (&acp->waiting_list)) {
498 /* get the next entry */
499 struct list_head *tmp = acp->waiting_list.next;
500 list_del (tmp);
501 acep = list_entry (tmp, auerchainelement_t, list);
502 urbp = acep->urbp;
503 urbp->context = acep->context;
504 urbp->complete = acep->complete;
505 list_add_tail (&acep->list, &acp->free_list);
506 spin_unlock_irqrestore (&acp->lock, flags);
507 dbg ("unlink waiting urb");
508 urbp->status = -ENOENT;
509 urbp->complete (urbp);
510 spin_lock_irqsave (&acp->lock, flags);
511 }
512 spin_unlock_irqrestore (&acp->lock, flags);
513
514 /* clear the active urb */
515 acep = acp->active;
516 if (acep) {
517 urbp = acep->urbp;
518 dbg ("unlink active urb");
519 usb_kill_urb (urbp);
520 }
521}
522
523
524/* free the chain.
525 this function must not be called from interrupt or completion handler.
526*/
527static void auerchain_free (pauerchain_t acp)
528{
529 unsigned long flags;
530 pauerchainelement_t acep;
531
532 dbg ("auerchain_free called");
533
534 /* first, cancel all pending urbs */
535 auerchain_unlink_all (acp);
536
537 /* free the elements */
538 spin_lock_irqsave (&acp->lock, flags);
539 while (!list_empty (&acp->free_list)) {
540 /* get the next entry */
541 struct list_head *tmp = acp->free_list.next;
542 list_del (tmp);
543 spin_unlock_irqrestore (&acp->lock, flags);
544 acep = list_entry (tmp, auerchainelement_t, list);
545 kfree (acep);
546 spin_lock_irqsave (&acp->lock, flags);
547 }
548 spin_unlock_irqrestore (&acp->lock, flags);
549}
550
551
552/* Init the chain control structure */
553static void auerchain_init (pauerchain_t acp)
554{
555 /* init the chain data structure */
556 acp->active = NULL;
557 spin_lock_init (&acp->lock);
558 INIT_LIST_HEAD (&acp->waiting_list);
559 INIT_LIST_HEAD (&acp->free_list);
560}
561
562/* setup a chain.
563 It is assumed that there is no concurrency while setting up the chain
564 requirement: auerchain_init()
565*/
566static int auerchain_setup (pauerchain_t acp, unsigned int numElements)
567{
568 pauerchainelement_t acep;
569
570 dbg ("auerchain_setup called with %d elements", numElements);
571
572 /* fill the list of free elements */
573 for (;numElements; numElements--) {
574 acep = kzalloc(sizeof(auerchainelement_t), GFP_KERNEL);
575 if (!acep)
576 goto ac_fail;
577 INIT_LIST_HEAD (&acep->list);
578 list_add_tail (&acep->list, &acp->free_list);
579 }
580 return 0;
581
582ac_fail:/* free the elements */
583 while (!list_empty (&acp->free_list)) {
584 /* get the next entry */
585 struct list_head *tmp = acp->free_list.next;
586 list_del (tmp);
587 acep = list_entry (tmp, auerchainelement_t, list);
588 kfree (acep);
589 }
590 return -ENOMEM;
591}
592
593
594/* completion handler for synchronous chained URBs */
595static void auerchain_blocking_completion (struct urb *urb)
596{
597 pauerchain_chs_t pchs = urb->context;
598 pchs->done = 1;
599 wmb();
600 wake_up (&pchs->wqh);
601}
602
603
604/* Starts chained urb and waits for completion or timeout */
605static int auerchain_start_wait_urb (pauerchain_t acp, struct urb *urb, int timeout, int* actual_length)
606{
607 auerchain_chs_t chs;
608 int status;
609
610 dbg ("auerchain_start_wait_urb called");
611 init_waitqueue_head (&chs.wqh);
612 chs.done = 0;
613
614 urb->context = &chs;
615 status = auerchain_submit_urb (acp, urb);
616 if (status)
617 /* something went wrong */
618 return status;
619
620 timeout = wait_event_timeout(chs.wqh, chs.done, timeout);
621
622 if (!timeout && !chs.done) {
623 if (urb->status != -EINPROGRESS) { /* No callback?!! */
624 dbg ("auerchain_start_wait_urb: raced timeout");
625 status = urb->status;
626 } else {
627 dbg ("auerchain_start_wait_urb: timeout");
628 auerchain_unlink_urb (acp, urb); /* remove urb safely */
629 status = -ETIMEDOUT;
630 }
631 } else
632 status = urb->status;
633
634 if (status >= 0)
635 *actual_length = urb->actual_length;
636
637 return status;
638}
639
640
641/* auerchain_control_msg - Builds a control urb, sends it off and waits for completion
642 acp: pointer to the auerchain
643 dev: pointer to the usb device to send the message to
644 pipe: endpoint "pipe" to send the message to
645 request: USB message request value
646 requesttype: USB message request type value
647 value: USB message value
648 index: USB message index value
649 data: pointer to the data to send
650 size: length in bytes of the data to send
651 timeout: time to wait for the message to complete before timing out (if 0 the wait is forever)
652
653 This function sends a simple control message to a specified endpoint
654 and waits for the message to complete, or timeout.
655
656 If successful, it returns the transferred length, otherwise a negative error number.
657
658 Don't use this function from within an interrupt context, like a
659 bottom half handler. If you need an asynchronous message, or need to send
660 a message from within interrupt context, use auerchain_submit_urb()
661*/
662static int auerchain_control_msg (pauerchain_t acp, struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
663 __u16 value, __u16 index, void *data, __u16 size, int timeout)
664{
665 int ret;
666 struct usb_ctrlrequest *dr;
667 struct urb *urb;
668 int uninitialized_var(length);
669
670 dbg ("auerchain_control_msg");
671 dr = kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL);
672 if (!dr)
673 return -ENOMEM;
674 urb = usb_alloc_urb (0, GFP_KERNEL);
675 if (!urb) {
676 kfree (dr);
677 return -ENOMEM;
678 }
679
680 dr->bRequestType = requesttype;
681 dr->bRequest = request;
682 dr->wValue = cpu_to_le16 (value);
683 dr->wIndex = cpu_to_le16 (index);
684 dr->wLength = cpu_to_le16 (size);
685
686 usb_fill_control_urb (urb, dev, pipe, (unsigned char*)dr, data, size, /* build urb */
687 auerchain_blocking_completion, NULL);
688 ret = auerchain_start_wait_urb (acp, urb, timeout, &length);
689
690 usb_free_urb (urb);
691 kfree (dr);
692
693 if (ret < 0)
694 return ret;
695 else
696 return length;
697}
698
699
700/*-------------------------------------------------------------------*/
701/* Buffer List helper functions */
702
703/* free a single auerbuf */
704static void auerbuf_free (pauerbuf_t bp)
705{
706 kfree(bp->bufp);
707 kfree(bp->dr);
708 usb_free_urb(bp->urbp);
709 kfree(bp);
710}
711
712/* free the buffers from an auerbuf list */
713static void auerbuf_free_list (struct list_head *q)
714{
715 struct list_head *tmp;
716 struct list_head *p;
717 pauerbuf_t bp;
718
719 dbg ("auerbuf_free_list");
720 for (p = q->next; p != q;) {
721 bp = list_entry (p, auerbuf_t, buff_list);
722 tmp = p->next;
723 list_del (p);
724 p = tmp;
725 auerbuf_free (bp);
726 }
727}
728
729/* init the members of a list control block */
730static void auerbuf_init (pauerbufctl_t bcp)
731{
732 dbg ("auerbuf_init");
733 spin_lock_init (&bcp->lock);
734 INIT_LIST_HEAD (&bcp->free_buff_list);
735 INIT_LIST_HEAD (&bcp->rec_buff_list);
736}
737
738/* free all buffers from an auerbuf chain */
739static void auerbuf_free_buffers (pauerbufctl_t bcp)
740{
741 unsigned long flags;
742 dbg ("auerbuf_free_buffers");
743
744 spin_lock_irqsave (&bcp->lock, flags);
745
746 auerbuf_free_list (&bcp->free_buff_list);
747 auerbuf_free_list (&bcp->rec_buff_list);
748
749 spin_unlock_irqrestore (&bcp->lock, flags);
750}
751
752/* setup a list of buffers */
753/* requirement: auerbuf_init() */
754static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned int bufsize)
755{
756 pauerbuf_t bep = NULL;
757
758 dbg ("auerbuf_setup called with %d elements of %d bytes", numElements, bufsize);
759
760 /* fill the list of free elements */
761 for (;numElements; numElements--) {
762 bep = kzalloc(sizeof(auerbuf_t), GFP_KERNEL);
763 if (!bep)
764 goto bl_fail;
765 bep->list = bcp;
766 INIT_LIST_HEAD (&bep->buff_list);
767 bep->bufp = kmalloc (bufsize, GFP_KERNEL);
768 if (!bep->bufp)
769 goto bl_fail;
770 bep->dr = kmalloc(sizeof (struct usb_ctrlrequest), GFP_KERNEL);
771 if (!bep->dr)
772 goto bl_fail;
773 bep->urbp = usb_alloc_urb (0, GFP_KERNEL);
774 if (!bep->urbp)
775 goto bl_fail;
776 list_add_tail (&bep->buff_list, &bcp->free_buff_list);
777 }
778 return 0;
779
780bl_fail:/* not enough memory. Free allocated elements */
781 dbg ("auerbuf_setup: no more memory");
782 auerbuf_free(bep);
783 auerbuf_free_buffers (bcp);
784 return -ENOMEM;
785}
786
787/* insert a used buffer into the free list */
788static void auerbuf_releasebuf( pauerbuf_t bp)
789{
790 unsigned long flags;
791 pauerbufctl_t bcp = bp->list;
792 bp->retries = 0;
793
794 dbg ("auerbuf_releasebuf called");
795 spin_lock_irqsave (&bcp->lock, flags);
796 list_add_tail (&bp->buff_list, &bcp->free_buff_list);
797 spin_unlock_irqrestore (&bcp->lock, flags);
798}
799
800
801/*-------------------------------------------------------------------*/
802/* Completion handlers */
803
804/* Values of urb->status or results of usb_submit_urb():
8050 Initial, OK
806-EINPROGRESS during submission until end
807-ENOENT if urb is unlinked
808-ETIME Device did not respond
809-ENOMEM Memory Overflow
810-ENODEV Specified USB-device or bus doesn't exist
811-ENXIO URB already queued
812-EINVAL a) Invalid transfer type specified (or not supported)
813 b) Invalid interrupt interval (0n256)
814-EAGAIN a) Specified ISO start frame too early
815 b) (using ISO-ASAP) Too much scheduled for the future wait some time and try again.
816-EFBIG Too much ISO frames requested (currently uhci900)
817-EPIPE Specified pipe-handle/Endpoint is already stalled
818-EMSGSIZE Endpoint message size is zero, do interface/alternate setting
819-EPROTO a) Bitstuff error
820 b) Unknown USB error
821-EILSEQ CRC mismatch
822-ENOSR Buffer error
823-EREMOTEIO Short packet detected
824-EXDEV ISO transfer only partially completed look at individual frame status for details
825-EINVAL ISO madness, if this happens: Log off and go home
826-EOVERFLOW babble
827*/
828
829/* check if a status code allows a retry */
830static int auerswald_status_retry (int status)
831{
832 switch (status) {
833 case 0:
834 case -ETIME:
835 case -EOVERFLOW:
836 case -EAGAIN:
837 case -EPIPE:
838 case -EPROTO:
839 case -EILSEQ:
840 case -ENOSR:
841 case -EREMOTEIO:
842 return 1; /* do a retry */
843 }
844 return 0; /* no retry possible */
845}
846
847/* Completion of asynchronous write block */
848static void auerchar_ctrlwrite_complete (struct urb * urb)
849{
850 pauerbuf_t bp = urb->context;
851 pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
852 dbg ("auerchar_ctrlwrite_complete called");
853
854 /* reuse the buffer */
855 auerbuf_releasebuf (bp);
856 /* Wake up all processes waiting for a buffer */
857 wake_up (&cp->bufferwait);
858}
859
860/* Completion handler for dummy retry packet */
861static void auerswald_ctrlread_wretcomplete (struct urb * urb)
862{
863 pauerbuf_t bp = urb->context;
864 pauerswald_t cp;
865 int ret;
866 int status = urb->status;
867
868 dbg ("auerswald_ctrlread_wretcomplete called");
869 dbg ("complete with status: %d", status);
870 cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
871
872 /* check if it is possible to advance */
873 if (!auerswald_status_retry(status) || !cp->usbdev) {
874 /* reuse the buffer */
875 err ("control dummy: transmission error %d, can not retry", status);
876 auerbuf_releasebuf (bp);
877 /* Wake up all processes waiting for a buffer */
878 wake_up (&cp->bufferwait);
879 return;
880 }
881
882 /* fill the control message */
883 bp->dr->bRequestType = AUT_RREQ;
884 bp->dr->bRequest = AUV_RBLOCK;
885 bp->dr->wLength = bp->dr->wValue; /* temporary stored */
886 bp->dr->wValue = cpu_to_le16 (1); /* Retry Flag */
887 /* bp->dr->index = channel id; remains */
888 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
889 (unsigned char*)bp->dr, bp->bufp, le16_to_cpu (bp->dr->wLength),
890 auerswald_ctrlread_complete,bp);
891
892 /* submit the control msg as next paket */
893 ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
894 if (ret) {
895 dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
896 bp->urbp->status = ret;
897 auerswald_ctrlread_complete (bp->urbp);
898 }
899}
900
901/* completion handler for receiving of control messages */
902static void auerswald_ctrlread_complete (struct urb * urb)
903{
904 unsigned int serviceid;
905 pauerswald_t cp;
906 pauerscon_t scp;
907 pauerbuf_t bp = urb->context;
908 int status = urb->status;
909 int ret;
910
911 dbg ("auerswald_ctrlread_complete called");
912
913 cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
914
915 /* check if there is valid data in this urb */
916 if (status) {
917 dbg ("complete with non-zero status: %d", status);
918 /* should we do a retry? */
919 if (!auerswald_status_retry(status)
920 || !cp->usbdev
921 || (cp->version < AUV_RETRY)
922 || (bp->retries >= AU_RETRIES)) {
923 /* reuse the buffer */
924 err ("control read: transmission error %d, can not retry", status);
925 auerbuf_releasebuf (bp);
926 /* Wake up all processes waiting for a buffer */
927 wake_up (&cp->bufferwait);
928 return;
929 }
930 bp->retries++;
931 dbg ("Retry count = %d", bp->retries);
932 /* send a long dummy control-write-message to allow device firmware to react */
933 bp->dr->bRequestType = AUT_WREQ;
934 bp->dr->bRequest = AUV_DUMMY;
935 bp->dr->wValue = bp->dr->wLength; /* temporary storage */
936 // bp->dr->wIndex channel ID remains
937 bp->dr->wLength = cpu_to_le16 (32); /* >= 8 bytes */
938 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0),
939 (unsigned char*)bp->dr, bp->bufp, 32,
940 auerswald_ctrlread_wretcomplete,bp);
941
942 /* submit the control msg as next paket */
943 ret = auerchain_submit_urb_list (&cp->controlchain, bp->urbp, 1);
944 if (ret) {
945 dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
946 bp->urbp->status = ret;
947 auerswald_ctrlread_wretcomplete (bp->urbp);
948 }
949 return;
950 }
951
952 /* get the actual bytecount (incl. headerbyte) */
953 bp->len = urb->actual_length;
954 serviceid = bp->bufp[0] & AUH_TYPEMASK;
955 dbg ("Paket with serviceid %d and %d bytes received", serviceid, bp->len);
956
957 /* dispatch the paket */
958 scp = cp->services[serviceid];
959 if (scp) {
960 /* look, Ma, a listener! */
961 scp->dispatch (scp, bp);
962 }
963
964 /* release the paket */
965 auerbuf_releasebuf (bp);
966 /* Wake up all processes waiting for a buffer */
967 wake_up (&cp->bufferwait);
968}
969
970/*-------------------------------------------------------------------*/
971/* Handling of Interrupt Endpoint */
972/* This interrupt Endpoint is used to inform the host about waiting
973 messages from the USB device.
974*/
975/* int completion handler. */
976static void auerswald_int_complete (struct urb * urb)
977{
978 unsigned long flags;
979 unsigned int channelid;
980 unsigned int bytecount;
981 int ret;
982 int status = urb->status;
983 pauerbuf_t bp = NULL;
984 pauerswald_t cp = urb->context;
985
986 dbg ("%s called", __func__);
987
988 switch (status) {
989 case 0:
990 /* success */
991 break;
992 case -ECONNRESET:
993 case -ENOENT:
994 case -ESHUTDOWN:
995 /* this urb is terminated, clean up */
996 dbg("%s - urb shutting down with status: %d", __func__, status);
997 return;
998 default:
999 dbg("%s - nonzero urb status received: %d", __func__, status);
1000 goto exit;
1001 }
1002
1003 /* check if all needed data was received */
1004 if (urb->actual_length < AU_IRQMINSIZE) {
1005 dbg ("invalid data length received: %d bytes", urb->actual_length);
1006 goto exit;
1007 }
1008
1009 /* check the command code */
1010 if (cp->intbufp[0] != AU_IRQCMDID) {
1011 dbg ("invalid command received: %d", cp->intbufp[0]);
1012 goto exit;
1013 }
1014
1015 /* check the command type */
1016 if (cp->intbufp[1] != AU_BLOCKRDY) {
1017 dbg ("invalid command type received: %d", cp->intbufp[1]);
1018 goto exit;
1019 }
1020
1021 /* now extract the information */
1022 channelid = cp->intbufp[2];
1023 bytecount = (unsigned char)cp->intbufp[3];
1024 bytecount |= (unsigned char)cp->intbufp[4] << 8;
1025
1026 /* check the channel id */
1027 if (channelid >= AUH_TYPESIZE) {
1028 dbg ("invalid channel id received: %d", channelid);
1029 goto exit;
1030 }
1031
1032 /* check the byte count */
1033 if (bytecount > (cp->maxControlLength+AUH_SIZE)) {
1034 dbg ("invalid byte count received: %d", bytecount);
1035 goto exit;
1036 }
1037 dbg ("Service Channel = %d", channelid);
1038 dbg ("Byte Count = %d", bytecount);
1039
1040 /* get a buffer for the next data paket */
1041 spin_lock_irqsave (&cp->bufctl.lock, flags);
1042 if (!list_empty (&cp->bufctl.free_buff_list)) {
1043 /* yes: get the entry */
1044 struct list_head *tmp = cp->bufctl.free_buff_list.next;
1045 list_del (tmp);
1046 bp = list_entry (tmp, auerbuf_t, buff_list);
1047 }
1048 spin_unlock_irqrestore (&cp->bufctl.lock, flags);
1049
1050 /* if no buffer available: skip it */
1051 if (!bp) {
1052 dbg ("auerswald_int_complete: no data buffer available");
1053 /* can we do something more?
1054 This is a big problem: if this int packet is ignored, the
1055 device will wait forever and not signal any more data.
1056 The only real solution is: having enough buffers!
1057 Or perhaps temporary disabling the int endpoint?
1058 */
1059 goto exit;
1060 }
1061
1062 /* fill the control message */
1063 bp->dr->bRequestType = AUT_RREQ;
1064 bp->dr->bRequest = AUV_RBLOCK;
1065 bp->dr->wValue = cpu_to_le16 (0);
1066 bp->dr->wIndex = cpu_to_le16 (channelid | AUH_DIRECT | AUH_UNSPLIT);
1067 bp->dr->wLength = cpu_to_le16 (bytecount);
1068 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_rcvctrlpipe (cp->usbdev, 0),
1069 (unsigned char*)bp->dr, bp->bufp, bytecount,
1070 auerswald_ctrlread_complete,bp);
1071
1072 /* submit the control msg */
1073 ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
1074 if (ret) {
1075 dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret);
1076 bp->urbp->status = ret;
1077 auerswald_ctrlread_complete( bp->urbp);
1078 /* here applies the same problem as above: device locking! */
1079 }
1080exit:
1081 ret = usb_submit_urb (urb, GFP_ATOMIC);
1082 if (ret)
1083 err ("%s - usb_submit_urb failed with result %d",
1084 __func__, ret);
1085}
1086
1087/* int memory deallocation
1088 NOTE: no mutex please!
1089*/
1090static void auerswald_int_free (pauerswald_t cp)
1091{
1092 if (cp->inturbp) {
1093 usb_free_urb(cp->inturbp);
1094 cp->inturbp = NULL;
1095 }
1096 kfree(cp->intbufp);
1097 cp->intbufp = NULL;
1098}
1099
1100/* This function is called to activate the interrupt
1101 endpoint. This function returns 0 if successful or an error code.
1102 NOTE: no mutex please!
1103*/
1104static int auerswald_int_open (pauerswald_t cp)
1105{
1106 int ret;
1107 struct usb_host_endpoint *ep;
1108 int irqsize;
1109 dbg ("auerswald_int_open");
1110
1111 ep = cp->usbdev->ep_in[AU_IRQENDP];
1112 if (!ep) {
1113 ret = -EFAULT;
1114 goto intoend;
1115 }
1116 irqsize = le16_to_cpu(ep->desc.wMaxPacketSize);
1117 cp->irqsize = irqsize;
1118
1119 /* allocate the urb and data buffer */
1120 if (!cp->inturbp) {
1121 cp->inturbp = usb_alloc_urb (0, GFP_KERNEL);
1122 if (!cp->inturbp) {
1123 ret = -ENOMEM;
1124 goto intoend;
1125 }
1126 }
1127 if (!cp->intbufp) {
1128 cp->intbufp = kmalloc (irqsize, GFP_KERNEL);
1129 if (!cp->intbufp) {
1130 ret = -ENOMEM;
1131 goto intoend;
1132 }
1133 }
1134 /* setup urb */
1135 usb_fill_int_urb (cp->inturbp, cp->usbdev,
1136 usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp,
1137 irqsize, auerswald_int_complete, cp, ep->desc.bInterval);
1138 /* start the urb */
1139 cp->inturbp->status = 0; /* needed! */
1140 ret = usb_submit_urb (cp->inturbp, GFP_KERNEL);
1141
1142intoend:
1143 if (ret < 0) {
1144 /* activation of interrupt endpoint has failed. Now clean up. */
1145 dbg ("auerswald_int_open: activation of int endpoint failed");
1146
1147 /* deallocate memory */
1148 auerswald_int_free (cp);
1149 }
1150 return ret;
1151}
1152
1153/* This function is called to deactivate the interrupt
1154 endpoint. This function returns 0 if successful or an error code.
1155 NOTE: no mutex please!
1156*/
1157static void auerswald_int_release (pauerswald_t cp)
1158{
1159 dbg ("auerswald_int_release");
1160
1161 /* stop the int endpoint */
1162 usb_kill_urb (cp->inturbp);
1163
1164 /* deallocate memory */
1165 auerswald_int_free (cp);
1166}
1167
1168/* --------------------------------------------------------------------- */
1169/* Helper functions */
1170
1171/* wake up waiting readers */
1172static void auerchar_disconnect (pauerscon_t scp)
1173{
1174 pauerchar_t ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext)));
1175 dbg ("auerchar_disconnect called");
1176 ccp->removed = 1;
1177 wake_up (&ccp->readwait);
1178}
1179
1180
1181/* dispatch a read paket to a waiting character device */
1182static void auerchar_ctrlread_dispatch (pauerscon_t scp, pauerbuf_t bp)
1183{
1184 unsigned long flags;
1185 pauerchar_t ccp;
1186 pauerbuf_t newbp = NULL;
1187 char * charp;
1188 dbg ("auerchar_ctrlread_dispatch called");
1189 ccp = ((pauerchar_t)((char *)(scp)-(unsigned long)(&((pauerchar_t)0)->scontext)));
1190
1191 /* get a read buffer from character device context */
1192 spin_lock_irqsave (&ccp->bufctl.lock, flags);
1193 if (!list_empty (&ccp->bufctl.free_buff_list)) {
1194 /* yes: get the entry */
1195 struct list_head *tmp = ccp->bufctl.free_buff_list.next;
1196 list_del (tmp);
1197 newbp = list_entry (tmp, auerbuf_t, buff_list);
1198 }
1199 spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
1200
1201 if (!newbp) {
1202 dbg ("No read buffer available, discard paket!");
1203 return; /* no buffer, no dispatch */
1204 }
1205
1206 /* copy information to new buffer element
1207 (all buffers have the same length) */
1208 charp = newbp->bufp;
1209 newbp->bufp = bp->bufp;
1210 bp->bufp = charp;
1211 newbp->len = bp->len;
1212
1213 /* insert new buffer in read list */
1214 spin_lock_irqsave (&ccp->bufctl.lock, flags);
1215 list_add_tail (&newbp->buff_list, &ccp->bufctl.rec_buff_list);
1216 spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
1217 dbg ("read buffer appended to rec_list");
1218
1219 /* wake up pending synchronous reads */
1220 wake_up (&ccp->readwait);
1221}
1222
1223
1224/* Delete an auerswald driver context */
1225static void auerswald_delete( pauerswald_t cp)
1226{
1227 dbg( "auerswald_delete");
1228 if (cp == NULL)
1229 return;
1230
1231 /* Wake up all processes waiting for a buffer */
1232 wake_up (&cp->bufferwait);
1233
1234 /* Cleaning up */
1235 auerswald_int_release (cp);
1236 auerchain_free (&cp->controlchain);
1237 auerbuf_free_buffers (&cp->bufctl);
1238
1239 /* release the memory */
1240 kfree( cp);
1241}
1242
1243
1244/* Delete an auerswald character context */
1245static void auerchar_delete( pauerchar_t ccp)
1246{
1247 dbg ("auerchar_delete");
1248 if (ccp == NULL)
1249 return;
1250
1251 /* wake up pending synchronous reads */
1252 ccp->removed = 1;
1253 wake_up (&ccp->readwait);
1254
1255 /* remove the read buffer */
1256 if (ccp->readbuf) {
1257 auerbuf_releasebuf (ccp->readbuf);
1258 ccp->readbuf = NULL;
1259 }
1260
1261 /* remove the character buffers */
1262 auerbuf_free_buffers (&ccp->bufctl);
1263
1264 /* release the memory */
1265 kfree( ccp);
1266}
1267
1268
1269/* add a new service to the device
1270 scp->id must be set!
1271 return: 0 if OK, else error code
1272*/
1273static int auerswald_addservice (pauerswald_t cp, pauerscon_t scp)
1274{
1275 int ret;
1276
1277 /* is the device available? */
1278 if (!cp->usbdev) {
1279 dbg ("usbdev == NULL");
1280 return -EIO; /*no: can not add a service, sorry*/
1281 }
1282
1283 /* is the service available? */
1284 if (cp->services[scp->id]) {
1285 dbg ("service is busy");
1286 return -EBUSY;
1287 }
1288
1289 /* device is available, service is free */
1290 cp->services[scp->id] = scp;
1291
1292 /* register service in device */
1293 ret = auerchain_control_msg(
1294 &cp->controlchain, /* pointer to control chain */
1295 cp->usbdev, /* pointer to device */
1296 usb_sndctrlpipe (cp->usbdev, 0), /* pipe to control endpoint */
1297 AUV_CHANNELCTL, /* USB message request value */
1298 AUT_WREQ, /* USB message request type value */
1299 0x01, /* open USB message value */
1300 scp->id, /* USB message index value */
1301 NULL, /* pointer to the data to send */
1302 0, /* length in bytes of the data to send */
1303 HZ * 2); /* time to wait for the message to complete before timing out */
1304 if (ret < 0) {
1305 dbg ("auerswald_addservice: auerchain_control_msg returned error code %d", ret);
1306 /* undo above actions */
1307 cp->services[scp->id] = NULL;
1308 return ret;
1309 }
1310
1311 dbg ("auerswald_addservice: channel open OK");
1312 return 0;
1313}
1314
1315
1316/* remove a service from the device
1317 scp->id must be set! */
1318static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp)
1319{
1320 dbg ("auerswald_removeservice called");
1321
1322 /* check if we have a service allocated */
1323 if (scp->id == AUH_UNASSIGNED)
1324 return;
1325
1326 /* If there is a device: close the channel */
1327 if (cp->usbdev) {
1328 /* Close the service channel inside the device */
1329 int ret = auerchain_control_msg(
1330 &cp->controlchain, /* pointer to control chain */
1331 cp->usbdev, /* pointer to device */
1332 usb_sndctrlpipe (cp->usbdev, 0), /* pipe to control endpoint */
1333 AUV_CHANNELCTL, /* USB message request value */
1334 AUT_WREQ, /* USB message request type value */
1335 0x00, // close /* USB message value */
1336 scp->id, /* USB message index value */
1337 NULL, /* pointer to the data to send */
1338 0, /* length in bytes of the data to send */
1339 HZ * 2); /* time to wait for the message to complete before timing out */
1340 if (ret < 0) {
1341 dbg ("auerswald_removeservice: auerchain_control_msg returned error code %d", ret);
1342 }
1343 else {
1344 dbg ("auerswald_removeservice: channel close OK");
1345 }
1346 }
1347
1348 /* remove the service from the device */
1349 cp->services[scp->id] = NULL;
1350 scp->id = AUH_UNASSIGNED;
1351}
1352
1353
1354/* --------------------------------------------------------------------- */
1355/* Char device functions */
1356
1357/* Open a new character device */
1358static int auerchar_open (struct inode *inode, struct file *file)
1359{
1360 int dtindex = iminor(inode);
1361 pauerswald_t cp = NULL;
1362 pauerchar_t ccp = NULL;
1363 struct usb_interface *intf;
1364 int ret;
1365
1366 /* minor number in range? */
1367 if (dtindex < 0) {
1368 return -ENODEV;
1369 }
1370 intf = usb_find_interface(&auerswald_driver, dtindex);
1371 if (!intf) {
1372 return -ENODEV;
1373 }
1374
1375 /* usb device available? */
1376 cp = usb_get_intfdata (intf);
1377 if (cp == NULL) {
1378 return -ENODEV;
1379 }
1380 if (mutex_lock_interruptible(&cp->mutex)) {
1381 return -ERESTARTSYS;
1382 }
1383
1384 /* we have access to the device. Now lets allocate memory */
1385 ccp = kzalloc(sizeof(auerchar_t), GFP_KERNEL);
1386 if (ccp == NULL) {
1387 err ("out of memory");
1388 ret = -ENOMEM;
1389 goto ofail;
1390 }
1391
1392 /* Initialize device descriptor */
1393 mutex_init(&ccp->mutex);
1394 mutex_init(&ccp->readmutex);
1395 auerbuf_init (&ccp->bufctl);
1396 ccp->scontext.id = AUH_UNASSIGNED;
1397 ccp->scontext.dispatch = auerchar_ctrlread_dispatch;
1398 ccp->scontext.disconnect = auerchar_disconnect;
1399 init_waitqueue_head (&ccp->readwait);
1400
1401 ret = auerbuf_setup (&ccp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE);
1402 if (ret) {
1403 goto ofail;
1404 }
1405
1406 cp->open_count++;
1407 ccp->auerdev = cp;
1408 dbg("open %s as /dev/%s", cp->dev_desc, cp->name);
1409 mutex_unlock(&cp->mutex);
1410
1411 /* file IO stuff */
1412 file->f_pos = 0;
1413 file->private_data = ccp;
1414 return nonseekable_open(inode, file);
1415
1416 /* Error exit */
1417ofail: mutex_unlock(&cp->mutex);
1418 auerchar_delete (ccp);
1419 return ret;
1420}
1421
1422
1423/* IOCTL functions */
1424static long auerchar_ioctl(struct file *file, unsigned int cmd,
1425 unsigned long arg)
1426{
1427 pauerchar_t ccp = (pauerchar_t) file->private_data;
1428 int ret = 0;
1429 audevinfo_t devinfo;
1430 pauerswald_t cp = NULL;
1431 unsigned int u;
1432 unsigned int __user *user_arg = (unsigned int __user *)arg;
1433
1434 dbg ("ioctl");
1435
1436 /* get the mutexes */
1437 if (mutex_lock_interruptible(&ccp->mutex)) {
1438 return -ERESTARTSYS;
1439 }
1440 cp = ccp->auerdev;
1441 if (!cp) {
1442 mutex_unlock(&ccp->mutex);
1443 return -ENODEV;
1444 }
1445 if (mutex_lock_interruptible(&cp->mutex)) {
1446 mutex_unlock(&ccp->mutex);
1447 return -ERESTARTSYS;
1448 }
1449
1450 /* Check for removal */
1451 if (!cp->usbdev) {
1452 mutex_unlock(&cp->mutex);
1453 mutex_unlock(&ccp->mutex);
1454 return -ENODEV;
1455 }
1456 lock_kernel();
1457 switch (cmd) {
1458
1459 /* return != 0 if Transmitt channel ready to send */
1460 case IOCTL_AU_TXREADY:
1461 dbg ("IOCTL_AU_TXREADY");
1462 u = ccp->auerdev
1463 && (ccp->scontext.id != AUH_UNASSIGNED)
1464 && !list_empty (&cp->bufctl.free_buff_list);
1465 ret = put_user (u, user_arg);
1466 break;
1467
1468 /* return != 0 if connected to a service channel */
1469 case IOCTL_AU_CONNECT:
1470 dbg ("IOCTL_AU_CONNECT");
1471 u = (ccp->scontext.id != AUH_UNASSIGNED);
1472 ret = put_user (u, user_arg);
1473 break;
1474
1475 /* return != 0 if Receive Data available */
1476 case IOCTL_AU_RXAVAIL:
1477 dbg ("IOCTL_AU_RXAVAIL");
1478 if (ccp->scontext.id == AUH_UNASSIGNED) {
1479 ret = -EIO;
1480 break;
1481 }
1482 u = 0; /* no data */
1483 if (ccp->readbuf) {
1484 int restlen = ccp->readbuf->len - ccp->readoffset;
1485 if (restlen > 0)
1486 u = 1;
1487 }
1488 if (!u) {
1489 if (!list_empty (&ccp->bufctl.rec_buff_list)) {
1490 u = 1;
1491 }
1492 }
1493 ret = put_user (u, user_arg);
1494 break;
1495
1496 /* return the max. buffer length for the device */
1497 case IOCTL_AU_BUFLEN:
1498 dbg ("IOCTL_AU_BUFLEN");
1499 u = cp->maxControlLength;
1500 ret = put_user (u, user_arg);
1501 break;
1502
1503 /* requesting a service channel */
1504 case IOCTL_AU_SERVREQ:
1505 dbg ("IOCTL_AU_SERVREQ");
1506 /* requesting a service means: release the previous one first */
1507 auerswald_removeservice (cp, &ccp->scontext);
1508 /* get the channel number */
1509 ret = get_user (u, user_arg);
1510 if (ret) {
1511 break;
1512 }
1513 if ((u < AUH_FIRSTUSERCH) || (u >= AUH_TYPESIZE)) {
1514 ret = -EIO;
1515 break;
1516 }
1517 dbg ("auerchar service request parameters are ok");
1518 ccp->scontext.id = u;
1519
1520 /* request the service now */
1521 ret = auerswald_addservice (cp, &ccp->scontext);
1522 if (ret) {
1523 /* no: revert service entry */
1524 ccp->scontext.id = AUH_UNASSIGNED;
1525 }
1526 break;
1527
1528 /* get a string descriptor for the device */
1529 case IOCTL_AU_DEVINFO:
1530 dbg ("IOCTL_AU_DEVINFO");
1531 if (copy_from_user (&devinfo, (void __user *) arg, sizeof (audevinfo_t))) {
1532 ret = -EFAULT;
1533 break;
1534 }
1535 u = strlen(cp->dev_desc)+1;
1536 if (u > devinfo.bsize) {
1537 u = devinfo.bsize;
1538 }
1539 ret = copy_to_user(devinfo.buf, cp->dev_desc, u) ? -EFAULT : 0;
1540 break;
1541
1542 /* get the max. string descriptor length */
1543 case IOCTL_AU_SLEN:
1544 dbg ("IOCTL_AU_SLEN");
1545 u = AUSI_DLEN;
1546 ret = put_user (u, user_arg);
1547 break;
1548
1549 default:
1550 dbg ("IOCTL_AU_UNKNOWN");
1551 ret = -ENOTTY;
1552 break;
1553 }
1554 unlock_kernel();
1555 /* release the mutexes */
1556 mutex_unlock(&cp->mutex);
1557 mutex_unlock(&ccp->mutex);
1558 return ret;
1559}
1560
1561/* Read data from the device */
1562static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
1563{
1564 unsigned long flags;
1565 pauerchar_t ccp = (pauerchar_t) file->private_data;
1566 pauerbuf_t bp = NULL;
1567 wait_queue_t wait;
1568
1569 dbg ("auerchar_read");
1570
1571 /* Error checking */
1572 if (!ccp)
1573 return -EIO;
1574 if (*ppos)
1575 return -ESPIPE;
1576 if (count == 0)
1577 return 0;
1578
1579 /* get the mutex */
1580 if (mutex_lock_interruptible(&ccp->mutex))
1581 return -ERESTARTSYS;
1582
1583 /* Can we expect to read something? */
1584 if (ccp->scontext.id == AUH_UNASSIGNED) {
1585 mutex_unlock(&ccp->mutex);
1586 return -EIO;
1587 }
1588
1589 /* only one reader per device allowed */
1590 if (mutex_lock_interruptible(&ccp->readmutex)) {
1591 mutex_unlock(&ccp->mutex);
1592 return -ERESTARTSYS;
1593 }
1594
1595 /* read data from readbuf, if available */
1596doreadbuf:
1597 bp = ccp->readbuf;
1598 if (bp) {
1599 /* read the maximum bytes */
1600 int restlen = bp->len - ccp->readoffset;
1601 if (restlen < 0)
1602 restlen = 0;
1603 if (count > restlen)
1604 count = restlen;
1605 if (count) {
1606 if (copy_to_user (buf, bp->bufp+ccp->readoffset, count)) {
1607 dbg ("auerswald_read: copy_to_user failed");
1608 mutex_unlock(&ccp->readmutex);
1609 mutex_unlock(&ccp->mutex);
1610 return -EFAULT;
1611 }
1612 }
1613 /* advance the read offset */
1614 ccp->readoffset += count;
1615 restlen -= count;
1616 // reuse the read buffer
1617 if (restlen <= 0) {
1618 auerbuf_releasebuf (bp);
1619 ccp->readbuf = NULL;
1620 }
1621 /* return with number of bytes read */
1622 if (count) {
1623 mutex_unlock(&ccp->readmutex);
1624 mutex_unlock(&ccp->mutex);
1625 return count;
1626 }
1627 }
1628
1629 /* a read buffer is not available. Try to get the next data block. */
1630doreadlist:
1631 /* Preparing for sleep */
1632 init_waitqueue_entry (&wait, current);
1633 set_current_state (TASK_INTERRUPTIBLE);
1634 add_wait_queue (&ccp->readwait, &wait);
1635
1636 bp = NULL;
1637 spin_lock_irqsave (&ccp->bufctl.lock, flags);
1638 if (!list_empty (&ccp->bufctl.rec_buff_list)) {
1639 /* yes: get the entry */
1640 struct list_head *tmp = ccp->bufctl.rec_buff_list.next;
1641 list_del (tmp);
1642 bp = list_entry (tmp, auerbuf_t, buff_list);
1643 }
1644 spin_unlock_irqrestore (&ccp->bufctl.lock, flags);
1645
1646 /* have we got data? */
1647 if (bp) {
1648 ccp->readbuf = bp;
1649 ccp->readoffset = AUH_SIZE; /* for headerbyte */
1650 set_current_state (TASK_RUNNING);
1651 remove_wait_queue (&ccp->readwait, &wait);
1652 goto doreadbuf; /* now we can read! */
1653 }
1654
1655 /* no data available. Should we wait? */
1656 if (file->f_flags & O_NONBLOCK) {
1657 dbg ("No read buffer available, returning -EAGAIN");
1658 set_current_state (TASK_RUNNING);
1659 remove_wait_queue (&ccp->readwait, &wait);
1660 mutex_unlock(&ccp->readmutex);
1661 mutex_unlock(&ccp->mutex);
1662 return -EAGAIN; /* nonblocking, no data available */
1663 }
1664
1665 /* yes, we should wait! */
1666 mutex_unlock(&ccp->mutex); /* allow other operations while we wait */
1667 schedule();
1668 remove_wait_queue (&ccp->readwait, &wait);
1669 if (signal_pending (current)) {
1670 /* waked up by a signal */
1671 mutex_unlock(&ccp->readmutex);
1672 return -ERESTARTSYS;
1673 }
1674
1675 /* Anything left to read? */
1676 if ((ccp->scontext.id == AUH_UNASSIGNED) || ccp->removed) {
1677 mutex_unlock(&ccp->readmutex);
1678 return -EIO;
1679 }
1680
1681 if (mutex_lock_interruptible(&ccp->mutex)) {
1682 mutex_unlock(&ccp->readmutex);
1683 return -ERESTARTSYS;
1684 }
1685
1686 /* try to read the incoming data again */
1687 goto doreadlist;
1688}
1689
1690
1691/* Write a data block into the right service channel of the device */
1692static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
1693{
1694 pauerchar_t ccp = (pauerchar_t) file->private_data;
1695 pauerswald_t cp = NULL;
1696 pauerbuf_t bp;
1697 unsigned long flags;
1698 int ret;
1699 wait_queue_t wait;
1700
1701 dbg ("auerchar_write %zd bytes", len);
1702
1703 /* Error checking */
1704 if (!ccp)
1705 return -EIO;
1706 if (*ppos)
1707 return -ESPIPE;
1708 if (len == 0)
1709 return 0;
1710
1711write_again:
1712 /* get the mutex */
1713 if (mutex_lock_interruptible(&ccp->mutex))
1714 return -ERESTARTSYS;
1715
1716 /* Can we expect to write something? */
1717 if (ccp->scontext.id == AUH_UNASSIGNED) {
1718 mutex_unlock(&ccp->mutex);
1719 return -EIO;
1720 }
1721
1722 cp = ccp->auerdev;
1723 if (!cp) {
1724 mutex_unlock(&ccp->mutex);
1725 return -ERESTARTSYS;
1726 }
1727 if (mutex_lock_interruptible(&cp->mutex)) {
1728 mutex_unlock(&ccp->mutex);
1729 return -ERESTARTSYS;
1730 }
1731 if (!cp->usbdev) {
1732 mutex_unlock(&cp->mutex);
1733 mutex_unlock(&ccp->mutex);
1734 return -EIO;
1735 }
1736 /* Prepare for sleep */
1737 init_waitqueue_entry (&wait, current);
1738 set_current_state (TASK_INTERRUPTIBLE);
1739 add_wait_queue (&cp->bufferwait, &wait);
1740
1741 /* Try to get a buffer from the device pool.
1742 We can't use a buffer from ccp->bufctl because the write
1743 command will last beond a release() */
1744 bp = NULL;
1745 spin_lock_irqsave (&cp->bufctl.lock, flags);
1746 if (!list_empty (&cp->bufctl.free_buff_list)) {
1747 /* yes: get the entry */
1748 struct list_head *tmp = cp->bufctl.free_buff_list.next;
1749 list_del (tmp);
1750 bp = list_entry (tmp, auerbuf_t, buff_list);
1751 }
1752 spin_unlock_irqrestore (&cp->bufctl.lock, flags);
1753
1754 /* are there any buffers left? */
1755 if (!bp) {
1756 mutex_unlock(&cp->mutex);
1757 mutex_unlock(&ccp->mutex);
1758
1759 /* NONBLOCK: don't wait */
1760 if (file->f_flags & O_NONBLOCK) {
1761 set_current_state (TASK_RUNNING);
1762 remove_wait_queue (&cp->bufferwait, &wait);
1763 return -EAGAIN;
1764 }
1765
1766 /* BLOCKING: wait */
1767 schedule();
1768 remove_wait_queue (&cp->bufferwait, &wait);
1769 if (signal_pending (current)) {
1770 /* waked up by a signal */
1771 return -ERESTARTSYS;
1772 }
1773 goto write_again;
1774 } else {
1775 set_current_state (TASK_RUNNING);
1776 remove_wait_queue (&cp->bufferwait, &wait);
1777 }
1778
1779 /* protect against too big write requests */
1780 if (len > cp->maxControlLength)
1781 len = cp->maxControlLength;
1782
1783 /* Fill the buffer */
1784 if (copy_from_user ( bp->bufp+AUH_SIZE, buf, len)) {
1785 dbg ("copy_from_user failed");
1786 auerbuf_releasebuf (bp);
1787 /* Wake up all processes waiting for a buffer */
1788 wake_up (&cp->bufferwait);
1789 mutex_unlock(&cp->mutex);
1790 mutex_unlock(&ccp->mutex);
1791 return -EFAULT;
1792 }
1793
1794 /* set the header byte */
1795 *(bp->bufp) = ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT;
1796
1797 /* Set the transfer Parameters */
1798 bp->len = len+AUH_SIZE;
1799 bp->dr->bRequestType = AUT_WREQ;
1800 bp->dr->bRequest = AUV_WBLOCK;
1801 bp->dr->wValue = cpu_to_le16 (0);
1802 bp->dr->wIndex = cpu_to_le16 (ccp->scontext.id | AUH_DIRECT | AUH_UNSPLIT);
1803 bp->dr->wLength = cpu_to_le16 (len+AUH_SIZE);
1804 usb_fill_control_urb (bp->urbp, cp->usbdev, usb_sndctrlpipe (cp->usbdev, 0),
1805 (unsigned char*)bp->dr, bp->bufp, len+AUH_SIZE,
1806 auerchar_ctrlwrite_complete, bp);
1807 /* up we go */
1808 ret = auerchain_submit_urb (&cp->controlchain, bp->urbp);
1809 mutex_unlock(&cp->mutex);
1810 if (ret) {
1811 dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret);
1812 auerbuf_releasebuf (bp);
1813 /* Wake up all processes waiting for a buffer */
1814 wake_up (&cp->bufferwait);
1815 mutex_unlock(&ccp->mutex);
1816 return -EIO;
1817 }
1818 else {
1819 dbg ("auerchar_write: Write OK");
1820 mutex_unlock(&ccp->mutex);
1821 return len;
1822 }
1823}
1824
1825
1826/* Close a character device */
1827static int auerchar_release (struct inode *inode, struct file *file)
1828{
1829 pauerchar_t ccp = (pauerchar_t) file->private_data;
1830 pauerswald_t cp;
1831 dbg("release");
1832
1833 mutex_lock(&ccp->mutex);
1834 cp = ccp->auerdev;
1835 if (cp) {
1836 mutex_lock(&cp->mutex);
1837 /* remove an open service */
1838 auerswald_removeservice (cp, &ccp->scontext);
1839 /* detach from device */
1840 if ((--cp->open_count <= 0) && (cp->usbdev == NULL)) {
1841 /* usb device waits for removal */
1842 mutex_unlock(&cp->mutex);
1843 auerswald_delete (cp);
1844 } else {
1845 mutex_unlock(&cp->mutex);
1846 }
1847 cp = NULL;
1848 ccp->auerdev = NULL;
1849 }
1850 mutex_unlock(&ccp->mutex);
1851 auerchar_delete (ccp);
1852
1853 return 0;
1854}
1855
1856
1857/*----------------------------------------------------------------------*/
1858/* File operation structure */
1859static const struct file_operations auerswald_fops =
1860{
1861 .owner = THIS_MODULE,
1862 .llseek = no_llseek,
1863 .read = auerchar_read,
1864 .write = auerchar_write,
1865 .unlocked_ioctl = auerchar_ioctl,
1866 .open = auerchar_open,
1867 .release = auerchar_release,
1868};
1869
1870static struct usb_class_driver auerswald_class = {
1871 .name = "auer%d",
1872 .fops = &auerswald_fops,
1873 .minor_base = AUER_MINOR_BASE,
1874};
1875
1876
1877/* --------------------------------------------------------------------- */
1878/* Special USB driver functions */
1879
1880/* Probe if this driver wants to serve an USB device
1881
1882 This entry point is called whenever a new device is attached to the bus.
1883 Then the device driver has to create a new instance of its internal data
1884 structures for the new device.
1885
1886 The dev argument specifies the device context, which contains pointers
1887 to all USB descriptors. The interface argument specifies the interface
1888 number. If a USB driver wants to bind itself to a particular device and
1889 interface it has to return a pointer. This pointer normally references
1890 the device driver's context structure.
1891
1892 Probing normally is done by checking the vendor and product identifications
1893 or the class and subclass definitions. If they match the interface number
1894 is compared with the ones supported by the driver. When probing is done
1895 class based it might be necessary to parse some more USB descriptors because
1896 the device properties can differ in a wide range.
1897*/
1898static int auerswald_probe (struct usb_interface *intf,
1899 const struct usb_device_id *id)
1900{
1901 struct usb_device *usbdev = interface_to_usbdev(intf);
1902 pauerswald_t cp = NULL;
1903 unsigned int u = 0;
1904 __le16 *pbuf;
1905 int ret;
1906
1907 dbg ("probe: vendor id 0x%x, device id 0x%x",
1908 le16_to_cpu(usbdev->descriptor.idVendor),
1909 le16_to_cpu(usbdev->descriptor.idProduct));
1910
1911 /* we use only the first -and only- interface */
1912 if (intf->altsetting->desc.bInterfaceNumber != 0)
1913 return -ENODEV;
1914
1915 /* allocate memory for our device and initialize it */
1916 cp = kzalloc (sizeof(auerswald_t), GFP_KERNEL);
1917 if (cp == NULL) {
1918 err ("out of memory");
1919 goto pfail;
1920 }
1921
1922 /* Initialize device descriptor */
1923 mutex_init(&cp->mutex);
1924 cp->usbdev = usbdev;
1925 auerchain_init (&cp->controlchain);
1926 auerbuf_init (&cp->bufctl);
1927 init_waitqueue_head (&cp->bufferwait);
1928
1929 ret = usb_register_dev(intf, &auerswald_class);
1930 if (ret) {
1931 err ("Not able to get a minor for this device.");
1932 goto pfail;
1933 }
1934
1935 /* Give the device a name */
1936 sprintf (cp->name, "usb/auer%d", intf->minor);
1937
1938 /* Store the index */
1939 cp->dtindex = intf->minor;
1940
1941 /* Get the usb version of the device */
1942 cp->version = le16_to_cpu(cp->usbdev->descriptor.bcdDevice);
1943 dbg ("Version is %X", cp->version);
1944
1945 /* allow some time to settle the device */
1946 msleep(334);
1947
1948 /* Try to get a suitable textual description of the device */
1949 /* Device name:*/
1950 ret = usb_string( cp->usbdev, AUSI_DEVICE, cp->dev_desc, AUSI_DLEN-1);
1951 if (ret >= 0) {
1952 u += ret;
1953 /* Append Serial Number */
1954 memcpy(&cp->dev_desc[u], ",Ser# ", 6);
1955 u += 6;
1956 ret = usb_string( cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u], AUSI_DLEN-u-1);
1957 if (ret >= 0) {
1958 u += ret;
1959 /* Append subscriber number */
1960 memcpy(&cp->dev_desc[u], ", ", 2);
1961 u += 2;
1962 ret = usb_string( cp->usbdev, AUSI_MSN, &cp->dev_desc[u], AUSI_DLEN-u-1);
1963 if (ret >= 0) {
1964 u += ret;
1965 }
1966 }
1967 }
1968 cp->dev_desc[u] = '\0';
1969 info("device is a %s", cp->dev_desc);
1970
1971 /* get the maximum allowed control transfer length */
1972 pbuf = kmalloc(2, GFP_KERNEL); /* use an allocated buffer because of urb target */
1973 if (!pbuf) {
1974 err( "out of memory");
1975 goto pfail;
1976 }
1977 ret = usb_control_msg(cp->usbdev, /* pointer to device */
1978 usb_rcvctrlpipe( cp->usbdev, 0 ), /* pipe to control endpoint */
1979 AUV_GETINFO, /* USB message request value */
1980 AUT_RREQ, /* USB message request type value */
1981 0, /* USB message value */
1982 AUDI_MBCTRANS, /* USB message index value */
1983 pbuf, /* pointer to the receive buffer */
1984 2, /* length of the buffer */
1985 2000); /* time to wait for the message to complete before timing out */
1986 if (ret == 2) {
1987 cp->maxControlLength = le16_to_cpup(pbuf);
1988 kfree(pbuf);
1989 dbg("setup: max. allowed control transfersize is %d bytes", cp->maxControlLength);
1990 } else {
1991 kfree(pbuf);
1992 err("setup: getting max. allowed control transfer length failed with error %d", ret);
1993 goto pfail;
1994 }
1995
1996 /* allocate a chain for the control messages */
1997 if (auerchain_setup (&cp->controlchain, AUCH_ELEMENTS)) {
1998 err ("out of memory");
1999 goto pfail;
2000 }
2001
2002 /* allocate buffers for control messages */
2003 if (auerbuf_setup (&cp->bufctl, AU_RBUFFERS, cp->maxControlLength+AUH_SIZE)) {
2004 err ("out of memory");
2005 goto pfail;
2006 }
2007
2008 /* start the interrupt endpoint */
2009 if (auerswald_int_open (cp)) {
2010 err ("int endpoint failed");
2011 goto pfail;
2012 }
2013
2014 /* all OK */
2015 usb_set_intfdata (intf, cp);
2016 return 0;
2017
2018 /* Error exit: clean up the memory */
2019pfail: auerswald_delete (cp);
2020 return -EIO;
2021}
2022
2023
2024/* Disconnect driver from a served device
2025
2026 This function is called whenever a device which was served by this driver
2027 is disconnected.
2028
2029 The argument dev specifies the device context and the driver_context
2030 returns a pointer to the previously registered driver_context of the
2031 probe function. After returning from the disconnect function the USB
2032 framework completely deallocates all data structures associated with
2033 this device. So especially the usb_device structure must not be used
2034 any longer by the usb driver.
2035*/
2036static void auerswald_disconnect (struct usb_interface *intf)
2037{
2038 pauerswald_t cp = usb_get_intfdata (intf);
2039 unsigned int u;
2040
2041 usb_set_intfdata (intf, NULL);
2042 if (!cp)
2043 return;
2044
2045 /* give back our USB minor number */
2046 usb_deregister_dev(intf, &auerswald_class);
2047
2048 mutex_lock(&cp->mutex);
2049 info ("device /dev/%s now disconnecting", cp->name);
2050
2051 /* Stop the interrupt endpoint */
2052 auerswald_int_release (cp);
2053
2054 /* remove the control chain allocated in auerswald_probe
2055 This has the benefit of
2056 a) all pending (a)synchronous urbs are unlinked
2057 b) all buffers dealing with urbs are reclaimed
2058 */
2059 auerchain_free (&cp->controlchain);
2060
2061 if (cp->open_count == 0) {
2062 /* nobody is using this device. So we can clean up now */
2063 mutex_unlock(&cp->mutex);
2064 /* mutex_unlock() is possible here because no other task
2065 can open the device (see above). I don't want
2066 to kfree() a locked mutex. */
2067
2068 auerswald_delete (cp);
2069 } else {
2070 /* device is used. Remove the pointer to the
2071 usb device (it's not valid any more). The last
2072 release() will do the clean up */
2073 cp->usbdev = NULL;
2074 mutex_unlock(&cp->mutex);
2075 /* Terminate waiting writers */
2076 wake_up (&cp->bufferwait);
2077 /* Inform all waiting readers */
2078 for ( u = 0; u < AUH_TYPESIZE; u++) {
2079 pauerscon_t scp = cp->services[u];
2080 if (scp)
2081 scp->disconnect( scp);
2082 }
2083 }
2084}
2085
2086/* Descriptor for the devices which are served by this driver.
2087 NOTE: this struct is parsed by the usbmanager install scripts.
2088 Don't change without caution!
2089*/
2090static struct usb_device_id auerswald_ids [] = {
2091 { USB_DEVICE (ID_AUERSWALD, 0x00C0) }, /* COMpact 2104 USB */
2092 { USB_DEVICE (ID_AUERSWALD, 0x00DB) }, /* COMpact 4410/2206 USB */
2093 { USB_DEVICE (ID_AUERSWALD, 0x00DC) }, /* COMpact 4406 DSL */
2094 { USB_DEVICE (ID_AUERSWALD, 0x00DD) }, /* COMpact 2204 USB */
2095 { USB_DEVICE (ID_AUERSWALD, 0x00F1) }, /* Comfort 2000 System Telephone */
2096 { USB_DEVICE (ID_AUERSWALD, 0x00F2) }, /* Comfort 1200 System Telephone */
2097 { } /* Terminating entry */
2098};
2099
2100/* Standard module device table */
2101MODULE_DEVICE_TABLE (usb, auerswald_ids);
2102
2103/* Standard usb driver struct */
2104static struct usb_driver auerswald_driver = {
2105 .name = "auerswald",
2106 .probe = auerswald_probe,
2107 .disconnect = auerswald_disconnect,
2108 .id_table = auerswald_ids,
2109};
2110
2111
2112/* --------------------------------------------------------------------- */
2113/* Module loading/unloading */
2114
2115/* Driver initialisation. Called after module loading.
2116 NOTE: there is no concurrency at _init
2117*/
2118static int __init auerswald_init (void)
2119{
2120 int result;
2121 dbg ("init");
2122
2123 /* register driver at the USB subsystem */
2124 result = usb_register (&auerswald_driver);
2125 if (result < 0) {
2126 err ("driver could not be registered");
2127 return -1;
2128 }
2129 return 0;
2130}
2131
2132/* Driver deinit. Called before module removal.
2133 NOTE: there is no concurrency at _cleanup
2134*/
2135static void __exit auerswald_cleanup (void)
2136{
2137 dbg ("cleanup");
2138 usb_deregister (&auerswald_driver);
2139}
2140
2141/* --------------------------------------------------------------------- */
2142/* Linux device driver module description */
2143
2144MODULE_AUTHOR (DRIVER_AUTHOR);
2145MODULE_DESCRIPTION (DRIVER_DESC);
2146MODULE_LICENSE ("GPL");
2147
2148module_init (auerswald_init);
2149module_exit (auerswald_cleanup);
2150
2151/* --------------------------------------------------------------------- */
2152
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c
index d94aa7387608..b897f6554ecd 100644
--- a/drivers/usb/misc/isight_firmware.c
+++ b/drivers/usb/misc/isight_firmware.c
@@ -48,7 +48,8 @@ static int isight_firmware_load(struct usb_interface *intf,
48 48
49 if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { 49 if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
50 printk(KERN_ERR "Unable to load isight firmware\n"); 50 printk(KERN_ERR "Unable to load isight firmware\n");
51 return -ENODEV; 51 ret = -ENODEV;
52 goto out;
52 } 53 }
53 54
54 ptr = firmware->data; 55 ptr = firmware->data;
@@ -91,7 +92,6 @@ static int isight_firmware_load(struct usb_interface *intf,
91 buf, llen, 300) != llen) { 92 buf, llen, 300) != llen) {
92 printk(KERN_ERR 93 printk(KERN_ERR
93 "Failed to load isight firmware\n"); 94 "Failed to load isight firmware\n");
94 kfree(buf);
95 ret = -ENODEV; 95 ret = -ENODEV;
96 goto out; 96 goto out;
97 } 97 }
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
new file mode 100644
index 000000000000..faca4333f27a
--- /dev/null
+++ b/drivers/usb/musb/Kconfig
@@ -0,0 +1,176 @@
1#
2# USB Dual Role (OTG-ready) Controller Drivers
3# for silicon based on Mentor Graphics INVENTRA designs
4#
5
6comment "Enable Host or Gadget support to see Inventra options"
7 depends on !USB && USB_GADGET=n
8
9# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
10config USB_MUSB_HDRC
11 depends on (USB || USB_GADGET) && HAVE_CLK
12 select TWL4030_USB if MACH_OMAP_3430SDP
13 tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
14 help
15 Say Y here if your system has a dual role high speed USB
16 controller based on the Mentor Graphics silicon IP. Then
17 configure options to match your silicon and the board
18 it's being used with, including the USB peripheral role,
19 or the USB host role, or both.
20
21 Texas Instruments parts using this IP include DaVinci 644x,
22 OMAP 243x, OMAP 343x, and TUSB 6010.
23
24 If you do not know what this is, please say N.
25
26 To compile this driver as a module, choose M here; the
27 module will be called "musb_hdrc".
28
29config USB_MUSB_SOC
30 boolean
31 depends on USB_MUSB_HDRC
32 default y if ARCH_DAVINCI
33 default y if ARCH_OMAP2430
34 default y if ARCH_OMAP34XX
35 help
36 Use a static <asm/arch/hdrc_cnf.h> file to describe how the
37 controller is configured (endpoints, mechanisms, etc) on the
38 current iteration of a given system-on-chip.
39
40comment "DaVinci 644x USB support"
41 depends on USB_MUSB_HDRC && ARCH_DAVINCI
42
43comment "OMAP 243x high speed USB support"
44 depends on USB_MUSB_HDRC && ARCH_OMAP2430
45
46comment "OMAP 343x high speed USB support"
47 depends on USB_MUSB_HDRC && ARCH_OMAP34XX
48
49config USB_TUSB6010
50 boolean "TUSB 6010 support"
51 depends on USB_MUSB_HDRC && !USB_MUSB_SOC
52 default y
53 help
54 The TUSB 6010 chip, from Texas Instruments, connects a discrete
55 HDRC core using a 16-bit parallel bus (NOR flash style) or VLYNQ
56 (a high speed serial link). It can use system-specific external
57 DMA controllers.
58
59choice
60 prompt "Driver Mode"
61 depends on USB_MUSB_HDRC
62 help
63 Dual-Role devices can support both host and peripheral roles,
64 as well as a the special "OTG Device" role which can switch
65 between both roles as needed.
66
67# use USB_MUSB_HDRC_HCD not USB_MUSB_HOST to #ifdef host side support;
68# OTG needs both roles, not just USB_MUSB_HOST.
69config USB_MUSB_HOST
70 depends on USB
71 bool "USB Host"
72 help
73 Say Y here if your system supports the USB host role.
74 If it has a USB "A" (rectangular), "Mini-A" (uncommon),
75 or "Mini-AB" connector, it supports the host role.
76 (With a "Mini-AB" connector, you should enable USB OTG.)
77
78# use USB_GADGET_MUSB_HDRC not USB_MUSB_PERIPHERAL to #ifdef peripheral
79# side support ... OTG needs both roles
80config USB_MUSB_PERIPHERAL
81 depends on USB_GADGET
82 bool "USB Peripheral (gadget stack)"
83 select USB_GADGET_MUSB_HDRC
84 help
85 Say Y here if your system supports the USB peripheral role.
86 If it has a USB "B" (squarish), "Mini-B", or "Mini-AB"
87 connector, it supports the peripheral role.
88 (With a "Mini-AB" connector, you should enable USB OTG.)
89
90config USB_MUSB_OTG
91 depends on USB && USB_GADGET && PM && EXPERIMENTAL
92 bool "Both host and peripheral: USB OTG (On The Go) Device"
93 select USB_GADGET_MUSB_HDRC
94 select USB_OTG
95 help
96 The most notable feature of USB OTG is support for a
97 "Dual-Role" device, which can act as either a device
98 or a host. The initial role choice can be changed
99 later, when two dual-role devices talk to each other.
100
101 At this writing, the OTG support in this driver is incomplete,
102 omitting the mandatory HNP or SRP protocols. However, some
103 of the cable based role switching works. (That is, grounding
104 the ID pin switches the controller to host mode, while leaving
105 it floating leaves it in peripheral mode.)
106
107 Select this if your system has a Mini-AB connector, or
108 to simplify certain kinds of configuration.
109
110 To implement your OTG Targeted Peripherals List (TPL), enable
111 USB_OTG_WHITELIST and update "drivers/usb/core/otg_whitelist.h"
112 to match your requirements.
113
114endchoice
115
116# enable peripheral support (including with OTG)
117config USB_GADGET_MUSB_HDRC
118 bool
119 depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
120# default y
121# select USB_GADGET_DUALSPEED
122# select USB_GADGET_SELECTED
123
124# enables host support (including with OTG)
125config USB_MUSB_HDRC_HCD
126 bool
127 depends on USB_MUSB_HDRC && (USB_MUSB_HOST || USB_MUSB_OTG)
128 select USB_OTG if USB_GADGET_MUSB_HDRC
129 default y
130
131
132config MUSB_PIO_ONLY
133 bool 'Disable DMA (always use PIO)'
134 depends on USB_MUSB_HDRC
135 default y if USB_TUSB6010
136 help
137 All data is copied between memory and FIFO by the CPU.
138 DMA controllers are ignored.
139
140 Do not select 'n' here unless DMA support for your SOC or board
141 is unavailable (or unstable). When DMA is enabled at compile time,
142 you can still disable it at run time using the "use_dma=n" module
143 parameter.
144
145config USB_INVENTRA_DMA
146 bool
147 depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
148 default ARCH_OMAP2430 || ARCH_OMAP34XX
149 help
150 Enable DMA transfers using Mentor's engine.
151
152config USB_TI_CPPI_DMA
153 bool
154 depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
155 default ARCH_DAVINCI
156 help
157 Enable DMA transfers when TI CPPI DMA is available.
158
159config USB_TUSB_OMAP_DMA
160 bool
161 depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
162 depends on USB_TUSB6010
163 depends on ARCH_OMAP
164 default y
165 help
166 Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
167
168config USB_MUSB_LOGLEVEL
169 depends on USB_MUSB_HDRC
170 int 'Logging Level (0 - none / 3 - annoying / ... )'
171 default 0
172 help
173 Set the logging level. 0 disables the debugging altogether,
174 although when USB_DEBUG is set the value is at least 1.
175 Starting at level 3, per-transfer (urb, usb_request, packet,
176 or dma transfer) tracing may kick in.
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
new file mode 100644
index 000000000000..88eb67de08ae
--- /dev/null
+++ b/drivers/usb/musb/Makefile
@@ -0,0 +1,86 @@
1#
2# for USB OTG silicon based on Mentor Graphics INVENTRA designs
3#
4
5musb_hdrc-objs := musb_core.o
6
7obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o
8
9ifeq ($(CONFIG_ARCH_DAVINCI),y)
10 musb_hdrc-objs += davinci.o
11endif
12
13ifeq ($(CONFIG_USB_TUSB6010),y)
14 musb_hdrc-objs += tusb6010.o
15endif
16
17ifeq ($(CONFIG_ARCH_OMAP2430),y)
18 musb_hdrc-objs += omap2430.o
19endif
20
21ifeq ($(CONFIG_ARCH_OMAP3430),y)
22 musb_hdrc-objs += omap2430.o
23endif
24
25ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y)
26 musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o
27endif
28
29ifeq ($(CONFIG_USB_MUSB_HDRC_HCD),y)
30 musb_hdrc-objs += musb_virthub.o musb_host.o
31endif
32
33# the kconfig must guarantee that only one of the
34# possible I/O schemes will be enabled at a time ...
35# PIO only, or DMA (several potential schemes).
36# though PIO is always there to back up DMA, and for ep0
37
38ifneq ($(CONFIG_MUSB_PIO_ONLY),y)
39
40 ifeq ($(CONFIG_USB_INVENTRA_DMA),y)
41 musb_hdrc-objs += musbhsdma.o
42
43 else
44 ifeq ($(CONFIG_USB_TI_CPPI_DMA),y)
45 musb_hdrc-objs += cppi_dma.o
46
47 else
48 ifeq ($(CONFIG_USB_TUSB_OMAP_DMA),y)
49 musb_hdrc-objs += tusb6010_omap.o
50
51 endif
52 endif
53 endif
54endif
55
56
57################################################################################
58
59# FIXME remove all these extra "-DMUSB_* things, stick to CONFIG_*
60
61ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y)
62 EXTRA_CFLAGS += -DMUSB_AHB_ID
63endif
64
65# Debugging
66
67MUSB_DEBUG:=$(CONFIG_USB_MUSB_LOGLEVEL)
68
69ifeq ("$(strip $(MUSB_DEBUG))","")
70 ifdef CONFIG_USB_DEBUG
71 MUSB_DEBUG:=1
72 else
73 MUSB_DEBUG:=0
74 endif
75endif
76
77ifneq ($(MUSB_DEBUG),0)
78 EXTRA_CFLAGS += -DDEBUG
79
80 ifeq ($(CONFIG_PROC_FS),y)
81 musb_hdrc-objs += musb_procfs.o
82 endif
83
84endif
85
86EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
new file mode 100644
index 000000000000..5ad6d0893cbe
--- /dev/null
+++ b/drivers/usb/musb/cppi_dma.c
@@ -0,0 +1,1540 @@
1/*
2 * Copyright (C) 2005-2006 by Texas Instruments
3 *
4 * This file implements a DMA interface using TI's CPPI DMA.
5 * For now it's DaVinci-only, but CPPI isn't specific to DaVinci or USB.
6 * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci.
7 */
8
9#include <linux/usb.h>
10
11#include "musb_core.h"
12#include "cppi_dma.h"
13
14
15/* CPPI DMA status 7-mar-2006:
16 *
17 * - See musb_{host,gadget}.c for more info
18 *
19 * - Correct RX DMA generally forces the engine into irq-per-packet mode,
20 * which can easily saturate the CPU under non-mass-storage loads.
21 *
22 * NOTES 24-aug-2006 (2.6.18-rc4):
23 *
24 * - peripheral RXDMA wedged in a test with packets of length 512/512/1.
25 * evidently after the 1 byte packet was received and acked, the queue
26 * of BDs got garbaged so it wouldn't empty the fifo. (rxcsr 0x2003,
27 * and RX DMA0: 4 left, 80000000 8feff880, 8feff860 8feff860; 8f321401
28 * 004001ff 00000001 .. 8feff860) Host was just getting NAKed on tx
29 * of its next (512 byte) packet. IRQ issues?
30 *
31 * REVISIT: the "transfer DMA" glue between CPPI and USB fifos will
32 * evidently also directly update the RX and TX CSRs ... so audit all
33 * host and peripheral side DMA code to avoid CSR access after DMA has
34 * been started.
35 */
36
37/* REVISIT now we can avoid preallocating these descriptors; or
38 * more simply, switch to a global freelist not per-channel ones.
39 * Note: at full speed, 64 descriptors == 4K bulk data.
40 */
41#define NUM_TXCHAN_BD 64
42#define NUM_RXCHAN_BD 64
43
44static inline void cpu_drain_writebuffer(void)
45{
46 wmb();
47#ifdef CONFIG_CPU_ARM926T
48 /* REVISIT this "should not be needed",
49 * but lack of it sure seemed to hurt ...
50 */
51 asm("mcr p15, 0, r0, c7, c10, 4 @ drain write buffer\n");
52#endif
53}
54
55static inline struct cppi_descriptor *cppi_bd_alloc(struct cppi_channel *c)
56{
57 struct cppi_descriptor *bd = c->freelist;
58
59 if (bd)
60 c->freelist = bd->next;
61 return bd;
62}
63
64static inline void
65cppi_bd_free(struct cppi_channel *c, struct cppi_descriptor *bd)
66{
67 if (!bd)
68 return;
69 bd->next = c->freelist;
70 c->freelist = bd;
71}
72
73/*
74 * Start DMA controller
75 *
76 * Initialize the DMA controller as necessary.
77 */
78
79/* zero out entire rx state RAM entry for the channel */
80static void cppi_reset_rx(struct cppi_rx_stateram __iomem *rx)
81{
82 musb_writel(&rx->rx_skipbytes, 0, 0);
83 musb_writel(&rx->rx_head, 0, 0);
84 musb_writel(&rx->rx_sop, 0, 0);
85 musb_writel(&rx->rx_current, 0, 0);
86 musb_writel(&rx->rx_buf_current, 0, 0);
87 musb_writel(&rx->rx_len_len, 0, 0);
88 musb_writel(&rx->rx_cnt_cnt, 0, 0);
89}
90
91/* zero out entire tx state RAM entry for the channel */
92static void cppi_reset_tx(struct cppi_tx_stateram __iomem *tx, u32 ptr)
93{
94 musb_writel(&tx->tx_head, 0, 0);
95 musb_writel(&tx->tx_buf, 0, 0);
96 musb_writel(&tx->tx_current, 0, 0);
97 musb_writel(&tx->tx_buf_current, 0, 0);
98 musb_writel(&tx->tx_info, 0, 0);
99 musb_writel(&tx->tx_rem_len, 0, 0);
100 /* musb_writel(&tx->tx_dummy, 0, 0); */
101 musb_writel(&tx->tx_complete, 0, ptr);
102}
103
104static void __init cppi_pool_init(struct cppi *cppi, struct cppi_channel *c)
105{
106 int j;
107
108 /* initialize channel fields */
109 c->head = NULL;
110 c->tail = NULL;
111 c->last_processed = NULL;
112 c->channel.status = MUSB_DMA_STATUS_UNKNOWN;
113 c->controller = cppi;
114 c->is_rndis = 0;
115 c->freelist = NULL;
116
117 /* build the BD Free list for the channel */
118 for (j = 0; j < NUM_TXCHAN_BD + 1; j++) {
119 struct cppi_descriptor *bd;
120 dma_addr_t dma;
121
122 bd = dma_pool_alloc(cppi->pool, GFP_KERNEL, &dma);
123 bd->dma = dma;
124 cppi_bd_free(c, bd);
125 }
126}
127
128static int cppi_channel_abort(struct dma_channel *);
129
130static void cppi_pool_free(struct cppi_channel *c)
131{
132 struct cppi *cppi = c->controller;
133 struct cppi_descriptor *bd;
134
135 (void) cppi_channel_abort(&c->channel);
136 c->channel.status = MUSB_DMA_STATUS_UNKNOWN;
137 c->controller = NULL;
138
139 /* free all its bds */
140 bd = c->last_processed;
141 do {
142 if (bd)
143 dma_pool_free(cppi->pool, bd, bd->dma);
144 bd = cppi_bd_alloc(c);
145 } while (bd);
146 c->last_processed = NULL;
147}
148
149static int __init cppi_controller_start(struct dma_controller *c)
150{
151 struct cppi *controller;
152 void __iomem *tibase;
153 int i;
154
155 controller = container_of(c, struct cppi, controller);
156
157 /* do whatever is necessary to start controller */
158 for (i = 0; i < ARRAY_SIZE(controller->tx); i++) {
159 controller->tx[i].transmit = true;
160 controller->tx[i].index = i;
161 }
162 for (i = 0; i < ARRAY_SIZE(controller->rx); i++) {
163 controller->rx[i].transmit = false;
164 controller->rx[i].index = i;
165 }
166
167 /* setup BD list on a per channel basis */
168 for (i = 0; i < ARRAY_SIZE(controller->tx); i++)
169 cppi_pool_init(controller, controller->tx + i);
170 for (i = 0; i < ARRAY_SIZE(controller->rx); i++)
171 cppi_pool_init(controller, controller->rx + i);
172
173 tibase = controller->tibase;
174 INIT_LIST_HEAD(&controller->tx_complete);
175
176 /* initialise tx/rx channel head pointers to zero */
177 for (i = 0; i < ARRAY_SIZE(controller->tx); i++) {
178 struct cppi_channel *tx_ch = controller->tx + i;
179 struct cppi_tx_stateram __iomem *tx;
180
181 INIT_LIST_HEAD(&tx_ch->tx_complete);
182
183 tx = tibase + DAVINCI_TXCPPI_STATERAM_OFFSET(i);
184 tx_ch->state_ram = tx;
185 cppi_reset_tx(tx, 0);
186 }
187 for (i = 0; i < ARRAY_SIZE(controller->rx); i++) {
188 struct cppi_channel *rx_ch = controller->rx + i;
189 struct cppi_rx_stateram __iomem *rx;
190
191 INIT_LIST_HEAD(&rx_ch->tx_complete);
192
193 rx = tibase + DAVINCI_RXCPPI_STATERAM_OFFSET(i);
194 rx_ch->state_ram = rx;
195 cppi_reset_rx(rx);
196 }
197
198 /* enable individual cppi channels */
199 musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
200 DAVINCI_DMA_ALL_CHANNELS_ENABLE);
201 musb_writel(tibase, DAVINCI_RXCPPI_INTENAB_REG,
202 DAVINCI_DMA_ALL_CHANNELS_ENABLE);
203
204 /* enable tx/rx CPPI control */
205 musb_writel(tibase, DAVINCI_TXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_ENABLE);
206 musb_writel(tibase, DAVINCI_RXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_ENABLE);
207
208 /* disable RNDIS mode, also host rx RNDIS autorequest */
209 musb_writel(tibase, DAVINCI_RNDIS_REG, 0);
210 musb_writel(tibase, DAVINCI_AUTOREQ_REG, 0);
211
212 return 0;
213}
214
215/*
216 * Stop DMA controller
217 *
218 * De-Init the DMA controller as necessary.
219 */
220
221static int cppi_controller_stop(struct dma_controller *c)
222{
223 struct cppi *controller;
224 void __iomem *tibase;
225 int i;
226
227 controller = container_of(c, struct cppi, controller);
228
229 tibase = controller->tibase;
230 /* DISABLE INDIVIDUAL CHANNEL Interrupts */
231 musb_writel(tibase, DAVINCI_TXCPPI_INTCLR_REG,
232 DAVINCI_DMA_ALL_CHANNELS_ENABLE);
233 musb_writel(tibase, DAVINCI_RXCPPI_INTCLR_REG,
234 DAVINCI_DMA_ALL_CHANNELS_ENABLE);
235
236 DBG(1, "Tearing down RX and TX Channels\n");
237 for (i = 0; i < ARRAY_SIZE(controller->tx); i++) {
238 /* FIXME restructure of txdma to use bds like rxdma */
239 controller->tx[i].last_processed = NULL;
240 cppi_pool_free(controller->tx + i);
241 }
242 for (i = 0; i < ARRAY_SIZE(controller->rx); i++)
243 cppi_pool_free(controller->rx + i);
244
245 /* in Tx Case proper teardown is supported. We resort to disabling
246 * Tx/Rx CPPI after cleanup of Tx channels. Before TX teardown is
247 * complete TX CPPI cannot be disabled.
248 */
249 /*disable tx/rx cppi */
250 musb_writel(tibase, DAVINCI_TXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE);
251 musb_writel(tibase, DAVINCI_RXCPPI_CTRL_REG, DAVINCI_DMA_CTRL_DISABLE);
252
253 return 0;
254}
255
256/* While dma channel is allocated, we only want the core irqs active
257 * for fault reports, otherwise we'd get irqs that we don't care about.
258 * Except for TX irqs, where dma done != fifo empty and reusable ...
259 *
260 * NOTE: docs don't say either way, but irq masking **enables** irqs.
261 *
262 * REVISIT same issue applies to pure PIO usage too, and non-cppi dma...
263 */
264static inline void core_rxirq_disable(void __iomem *tibase, unsigned epnum)
265{
266 musb_writel(tibase, DAVINCI_USB_INT_MASK_CLR_REG, 1 << (epnum + 8));
267}
268
269static inline void core_rxirq_enable(void __iomem *tibase, unsigned epnum)
270{
271 musb_writel(tibase, DAVINCI_USB_INT_MASK_SET_REG, 1 << (epnum + 8));
272}
273
274
275/*
276 * Allocate a CPPI Channel for DMA. With CPPI, channels are bound to
277 * each transfer direction of a non-control endpoint, so allocating
278 * (and deallocating) is mostly a way to notice bad housekeeping on
279 * the software side. We assume the irqs are always active.
280 */
281static struct dma_channel *
282cppi_channel_allocate(struct dma_controller *c,
283 struct musb_hw_ep *ep, u8 transmit)
284{
285 struct cppi *controller;
286 u8 index;
287 struct cppi_channel *cppi_ch;
288 void __iomem *tibase;
289
290 controller = container_of(c, struct cppi, controller);
291 tibase = controller->tibase;
292
293 /* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */
294 index = ep->epnum - 1;
295
296 /* return the corresponding CPPI Channel Handle, and
297 * probably disable the non-CPPI irq until we need it.
298 */
299 if (transmit) {
300 if (index >= ARRAY_SIZE(controller->tx)) {
301 DBG(1, "no %cX%d CPPI channel\n", 'T', index);
302 return NULL;
303 }
304 cppi_ch = controller->tx + index;
305 } else {
306 if (index >= ARRAY_SIZE(controller->rx)) {
307 DBG(1, "no %cX%d CPPI channel\n", 'R', index);
308 return NULL;
309 }
310 cppi_ch = controller->rx + index;
311 core_rxirq_disable(tibase, ep->epnum);
312 }
313
314 /* REVISIT make this an error later once the same driver code works
315 * with the other DMA engine too
316 */
317 if (cppi_ch->hw_ep)
318 DBG(1, "re-allocating DMA%d %cX channel %p\n",
319 index, transmit ? 'T' : 'R', cppi_ch);
320 cppi_ch->hw_ep = ep;
321 cppi_ch->channel.status = MUSB_DMA_STATUS_FREE;
322
323 DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R');
324 return &cppi_ch->channel;
325}
326
327/* Release a CPPI Channel. */
328static void cppi_channel_release(struct dma_channel *channel)
329{
330 struct cppi_channel *c;
331 void __iomem *tibase;
332
333 /* REVISIT: for paranoia, check state and abort if needed... */
334
335 c = container_of(channel, struct cppi_channel, channel);
336 tibase = c->controller->tibase;
337 if (!c->hw_ep)
338 DBG(1, "releasing idle DMA channel %p\n", c);
339 else if (!c->transmit)
340 core_rxirq_enable(tibase, c->index + 1);
341
342 /* for now, leave its cppi IRQ enabled (we won't trigger it) */
343 c->hw_ep = NULL;
344 channel->status = MUSB_DMA_STATUS_UNKNOWN;
345}
346
347/* Context: controller irqlocked */
348static void
349cppi_dump_rx(int level, struct cppi_channel *c, const char *tag)
350{
351 void __iomem *base = c->controller->mregs;
352 struct cppi_rx_stateram __iomem *rx = c->state_ram;
353
354 musb_ep_select(base, c->index + 1);
355
356 DBG(level, "RX DMA%d%s: %d left, csr %04x, "
357 "%08x H%08x S%08x C%08x, "
358 "B%08x L%08x %08x .. %08x"
359 "\n",
360 c->index, tag,
361 musb_readl(c->controller->tibase,
362 DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index),
363 musb_readw(c->hw_ep->regs, MUSB_RXCSR),
364
365 musb_readl(&rx->rx_skipbytes, 0),
366 musb_readl(&rx->rx_head, 0),
367 musb_readl(&rx->rx_sop, 0),
368 musb_readl(&rx->rx_current, 0),
369
370 musb_readl(&rx->rx_buf_current, 0),
371 musb_readl(&rx->rx_len_len, 0),
372 musb_readl(&rx->rx_cnt_cnt, 0),
373 musb_readl(&rx->rx_complete, 0)
374 );
375}
376
377/* Context: controller irqlocked */
378static void
379cppi_dump_tx(int level, struct cppi_channel *c, const char *tag)
380{
381 void __iomem *base = c->controller->mregs;
382 struct cppi_tx_stateram __iomem *tx = c->state_ram;
383
384 musb_ep_select(base, c->index + 1);
385
386 DBG(level, "TX DMA%d%s: csr %04x, "
387 "H%08x S%08x C%08x %08x, "
388 "F%08x L%08x .. %08x"
389 "\n",
390 c->index, tag,
391 musb_readw(c->hw_ep->regs, MUSB_TXCSR),
392
393 musb_readl(&tx->tx_head, 0),
394 musb_readl(&tx->tx_buf, 0),
395 musb_readl(&tx->tx_current, 0),
396 musb_readl(&tx->tx_buf_current, 0),
397
398 musb_readl(&tx->tx_info, 0),
399 musb_readl(&tx->tx_rem_len, 0),
400 /* dummy/unused word 6 */
401 musb_readl(&tx->tx_complete, 0)
402 );
403}
404
405/* Context: controller irqlocked */
406static inline void
407cppi_rndis_update(struct cppi_channel *c, int is_rx,
408 void __iomem *tibase, int is_rndis)
409{
410 /* we may need to change the rndis flag for this cppi channel */
411 if (c->is_rndis != is_rndis) {
412 u32 value = musb_readl(tibase, DAVINCI_RNDIS_REG);
413 u32 temp = 1 << (c->index);
414
415 if (is_rx)
416 temp <<= 16;
417 if (is_rndis)
418 value |= temp;
419 else
420 value &= ~temp;
421 musb_writel(tibase, DAVINCI_RNDIS_REG, value);
422 c->is_rndis = is_rndis;
423 }
424}
425
426static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd)
427{
428 pr_debug("RXBD/%s %08x: "
429 "nxt %08x buf %08x off.blen %08x opt.plen %08x\n",
430 tag, bd->dma,
431 bd->hw_next, bd->hw_bufp, bd->hw_off_len,
432 bd->hw_options);
433}
434
435static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx)
436{
437#if MUSB_DEBUG > 0
438 struct cppi_descriptor *bd;
439
440 if (!_dbg_level(level))
441 return;
442 cppi_dump_rx(level, rx, tag);
443 if (rx->last_processed)
444 cppi_dump_rxbd("last", rx->last_processed);
445 for (bd = rx->head; bd; bd = bd->next)
446 cppi_dump_rxbd("active", bd);
447#endif
448}
449
450
451/* NOTE: DaVinci autoreq is ignored except for host side "RNDIS" mode RX;
452 * so we won't ever use it (see "CPPI RX Woes" below).
453 */
454static inline int cppi_autoreq_update(struct cppi_channel *rx,
455 void __iomem *tibase, int onepacket, unsigned n_bds)
456{
457 u32 val;
458
459#ifdef RNDIS_RX_IS_USABLE
460 u32 tmp;
461 /* assert(is_host_active(musb)) */
462
463 /* start from "AutoReq never" */
464 tmp = musb_readl(tibase, DAVINCI_AUTOREQ_REG);
465 val = tmp & ~((0x3) << (rx->index * 2));
466
467 /* HCD arranged reqpkt for packet #1. we arrange int
468 * for all but the last one, maybe in two segments.
469 */
470 if (!onepacket) {
471#if 0
472 /* use two segments, autoreq "all" then the last "never" */
473 val |= ((0x3) << (rx->index * 2));
474 n_bds--;
475#else
476 /* one segment, autoreq "all-but-last" */
477 val |= ((0x1) << (rx->index * 2));
478#endif
479 }
480
481 if (val != tmp) {
482 int n = 100;
483
484 /* make sure that autoreq is updated before continuing */
485 musb_writel(tibase, DAVINCI_AUTOREQ_REG, val);
486 do {
487 tmp = musb_readl(tibase, DAVINCI_AUTOREQ_REG);
488 if (tmp == val)
489 break;
490 cpu_relax();
491 } while (n-- > 0);
492 }
493#endif
494
495 /* REQPKT is turned off after each segment */
496 if (n_bds && rx->channel.actual_len) {
497 void __iomem *regs = rx->hw_ep->regs;
498
499 val = musb_readw(regs, MUSB_RXCSR);
500 if (!(val & MUSB_RXCSR_H_REQPKT)) {
501 val |= MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_H_WZC_BITS;
502 musb_writew(regs, MUSB_RXCSR, val);
503 /* flush writebufer */
504 val = musb_readw(regs, MUSB_RXCSR);
505 }
506 }
507 return n_bds;
508}
509
510
511/* Buffer enqueuing Logic:
512 *
513 * - RX builds new queues each time, to help handle routine "early
514 * termination" cases (faults, including errors and short reads)
515 * more correctly.
516 *
517 * - for now, TX reuses the same queue of BDs every time
518 *
519 * REVISIT long term, we want a normal dynamic model.
520 * ... the goal will be to append to the
521 * existing queue, processing completed "dma buffers" (segments) on the fly.
522 *
523 * Otherwise we force an IRQ latency between requests, which slows us a lot
524 * (especially in "transparent" dma). Unfortunately that model seems to be
525 * inherent in the DMA model from the Mentor code, except in the rare case
526 * of transfers big enough (~128+ KB) that we could append "middle" segments
527 * in the TX paths. (RX can't do this, see below.)
528 *
529 * That's true even in the CPPI- friendly iso case, where most urbs have
530 * several small segments provided in a group and where the "packet at a time"
531 * "transparent" DMA model is always correct, even on the RX side.
532 */
533
534/*
535 * CPPI TX:
536 * ========
537 * TX is a lot more reasonable than RX; it doesn't need to run in
538 * irq-per-packet mode very often. RNDIS mode seems to behave too
539 * (except how it handles the exactly-N-packets case). Building a
540 * txdma queue with multiple requests (urb or usb_request) looks
541 * like it would work ... but fault handling would need much testing.
542 *
543 * The main issue with TX mode RNDIS relates to transfer lengths that
544 * are an exact multiple of the packet length. It appears that there's
545 * a hiccup in that case (maybe the DMA completes before the ZLP gets
546 * written?) boiling down to not being able to rely on CPPI writing any
547 * terminating zero length packet before the next transfer is written.
548 * So that's punted to PIO; better yet, gadget drivers can avoid it.
549 *
550 * Plus, there's allegedly an undocumented constraint that rndis transfer
551 * length be a multiple of 64 bytes ... but the chip doesn't act that
552 * way, and we really don't _want_ that behavior anyway.
553 *
554 * On TX, "transparent" mode works ... although experiments have shown
555 * problems trying to use the SOP/EOP bits in different USB packets.
556 *
557 * REVISIT try to handle terminating zero length packets using CPPI
558 * instead of doing it by PIO after an IRQ. (Meanwhile, make Ethernet
559 * links avoid that issue by forcing them to avoid zlps.)
560 */
561static void
562cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)
563{
564 unsigned maxpacket = tx->maxpacket;
565 dma_addr_t addr = tx->buf_dma + tx->offset;
566 size_t length = tx->buf_len - tx->offset;
567 struct cppi_descriptor *bd;
568 unsigned n_bds;
569 unsigned i;
570 struct cppi_tx_stateram __iomem *tx_ram = tx->state_ram;
571 int rndis;
572
573 /* TX can use the CPPI "rndis" mode, where we can probably fit this
574 * transfer in one BD and one IRQ. The only time we would NOT want
575 * to use it is when hardware constraints prevent it, or if we'd
576 * trigger the "send a ZLP?" confusion.
577 */
578 rndis = (maxpacket & 0x3f) == 0
579 && length < 0xffff
580 && (length % maxpacket) != 0;
581
582 if (rndis) {
583 maxpacket = length;
584 n_bds = 1;
585 } else {
586 n_bds = length / maxpacket;
587 if (!length || (length % maxpacket))
588 n_bds++;
589 n_bds = min(n_bds, (unsigned) NUM_TXCHAN_BD);
590 length = min(n_bds * maxpacket, length);
591 }
592
593 DBG(4, "TX DMA%d, pktSz %d %s bds %d dma 0x%x len %u\n",
594 tx->index,
595 maxpacket,
596 rndis ? "rndis" : "transparent",
597 n_bds,
598 addr, length);
599
600 cppi_rndis_update(tx, 0, musb->ctrl_base, rndis);
601
602 /* assuming here that channel_program is called during
603 * transfer initiation ... current code maintains state
604 * for one outstanding request only (no queues, not even
605 * the implicit ones of an iso urb).
606 */
607
608 bd = tx->freelist;
609 tx->head = bd;
610 tx->last_processed = NULL;
611
612 /* FIXME use BD pool like RX side does, and just queue
613 * the minimum number for this request.
614 */
615
616 /* Prepare queue of BDs first, then hand it to hardware.
617 * All BDs except maybe the last should be of full packet
618 * size; for RNDIS there _is_ only that last packet.
619 */
620 for (i = 0; i < n_bds; ) {
621 if (++i < n_bds && bd->next)
622 bd->hw_next = bd->next->dma;
623 else
624 bd->hw_next = 0;
625
626 bd->hw_bufp = tx->buf_dma + tx->offset;
627
628 /* FIXME set EOP only on the last packet,
629 * SOP only on the first ... avoid IRQs
630 */
631 if ((tx->offset + maxpacket) <= tx->buf_len) {
632 tx->offset += maxpacket;
633 bd->hw_off_len = maxpacket;
634 bd->hw_options = CPPI_SOP_SET | CPPI_EOP_SET
635 | CPPI_OWN_SET | maxpacket;
636 } else {
637 /* only this one may be a partial USB Packet */
638 u32 partial_len;
639
640 partial_len = tx->buf_len - tx->offset;
641 tx->offset = tx->buf_len;
642 bd->hw_off_len = partial_len;
643
644 bd->hw_options = CPPI_SOP_SET | CPPI_EOP_SET
645 | CPPI_OWN_SET | partial_len;
646 if (partial_len == 0)
647 bd->hw_options |= CPPI_ZERO_SET;
648 }
649
650 DBG(5, "TXBD %p: nxt %08x buf %08x len %04x opt %08x\n",
651 bd, bd->hw_next, bd->hw_bufp,
652 bd->hw_off_len, bd->hw_options);
653
654 /* update the last BD enqueued to the list */
655 tx->tail = bd;
656 bd = bd->next;
657 }
658
659 /* BDs live in DMA-coherent memory, but writes might be pending */
660 cpu_drain_writebuffer();
661
662 /* Write to the HeadPtr in state RAM to trigger */
663 musb_writel(&tx_ram->tx_head, 0, (u32)tx->freelist->dma);
664
665 cppi_dump_tx(5, tx, "/S");
666}
667
668/*
669 * CPPI RX Woes:
670 * =============
671 * Consider a 1KB bulk RX buffer in two scenarios: (a) it's fed two 300 byte
672 * packets back-to-back, and (b) it's fed two 512 byte packets back-to-back.
673 * (Full speed transfers have similar scenarios.)
674 *
675 * The correct behavior for Linux is that (a) fills the buffer with 300 bytes,
676 * and the next packet goes into a buffer that's queued later; while (b) fills
677 * the buffer with 1024 bytes. How to do that with CPPI?
678 *
679 * - RX queues in "rndis" mode -- one single BD -- handle (a) correctly, but
680 * (b) loses **BADLY** because nothing (!) happens when that second packet
681 * fills the buffer, much less when a third one arrives. (Which makes this
682 * not a "true" RNDIS mode. In the RNDIS protocol short-packet termination
683 * is optional, and it's fine if peripherals -- not hosts! -- pad messages
684 * out to end-of-buffer. Standard PCI host controller DMA descriptors
685 * implement that mode by default ... which is no accident.)
686 *
687 * - RX queues in "transparent" mode -- two BDs with 512 bytes each -- have
688 * converse problems: (b) is handled right, but (a) loses badly. CPPI RX
689 * ignores SOP/EOP markings and processes both of those BDs; so both packets
690 * are loaded into the buffer (with a 212 byte gap between them), and the next
691 * buffer queued will NOT get its 300 bytes of data. (It seems like SOP/EOP
692 * are intended as outputs for RX queues, not inputs...)
693 *
694 * - A variant of "transparent" mode -- one BD at a time -- is the only way to
695 * reliably make both cases work, with software handling both cases correctly
696 * and at the significant penalty of needing an IRQ per packet. (The lack of
697 * I/O overlap can be slightly ameliorated by enabling double buffering.)
698 *
699 * So how to get rid of IRQ-per-packet? The transparent multi-BD case could
700 * be used in special cases like mass storage, which sets URB_SHORT_NOT_OK
701 * (or maybe its peripheral side counterpart) to flag (a) scenarios as errors
702 * with guaranteed driver level fault recovery and scrubbing out what's left
703 * of that garbaged datastream.
704 *
705 * But there seems to be no way to identify the cases where CPPI RNDIS mode
706 * is appropriate -- which do NOT include RNDIS host drivers, but do include
707 * the CDC Ethernet driver! -- and the documentation is incomplete/wrong.
708 * So we can't _ever_ use RX RNDIS mode ... except by using a heuristic
709 * that applies best on the peripheral side (and which could fail rudely).
710 *
711 * Leaving only "transparent" mode; we avoid multi-bd modes in almost all
712 * cases other than mass storage class. Otherwise we're correct but slow,
713 * since CPPI penalizes our need for a "true RNDIS" default mode.
714 */
715
716
717/* Heuristic, intended to kick in for ethernet/rndis peripheral ONLY
718 *
719 * IFF
720 * (a) peripheral mode ... since rndis peripherals could pad their
721 * writes to hosts, causing i/o failure; or we'd have to cope with
722 * a largely unknowable variety of host side protocol variants
723 * (b) and short reads are NOT errors ... since full reads would
724 * cause those same i/o failures
725 * (c) and read length is
726 * - less than 64KB (max per cppi descriptor)
727 * - not a multiple of 4096 (g_zero default, full reads typical)
728 * - N (>1) packets long, ditto (full reads not EXPECTED)
729 * THEN
730 * try rx rndis mode
731 *
732 * Cost of heuristic failing: RXDMA wedges at the end of transfers that
733 * fill out the whole buffer. Buggy host side usb network drivers could
734 * trigger that, but "in the field" such bugs seem to be all but unknown.
735 *
736 * So this module parameter lets the heuristic be disabled. When using
737 * gadgetfs, the heuristic will probably need to be disabled.
738 */
739static int cppi_rx_rndis = 1;
740
741module_param(cppi_rx_rndis, bool, 0);
742MODULE_PARM_DESC(cppi_rx_rndis, "enable/disable RX RNDIS heuristic");
743
744
745/**
746 * cppi_next_rx_segment - dma read for the next chunk of a buffer
747 * @musb: the controller
748 * @rx: dma channel
749 * @onepacket: true unless caller treats short reads as errors, and
750 * performs fault recovery above usbcore.
751 * Context: controller irqlocked
752 *
753 * See above notes about why we can't use multi-BD RX queues except in
754 * rare cases (mass storage class), and can never use the hardware "rndis"
755 * mode (since it's not a "true" RNDIS mode) with complete safety..
756 *
757 * It's ESSENTIAL that callers specify "onepacket" mode unless they kick in
758 * code to recover from corrupted datastreams after each short transfer.
759 */
760static void
761cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket)
762{
763 unsigned maxpacket = rx->maxpacket;
764 dma_addr_t addr = rx->buf_dma + rx->offset;
765 size_t length = rx->buf_len - rx->offset;
766 struct cppi_descriptor *bd, *tail;
767 unsigned n_bds;
768 unsigned i;
769 void __iomem *tibase = musb->ctrl_base;
770 int is_rndis = 0;
771 struct cppi_rx_stateram __iomem *rx_ram = rx->state_ram;
772
773 if (onepacket) {
774 /* almost every USB driver, host or peripheral side */
775 n_bds = 1;
776
777 /* maybe apply the heuristic above */
778 if (cppi_rx_rndis
779 && is_peripheral_active(musb)
780 && length > maxpacket
781 && (length & ~0xffff) == 0
782 && (length & 0x0fff) != 0
783 && (length & (maxpacket - 1)) == 0) {
784 maxpacket = length;
785 is_rndis = 1;
786 }
787 } else {
788 /* virtually nothing except mass storage class */
789 if (length > 0xffff) {
790 n_bds = 0xffff / maxpacket;
791 length = n_bds * maxpacket;
792 } else {
793 n_bds = length / maxpacket;
794 if (length % maxpacket)
795 n_bds++;
796 }
797 if (n_bds == 1)
798 onepacket = 1;
799 else
800 n_bds = min(n_bds, (unsigned) NUM_RXCHAN_BD);
801 }
802
803 /* In host mode, autorequest logic can generate some IN tokens; it's
804 * tricky since we can't leave REQPKT set in RXCSR after the transfer
805 * finishes. So: multipacket transfers involve two or more segments.
806 * And always at least two IRQs ... RNDIS mode is not an option.
807 */
808 if (is_host_active(musb))
809 n_bds = cppi_autoreq_update(rx, tibase, onepacket, n_bds);
810
811 cppi_rndis_update(rx, 1, musb->ctrl_base, is_rndis);
812
813 length = min(n_bds * maxpacket, length);
814
815 DBG(4, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) "
816 "dma 0x%x len %u %u/%u\n",
817 rx->index, maxpacket,
818 onepacket
819 ? (is_rndis ? "rndis" : "onepacket")
820 : "multipacket",
821 n_bds,
822 musb_readl(tibase,
823 DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4))
824 & 0xffff,
825 addr, length, rx->channel.actual_len, rx->buf_len);
826
827 /* only queue one segment at a time, since the hardware prevents
828 * correct queue shutdown after unexpected short packets
829 */
830 bd = cppi_bd_alloc(rx);
831 rx->head = bd;
832
833 /* Build BDs for all packets in this segment */
834 for (i = 0, tail = NULL; bd && i < n_bds; i++, tail = bd) {
835 u32 bd_len;
836
837 if (i) {
838 bd = cppi_bd_alloc(rx);
839 if (!bd)
840 break;
841 tail->next = bd;
842 tail->hw_next = bd->dma;
843 }
844 bd->hw_next = 0;
845
846 /* all but the last packet will be maxpacket size */
847 if (maxpacket < length)
848 bd_len = maxpacket;
849 else
850 bd_len = length;
851
852 bd->hw_bufp = addr;
853 addr += bd_len;
854 rx->offset += bd_len;
855
856 bd->hw_off_len = (0 /*offset*/ << 16) + bd_len;
857 bd->buflen = bd_len;
858
859 bd->hw_options = CPPI_OWN_SET | (i == 0 ? length : 0);
860 length -= bd_len;
861 }
862
863 /* we always expect at least one reusable BD! */
864 if (!tail) {
865 WARNING("rx dma%d -- no BDs? need %d\n", rx->index, n_bds);
866 return;
867 } else if (i < n_bds)
868 WARNING("rx dma%d -- only %d of %d BDs\n", rx->index, i, n_bds);
869
870 tail->next = NULL;
871 tail->hw_next = 0;
872
873 bd = rx->head;
874 rx->tail = tail;
875
876 /* short reads and other faults should terminate this entire
877 * dma segment. we want one "dma packet" per dma segment, not
878 * one per USB packet, terminating the whole queue at once...
879 * NOTE that current hardware seems to ignore SOP and EOP.
880 */
881 bd->hw_options |= CPPI_SOP_SET;
882 tail->hw_options |= CPPI_EOP_SET;
883
884 if (debug >= 5) {
885 struct cppi_descriptor *d;
886
887 for (d = rx->head; d; d = d->next)
888 cppi_dump_rxbd("S", d);
889 }
890
891 /* in case the preceding transfer left some state... */
892 tail = rx->last_processed;
893 if (tail) {
894 tail->next = bd;
895 tail->hw_next = bd->dma;
896 }
897
898 core_rxirq_enable(tibase, rx->index + 1);
899
900 /* BDs live in DMA-coherent memory, but writes might be pending */
901 cpu_drain_writebuffer();
902
903 /* REVISIT specs say to write this AFTER the BUFCNT register
904 * below ... but that loses badly.
905 */
906 musb_writel(&rx_ram->rx_head, 0, bd->dma);
907
908 /* bufferCount must be at least 3, and zeroes on completion
909 * unless it underflows below zero, or stops at two, or keeps
910 * growing ... grr.
911 */
912 i = musb_readl(tibase,
913 DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4))
914 & 0xffff;
915
916 if (!i)
917 musb_writel(tibase,
918 DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4),
919 n_bds + 2);
920 else if (n_bds > (i - 3))
921 musb_writel(tibase,
922 DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4),
923 n_bds - (i - 3));
924
925 i = musb_readl(tibase,
926 DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4))
927 & 0xffff;
928 if (i < (2 + n_bds)) {
929 DBG(2, "bufcnt%d underrun - %d (for %d)\n",
930 rx->index, i, n_bds);
931 musb_writel(tibase,
932 DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4),
933 n_bds + 2);
934 }
935
936 cppi_dump_rx(4, rx, "/S");
937}
938
939/**
940 * cppi_channel_program - program channel for data transfer
941 * @ch: the channel
942 * @maxpacket: max packet size
943 * @mode: For RX, 1 unless the usb protocol driver promised to treat
944 * all short reads as errors and kick in high level fault recovery.
945 * For TX, ignored because of RNDIS mode races/glitches.
946 * @dma_addr: dma address of buffer
947 * @len: length of buffer
948 * Context: controller irqlocked
949 */
950static int cppi_channel_program(struct dma_channel *ch,
951 u16 maxpacket, u8 mode,
952 dma_addr_t dma_addr, u32 len)
953{
954 struct cppi_channel *cppi_ch;
955 struct cppi *controller;
956 struct musb *musb;
957
958 cppi_ch = container_of(ch, struct cppi_channel, channel);
959 controller = cppi_ch->controller;
960 musb = controller->musb;
961
962 switch (ch->status) {
963 case MUSB_DMA_STATUS_BUS_ABORT:
964 case MUSB_DMA_STATUS_CORE_ABORT:
965 /* fault irq handler should have handled cleanup */
966 WARNING("%cX DMA%d not cleaned up after abort!\n",
967 cppi_ch->transmit ? 'T' : 'R',
968 cppi_ch->index);
969 /* WARN_ON(1); */
970 break;
971 case MUSB_DMA_STATUS_BUSY:
972 WARNING("program active channel? %cX DMA%d\n",
973 cppi_ch->transmit ? 'T' : 'R',
974 cppi_ch->index);
975 /* WARN_ON(1); */
976 break;
977 case MUSB_DMA_STATUS_UNKNOWN:
978 DBG(1, "%cX DMA%d not allocated!\n",
979 cppi_ch->transmit ? 'T' : 'R',
980 cppi_ch->index);
981 /* FALLTHROUGH */
982 case MUSB_DMA_STATUS_FREE:
983 break;
984 }
985
986 ch->status = MUSB_DMA_STATUS_BUSY;
987
988 /* set transfer parameters, then queue up its first segment */
989 cppi_ch->buf_dma = dma_addr;
990 cppi_ch->offset = 0;
991 cppi_ch->maxpacket = maxpacket;
992 cppi_ch->buf_len = len;
993
994 /* TX channel? or RX? */
995 if (cppi_ch->transmit)
996 cppi_next_tx_segment(musb, cppi_ch);
997 else
998 cppi_next_rx_segment(musb, cppi_ch, mode);
999
1000 return true;
1001}
1002
1003static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)
1004{
1005 struct cppi_channel *rx = &cppi->rx[ch];
1006 struct cppi_rx_stateram __iomem *state = rx->state_ram;
1007 struct cppi_descriptor *bd;
1008 struct cppi_descriptor *last = rx->last_processed;
1009 bool completed = false;
1010 bool acked = false;
1011 int i;
1012 dma_addr_t safe2ack;
1013 void __iomem *regs = rx->hw_ep->regs;
1014
1015 cppi_dump_rx(6, rx, "/K");
1016
1017 bd = last ? last->next : rx->head;
1018 if (!bd)
1019 return false;
1020
1021 /* run through all completed BDs */
1022 for (i = 0, safe2ack = musb_readl(&state->rx_complete, 0);
1023 (safe2ack || completed) && bd && i < NUM_RXCHAN_BD;
1024 i++, bd = bd->next) {
1025 u16 len;
1026
1027 /* catch latest BD writes from CPPI */
1028 rmb();
1029 if (!completed && (bd->hw_options & CPPI_OWN_SET))
1030 break;
1031
1032 DBG(5, "C/RXBD %08x: nxt %08x buf %08x "
1033 "off.len %08x opt.len %08x (%d)\n",
1034 bd->dma, bd->hw_next, bd->hw_bufp,
1035 bd->hw_off_len, bd->hw_options,
1036 rx->channel.actual_len);
1037
1038 /* actual packet received length */
1039 if ((bd->hw_options & CPPI_SOP_SET) && !completed)
1040 len = bd->hw_off_len & CPPI_RECV_PKTLEN_MASK;
1041 else
1042 len = 0;
1043
1044 if (bd->hw_options & CPPI_EOQ_MASK)
1045 completed = true;
1046
1047 if (!completed && len < bd->buflen) {
1048 /* NOTE: when we get a short packet, RXCSR_H_REQPKT
1049 * must have been cleared, and no more DMA packets may
1050 * active be in the queue... TI docs didn't say, but
1051 * CPPI ignores those BDs even though OWN is still set.
1052 */
1053 completed = true;
1054 DBG(3, "rx short %d/%d (%d)\n",
1055 len, bd->buflen,
1056 rx->channel.actual_len);
1057 }
1058
1059 /* If we got here, we expect to ack at least one BD; meanwhile
1060 * CPPI may completing other BDs while we scan this list...
1061 *
1062 * RACE: we can notice OWN cleared before CPPI raises the
1063 * matching irq by writing that BD as the completion pointer.
1064 * In such cases, stop scanning and wait for the irq, avoiding
1065 * lost acks and states where BD ownership is unclear.
1066 */
1067 if (bd->dma == safe2ack) {
1068 musb_writel(&state->rx_complete, 0, safe2ack);
1069 safe2ack = musb_readl(&state->rx_complete, 0);
1070 acked = true;
1071 if (bd->dma == safe2ack)
1072 safe2ack = 0;
1073 }
1074
1075 rx->channel.actual_len += len;
1076
1077 cppi_bd_free(rx, last);
1078 last = bd;
1079
1080 /* stop scanning on end-of-segment */
1081 if (bd->hw_next == 0)
1082 completed = true;
1083 }
1084 rx->last_processed = last;
1085
1086 /* dma abort, lost ack, or ... */
1087 if (!acked && last) {
1088 int csr;
1089
1090 if (safe2ack == 0 || safe2ack == rx->last_processed->dma)
1091 musb_writel(&state->rx_complete, 0, safe2ack);
1092 if (safe2ack == 0) {
1093 cppi_bd_free(rx, last);
1094 rx->last_processed = NULL;
1095
1096 /* if we land here on the host side, H_REQPKT will
1097 * be clear and we need to restart the queue...
1098 */
1099 WARN_ON(rx->head);
1100 }
1101 musb_ep_select(cppi->mregs, rx->index + 1);
1102 csr = musb_readw(regs, MUSB_RXCSR);
1103 if (csr & MUSB_RXCSR_DMAENAB) {
1104 DBG(4, "list%d %p/%p, last %08x%s, csr %04x\n",
1105 rx->index,
1106 rx->head, rx->tail,
1107 rx->last_processed
1108 ? rx->last_processed->dma
1109 : 0,
1110 completed ? ", completed" : "",
1111 csr);
1112 cppi_dump_rxq(4, "/what?", rx);
1113 }
1114 }
1115 if (!completed) {
1116 int csr;
1117
1118 rx->head = bd;
1119
1120 /* REVISIT seems like "autoreq all but EOP" doesn't...
1121 * setting it here "should" be racey, but seems to work
1122 */
1123 csr = musb_readw(rx->hw_ep->regs, MUSB_RXCSR);
1124 if (is_host_active(cppi->musb)
1125 && bd
1126 && !(csr & MUSB_RXCSR_H_REQPKT)) {
1127 csr |= MUSB_RXCSR_H_REQPKT;
1128 musb_writew(regs, MUSB_RXCSR,
1129 MUSB_RXCSR_H_WZC_BITS | csr);
1130 csr = musb_readw(rx->hw_ep->regs, MUSB_RXCSR);
1131 }
1132 } else {
1133 rx->head = NULL;
1134 rx->tail = NULL;
1135 }
1136
1137 cppi_dump_rx(6, rx, completed ? "/completed" : "/cleaned");
1138 return completed;
1139}
1140
1141void cppi_completion(struct musb *musb, u32 rx, u32 tx)
1142{
1143 void __iomem *tibase;
1144 int i, index;
1145 struct cppi *cppi;
1146 struct musb_hw_ep *hw_ep = NULL;
1147
1148 cppi = container_of(musb->dma_controller, struct cppi, controller);
1149
1150 tibase = musb->ctrl_base;
1151
1152 /* process TX channels */
1153 for (index = 0; tx; tx = tx >> 1, index++) {
1154 struct cppi_channel *tx_ch;
1155 struct cppi_tx_stateram __iomem *tx_ram;
1156 bool completed = false;
1157 struct cppi_descriptor *bd;
1158
1159 if (!(tx & 1))
1160 continue;
1161
1162 tx_ch = cppi->tx + index;
1163 tx_ram = tx_ch->state_ram;
1164
1165 /* FIXME need a cppi_tx_scan() routine, which
1166 * can also be called from abort code
1167 */
1168
1169 cppi_dump_tx(5, tx_ch, "/E");
1170
1171 bd = tx_ch->head;
1172
1173 if (NULL == bd) {
1174 DBG(1, "null BD\n");
1175 continue;
1176 }
1177
1178 /* run through all completed BDs */
1179 for (i = 0; !completed && bd && i < NUM_TXCHAN_BD;
1180 i++, bd = bd->next) {
1181 u16 len;
1182
1183 /* catch latest BD writes from CPPI */
1184 rmb();
1185 if (bd->hw_options & CPPI_OWN_SET)
1186 break;
1187
1188 DBG(5, "C/TXBD %p n %x b %x off %x opt %x\n",
1189 bd, bd->hw_next, bd->hw_bufp,
1190 bd->hw_off_len, bd->hw_options);
1191
1192 len = bd->hw_off_len & CPPI_BUFFER_LEN_MASK;
1193 tx_ch->channel.actual_len += len;
1194
1195 tx_ch->last_processed = bd;
1196
1197 /* write completion register to acknowledge
1198 * processing of completed BDs, and possibly
1199 * release the IRQ; EOQ might not be set ...
1200 *
1201 * REVISIT use the same ack strategy as rx
1202 *
1203 * REVISIT have observed bit 18 set; huh??
1204 */
1205 /* if ((bd->hw_options & CPPI_EOQ_MASK)) */
1206 musb_writel(&tx_ram->tx_complete, 0, bd->dma);
1207
1208 /* stop scanning on end-of-segment */
1209 if (bd->hw_next == 0)
1210 completed = true;
1211 }
1212
1213 /* on end of segment, maybe go to next one */
1214 if (completed) {
1215 /* cppi_dump_tx(4, tx_ch, "/complete"); */
1216
1217 /* transfer more, or report completion */
1218 if (tx_ch->offset >= tx_ch->buf_len) {
1219 tx_ch->head = NULL;
1220 tx_ch->tail = NULL;
1221 tx_ch->channel.status = MUSB_DMA_STATUS_FREE;
1222
1223 hw_ep = tx_ch->hw_ep;
1224
1225 /* Peripheral role never repurposes the
1226 * endpoint, so immediate completion is
1227 * safe. Host role waits for the fifo
1228 * to empty (TXPKTRDY irq) before going
1229 * to the next queued bulk transfer.
1230 */
1231 if (is_host_active(cppi->musb)) {
1232#if 0
1233 /* WORKAROUND because we may
1234 * not always get TXKPTRDY ...
1235 */
1236 int csr;
1237
1238 csr = musb_readw(hw_ep->regs,
1239 MUSB_TXCSR);
1240 if (csr & MUSB_TXCSR_TXPKTRDY)
1241#endif
1242 completed = false;
1243 }
1244 if (completed)
1245 musb_dma_completion(musb, index + 1, 1);
1246
1247 } else {
1248 /* Bigger transfer than we could fit in
1249 * that first batch of descriptors...
1250 */
1251 cppi_next_tx_segment(musb, tx_ch);
1252 }
1253 } else
1254 tx_ch->head = bd;
1255 }
1256
1257 /* Start processing the RX block */
1258 for (index = 0; rx; rx = rx >> 1, index++) {
1259
1260 if (rx & 1) {
1261 struct cppi_channel *rx_ch;
1262
1263 rx_ch = cppi->rx + index;
1264
1265 /* let incomplete dma segments finish */
1266 if (!cppi_rx_scan(cppi, index))
1267 continue;
1268
1269 /* start another dma segment if needed */
1270 if (rx_ch->channel.actual_len != rx_ch->buf_len
1271 && rx_ch->channel.actual_len
1272 == rx_ch->offset) {
1273 cppi_next_rx_segment(musb, rx_ch, 1);
1274 continue;
1275 }
1276
1277 /* all segments completed! */
1278 rx_ch->channel.status = MUSB_DMA_STATUS_FREE;
1279
1280 hw_ep = rx_ch->hw_ep;
1281
1282 core_rxirq_disable(tibase, index + 1);
1283 musb_dma_completion(musb, index + 1, 0);
1284 }
1285 }
1286
1287 /* write to CPPI EOI register to re-enable interrupts */
1288 musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0);
1289}
1290
1291/* Instantiate a software object representing a DMA controller. */
1292struct dma_controller *__init
1293dma_controller_create(struct musb *musb, void __iomem *mregs)
1294{
1295 struct cppi *controller;
1296
1297 controller = kzalloc(sizeof *controller, GFP_KERNEL);
1298 if (!controller)
1299 return NULL;
1300
1301 controller->mregs = mregs;
1302 controller->tibase = mregs - DAVINCI_BASE_OFFSET;
1303
1304 controller->musb = musb;
1305 controller->controller.start = cppi_controller_start;
1306 controller->controller.stop = cppi_controller_stop;
1307 controller->controller.channel_alloc = cppi_channel_allocate;
1308 controller->controller.channel_release = cppi_channel_release;
1309 controller->controller.channel_program = cppi_channel_program;
1310 controller->controller.channel_abort = cppi_channel_abort;
1311
1312 /* NOTE: allocating from on-chip SRAM would give the least
1313 * contention for memory access, if that ever matters here.
1314 */
1315
1316 /* setup BufferPool */
1317 controller->pool = dma_pool_create("cppi",
1318 controller->musb->controller,
1319 sizeof(struct cppi_descriptor),
1320 CPPI_DESCRIPTOR_ALIGN, 0);
1321 if (!controller->pool) {
1322 kfree(controller);
1323 return NULL;
1324 }
1325
1326 return &controller->controller;
1327}
1328
1329/*
1330 * Destroy a previously-instantiated DMA controller.
1331 */
1332void dma_controller_destroy(struct dma_controller *c)
1333{
1334 struct cppi *cppi;
1335
1336 cppi = container_of(c, struct cppi, controller);
1337
1338 /* assert: caller stopped the controller first */
1339 dma_pool_destroy(cppi->pool);
1340
1341 kfree(cppi);
1342}
1343
1344/*
1345 * Context: controller irqlocked, endpoint selected
1346 */
1347static int cppi_channel_abort(struct dma_channel *channel)
1348{
1349 struct cppi_channel *cppi_ch;
1350 struct cppi *controller;
1351 void __iomem *mbase;
1352 void __iomem *tibase;
1353 void __iomem *regs;
1354 u32 value;
1355 struct cppi_descriptor *queue;
1356
1357 cppi_ch = container_of(channel, struct cppi_channel, channel);
1358
1359 controller = cppi_ch->controller;
1360
1361 switch (channel->status) {
1362 case MUSB_DMA_STATUS_BUS_ABORT:
1363 case MUSB_DMA_STATUS_CORE_ABORT:
1364 /* from RX or TX fault irq handler */
1365 case MUSB_DMA_STATUS_BUSY:
1366 /* the hardware needs shutting down */
1367 regs = cppi_ch->hw_ep->regs;
1368 break;
1369 case MUSB_DMA_STATUS_UNKNOWN:
1370 case MUSB_DMA_STATUS_FREE:
1371 return 0;
1372 default:
1373 return -EINVAL;
1374 }
1375
1376 if (!cppi_ch->transmit && cppi_ch->head)
1377 cppi_dump_rxq(3, "/abort", cppi_ch);
1378
1379 mbase = controller->mregs;
1380 tibase = controller->tibase;
1381
1382 queue = cppi_ch->head;
1383 cppi_ch->head = NULL;
1384 cppi_ch->tail = NULL;
1385
1386 /* REVISIT should rely on caller having done this,
1387 * and caller should rely on us not changing it.
1388 * peripheral code is safe ... check host too.
1389 */
1390 musb_ep_select(mbase, cppi_ch->index + 1);
1391
1392 if (cppi_ch->transmit) {
1393 struct cppi_tx_stateram __iomem *tx_ram;
1394 int enabled;
1395
1396 /* mask interrupts raised to signal teardown complete. */
1397 enabled = musb_readl(tibase, DAVINCI_TXCPPI_INTENAB_REG)
1398 & (1 << cppi_ch->index);
1399 if (enabled)
1400 musb_writel(tibase, DAVINCI_TXCPPI_INTCLR_REG,
1401 (1 << cppi_ch->index));
1402
1403 /* REVISIT put timeouts on these controller handshakes */
1404
1405 cppi_dump_tx(6, cppi_ch, " (teardown)");
1406
1407 /* teardown DMA engine then usb core */
1408 do {
1409 value = musb_readl(tibase, DAVINCI_TXCPPI_TEAR_REG);
1410 } while (!(value & CPPI_TEAR_READY));
1411 musb_writel(tibase, DAVINCI_TXCPPI_TEAR_REG, cppi_ch->index);
1412
1413 tx_ram = cppi_ch->state_ram;
1414 do {
1415 value = musb_readl(&tx_ram->tx_complete, 0);
1416 } while (0xFFFFFFFC != value);
1417 musb_writel(&tx_ram->tx_complete, 0, 0xFFFFFFFC);
1418
1419 /* FIXME clean up the transfer state ... here?
1420 * the completion routine should get called with
1421 * an appropriate status code.
1422 */
1423
1424 value = musb_readw(regs, MUSB_TXCSR);
1425 value &= ~MUSB_TXCSR_DMAENAB;
1426 value |= MUSB_TXCSR_FLUSHFIFO;
1427 musb_writew(regs, MUSB_TXCSR, value);
1428 musb_writew(regs, MUSB_TXCSR, value);
1429
1430 /* re-enable interrupt */
1431 if (enabled)
1432 musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
1433 (1 << cppi_ch->index));
1434
1435 /* While we scrub the TX state RAM, ensure that we clean
1436 * up any interrupt that's currently asserted:
1437 * 1. Write to completion Ptr value 0x1(bit 0 set)
1438 * (write back mode)
1439 * 2. Write to completion Ptr value 0x0(bit 0 cleared)
1440 * (compare mode)
1441 * Value written is compared(for bits 31:2) and when
1442 * equal, interrupt is deasserted.
1443 */
1444 cppi_reset_tx(tx_ram, 1);
1445 musb_writel(&tx_ram->tx_complete, 0, 0);
1446
1447 cppi_dump_tx(5, cppi_ch, " (done teardown)");
1448
1449 /* REVISIT tx side _should_ clean up the same way
1450 * as the RX side ... this does no cleanup at all!
1451 */
1452
1453 } else /* RX */ {
1454 u16 csr;
1455
1456 /* NOTE: docs don't guarantee any of this works ... we
1457 * expect that if the usb core stops telling the cppi core
1458 * to pull more data from it, then it'll be safe to flush
1459 * current RX DMA state iff any pending fifo transfer is done.
1460 */
1461
1462 core_rxirq_disable(tibase, cppi_ch->index + 1);
1463
1464 /* for host, ensure ReqPkt is never set again */
1465 if (is_host_active(cppi_ch->controller->musb)) {
1466 value = musb_readl(tibase, DAVINCI_AUTOREQ_REG);
1467 value &= ~((0x3) << (cppi_ch->index * 2));
1468 musb_writel(tibase, DAVINCI_AUTOREQ_REG, value);
1469 }
1470
1471 csr = musb_readw(regs, MUSB_RXCSR);
1472
1473 /* for host, clear (just) ReqPkt at end of current packet(s) */
1474 if (is_host_active(cppi_ch->controller->musb)) {
1475 csr |= MUSB_RXCSR_H_WZC_BITS;
1476 csr &= ~MUSB_RXCSR_H_REQPKT;
1477 } else
1478 csr |= MUSB_RXCSR_P_WZC_BITS;
1479
1480 /* clear dma enable */
1481 csr &= ~(MUSB_RXCSR_DMAENAB);
1482 musb_writew(regs, MUSB_RXCSR, csr);
1483 csr = musb_readw(regs, MUSB_RXCSR);
1484
1485 /* Quiesce: wait for current dma to finish (if not cleanup).
1486 * We can't use bit zero of stateram->rx_sop, since that
1487 * refers to an entire "DMA packet" not just emptying the
1488 * current fifo. Most segments need multiple usb packets.
1489 */
1490 if (channel->status == MUSB_DMA_STATUS_BUSY)
1491 udelay(50);
1492
1493 /* scan the current list, reporting any data that was
1494 * transferred and acking any IRQ
1495 */
1496 cppi_rx_scan(controller, cppi_ch->index);
1497
1498 /* clobber the existing state once it's idle
1499 *
1500 * NOTE: arguably, we should also wait for all the other
1501 * RX channels to quiesce (how??) and then temporarily
1502 * disable RXCPPI_CTRL_REG ... but it seems that we can
1503 * rely on the controller restarting from state ram, with
1504 * only RXCPPI_BUFCNT state being bogus. BUFCNT will
1505 * correct itself after the next DMA transfer though.
1506 *
1507 * REVISIT does using rndis mode change that?
1508 */
1509 cppi_reset_rx(cppi_ch->state_ram);
1510
1511 /* next DMA request _should_ load cppi head ptr */
1512
1513 /* ... we don't "free" that list, only mutate it in place. */
1514 cppi_dump_rx(5, cppi_ch, " (done abort)");
1515
1516 /* clean up previously pending bds */
1517 cppi_bd_free(cppi_ch, cppi_ch->last_processed);
1518 cppi_ch->last_processed = NULL;
1519
1520 while (queue) {
1521 struct cppi_descriptor *tmp = queue->next;
1522
1523 cppi_bd_free(cppi_ch, queue);
1524 queue = tmp;
1525 }
1526 }
1527
1528 channel->status = MUSB_DMA_STATUS_FREE;
1529 cppi_ch->buf_dma = 0;
1530 cppi_ch->offset = 0;
1531 cppi_ch->buf_len = 0;
1532 cppi_ch->maxpacket = 0;
1533 return 0;
1534}
1535
1536/* TBD Queries:
1537 *
1538 * Power Management ... probably turn off cppi during suspend, restart;
1539 * check state ram? Clocking is presumably shared with usb core.
1540 */
diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h
new file mode 100644
index 000000000000..fc5216b5d2c5
--- /dev/null
+++ b/drivers/usb/musb/cppi_dma.h
@@ -0,0 +1,133 @@
1/* Copyright (C) 2005-2006 by Texas Instruments */
2
3#ifndef _CPPI_DMA_H_
4#define _CPPI_DMA_H_
5
6#include <linux/slab.h>
7#include <linux/list.h>
8#include <linux/smp_lock.h>
9#include <linux/errno.h>
10#include <linux/dmapool.h>
11
12#include "musb_dma.h"
13#include "musb_core.h"
14
15
16/* FIXME fully isolate CPPI from DaVinci ... the "CPPI generic" registers
17 * would seem to be shared with the TUSB6020 (over VLYNQ).
18 */
19
20#include "davinci.h"
21
22
23/* CPPI RX/TX state RAM */
24
25struct cppi_tx_stateram {
26 u32 tx_head; /* "DMA packet" head descriptor */
27 u32 tx_buf;
28 u32 tx_current; /* current descriptor */
29 u32 tx_buf_current;
30 u32 tx_info; /* flags, remaining buflen */
31 u32 tx_rem_len;
32 u32 tx_dummy; /* unused */
33 u32 tx_complete;
34};
35
36struct cppi_rx_stateram {
37 u32 rx_skipbytes;
38 u32 rx_head;
39 u32 rx_sop; /* "DMA packet" head descriptor */
40 u32 rx_current; /* current descriptor */
41 u32 rx_buf_current;
42 u32 rx_len_len;
43 u32 rx_cnt_cnt;
44 u32 rx_complete;
45};
46
47/* hw_options bits in CPPI buffer descriptors */
48#define CPPI_SOP_SET ((u32)(1 << 31))
49#define CPPI_EOP_SET ((u32)(1 << 30))
50#define CPPI_OWN_SET ((u32)(1 << 29)) /* owned by cppi */
51#define CPPI_EOQ_MASK ((u32)(1 << 28))
52#define CPPI_ZERO_SET ((u32)(1 << 23)) /* rx saw zlp; tx issues one */
53#define CPPI_RXABT_MASK ((u32)(1 << 19)) /* need more rx buffers */
54
55#define CPPI_RECV_PKTLEN_MASK 0xFFFF
56#define CPPI_BUFFER_LEN_MASK 0xFFFF
57
58#define CPPI_TEAR_READY ((u32)(1 << 31))
59
60/* CPPI data structure definitions */
61
62#define CPPI_DESCRIPTOR_ALIGN 16 /* bytes; 5-dec docs say 4-byte align */
63
64struct cppi_descriptor {
65 /* hardware overlay */
66 u32 hw_next; /* next buffer descriptor Pointer */
67 u32 hw_bufp; /* i/o buffer pointer */
68 u32 hw_off_len; /* buffer_offset16, buffer_length16 */
69 u32 hw_options; /* flags: SOP, EOP etc*/
70
71 struct cppi_descriptor *next;
72 dma_addr_t dma; /* address of this descriptor */
73 u32 buflen; /* for RX: original buffer length */
74} __attribute__ ((aligned(CPPI_DESCRIPTOR_ALIGN)));
75
76
77struct cppi;
78
79/* CPPI Channel Control structure */
80struct cppi_channel {
81 struct dma_channel channel;
82
83 /* back pointer to the DMA controller structure */
84 struct cppi *controller;
85
86 /* which direction of which endpoint? */
87 struct musb_hw_ep *hw_ep;
88 bool transmit;
89 u8 index;
90
91 /* DMA modes: RNDIS or "transparent" */
92 u8 is_rndis;
93
94 /* book keeping for current transfer request */
95 dma_addr_t buf_dma;
96 u32 buf_len;
97 u32 maxpacket;
98 u32 offset; /* dma requested */
99
100 void __iomem *state_ram; /* CPPI state */
101
102 struct cppi_descriptor *freelist;
103
104 /* BD management fields */
105 struct cppi_descriptor *head;
106 struct cppi_descriptor *tail;
107 struct cppi_descriptor *last_processed;
108
109 /* use tx_complete in host role to track endpoints waiting for
110 * FIFONOTEMPTY to clear.
111 */
112 struct list_head tx_complete;
113};
114
115/* CPPI DMA controller object */
116struct cppi {
117 struct dma_controller controller;
118 struct musb *musb;
119 void __iomem *mregs; /* Mentor regs */
120 void __iomem *tibase; /* TI/CPPI regs */
121
122 struct cppi_channel tx[MUSB_C_NUM_EPT - 1];
123 struct cppi_channel rx[MUSB_C_NUM_EPR - 1];
124
125 struct dma_pool *pool;
126
127 struct list_head tx_complete;
128};
129
130/* irq handling hook */
131extern void cppi_completion(struct musb *, u32 rx, u32 tx);
132
133#endif /* end of ifndef _CPPI_DMA_H_ */
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
new file mode 100644
index 000000000000..75baf181a8cd
--- /dev/null
+++ b/drivers/usb/musb/davinci.c
@@ -0,0 +1,462 @@
1/*
2 * Copyright (C) 2005-2006 by Texas Instruments
3 *
4 * This file is part of the Inventra Controller Driver for Linux.
5 *
6 * The Inventra Controller Driver for Linux is free software; you
7 * can redistribute it and/or modify it under the terms of the GNU
8 * General Public License version 2 as published by the Free Software
9 * Foundation.
10 *
11 * The Inventra Controller Driver for Linux is distributed in
12 * the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with The Inventra Controller Driver for Linux ; if not,
19 * write to the Free Software Foundation, Inc., 59 Temple Place,
20 * Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/slab.h>
28#include <linux/init.h>
29#include <linux/list.h>
30#include <linux/delay.h>
31#include <linux/clk.h>
32#include <linux/io.h>
33
34#include <asm/arch/hardware.h>
35#include <asm/arch/memory.h>
36#include <asm/arch/gpio.h>
37#include <asm/mach-types.h>
38
39#include "musb_core.h"
40
41#ifdef CONFIG_MACH_DAVINCI_EVM
42#include <asm/arch/i2c-client.h>
43#endif
44
45#include "davinci.h"
46#include "cppi_dma.h"
47
48
49/* REVISIT (PM) we should be able to keep the PHY in low power mode most
50 * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
51 * and, when in host mode, autosuspending idle root ports... PHYPLLON
52 * (overriding SUSPENDM?) then likely needs to stay off.
53 */
54
55static inline void phy_on(void)
56{
57 /* start the on-chip PHY and its PLL */
58 __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON,
59 (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR));
60 while ((__raw_readl((void __force __iomem *)
61 IO_ADDRESS(USBPHY_CTL_PADDR))
62 & USBPHY_PHYCLKGD) == 0)
63 cpu_relax();
64}
65
66static inline void phy_off(void)
67{
68 /* powerdown the on-chip PHY and its oscillator */
69 __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *)
70 IO_ADDRESS(USBPHY_CTL_PADDR));
71}
72
73static int dma_off = 1;
74
75void musb_platform_enable(struct musb *musb)
76{
77 u32 tmp, old, val;
78
79 /* workaround: setup irqs through both register sets */
80 tmp = (musb->epmask & DAVINCI_USB_TX_ENDPTS_MASK)
81 << DAVINCI_USB_TXINT_SHIFT;
82 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
83 old = tmp;
84 tmp = (musb->epmask & (0xfffe & DAVINCI_USB_RX_ENDPTS_MASK))
85 << DAVINCI_USB_RXINT_SHIFT;
86 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
87 tmp |= old;
88
89 val = ~MUSB_INTR_SOF;
90 tmp |= ((val & 0x01ff) << DAVINCI_USB_USBINT_SHIFT);
91 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_SET_REG, tmp);
92
93 if (is_dma_capable() && !dma_off)
94 printk(KERN_WARNING "%s %s: dma not reactivated\n",
95 __FILE__, __func__);
96 else
97 dma_off = 0;
98
99 /* force a DRVVBUS irq so we can start polling for ID change */
100 if (is_otg_enabled(musb))
101 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
102 DAVINCI_INTR_DRVVBUS << DAVINCI_USB_USBINT_SHIFT);
103}
104
105/*
106 * Disable the HDRC and flush interrupts
107 */
108void musb_platform_disable(struct musb *musb)
109{
110 /* because we don't set CTRLR.UINT, "important" to:
111 * - not read/write INTRUSB/INTRUSBE
112 * - (except during initial setup, as workaround)
113 * - use INTSETR/INTCLRR instead
114 */
115 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_CLR_REG,
116 DAVINCI_USB_USBINT_MASK
117 | DAVINCI_USB_TXINT_MASK
118 | DAVINCI_USB_RXINT_MASK);
119 musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
120 musb_writel(musb->ctrl_base, DAVINCI_USB_EOI_REG, 0);
121
122 if (is_dma_capable() && !dma_off)
123 WARNING("dma still active\n");
124}
125
126
127/* REVISIT it's not clear whether DaVinci can support full OTG. */
128
129static int vbus_state = -1;
130
131#ifdef CONFIG_USB_MUSB_HDRC_HCD
132#define portstate(stmt) stmt
133#else
134#define portstate(stmt)
135#endif
136
137
138/* VBUS SWITCHING IS BOARD-SPECIFIC */
139
140#ifdef CONFIG_MACH_DAVINCI_EVM
141#ifndef CONFIG_MACH_DAVINCI_EVM_OTG
142
143/* I2C operations are always synchronous, and require a task context.
144 * With unloaded systems, using the shared workqueue seems to suffice
145 * to satisfy the 100msec A_WAIT_VRISE timeout...
146 */
147static void evm_deferred_drvvbus(struct work_struct *ignored)
148{
149 davinci_i2c_expander_op(0x3a, USB_DRVVBUS, vbus_state);
150 vbus_state = !vbus_state;
151}
152static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
153
154#endif /* modified board */
155#endif /* EVM */
156
157static void davinci_source_power(struct musb *musb, int is_on, int immediate)
158{
159 if (is_on)
160 is_on = 1;
161
162 if (vbus_state == is_on)
163 return;
164 vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */
165
166#ifdef CONFIG_MACH_DAVINCI_EVM
167 if (machine_is_davinci_evm()) {
168#ifdef CONFIG_MACH_DAVINCI_EVM_OTG
169 /* modified EVM board switching VBUS with GPIO(6) not I2C
170 * NOTE: PINMUX0.RGB888 (bit23) must be clear
171 */
172 if (is_on)
173 gpio_set(GPIO(6));
174 else
175 gpio_clear(GPIO(6));
176 immediate = 1;
177#else
178 if (immediate)
179 davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
180 else
181 schedule_work(&evm_vbus_work);
182#endif
183 }
184#endif
185 if (immediate)
186 vbus_state = is_on;
187}
188
189static void davinci_set_vbus(struct musb *musb, int is_on)
190{
191 WARN_ON(is_on && is_peripheral_active(musb));
192 davinci_source_power(musb, is_on, 0);
193}
194
195
196#define POLL_SECONDS 2
197
198static struct timer_list otg_workaround;
199
200static void otg_timer(unsigned long _musb)
201{
202 struct musb *musb = (void *)_musb;
203 void __iomem *mregs = musb->mregs;
204 u8 devctl;
205 unsigned long flags;
206
207 /* We poll because DaVinci's won't expose several OTG-critical
208 * status change events (from the transceiver) otherwise.
209 */
210 devctl = musb_readb(mregs, MUSB_DEVCTL);
211 DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb));
212
213 spin_lock_irqsave(&musb->lock, flags);
214 switch (musb->xceiv.state) {
215 case OTG_STATE_A_WAIT_VFALL:
216 /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
217 * seems to mis-handle session "start" otherwise (or in our
218 * case "recover"), in routine "VBUS was valid by the time
219 * VBUSERR got reported during enumeration" cases.
220 */
221 if (devctl & MUSB_DEVCTL_VBUS) {
222 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
223 break;
224 }
225 musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
226 musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
227 MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT);
228 break;
229 case OTG_STATE_B_IDLE:
230 if (!is_peripheral_enabled(musb))
231 break;
232
233 /* There's no ID-changed IRQ, so we have no good way to tell
234 * when to switch to the A-Default state machine (by setting
235 * the DEVCTL.SESSION flag).
236 *
237 * Workaround: whenever we're in B_IDLE, try setting the
238 * session flag every few seconds. If it works, ID was
239 * grounded and we're now in the A-Default state machine.
240 *
241 * NOTE setting the session flag is _supposed_ to trigger
242 * SRP, but clearly it doesn't.
243 */
244 musb_writeb(mregs, MUSB_DEVCTL,
245 devctl | MUSB_DEVCTL_SESSION);
246 devctl = musb_readb(mregs, MUSB_DEVCTL);
247 if (devctl & MUSB_DEVCTL_BDEVICE)
248 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
249 else
250 musb->xceiv.state = OTG_STATE_A_IDLE;
251 break;
252 default:
253 break;
254 }
255 spin_unlock_irqrestore(&musb->lock, flags);
256}
257
258static irqreturn_t davinci_interrupt(int irq, void *__hci)
259{
260 unsigned long flags;
261 irqreturn_t retval = IRQ_NONE;
262 struct musb *musb = __hci;
263 void __iomem *tibase = musb->ctrl_base;
264 u32 tmp;
265
266 spin_lock_irqsave(&musb->lock, flags);
267
268 /* NOTE: DaVinci shadows the Mentor IRQs. Don't manage them through
269 * the Mentor registers (except for setup), use the TI ones and EOI.
270 *
271 * Docs describe irq "vector" registers asociated with the CPPI and
272 * USB EOI registers. These hold a bitmask corresponding to the
273 * current IRQ, not an irq handler address. Would using those bits
274 * resolve some of the races observed in this dispatch code??
275 */
276
277 /* CPPI interrupts share the same IRQ line, but have their own
278 * mask, state, "vector", and EOI registers.
279 */
280 if (is_cppi_enabled()) {
281 u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
282 u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);
283
284 if (cppi_tx || cppi_rx) {
285 DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx);
286 cppi_completion(musb, cppi_rx, cppi_tx);
287 retval = IRQ_HANDLED;
288 }
289 }
290
291 /* ack and handle non-CPPI interrupts */
292 tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG);
293 musb_writel(tibase, DAVINCI_USB_INT_SRC_CLR_REG, tmp);
294 DBG(4, "IRQ %08x\n", tmp);
295
296 musb->int_rx = (tmp & DAVINCI_USB_RXINT_MASK)
297 >> DAVINCI_USB_RXINT_SHIFT;
298 musb->int_tx = (tmp & DAVINCI_USB_TXINT_MASK)
299 >> DAVINCI_USB_TXINT_SHIFT;
300 musb->int_usb = (tmp & DAVINCI_USB_USBINT_MASK)
301 >> DAVINCI_USB_USBINT_SHIFT;
302
303 /* DRVVBUS irqs are the only proxy we have (a very poor one!) for
304 * DaVinci's missing ID change IRQ. We need an ID change IRQ to
305 * switch appropriately between halves of the OTG state machine.
306 * Managing DEVCTL.SESSION per Mentor docs requires we know its
307 * value, but DEVCTL.BDEVICE is invalid without DEVCTL.SESSION set.
308 * Also, DRVVBUS pulses for SRP (but not at 5V) ...
309 */
310 if (tmp & (DAVINCI_INTR_DRVVBUS << DAVINCI_USB_USBINT_SHIFT)) {
311 int drvvbus = musb_readl(tibase, DAVINCI_USB_STAT_REG);
312 void __iomem *mregs = musb->mregs;
313 u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
314 int err = musb->int_usb & MUSB_INTR_VBUSERROR;
315
316 err = is_host_enabled(musb)
317 && (musb->int_usb & MUSB_INTR_VBUSERROR);
318 if (err) {
319 /* The Mentor core doesn't debounce VBUS as needed
320 * to cope with device connect current spikes. This
321 * means it's not uncommon for bus-powered devices
322 * to get VBUS errors during enumeration.
323 *
324 * This is a workaround, but newer RTL from Mentor
325 * seems to allow a better one: "re"starting sessions
326 * without waiting (on EVM, a **long** time) for VBUS
327 * to stop registering in devctl.
328 */
329 musb->int_usb &= ~MUSB_INTR_VBUSERROR;
330 musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
331 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
332 WARNING("VBUS error workaround (delay coming)\n");
333 } else if (is_host_enabled(musb) && drvvbus) {
334 musb->is_active = 1;
335 MUSB_HST_MODE(musb);
336 musb->xceiv.default_a = 1;
337 musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
338 portstate(musb->port1_status |= USB_PORT_STAT_POWER);
339 del_timer(&otg_workaround);
340 } else {
341 musb->is_active = 0;
342 MUSB_DEV_MODE(musb);
343 musb->xceiv.default_a = 0;
344 musb->xceiv.state = OTG_STATE_B_IDLE;
345 portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
346 }
347
348 /* NOTE: this must complete poweron within 100 msec */
349 davinci_source_power(musb, drvvbus, 0);
350 DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
351 drvvbus ? "on" : "off",
352 otg_state_string(musb),
353 err ? " ERROR" : "",
354 devctl);
355 retval = IRQ_HANDLED;
356 }
357
358 if (musb->int_tx || musb->int_rx || musb->int_usb)
359 retval |= musb_interrupt(musb);
360
361 /* irq stays asserted until EOI is written */
362 musb_writel(tibase, DAVINCI_USB_EOI_REG, 0);
363
364 /* poll for ID change */
365 if (is_otg_enabled(musb)
366 && musb->xceiv.state == OTG_STATE_B_IDLE)
367 mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
368
369 spin_unlock_irqrestore(&musb->lock, flags);
370
371 /* REVISIT we sometimes get unhandled IRQs
372 * (e.g. ep0). not clear why...
373 */
374 if (retval != IRQ_HANDLED)
375 DBG(5, "unhandled? %08x\n", tmp);
376 return IRQ_HANDLED;
377}
378
379int __init musb_platform_init(struct musb *musb)
380{
381 void __iomem *tibase = musb->ctrl_base;
382 u32 revision;
383
384 musb->mregs += DAVINCI_BASE_OFFSET;
385#if 0
386 /* REVISIT there's something odd about clocking, this
387 * didn't appear do the job ...
388 */
389 musb->clock = clk_get(pDevice, "usb");
390 if (IS_ERR(musb->clock))
391 return PTR_ERR(musb->clock);
392
393 status = clk_enable(musb->clock);
394 if (status < 0)
395 return -ENODEV;
396#endif
397
398 /* returns zero if e.g. not clocked */
399 revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG);
400 if (revision == 0)
401 return -ENODEV;
402
403 if (is_host_enabled(musb))
404 setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
405
406 musb->board_set_vbus = davinci_set_vbus;
407 davinci_source_power(musb, 0, 1);
408
409 /* reset the controller */
410 musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
411
412 /* start the on-chip PHY and its PLL */
413 phy_on();
414
415 msleep(5);
416
417 /* NOTE: irqs are in mixed mode, not bypass to pure-musb */
418 pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n",
419 revision, __raw_readl((void __force __iomem *)
420 IO_ADDRESS(USBPHY_CTL_PADDR)),
421 musb_readb(tibase, DAVINCI_USB_CTRL_REG));
422
423 musb->isr = davinci_interrupt;
424 return 0;
425}
426
427int musb_platform_exit(struct musb *musb)
428{
429 if (is_host_enabled(musb))
430 del_timer_sync(&otg_workaround);
431
432 davinci_source_power(musb, 0 /*off*/, 1);
433
434 /* delay, to avoid problems with module reload */
435 if (is_host_enabled(musb) && musb->xceiv.default_a) {
436 int maxdelay = 30;
437 u8 devctl, warn = 0;
438
439 /* if there's no peripheral connected, this can take a
440 * long time to fall, especially on EVM with huge C133.
441 */
442 do {
443 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
444 if (!(devctl & MUSB_DEVCTL_VBUS))
445 break;
446 if ((devctl & MUSB_DEVCTL_VBUS) != warn) {
447 warn = devctl & MUSB_DEVCTL_VBUS;
448 DBG(1, "VBUS %d\n",
449 warn >> MUSB_DEVCTL_VBUS_SHIFT);
450 }
451 msleep(1000);
452 maxdelay--;
453 } while (maxdelay > 0);
454
455 /* in OTG mode, another host might be connected */
456 if (devctl & MUSB_DEVCTL_VBUS)
457 DBG(1, "VBUS off timeout (devctl %02x)\n", devctl);
458 }
459
460 phy_off();
461 return 0;
462}
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h
new file mode 100644
index 000000000000..7fb6238e270f
--- /dev/null
+++ b/drivers/usb/musb/davinci.h
@@ -0,0 +1,100 @@
1/*
2 * Copyright (C) 2005-2006 by Texas Instruments
3 *
4 * The Inventra Controller Driver for Linux is free software; you
5 * can redistribute it and/or modify it under the terms of the GNU
6 * General Public License version 2 as published by the Free Software
7 * Foundation.
8 */
9
10#ifndef __MUSB_HDRDF_H__
11#define __MUSB_HDRDF_H__
12
13/*
14 * DaVinci-specific definitions
15 */
16
17/* Integrated highspeed/otg PHY */
18#define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34)
19#define USBPHY_PHYCLKGD (1 << 8)
20#define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */
21#define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */
22#define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */
23#define USBPHY_CLKO1SEL (1 << 3)
24#define USBPHY_OSCPDWN (1 << 2)
25#define USBPHY_PHYPDWN (1 << 0)
26
27/* For now include usb OTG module registers here */
28#define DAVINCI_USB_VERSION_REG 0x00
29#define DAVINCI_USB_CTRL_REG 0x04
30#define DAVINCI_USB_STAT_REG 0x08
31#define DAVINCI_RNDIS_REG 0x10
32#define DAVINCI_AUTOREQ_REG 0x14
33#define DAVINCI_USB_INT_SOURCE_REG 0x20
34#define DAVINCI_USB_INT_SET_REG 0x24
35#define DAVINCI_USB_INT_SRC_CLR_REG 0x28
36#define DAVINCI_USB_INT_MASK_REG 0x2c
37#define DAVINCI_USB_INT_MASK_SET_REG 0x30
38#define DAVINCI_USB_INT_MASK_CLR_REG 0x34
39#define DAVINCI_USB_INT_SRC_MASKED_REG 0x38
40#define DAVINCI_USB_EOI_REG 0x3c
41#define DAVINCI_USB_EOI_INTVEC 0x40
42
43/* BEGIN CPPI-generic (?) */
44
45/* CPPI related registers */
46#define DAVINCI_TXCPPI_CTRL_REG 0x80
47#define DAVINCI_TXCPPI_TEAR_REG 0x84
48#define DAVINCI_CPPI_EOI_REG 0x88
49#define DAVINCI_CPPI_INTVEC_REG 0x8c
50#define DAVINCI_TXCPPI_MASKED_REG 0x90
51#define DAVINCI_TXCPPI_RAW_REG 0x94
52#define DAVINCI_TXCPPI_INTENAB_REG 0x98
53#define DAVINCI_TXCPPI_INTCLR_REG 0x9c
54
55#define DAVINCI_RXCPPI_CTRL_REG 0xC0
56#define DAVINCI_RXCPPI_MASKED_REG 0xD0
57#define DAVINCI_RXCPPI_RAW_REG 0xD4
58#define DAVINCI_RXCPPI_INTENAB_REG 0xD8
59#define DAVINCI_RXCPPI_INTCLR_REG 0xDC
60
61#define DAVINCI_RXCPPI_BUFCNT0_REG 0xE0
62#define DAVINCI_RXCPPI_BUFCNT1_REG 0xE4
63#define DAVINCI_RXCPPI_BUFCNT2_REG 0xE8
64#define DAVINCI_RXCPPI_BUFCNT3_REG 0xEC
65
66/* CPPI state RAM entries */
67#define DAVINCI_CPPI_STATERAM_BASE_OFFSET 0x100
68
69#define DAVINCI_TXCPPI_STATERAM_OFFSET(chnum) \
70 (DAVINCI_CPPI_STATERAM_BASE_OFFSET + ((chnum) * 0x40))
71#define DAVINCI_RXCPPI_STATERAM_OFFSET(chnum) \
72 (DAVINCI_CPPI_STATERAM_BASE_OFFSET + 0x20 + ((chnum) * 0x40))
73
74/* CPPI masks */
75#define DAVINCI_DMA_CTRL_ENABLE 1
76#define DAVINCI_DMA_CTRL_DISABLE 0
77
78#define DAVINCI_DMA_ALL_CHANNELS_ENABLE 0xF
79#define DAVINCI_DMA_ALL_CHANNELS_DISABLE 0xF
80
81/* END CPPI-generic (?) */
82
83#define DAVINCI_USB_TX_ENDPTS_MASK 0x1f /* ep0 + 4 tx */
84#define DAVINCI_USB_RX_ENDPTS_MASK 0x1e /* 4 rx */
85
86#define DAVINCI_USB_USBINT_SHIFT 16
87#define DAVINCI_USB_TXINT_SHIFT 0
88#define DAVINCI_USB_RXINT_SHIFT 8
89
90#define DAVINCI_INTR_DRVVBUS 0x0100
91
92#define DAVINCI_USB_USBINT_MASK 0x01ff0000 /* 8 Mentor, DRVVBUS */
93#define DAVINCI_USB_TXINT_MASK \
94 (DAVINCI_USB_TX_ENDPTS_MASK << DAVINCI_USB_TXINT_SHIFT)
95#define DAVINCI_USB_RXINT_MASK \
96 (DAVINCI_USB_RX_ENDPTS_MASK << DAVINCI_USB_RXINT_SHIFT)
97
98#define DAVINCI_BASE_OFFSET 0x400
99
100#endif /* __MUSB_HDRDF_H__ */
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
new file mode 100644
index 000000000000..d68ec6daf335
--- /dev/null
+++ b/drivers/usb/musb/musb_core.c
@@ -0,0 +1,2261 @@
1/*
2 * MUSB OTG driver core code
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35/*
36 * Inventra (Multipoint) Dual-Role Controller Driver for Linux.
37 *
38 * This consists of a Host Controller Driver (HCD) and a peripheral
39 * controller driver implementing the "Gadget" API; OTG support is
40 * in the works. These are normal Linux-USB controller drivers which
41 * use IRQs and have no dedicated thread.
42 *
43 * This version of the driver has only been used with products from
44 * Texas Instruments. Those products integrate the Inventra logic
45 * with other DMA, IRQ, and bus modules, as well as other logic that
46 * needs to be reflected in this driver.
47 *
48 *
49 * NOTE: the original Mentor code here was pretty much a collection
50 * of mechanisms that don't seem to have been fully integrated/working
51 * for *any* Linux kernel version. This version aims at Linux 2.6.now,
52 * Key open issues include:
53 *
54 * - Lack of host-side transaction scheduling, for all transfer types.
55 * The hardware doesn't do it; instead, software must.
56 *
57 * This is not an issue for OTG devices that don't support external
58 * hubs, but for more "normal" USB hosts it's a user issue that the
59 * "multipoint" support doesn't scale in the expected ways. That
60 * includes DaVinci EVM in a common non-OTG mode.
61 *
62 * * Control and bulk use dedicated endpoints, and there's as
63 * yet no mechanism to either (a) reclaim the hardware when
64 * peripherals are NAKing, which gets complicated with bulk
65 * endpoints, or (b) use more than a single bulk endpoint in
66 * each direction.
67 *
68 * RESULT: one device may be perceived as blocking another one.
69 *
70 * * Interrupt and isochronous will dynamically allocate endpoint
71 * hardware, but (a) there's no record keeping for bandwidth;
72 * (b) in the common case that few endpoints are available, there
73 * is no mechanism to reuse endpoints to talk to multiple devices.
74 *
75 * RESULT: At one extreme, bandwidth can be overcommitted in
76 * some hardware configurations, no faults will be reported.
77 * At the other extreme, the bandwidth capabilities which do
78 * exist tend to be severely undercommitted. You can't yet hook
79 * up both a keyboard and a mouse to an external USB hub.
80 */
81
82/*
83 * This gets many kinds of configuration information:
84 * - Kconfig for everything user-configurable
85 * - <asm/arch/hdrc_cnf.h> for SOC or family details
86 * - platform_device for addressing, irq, and platform_data
87 * - platform_data is mostly for board-specific informarion
88 *
89 * Most of the conditional compilation will (someday) vanish.
90 */
91
92#include <linux/module.h>
93#include <linux/kernel.h>
94#include <linux/sched.h>
95#include <linux/slab.h>
96#include <linux/init.h>
97#include <linux/list.h>
98#include <linux/kobject.h>
99#include <linux/platform_device.h>
100#include <linux/io.h>
101
102#ifdef CONFIG_ARM
103#include <asm/arch/hardware.h>
104#include <asm/arch/memory.h>
105#include <asm/mach-types.h>
106#endif
107
108#include "musb_core.h"
109
110
111#ifdef CONFIG_ARCH_DAVINCI
112#include "davinci.h"
113#endif
114
115
116
117#if MUSB_DEBUG > 0
118unsigned debug = MUSB_DEBUG;
119module_param(debug, uint, 0);
120MODULE_PARM_DESC(debug, "initial debug message level");
121
122#define MUSB_VERSION_SUFFIX "/dbg"
123#endif
124
125#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
126#define DRIVER_DESC "Inventra Dual-Role USB Controller Driver"
127
128#define MUSB_VERSION_BASE "6.0"
129
130#ifndef MUSB_VERSION_SUFFIX
131#define MUSB_VERSION_SUFFIX ""
132#endif
133#define MUSB_VERSION MUSB_VERSION_BASE MUSB_VERSION_SUFFIX
134
135#define DRIVER_INFO DRIVER_DESC ", v" MUSB_VERSION
136
137#define MUSB_DRIVER_NAME "musb_hdrc"
138const char musb_driver_name[] = MUSB_DRIVER_NAME;
139
140MODULE_DESCRIPTION(DRIVER_INFO);
141MODULE_AUTHOR(DRIVER_AUTHOR);
142MODULE_LICENSE("GPL");
143MODULE_ALIAS("platform:" MUSB_DRIVER_NAME);
144
145
146/*-------------------------------------------------------------------------*/
147
148static inline struct musb *dev_to_musb(struct device *dev)
149{
150#ifdef CONFIG_USB_MUSB_HDRC_HCD
151 /* usbcore insists dev->driver_data is a "struct hcd *" */
152 return hcd_to_musb(dev_get_drvdata(dev));
153#else
154 return dev_get_drvdata(dev);
155#endif
156}
157
158/*-------------------------------------------------------------------------*/
159
160#ifndef CONFIG_USB_TUSB6010
161/*
162 * Load an endpoint's FIFO
163 */
164void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
165{
166 void __iomem *fifo = hw_ep->fifo;
167
168 prefetch((u8 *)src);
169
170 DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
171 'T', hw_ep->epnum, fifo, len, src);
172
173 /* we can't assume unaligned reads work */
174 if (likely((0x01 & (unsigned long) src) == 0)) {
175 u16 index = 0;
176
177 /* best case is 32bit-aligned source address */
178 if ((0x02 & (unsigned long) src) == 0) {
179 if (len >= 4) {
180 writesl(fifo, src + index, len >> 2);
181 index += len & ~0x03;
182 }
183 if (len & 0x02) {
184 musb_writew(fifo, 0, *(u16 *)&src[index]);
185 index += 2;
186 }
187 } else {
188 if (len >= 2) {
189 writesw(fifo, src + index, len >> 1);
190 index += len & ~0x01;
191 }
192 }
193 if (len & 0x01)
194 musb_writeb(fifo, 0, src[index]);
195 } else {
196 /* byte aligned */
197 writesb(fifo, src, len);
198 }
199}
200
201/*
202 * Unload an endpoint's FIFO
203 */
204void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
205{
206 void __iomem *fifo = hw_ep->fifo;
207
208 DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
209 'R', hw_ep->epnum, fifo, len, dst);
210
211 /* we can't assume unaligned writes work */
212 if (likely((0x01 & (unsigned long) dst) == 0)) {
213 u16 index = 0;
214
215 /* best case is 32bit-aligned destination address */
216 if ((0x02 & (unsigned long) dst) == 0) {
217 if (len >= 4) {
218 readsl(fifo, dst, len >> 2);
219 index = len & ~0x03;
220 }
221 if (len & 0x02) {
222 *(u16 *)&dst[index] = musb_readw(fifo, 0);
223 index += 2;
224 }
225 } else {
226 if (len >= 2) {
227 readsw(fifo, dst, len >> 1);
228 index = len & ~0x01;
229 }
230 }
231 if (len & 0x01)
232 dst[index] = musb_readb(fifo, 0);
233 } else {
234 /* byte aligned */
235 readsb(fifo, dst, len);
236 }
237}
238
239#endif /* normal PIO */
240
241
242/*-------------------------------------------------------------------------*/
243
244/* for high speed test mode; see USB 2.0 spec 7.1.20 */
245static const u8 musb_test_packet[53] = {
246 /* implicit SYNC then DATA0 to start */
247
248 /* JKJKJKJK x9 */
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 /* JJKKJJKK x8 */
251 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
252 /* JJJJKKKK x8 */
253 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
254 /* JJJJJJJKKKKKKK x8 */
255 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
256 /* JJJJJJJK x8 */
257 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
258 /* JKKKKKKK x10, JK */
259 0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e
260
261 /* implicit CRC16 then EOP to end */
262};
263
264void musb_load_testpacket(struct musb *musb)
265{
266 void __iomem *regs = musb->endpoints[0].regs;
267
268 musb_ep_select(musb->mregs, 0);
269 musb_write_fifo(musb->control_ep,
270 sizeof(musb_test_packet), musb_test_packet);
271 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_TXPKTRDY);
272}
273
274/*-------------------------------------------------------------------------*/
275
276const char *otg_state_string(struct musb *musb)
277{
278 switch (musb->xceiv.state) {
279 case OTG_STATE_A_IDLE: return "a_idle";
280 case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise";
281 case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon";
282 case OTG_STATE_A_HOST: return "a_host";
283 case OTG_STATE_A_SUSPEND: return "a_suspend";
284 case OTG_STATE_A_PERIPHERAL: return "a_peripheral";
285 case OTG_STATE_A_WAIT_VFALL: return "a_wait_vfall";
286 case OTG_STATE_A_VBUS_ERR: return "a_vbus_err";
287 case OTG_STATE_B_IDLE: return "b_idle";
288 case OTG_STATE_B_SRP_INIT: return "b_srp_init";
289 case OTG_STATE_B_PERIPHERAL: return "b_peripheral";
290 case OTG_STATE_B_WAIT_ACON: return "b_wait_acon";
291 case OTG_STATE_B_HOST: return "b_host";
292 default: return "UNDEFINED";
293 }
294}
295
296#ifdef CONFIG_USB_MUSB_OTG
297
298/*
299 * See also USB_OTG_1-3.pdf 6.6.5 Timers
300 * REVISIT: Are the other timers done in the hardware?
301 */
302#define TB_ASE0_BRST 100 /* Min 3.125 ms */
303
304/*
305 * Handles OTG hnp timeouts, such as b_ase0_brst
306 */
307void musb_otg_timer_func(unsigned long data)
308{
309 struct musb *musb = (struct musb *)data;
310 unsigned long flags;
311
312 spin_lock_irqsave(&musb->lock, flags);
313 switch (musb->xceiv.state) {
314 case OTG_STATE_B_WAIT_ACON:
315 DBG(1, "HNP: b_wait_acon timeout; back to b_peripheral\n");
316 musb_g_disconnect(musb);
317 musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
318 musb->is_active = 0;
319 break;
320 case OTG_STATE_A_WAIT_BCON:
321 DBG(1, "HNP: a_wait_bcon timeout; back to a_host\n");
322 musb_hnp_stop(musb);
323 break;
324 default:
325 DBG(1, "HNP: Unhandled mode %s\n", otg_state_string(musb));
326 }
327 musb->ignore_disconnect = 0;
328 spin_unlock_irqrestore(&musb->lock, flags);
329}
330
331static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0);
332
333/*
334 * Stops the B-device HNP state. Caller must take care of locking.
335 */
336void musb_hnp_stop(struct musb *musb)
337{
338 struct usb_hcd *hcd = musb_to_hcd(musb);
339 void __iomem *mbase = musb->mregs;
340 u8 reg;
341
342 switch (musb->xceiv.state) {
343 case OTG_STATE_A_PERIPHERAL:
344 case OTG_STATE_A_WAIT_VFALL:
345 case OTG_STATE_A_WAIT_BCON:
346 DBG(1, "HNP: Switching back to A-host\n");
347 musb_g_disconnect(musb);
348 musb->xceiv.state = OTG_STATE_A_IDLE;
349 MUSB_HST_MODE(musb);
350 musb->is_active = 0;
351 break;
352 case OTG_STATE_B_HOST:
353 DBG(1, "HNP: Disabling HR\n");
354 hcd->self.is_b_host = 0;
355 musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
356 MUSB_DEV_MODE(musb);
357 reg = musb_readb(mbase, MUSB_POWER);
358 reg |= MUSB_POWER_SUSPENDM;
359 musb_writeb(mbase, MUSB_POWER, reg);
360 /* REVISIT: Start SESSION_REQUEST here? */
361 break;
362 default:
363 DBG(1, "HNP: Stopping in unknown state %s\n",
364 otg_state_string(musb));
365 }
366
367 /*
368 * When returning to A state after HNP, avoid hub_port_rebounce(),
369 * which cause occasional OPT A "Did not receive reset after connect"
370 * errors.
371 */
372 musb->port1_status &=
373 ~(1 << USB_PORT_FEAT_C_CONNECTION);
374}
375
376#endif
377
378/*
379 * Interrupt Service Routine to record USB "global" interrupts.
380 * Since these do not happen often and signify things of
381 * paramount importance, it seems OK to check them individually;
382 * the order of the tests is specified in the manual
383 *
384 * @param musb instance pointer
385 * @param int_usb register contents
386 * @param devctl
387 * @param power
388 */
389
390#define STAGE0_MASK (MUSB_INTR_RESUME | MUSB_INTR_SESSREQ \
391 | MUSB_INTR_VBUSERROR | MUSB_INTR_CONNECT \
392 | MUSB_INTR_RESET)
393
394static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
395 u8 devctl, u8 power)
396{
397 irqreturn_t handled = IRQ_NONE;
398 void __iomem *mbase = musb->mregs;
399
400 DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
401 int_usb);
402
403 /* in host mode, the peripheral may issue remote wakeup.
404 * in peripheral mode, the host may resume the link.
405 * spurious RESUME irqs happen too, paired with SUSPEND.
406 */
407 if (int_usb & MUSB_INTR_RESUME) {
408 handled = IRQ_HANDLED;
409 DBG(3, "RESUME (%s)\n", otg_state_string(musb));
410
411 if (devctl & MUSB_DEVCTL_HM) {
412#ifdef CONFIG_USB_MUSB_HDRC_HCD
413 switch (musb->xceiv.state) {
414 case OTG_STATE_A_SUSPEND:
415 /* remote wakeup? later, GetPortStatus
416 * will stop RESUME signaling
417 */
418
419 if (power & MUSB_POWER_SUSPENDM) {
420 /* spurious */
421 musb->int_usb &= ~MUSB_INTR_SUSPEND;
422 DBG(2, "Spurious SUSPENDM\n");
423 break;
424 }
425
426 power &= ~MUSB_POWER_SUSPENDM;
427 musb_writeb(mbase, MUSB_POWER,
428 power | MUSB_POWER_RESUME);
429
430 musb->port1_status |=
431 (USB_PORT_STAT_C_SUSPEND << 16)
432 | MUSB_PORT_STAT_RESUME;
433 musb->rh_timer = jiffies
434 + msecs_to_jiffies(20);
435
436 musb->xceiv.state = OTG_STATE_A_HOST;
437 musb->is_active = 1;
438 usb_hcd_resume_root_hub(musb_to_hcd(musb));
439 break;
440 case OTG_STATE_B_WAIT_ACON:
441 musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
442 musb->is_active = 1;
443 MUSB_DEV_MODE(musb);
444 break;
445 default:
446 WARNING("bogus %s RESUME (%s)\n",
447 "host",
448 otg_state_string(musb));
449 }
450#endif
451 } else {
452 switch (musb->xceiv.state) {
453#ifdef CONFIG_USB_MUSB_HDRC_HCD
454 case OTG_STATE_A_SUSPEND:
455 /* possibly DISCONNECT is upcoming */
456 musb->xceiv.state = OTG_STATE_A_HOST;
457 usb_hcd_resume_root_hub(musb_to_hcd(musb));
458 break;
459#endif
460#ifdef CONFIG_USB_GADGET_MUSB_HDRC
461 case OTG_STATE_B_WAIT_ACON:
462 case OTG_STATE_B_PERIPHERAL:
463 /* disconnect while suspended? we may
464 * not get a disconnect irq...
465 */
466 if ((devctl & MUSB_DEVCTL_VBUS)
467 != (3 << MUSB_DEVCTL_VBUS_SHIFT)
468 ) {
469 musb->int_usb |= MUSB_INTR_DISCONNECT;
470 musb->int_usb &= ~MUSB_INTR_SUSPEND;
471 break;
472 }
473 musb_g_resume(musb);
474 break;
475 case OTG_STATE_B_IDLE:
476 musb->int_usb &= ~MUSB_INTR_SUSPEND;
477 break;
478#endif
479 default:
480 WARNING("bogus %s RESUME (%s)\n",
481 "peripheral",
482 otg_state_string(musb));
483 }
484 }
485 }
486
487#ifdef CONFIG_USB_MUSB_HDRC_HCD
488 /* see manual for the order of the tests */
489 if (int_usb & MUSB_INTR_SESSREQ) {
490 DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb));
491
492 /* IRQ arrives from ID pin sense or (later, if VBUS power
493 * is removed) SRP. responses are time critical:
494 * - turn on VBUS (with silicon-specific mechanism)
495 * - go through A_WAIT_VRISE
496 * - ... to A_WAIT_BCON.
497 * a_wait_vrise_tmout triggers VBUS_ERROR transitions
498 */
499 musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
500 musb->ep0_stage = MUSB_EP0_START;
501 musb->xceiv.state = OTG_STATE_A_IDLE;
502 MUSB_HST_MODE(musb);
503 musb_set_vbus(musb, 1);
504
505 handled = IRQ_HANDLED;
506 }
507
508 if (int_usb & MUSB_INTR_VBUSERROR) {
509 int ignore = 0;
510
511 /* During connection as an A-Device, we may see a short
512 * current spikes causing voltage drop, because of cable
513 * and peripheral capacitance combined with vbus draw.
514 * (So: less common with truly self-powered devices, where
515 * vbus doesn't act like a power supply.)
516 *
517 * Such spikes are short; usually less than ~500 usec, max
518 * of ~2 msec. That is, they're not sustained overcurrent
519 * errors, though they're reported using VBUSERROR irqs.
520 *
521 * Workarounds: (a) hardware: use self powered devices.
522 * (b) software: ignore non-repeated VBUS errors.
523 *
524 * REVISIT: do delays from lots of DEBUG_KERNEL checks
525 * make trouble here, keeping VBUS < 4.4V ?
526 */
527 switch (musb->xceiv.state) {
528 case OTG_STATE_A_HOST:
529 /* recovery is dicey once we've gotten past the
530 * initial stages of enumeration, but if VBUS
531 * stayed ok at the other end of the link, and
532 * another reset is due (at least for high speed,
533 * to redo the chirp etc), it might work OK...
534 */
535 case OTG_STATE_A_WAIT_BCON:
536 case OTG_STATE_A_WAIT_VRISE:
537 if (musb->vbuserr_retry) {
538 musb->vbuserr_retry--;
539 ignore = 1;
540 devctl |= MUSB_DEVCTL_SESSION;
541 musb_writeb(mbase, MUSB_DEVCTL, devctl);
542 } else {
543 musb->port1_status |=
544 (1 << USB_PORT_FEAT_OVER_CURRENT)
545 | (1 << USB_PORT_FEAT_C_OVER_CURRENT);
546 }
547 break;
548 default:
549 break;
550 }
551
552 DBG(1, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n",
553 otg_state_string(musb),
554 devctl,
555 ({ char *s;
556 switch (devctl & MUSB_DEVCTL_VBUS) {
557 case 0 << MUSB_DEVCTL_VBUS_SHIFT:
558 s = "<SessEnd"; break;
559 case 1 << MUSB_DEVCTL_VBUS_SHIFT:
560 s = "<AValid"; break;
561 case 2 << MUSB_DEVCTL_VBUS_SHIFT:
562 s = "<VBusValid"; break;
563 /* case 3 << MUSB_DEVCTL_VBUS_SHIFT: */
564 default:
565 s = "VALID"; break;
566 }; s; }),
567 VBUSERR_RETRY_COUNT - musb->vbuserr_retry,
568 musb->port1_status);
569
570 /* go through A_WAIT_VFALL then start a new session */
571 if (!ignore)
572 musb_set_vbus(musb, 0);
573 handled = IRQ_HANDLED;
574 }
575
576 if (int_usb & MUSB_INTR_CONNECT) {
577 struct usb_hcd *hcd = musb_to_hcd(musb);
578
579 handled = IRQ_HANDLED;
580 musb->is_active = 1;
581 set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
582
583 musb->ep0_stage = MUSB_EP0_START;
584
585#ifdef CONFIG_USB_MUSB_OTG
586 /* flush endpoints when transitioning from Device Mode */
587 if (is_peripheral_active(musb)) {
588 /* REVISIT HNP; just force disconnect */
589 }
590 musb_writew(mbase, MUSB_INTRTXE, musb->epmask);
591 musb_writew(mbase, MUSB_INTRRXE, musb->epmask & 0xfffe);
592 musb_writeb(mbase, MUSB_INTRUSBE, 0xf7);
593#endif
594 musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED
595 |USB_PORT_STAT_HIGH_SPEED
596 |USB_PORT_STAT_ENABLE
597 );
598 musb->port1_status |= USB_PORT_STAT_CONNECTION
599 |(USB_PORT_STAT_C_CONNECTION << 16);
600
601 /* high vs full speed is just a guess until after reset */
602 if (devctl & MUSB_DEVCTL_LSDEV)
603 musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
604
605 if (hcd->status_urb)
606 usb_hcd_poll_rh_status(hcd);
607 else
608 usb_hcd_resume_root_hub(hcd);
609
610 MUSB_HST_MODE(musb);
611
612 /* indicate new connection to OTG machine */
613 switch (musb->xceiv.state) {
614 case OTG_STATE_B_PERIPHERAL:
615 if (int_usb & MUSB_INTR_SUSPEND) {
616 DBG(1, "HNP: SUSPEND+CONNECT, now b_host\n");
617 musb->xceiv.state = OTG_STATE_B_HOST;
618 hcd->self.is_b_host = 1;
619 int_usb &= ~MUSB_INTR_SUSPEND;
620 } else
621 DBG(1, "CONNECT as b_peripheral???\n");
622 break;
623 case OTG_STATE_B_WAIT_ACON:
624 DBG(1, "HNP: Waiting to switch to b_host state\n");
625 musb->xceiv.state = OTG_STATE_B_HOST;
626 hcd->self.is_b_host = 1;
627 break;
628 default:
629 if ((devctl & MUSB_DEVCTL_VBUS)
630 == (3 << MUSB_DEVCTL_VBUS_SHIFT)) {
631 musb->xceiv.state = OTG_STATE_A_HOST;
632 hcd->self.is_b_host = 0;
633 }
634 break;
635 }
636 DBG(1, "CONNECT (%s) devctl %02x\n",
637 otg_state_string(musb), devctl);
638 }
639#endif /* CONFIG_USB_MUSB_HDRC_HCD */
640
641 /* mentor saves a bit: bus reset and babble share the same irq.
642 * only host sees babble; only peripheral sees bus reset.
643 */
644 if (int_usb & MUSB_INTR_RESET) {
645 if (is_host_capable() && (devctl & MUSB_DEVCTL_HM) != 0) {
646 /*
647 * Looks like non-HS BABBLE can be ignored, but
648 * HS BABBLE is an error condition. For HS the solution
649 * is to avoid babble in the first place and fix what
650 * caused BABBLE. When HS BABBLE happens we can only
651 * stop the session.
652 */
653 if (devctl & (MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV))
654 DBG(1, "BABBLE devctl: %02x\n", devctl);
655 else {
656 ERR("Stopping host session -- babble\n");
657 musb_writeb(mbase, MUSB_DEVCTL, 0);
658 }
659 } else if (is_peripheral_capable()) {
660 DBG(1, "BUS RESET as %s\n", otg_state_string(musb));
661 switch (musb->xceiv.state) {
662#ifdef CONFIG_USB_OTG
663 case OTG_STATE_A_SUSPEND:
664 /* We need to ignore disconnect on suspend
665 * otherwise tusb 2.0 won't reconnect after a
666 * power cycle, which breaks otg compliance.
667 */
668 musb->ignore_disconnect = 1;
669 musb_g_reset(musb);
670 /* FALLTHROUGH */
671 case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */
672 DBG(1, "HNP: Setting timer as %s\n",
673 otg_state_string(musb));
674 musb_otg_timer.data = (unsigned long)musb;
675 mod_timer(&musb_otg_timer, jiffies
676 + msecs_to_jiffies(100));
677 break;
678 case OTG_STATE_A_PERIPHERAL:
679 musb_hnp_stop(musb);
680 break;
681 case OTG_STATE_B_WAIT_ACON:
682 DBG(1, "HNP: RESET (%s), to b_peripheral\n",
683 otg_state_string(musb));
684 musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
685 musb_g_reset(musb);
686 break;
687#endif
688 case OTG_STATE_B_IDLE:
689 musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
690 /* FALLTHROUGH */
691 case OTG_STATE_B_PERIPHERAL:
692 musb_g_reset(musb);
693 break;
694 default:
695 DBG(1, "Unhandled BUS RESET as %s\n",
696 otg_state_string(musb));
697 }
698 }
699
700 handled = IRQ_HANDLED;
701 }
702 schedule_work(&musb->irq_work);
703
704 return handled;
705}
706
707/*
708 * Interrupt Service Routine to record USB "global" interrupts.
709 * Since these do not happen often and signify things of
710 * paramount importance, it seems OK to check them individually;
711 * the order of the tests is specified in the manual
712 *
713 * @param musb instance pointer
714 * @param int_usb register contents
715 * @param devctl
716 * @param power
717 */
718static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
719 u8 devctl, u8 power)
720{
721 irqreturn_t handled = IRQ_NONE;
722
723#if 0
724/* REVISIT ... this would be for multiplexing periodic endpoints, or
725 * supporting transfer phasing to prevent exceeding ISO bandwidth
726 * limits of a given frame or microframe.
727 *
728 * It's not needed for peripheral side, which dedicates endpoints;
729 * though it _might_ use SOF irqs for other purposes.
730 *
731 * And it's not currently needed for host side, which also dedicates
732 * endpoints, relies on TX/RX interval registers, and isn't claimed
733 * to support ISO transfers yet.
734 */
735 if (int_usb & MUSB_INTR_SOF) {
736 void __iomem *mbase = musb->mregs;
737 struct musb_hw_ep *ep;
738 u8 epnum;
739 u16 frame;
740
741 DBG(6, "START_OF_FRAME\n");
742 handled = IRQ_HANDLED;
743
744 /* start any periodic Tx transfers waiting for current frame */
745 frame = musb_readw(mbase, MUSB_FRAME);
746 ep = musb->endpoints;
747 for (epnum = 1; (epnum < musb->nr_endpoints)
748 && (musb->epmask >= (1 << epnum));
749 epnum++, ep++) {
750 /*
751 * FIXME handle framecounter wraps (12 bits)
752 * eliminate duplicated StartUrb logic
753 */
754 if (ep->dwWaitFrame >= frame) {
755 ep->dwWaitFrame = 0;
756 pr_debug("SOF --> periodic TX%s on %d\n",
757 ep->tx_channel ? " DMA" : "",
758 epnum);
759 if (!ep->tx_channel)
760 musb_h_tx_start(musb, epnum);
761 else
762 cppi_hostdma_start(musb, epnum);
763 }
764 } /* end of for loop */
765 }
766#endif
767
768 if ((int_usb & MUSB_INTR_DISCONNECT) && !musb->ignore_disconnect) {
769 DBG(1, "DISCONNECT (%s) as %s, devctl %02x\n",
770 otg_state_string(musb),
771 MUSB_MODE(musb), devctl);
772 handled = IRQ_HANDLED;
773
774 switch (musb->xceiv.state) {
775#ifdef CONFIG_USB_MUSB_HDRC_HCD
776 case OTG_STATE_A_HOST:
777 case OTG_STATE_A_SUSPEND:
778 musb_root_disconnect(musb);
779 if (musb->a_wait_bcon != 0)
780 musb_platform_try_idle(musb, jiffies
781 + msecs_to_jiffies(musb->a_wait_bcon));
782 break;
783#endif /* HOST */
784#ifdef CONFIG_USB_MUSB_OTG
785 case OTG_STATE_B_HOST:
786 musb_hnp_stop(musb);
787 break;
788 case OTG_STATE_A_PERIPHERAL:
789 musb_hnp_stop(musb);
790 musb_root_disconnect(musb);
791 /* FALLTHROUGH */
792 case OTG_STATE_B_WAIT_ACON:
793 /* FALLTHROUGH */
794#endif /* OTG */
795#ifdef CONFIG_USB_GADGET_MUSB_HDRC
796 case OTG_STATE_B_PERIPHERAL:
797 case OTG_STATE_B_IDLE:
798 musb_g_disconnect(musb);
799 break;
800#endif /* GADGET */
801 default:
802 WARNING("unhandled DISCONNECT transition (%s)\n",
803 otg_state_string(musb));
804 break;
805 }
806
807 schedule_work(&musb->irq_work);
808 }
809
810 if (int_usb & MUSB_INTR_SUSPEND) {
811 DBG(1, "SUSPEND (%s) devctl %02x power %02x\n",
812 otg_state_string(musb), devctl, power);
813 handled = IRQ_HANDLED;
814
815 switch (musb->xceiv.state) {
816#ifdef CONFIG_USB_MUSB_OTG
817 case OTG_STATE_A_PERIPHERAL:
818 /*
819 * We cannot stop HNP here, devctl BDEVICE might be
820 * still set.
821 */
822 break;
823#endif
824 case OTG_STATE_B_PERIPHERAL:
825 musb_g_suspend(musb);
826 musb->is_active = is_otg_enabled(musb)
827 && musb->xceiv.gadget->b_hnp_enable;
828 if (musb->is_active) {
829#ifdef CONFIG_USB_MUSB_OTG
830 musb->xceiv.state = OTG_STATE_B_WAIT_ACON;
831 DBG(1, "HNP: Setting timer for b_ase0_brst\n");
832 musb_otg_timer.data = (unsigned long)musb;
833 mod_timer(&musb_otg_timer, jiffies
834 + msecs_to_jiffies(TB_ASE0_BRST));
835#endif
836 }
837 break;
838 case OTG_STATE_A_WAIT_BCON:
839 if (musb->a_wait_bcon != 0)
840 musb_platform_try_idle(musb, jiffies
841 + msecs_to_jiffies(musb->a_wait_bcon));
842 break;
843 case OTG_STATE_A_HOST:
844 musb->xceiv.state = OTG_STATE_A_SUSPEND;
845 musb->is_active = is_otg_enabled(musb)
846 && musb->xceiv.host->b_hnp_enable;
847 break;
848 case OTG_STATE_B_HOST:
849 /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
850 DBG(1, "REVISIT: SUSPEND as B_HOST\n");
851 break;
852 default:
853 /* "should not happen" */
854 musb->is_active = 0;
855 break;
856 }
857 schedule_work(&musb->irq_work);
858 }
859
860
861 return handled;
862}
863
864/*-------------------------------------------------------------------------*/
865
866/*
867* Program the HDRC to start (enable interrupts, dma, etc.).
868*/
869void musb_start(struct musb *musb)
870{
871 void __iomem *regs = musb->mregs;
872 u8 devctl = musb_readb(regs, MUSB_DEVCTL);
873
874 DBG(2, "<== devctl %02x\n", devctl);
875
876 /* Set INT enable registers, enable interrupts */
877 musb_writew(regs, MUSB_INTRTXE, musb->epmask);
878 musb_writew(regs, MUSB_INTRRXE, musb->epmask & 0xfffe);
879 musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
880
881 musb_writeb(regs, MUSB_TESTMODE, 0);
882
883 /* put into basic highspeed mode and start session */
884 musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
885 | MUSB_POWER_SOFTCONN
886 | MUSB_POWER_HSENAB
887 /* ENSUSPEND wedges tusb */
888 /* | MUSB_POWER_ENSUSPEND */
889 );
890
891 musb->is_active = 0;
892 devctl = musb_readb(regs, MUSB_DEVCTL);
893 devctl &= ~MUSB_DEVCTL_SESSION;
894
895 if (is_otg_enabled(musb)) {
896 /* session started after:
897 * (a) ID-grounded irq, host mode;
898 * (b) vbus present/connect IRQ, peripheral mode;
899 * (c) peripheral initiates, using SRP
900 */
901 if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
902 musb->is_active = 1;
903 else
904 devctl |= MUSB_DEVCTL_SESSION;
905
906 } else if (is_host_enabled(musb)) {
907 /* assume ID pin is hard-wired to ground */
908 devctl |= MUSB_DEVCTL_SESSION;
909
910 } else /* peripheral is enabled */ {
911 if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
912 musb->is_active = 1;
913 }
914 musb_platform_enable(musb);
915 musb_writeb(regs, MUSB_DEVCTL, devctl);
916}
917
918
919static void musb_generic_disable(struct musb *musb)
920{
921 void __iomem *mbase = musb->mregs;
922 u16 temp;
923
924 /* disable interrupts */
925 musb_writeb(mbase, MUSB_INTRUSBE, 0);
926 musb_writew(mbase, MUSB_INTRTXE, 0);
927 musb_writew(mbase, MUSB_INTRRXE, 0);
928
929 /* off */
930 musb_writeb(mbase, MUSB_DEVCTL, 0);
931
932 /* flush pending interrupts */
933 temp = musb_readb(mbase, MUSB_INTRUSB);
934 temp = musb_readw(mbase, MUSB_INTRTX);
935 temp = musb_readw(mbase, MUSB_INTRRX);
936
937}
938
939/*
940 * Make the HDRC stop (disable interrupts, etc.);
941 * reversible by musb_start
942 * called on gadget driver unregister
943 * with controller locked, irqs blocked
944 * acts as a NOP unless some role activated the hardware
945 */
946void musb_stop(struct musb *musb)
947{
948 /* stop IRQs, timers, ... */
949 musb_platform_disable(musb);
950 musb_generic_disable(musb);
951 DBG(3, "HDRC disabled\n");
952
953 /* FIXME
954 * - mark host and/or peripheral drivers unusable/inactive
955 * - disable DMA (and enable it in HdrcStart)
956 * - make sure we can musb_start() after musb_stop(); with
957 * OTG mode, gadget driver module rmmod/modprobe cycles that
958 * - ...
959 */
960 musb_platform_try_idle(musb, 0);
961}
962
963static void musb_shutdown(struct platform_device *pdev)
964{
965 struct musb *musb = dev_to_musb(&pdev->dev);
966 unsigned long flags;
967
968 spin_lock_irqsave(&musb->lock, flags);
969 musb_platform_disable(musb);
970 musb_generic_disable(musb);
971 if (musb->clock) {
972 clk_put(musb->clock);
973 musb->clock = NULL;
974 }
975 spin_unlock_irqrestore(&musb->lock, flags);
976
977 /* FIXME power down */
978}
979
980
981/*-------------------------------------------------------------------------*/
982
983/*
984 * The silicon either has hard-wired endpoint configurations, or else
985 * "dynamic fifo" sizing. The driver has support for both, though at this
986 * writing only the dynamic sizing is very well tested. We use normal
987 * idioms to so both modes are compile-tested, but dead code elimination
988 * leaves only the relevant one in the object file.
989 *
990 * We don't currently use dynamic fifo setup capability to do anything
991 * more than selecting one of a bunch of predefined configurations.
992 */
993#if defined(CONFIG_USB_TUSB6010) || \
994 defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
995static ushort __initdata fifo_mode = 4;
996#else
997static ushort __initdata fifo_mode = 2;
998#endif
999
1000/* "modprobe ... fifo_mode=1" etc */
1001module_param(fifo_mode, ushort, 0);
1002MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration");
1003
1004
1005enum fifo_style { FIFO_RXTX, FIFO_TX, FIFO_RX } __attribute__ ((packed));
1006enum buf_mode { BUF_SINGLE, BUF_DOUBLE } __attribute__ ((packed));
1007
1008struct fifo_cfg {
1009 u8 hw_ep_num;
1010 enum fifo_style style;
1011 enum buf_mode mode;
1012 u16 maxpacket;
1013};
1014
1015/*
1016 * tables defining fifo_mode values. define more if you like.
1017 * for host side, make sure both halves of ep1 are set up.
1018 */
1019
1020/* mode 0 - fits in 2KB */
1021static struct fifo_cfg __initdata mode_0_cfg[] = {
1022{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
1023{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
1024{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, },
1025{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
1026{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
1027};
1028
1029/* mode 1 - fits in 4KB */
1030static struct fifo_cfg __initdata mode_1_cfg[] = {
1031{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
1032{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
1033{ .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, },
1034{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
1035{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
1036};
1037
1038/* mode 2 - fits in 4KB */
1039static struct fifo_cfg __initdata mode_2_cfg[] = {
1040{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
1041{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
1042{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
1043{ .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, },
1044{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
1045{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
1046};
1047
1048/* mode 3 - fits in 4KB */
1049static struct fifo_cfg __initdata mode_3_cfg[] = {
1050{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, },
1051{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, },
1052{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
1053{ .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, },
1054{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, },
1055{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, },
1056};
1057
1058/* mode 4 - fits in 16KB */
1059static struct fifo_cfg __initdata mode_4_cfg[] = {
1060{ .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, },
1061{ .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, },
1062{ .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, },
1063{ .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, },
1064{ .hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512, },
1065{ .hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512, },
1066{ .hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 512, },
1067{ .hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 512, },
1068{ .hw_ep_num = 5, .style = FIFO_TX, .maxpacket = 512, },
1069{ .hw_ep_num = 5, .style = FIFO_RX, .maxpacket = 512, },
1070{ .hw_ep_num = 6, .style = FIFO_TX, .maxpacket = 512, },
1071{ .hw_ep_num = 6, .style = FIFO_RX, .maxpacket = 512, },
1072{ .hw_ep_num = 7, .style = FIFO_TX, .maxpacket = 512, },
1073{ .hw_ep_num = 7, .style = FIFO_RX, .maxpacket = 512, },
1074{ .hw_ep_num = 8, .style = FIFO_TX, .maxpacket = 512, },
1075{ .hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 512, },
1076{ .hw_ep_num = 9, .style = FIFO_TX, .maxpacket = 512, },
1077{ .hw_ep_num = 9, .style = FIFO_RX, .maxpacket = 512, },
1078{ .hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 512, },
1079{ .hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 512, },
1080{ .hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 512, },
1081{ .hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 512, },
1082{ .hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 512, },
1083{ .hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 512, },
1084{ .hw_ep_num = 13, .style = FIFO_TX, .maxpacket = 512, },
1085{ .hw_ep_num = 13, .style = FIFO_RX, .maxpacket = 512, },
1086{ .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, },
1087{ .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
1088};
1089
1090
1091/*
1092 * configure a fifo; for non-shared endpoints, this may be called
1093 * once for a tx fifo and once for an rx fifo.
1094 *
1095 * returns negative errno or offset for next fifo.
1096 */
1097static int __init
1098fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep,
1099 const struct fifo_cfg *cfg, u16 offset)
1100{
1101 void __iomem *mbase = musb->mregs;
1102 int size = 0;
1103 u16 maxpacket = cfg->maxpacket;
1104 u16 c_off = offset >> 3;
1105 u8 c_size;
1106
1107 /* expect hw_ep has already been zero-initialized */
1108
1109 size = ffs(max(maxpacket, (u16) 8)) - 1;
1110 maxpacket = 1 << size;
1111
1112 c_size = size - 3;
1113 if (cfg->mode == BUF_DOUBLE) {
1114 if ((offset + (maxpacket << 1)) >
1115 (1 << (musb->config->ram_bits + 2)))
1116 return -EMSGSIZE;
1117 c_size |= MUSB_FIFOSZ_DPB;
1118 } else {
1119 if ((offset + maxpacket) > (1 << (musb->config->ram_bits + 2)))
1120 return -EMSGSIZE;
1121 }
1122
1123 /* configure the FIFO */
1124 musb_writeb(mbase, MUSB_INDEX, hw_ep->epnum);
1125
1126#ifdef CONFIG_USB_MUSB_HDRC_HCD
1127 /* EP0 reserved endpoint for control, bidirectional;
1128 * EP1 reserved for bulk, two unidirection halves.
1129 */
1130 if (hw_ep->epnum == 1)
1131 musb->bulk_ep = hw_ep;
1132 /* REVISIT error check: be sure ep0 can both rx and tx ... */
1133#endif
1134 switch (cfg->style) {
1135 case FIFO_TX:
1136 musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
1137 musb_writew(mbase, MUSB_TXFIFOADD, c_off);
1138 hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
1139 hw_ep->max_packet_sz_tx = maxpacket;
1140 break;
1141 case FIFO_RX:
1142 musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
1143 musb_writew(mbase, MUSB_RXFIFOADD, c_off);
1144 hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
1145 hw_ep->max_packet_sz_rx = maxpacket;
1146 break;
1147 case FIFO_RXTX:
1148 musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
1149 musb_writew(mbase, MUSB_TXFIFOADD, c_off);
1150 hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB);
1151 hw_ep->max_packet_sz_rx = maxpacket;
1152
1153 musb_writeb(mbase, MUSB_RXFIFOSZ, c_size);
1154 musb_writew(mbase, MUSB_RXFIFOADD, c_off);
1155 hw_ep->tx_double_buffered = hw_ep->rx_double_buffered;
1156 hw_ep->max_packet_sz_tx = maxpacket;
1157
1158 hw_ep->is_shared_fifo = true;
1159 break;
1160 }
1161
1162 /* NOTE rx and tx endpoint irqs aren't managed separately,
1163 * which happens to be ok
1164 */
1165 musb->epmask |= (1 << hw_ep->epnum);
1166
1167 return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0));
1168}
1169
1170static struct fifo_cfg __initdata ep0_cfg = {
1171 .style = FIFO_RXTX, .maxpacket = 64,
1172};
1173
1174static int __init ep_config_from_table(struct musb *musb)
1175{
1176 const struct fifo_cfg *cfg;
1177 unsigned i, n;
1178 int offset;
1179 struct musb_hw_ep *hw_ep = musb->endpoints;
1180
1181 switch (fifo_mode) {
1182 default:
1183 fifo_mode = 0;
1184 /* FALLTHROUGH */
1185 case 0:
1186 cfg = mode_0_cfg;
1187 n = ARRAY_SIZE(mode_0_cfg);
1188 break;
1189 case 1:
1190 cfg = mode_1_cfg;
1191 n = ARRAY_SIZE(mode_1_cfg);
1192 break;
1193 case 2:
1194 cfg = mode_2_cfg;
1195 n = ARRAY_SIZE(mode_2_cfg);
1196 break;
1197 case 3:
1198 cfg = mode_3_cfg;
1199 n = ARRAY_SIZE(mode_3_cfg);
1200 break;
1201 case 4:
1202 cfg = mode_4_cfg;
1203 n = ARRAY_SIZE(mode_4_cfg);
1204 break;
1205 }
1206
1207 printk(KERN_DEBUG "%s: setup fifo_mode %d\n",
1208 musb_driver_name, fifo_mode);
1209
1210
1211 offset = fifo_setup(musb, hw_ep, &ep0_cfg, 0);
1212 /* assert(offset > 0) */
1213
1214 /* NOTE: for RTL versions >= 1.400 EPINFO and RAMINFO would
1215 * be better than static musb->config->num_eps and DYN_FIFO_SIZE...
1216 */
1217
1218 for (i = 0; i < n; i++) {
1219 u8 epn = cfg->hw_ep_num;
1220
1221 if (epn >= musb->config->num_eps) {
1222 pr_debug("%s: invalid ep %d\n",
1223 musb_driver_name, epn);
1224 continue;
1225 }
1226 offset = fifo_setup(musb, hw_ep + epn, cfg++, offset);
1227 if (offset < 0) {
1228 pr_debug("%s: mem overrun, ep %d\n",
1229 musb_driver_name, epn);
1230 return -EINVAL;
1231 }
1232 epn++;
1233 musb->nr_endpoints = max(epn, musb->nr_endpoints);
1234 }
1235
1236 printk(KERN_DEBUG "%s: %d/%d max ep, %d/%d memory\n",
1237 musb_driver_name,
1238 n + 1, musb->config->num_eps * 2 - 1,
1239 offset, (1 << (musb->config->ram_bits + 2)));
1240
1241#ifdef CONFIG_USB_MUSB_HDRC_HCD
1242 if (!musb->bulk_ep) {
1243 pr_debug("%s: missing bulk\n", musb_driver_name);
1244 return -EINVAL;
1245 }
1246#endif
1247
1248 return 0;
1249}
1250
1251
1252/*
1253 * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false
1254 * @param musb the controller
1255 */
1256static int __init ep_config_from_hw(struct musb *musb)
1257{
1258 u8 epnum = 0, reg;
1259 struct musb_hw_ep *hw_ep;
1260 void *mbase = musb->mregs;
1261
1262 DBG(2, "<== static silicon ep config\n");
1263
1264 /* FIXME pick up ep0 maxpacket size */
1265
1266 for (epnum = 1; epnum < musb->config->num_eps; epnum++) {
1267 musb_ep_select(mbase, epnum);
1268 hw_ep = musb->endpoints + epnum;
1269
1270 /* read from core using indexed model */
1271 reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE);
1272 if (!reg) {
1273 /* 0's returned when no more endpoints */
1274 break;
1275 }
1276 musb->nr_endpoints++;
1277 musb->epmask |= (1 << epnum);
1278
1279 hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f);
1280
1281 /* shared TX/RX FIFO? */
1282 if ((reg & 0xf0) == 0xf0) {
1283 hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx;
1284 hw_ep->is_shared_fifo = true;
1285 continue;
1286 } else {
1287 hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4);
1288 hw_ep->is_shared_fifo = false;
1289 }
1290
1291 /* FIXME set up hw_ep->{rx,tx}_double_buffered */
1292
1293#ifdef CONFIG_USB_MUSB_HDRC_HCD
1294 /* pick an RX/TX endpoint for bulk */
1295 if (hw_ep->max_packet_sz_tx < 512
1296 || hw_ep->max_packet_sz_rx < 512)
1297 continue;
1298
1299 /* REVISIT: this algorithm is lazy, we should at least
1300 * try to pick a double buffered endpoint.
1301 */
1302 if (musb->bulk_ep)
1303 continue;
1304 musb->bulk_ep = hw_ep;
1305#endif
1306 }
1307
1308#ifdef CONFIG_USB_MUSB_HDRC_HCD
1309 if (!musb->bulk_ep) {
1310 pr_debug("%s: missing bulk\n", musb_driver_name);
1311 return -EINVAL;
1312 }
1313#endif
1314
1315 return 0;
1316}
1317
1318enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, };
1319
1320/* Initialize MUSB (M)HDRC part of the USB hardware subsystem;
1321 * configure endpoints, or take their config from silicon
1322 */
1323static int __init musb_core_init(u16 musb_type, struct musb *musb)
1324{
1325#ifdef MUSB_AHB_ID
1326 u32 data;
1327#endif
1328 u8 reg;
1329 char *type;
1330 u16 hwvers, rev_major, rev_minor;
1331 char aInfo[78], aRevision[32], aDate[12];
1332 void __iomem *mbase = musb->mregs;
1333 int status = 0;
1334 int i;
1335
1336 /* log core options (read using indexed model) */
1337 musb_ep_select(mbase, 0);
1338 reg = musb_readb(mbase, 0x10 + MUSB_CONFIGDATA);
1339
1340 strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8");
1341 if (reg & MUSB_CONFIGDATA_DYNFIFO)
1342 strcat(aInfo, ", dyn FIFOs");
1343 if (reg & MUSB_CONFIGDATA_MPRXE) {
1344 strcat(aInfo, ", bulk combine");
1345#ifdef C_MP_RX
1346 musb->bulk_combine = true;
1347#else
1348 strcat(aInfo, " (X)"); /* no driver support */
1349#endif
1350 }
1351 if (reg & MUSB_CONFIGDATA_MPTXE) {
1352 strcat(aInfo, ", bulk split");
1353#ifdef C_MP_TX
1354 musb->bulk_split = true;
1355#else
1356 strcat(aInfo, " (X)"); /* no driver support */
1357#endif
1358 }
1359 if (reg & MUSB_CONFIGDATA_HBRXE) {
1360 strcat(aInfo, ", HB-ISO Rx");
1361 strcat(aInfo, " (X)"); /* no driver support */
1362 }
1363 if (reg & MUSB_CONFIGDATA_HBTXE) {
1364 strcat(aInfo, ", HB-ISO Tx");
1365 strcat(aInfo, " (X)"); /* no driver support */
1366 }
1367 if (reg & MUSB_CONFIGDATA_SOFTCONE)
1368 strcat(aInfo, ", SoftConn");
1369
1370 printk(KERN_DEBUG "%s: ConfigData=0x%02x (%s)\n",
1371 musb_driver_name, reg, aInfo);
1372
1373#ifdef MUSB_AHB_ID
1374 data = musb_readl(mbase, 0x404);
1375 sprintf(aDate, "%04d-%02x-%02x", (data & 0xffff),
1376 (data >> 16) & 0xff, (data >> 24) & 0xff);
1377 /* FIXME ID2 and ID3 are unused */
1378 data = musb_readl(mbase, 0x408);
1379 printk(KERN_DEBUG "ID2=%lx\n", (long unsigned)data);
1380 data = musb_readl(mbase, 0x40c);
1381 printk(KERN_DEBUG "ID3=%lx\n", (long unsigned)data);
1382 reg = musb_readb(mbase, 0x400);
1383 musb_type = ('M' == reg) ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC;
1384#else
1385 aDate[0] = 0;
1386#endif
1387 if (MUSB_CONTROLLER_MHDRC == musb_type) {
1388 musb->is_multipoint = 1;
1389 type = "M";
1390 } else {
1391 musb->is_multipoint = 0;
1392 type = "";
1393#ifdef CONFIG_USB_MUSB_HDRC_HCD
1394#ifndef CONFIG_USB_OTG_BLACKLIST_HUB
1395 printk(KERN_ERR
1396 "%s: kernel must blacklist external hubs\n",
1397 musb_driver_name);
1398#endif
1399#endif
1400 }
1401
1402 /* log release info */
1403 hwvers = musb_readw(mbase, MUSB_HWVERS);
1404 rev_major = (hwvers >> 10) & 0x1f;
1405 rev_minor = hwvers & 0x3ff;
1406 snprintf(aRevision, 32, "%d.%d%s", rev_major,
1407 rev_minor, (hwvers & 0x8000) ? "RC" : "");
1408 printk(KERN_DEBUG "%s: %sHDRC RTL version %s %s\n",
1409 musb_driver_name, type, aRevision, aDate);
1410
1411 /* configure ep0 */
1412 musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE;
1413 musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
1414
1415 /* discover endpoint configuration */
1416 musb->nr_endpoints = 1;
1417 musb->epmask = 1;
1418
1419 if (reg & MUSB_CONFIGDATA_DYNFIFO) {
1420 if (musb->config->dyn_fifo)
1421 status = ep_config_from_table(musb);
1422 else {
1423 ERR("reconfigure software for Dynamic FIFOs\n");
1424 status = -ENODEV;
1425 }
1426 } else {
1427 if (!musb->config->dyn_fifo)
1428 status = ep_config_from_hw(musb);
1429 else {
1430 ERR("reconfigure software for static FIFOs\n");
1431 return -ENODEV;
1432 }
1433 }
1434
1435 if (status < 0)
1436 return status;
1437
1438 /* finish init, and print endpoint config */
1439 for (i = 0; i < musb->nr_endpoints; i++) {
1440 struct musb_hw_ep *hw_ep = musb->endpoints + i;
1441
1442 hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase;
1443#ifdef CONFIG_USB_TUSB6010
1444 hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i);
1445 hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i);
1446 hw_ep->fifo_sync_va =
1447 musb->sync_va + 0x400 + MUSB_FIFO_OFFSET(i);
1448
1449 if (i == 0)
1450 hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF;
1451 else
1452 hw_ep->conf = mbase + 0x400 + (((i - 1) & 0xf) << 2);
1453#endif
1454
1455 hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase;
1456#ifdef CONFIG_USB_MUSB_HDRC_HCD
1457 hw_ep->target_regs = MUSB_BUSCTL_OFFSET(i, 0) + mbase;
1458 hw_ep->rx_reinit = 1;
1459 hw_ep->tx_reinit = 1;
1460#endif
1461
1462 if (hw_ep->max_packet_sz_tx) {
1463 printk(KERN_DEBUG
1464 "%s: hw_ep %d%s, %smax %d\n",
1465 musb_driver_name, i,
1466 hw_ep->is_shared_fifo ? "shared" : "tx",
1467 hw_ep->tx_double_buffered
1468 ? "doublebuffer, " : "",
1469 hw_ep->max_packet_sz_tx);
1470 }
1471 if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) {
1472 printk(KERN_DEBUG
1473 "%s: hw_ep %d%s, %smax %d\n",
1474 musb_driver_name, i,
1475 "rx",
1476 hw_ep->rx_double_buffered
1477 ? "doublebuffer, " : "",
1478 hw_ep->max_packet_sz_rx);
1479 }
1480 if (!(hw_ep->max_packet_sz_tx || hw_ep->max_packet_sz_rx))
1481 DBG(1, "hw_ep %d not configured\n", i);
1482 }
1483
1484 return 0;
1485}
1486
1487/*-------------------------------------------------------------------------*/
1488
1489#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
1490
1491static irqreturn_t generic_interrupt(int irq, void *__hci)
1492{
1493 unsigned long flags;
1494 irqreturn_t retval = IRQ_NONE;
1495 struct musb *musb = __hci;
1496
1497 spin_lock_irqsave(&musb->lock, flags);
1498
1499 musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
1500 musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
1501 musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
1502
1503 if (musb->int_usb || musb->int_tx || musb->int_rx)
1504 retval = musb_interrupt(musb);
1505
1506 spin_unlock_irqrestore(&musb->lock, flags);
1507
1508 /* REVISIT we sometimes get spurious IRQs on g_ep0
1509 * not clear why...
1510 */
1511 if (retval != IRQ_HANDLED)
1512 DBG(5, "spurious?\n");
1513
1514 return IRQ_HANDLED;
1515}
1516
1517#else
1518#define generic_interrupt NULL
1519#endif
1520
1521/*
1522 * handle all the irqs defined by the HDRC core. for now we expect: other
1523 * irq sources (phy, dma, etc) will be handled first, musb->int_* values
1524 * will be assigned, and the irq will already have been acked.
1525 *
1526 * called in irq context with spinlock held, irqs blocked
1527 */
1528irqreturn_t musb_interrupt(struct musb *musb)
1529{
1530 irqreturn_t retval = IRQ_NONE;
1531 u8 devctl, power;
1532 int ep_num;
1533 u32 reg;
1534
1535 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
1536 power = musb_readb(musb->mregs, MUSB_POWER);
1537
1538 DBG(4, "** IRQ %s usb%04x tx%04x rx%04x\n",
1539 (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral",
1540 musb->int_usb, musb->int_tx, musb->int_rx);
1541
1542 /* the core can interrupt us for multiple reasons; docs have
1543 * a generic interrupt flowchart to follow
1544 */
1545 if (musb->int_usb & STAGE0_MASK)
1546 retval |= musb_stage0_irq(musb, musb->int_usb,
1547 devctl, power);
1548
1549 /* "stage 1" is handling endpoint irqs */
1550
1551 /* handle endpoint 0 first */
1552 if (musb->int_tx & 1) {
1553 if (devctl & MUSB_DEVCTL_HM)
1554 retval |= musb_h_ep0_irq(musb);
1555 else
1556 retval |= musb_g_ep0_irq(musb);
1557 }
1558
1559 /* RX on endpoints 1-15 */
1560 reg = musb->int_rx >> 1;
1561 ep_num = 1;
1562 while (reg) {
1563 if (reg & 1) {
1564 /* musb_ep_select(musb->mregs, ep_num); */
1565 /* REVISIT just retval = ep->rx_irq(...) */
1566 retval = IRQ_HANDLED;
1567 if (devctl & MUSB_DEVCTL_HM) {
1568 if (is_host_capable())
1569 musb_host_rx(musb, ep_num);
1570 } else {
1571 if (is_peripheral_capable())
1572 musb_g_rx(musb, ep_num);
1573 }
1574 }
1575
1576 reg >>= 1;
1577 ep_num++;
1578 }
1579
1580 /* TX on endpoints 1-15 */
1581 reg = musb->int_tx >> 1;
1582 ep_num = 1;
1583 while (reg) {
1584 if (reg & 1) {
1585 /* musb_ep_select(musb->mregs, ep_num); */
1586 /* REVISIT just retval |= ep->tx_irq(...) */
1587 retval = IRQ_HANDLED;
1588 if (devctl & MUSB_DEVCTL_HM) {
1589 if (is_host_capable())
1590 musb_host_tx(musb, ep_num);
1591 } else {
1592 if (is_peripheral_capable())
1593 musb_g_tx(musb, ep_num);
1594 }
1595 }
1596 reg >>= 1;
1597 ep_num++;
1598 }
1599
1600 /* finish handling "global" interrupts after handling fifos */
1601 if (musb->int_usb)
1602 retval |= musb_stage2_irq(musb,
1603 musb->int_usb, devctl, power);
1604
1605 return retval;
1606}
1607
1608
1609#ifndef CONFIG_MUSB_PIO_ONLY
1610static int __initdata use_dma = 1;
1611
1612/* "modprobe ... use_dma=0" etc */
1613module_param(use_dma, bool, 0);
1614MODULE_PARM_DESC(use_dma, "enable/disable use of DMA");
1615
1616void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit)
1617{
1618 u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
1619
1620 /* called with controller lock already held */
1621
1622 if (!epnum) {
1623#ifndef CONFIG_USB_TUSB_OMAP_DMA
1624 if (!is_cppi_enabled()) {
1625 /* endpoint 0 */
1626 if (devctl & MUSB_DEVCTL_HM)
1627 musb_h_ep0_irq(musb);
1628 else
1629 musb_g_ep0_irq(musb);
1630 }
1631#endif
1632 } else {
1633 /* endpoints 1..15 */
1634 if (transmit) {
1635 if (devctl & MUSB_DEVCTL_HM) {
1636 if (is_host_capable())
1637 musb_host_tx(musb, epnum);
1638 } else {
1639 if (is_peripheral_capable())
1640 musb_g_tx(musb, epnum);
1641 }
1642 } else {
1643 /* receive */
1644 if (devctl & MUSB_DEVCTL_HM) {
1645 if (is_host_capable())
1646 musb_host_rx(musb, epnum);
1647 } else {
1648 if (is_peripheral_capable())
1649 musb_g_rx(musb, epnum);
1650 }
1651 }
1652 }
1653}
1654
1655#else
1656#define use_dma 0
1657#endif
1658
1659/*-------------------------------------------------------------------------*/
1660
1661#ifdef CONFIG_SYSFS
1662
1663static ssize_t
1664musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
1665{
1666 struct musb *musb = dev_to_musb(dev);
1667 unsigned long flags;
1668 int ret = -EINVAL;
1669
1670 spin_lock_irqsave(&musb->lock, flags);
1671 ret = sprintf(buf, "%s\n", otg_state_string(musb));
1672 spin_unlock_irqrestore(&musb->lock, flags);
1673
1674 return ret;
1675}
1676
1677static ssize_t
1678musb_mode_store(struct device *dev, struct device_attribute *attr,
1679 const char *buf, size_t n)
1680{
1681 struct musb *musb = dev_to_musb(dev);
1682 unsigned long flags;
1683
1684 spin_lock_irqsave(&musb->lock, flags);
1685 if (!strncmp(buf, "host", 4))
1686 musb_platform_set_mode(musb, MUSB_HOST);
1687 if (!strncmp(buf, "peripheral", 10))
1688 musb_platform_set_mode(musb, MUSB_PERIPHERAL);
1689 if (!strncmp(buf, "otg", 3))
1690 musb_platform_set_mode(musb, MUSB_OTG);
1691 spin_unlock_irqrestore(&musb->lock, flags);
1692
1693 return n;
1694}
1695static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store);
1696
1697static ssize_t
1698musb_vbus_store(struct device *dev, struct device_attribute *attr,
1699 const char *buf, size_t n)
1700{
1701 struct musb *musb = dev_to_musb(dev);
1702 unsigned long flags;
1703 unsigned long val;
1704
1705 if (sscanf(buf, "%lu", &val) < 1) {
1706 printk(KERN_ERR "Invalid VBUS timeout ms value\n");
1707 return -EINVAL;
1708 }
1709
1710 spin_lock_irqsave(&musb->lock, flags);
1711 musb->a_wait_bcon = val;
1712 if (musb->xceiv.state == OTG_STATE_A_WAIT_BCON)
1713 musb->is_active = 0;
1714 musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val));
1715 spin_unlock_irqrestore(&musb->lock, flags);
1716
1717 return n;
1718}
1719
1720static ssize_t
1721musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf)
1722{
1723 struct musb *musb = dev_to_musb(dev);
1724 unsigned long flags;
1725 unsigned long val;
1726 int vbus;
1727
1728 spin_lock_irqsave(&musb->lock, flags);
1729 val = musb->a_wait_bcon;
1730 vbus = musb_platform_get_vbus_status(musb);
1731 spin_unlock_irqrestore(&musb->lock, flags);
1732
1733 return sprintf(buf, "Vbus %s, timeout %lu\n",
1734 vbus ? "on" : "off", val);
1735}
1736static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store);
1737
1738#ifdef CONFIG_USB_GADGET_MUSB_HDRC
1739
1740/* Gadget drivers can't know that a host is connected so they might want
1741 * to start SRP, but users can. This allows userspace to trigger SRP.
1742 */
1743static ssize_t
1744musb_srp_store(struct device *dev, struct device_attribute *attr,
1745 const char *buf, size_t n)
1746{
1747 struct musb *musb = dev_to_musb(dev);
1748 unsigned short srp;
1749
1750 if (sscanf(buf, "%hu", &srp) != 1
1751 || (srp != 1)) {
1752 printk(KERN_ERR "SRP: Value must be 1\n");
1753 return -EINVAL;
1754 }
1755
1756 if (srp == 1)
1757 musb_g_wakeup(musb);
1758
1759 return n;
1760}
1761static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store);
1762
1763#endif /* CONFIG_USB_GADGET_MUSB_HDRC */
1764
1765#endif /* sysfs */
1766
1767/* Only used to provide driver mode change events */
1768static void musb_irq_work(struct work_struct *data)
1769{
1770 struct musb *musb = container_of(data, struct musb, irq_work);
1771 static int old_state;
1772
1773 if (musb->xceiv.state != old_state) {
1774 old_state = musb->xceiv.state;
1775 sysfs_notify(&musb->controller->kobj, NULL, "mode");
1776 }
1777}
1778
1779/* --------------------------------------------------------------------------
1780 * Init support
1781 */
1782
1783static struct musb *__init
1784allocate_instance(struct device *dev,
1785 struct musb_hdrc_config *config, void __iomem *mbase)
1786{
1787 struct musb *musb;
1788 struct musb_hw_ep *ep;
1789 int epnum;
1790#ifdef CONFIG_USB_MUSB_HDRC_HCD
1791 struct usb_hcd *hcd;
1792
1793 hcd = usb_create_hcd(&musb_hc_driver, dev, dev->bus_id);
1794 if (!hcd)
1795 return NULL;
1796 /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */
1797
1798 musb = hcd_to_musb(hcd);
1799 INIT_LIST_HEAD(&musb->control);
1800 INIT_LIST_HEAD(&musb->in_bulk);
1801 INIT_LIST_HEAD(&musb->out_bulk);
1802
1803 hcd->uses_new_polling = 1;
1804
1805 musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
1806#else
1807 musb = kzalloc(sizeof *musb, GFP_KERNEL);
1808 if (!musb)
1809 return NULL;
1810 dev_set_drvdata(dev, musb);
1811
1812#endif
1813
1814 musb->mregs = mbase;
1815 musb->ctrl_base = mbase;
1816 musb->nIrq = -ENODEV;
1817 musb->config = config;
1818 for (epnum = 0, ep = musb->endpoints;
1819 epnum < musb->config->num_eps;
1820 epnum++, ep++) {
1821
1822 ep->musb = musb;
1823 ep->epnum = epnum;
1824 }
1825
1826 musb->controller = dev;
1827 return musb;
1828}
1829
1830static void musb_free(struct musb *musb)
1831{
1832 /* this has multiple entry modes. it handles fault cleanup after
1833 * probe(), where things may be partially set up, as well as rmmod
1834 * cleanup after everything's been de-activated.
1835 */
1836
1837#ifdef CONFIG_SYSFS
1838 device_remove_file(musb->controller, &dev_attr_mode);
1839 device_remove_file(musb->controller, &dev_attr_vbus);
1840#ifdef CONFIG_USB_MUSB_OTG
1841 device_remove_file(musb->controller, &dev_attr_srp);
1842#endif
1843#endif
1844
1845#ifdef CONFIG_USB_GADGET_MUSB_HDRC
1846 musb_gadget_cleanup(musb);
1847#endif
1848
1849 if (musb->nIrq >= 0) {
1850 disable_irq_wake(musb->nIrq);
1851 free_irq(musb->nIrq, musb);
1852 }
1853 if (is_dma_capable() && musb->dma_controller) {
1854 struct dma_controller *c = musb->dma_controller;
1855
1856 (void) c->stop(c);
1857 dma_controller_destroy(c);
1858 }
1859
1860 musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
1861 musb_platform_exit(musb);
1862 musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
1863
1864 if (musb->clock) {
1865 clk_disable(musb->clock);
1866 clk_put(musb->clock);
1867 }
1868
1869#ifdef CONFIG_USB_MUSB_OTG
1870 put_device(musb->xceiv.dev);
1871#endif
1872
1873#ifdef CONFIG_USB_MUSB_HDRC_HCD
1874 usb_put_hcd(musb_to_hcd(musb));
1875#else
1876 kfree(musb);
1877#endif
1878}
1879
1880/*
1881 * Perform generic per-controller initialization.
1882 *
1883 * @pDevice: the controller (already clocked, etc)
1884 * @nIrq: irq
1885 * @mregs: virtual address of controller registers,
1886 * not yet corrected for platform-specific offsets
1887 */
1888static int __init
1889musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
1890{
1891 int status;
1892 struct musb *musb;
1893 struct musb_hdrc_platform_data *plat = dev->platform_data;
1894
1895 /* The driver might handle more features than the board; OK.
1896 * Fail when the board needs a feature that's not enabled.
1897 */
1898 if (!plat) {
1899 dev_dbg(dev, "no platform_data?\n");
1900 return -ENODEV;
1901 }
1902 switch (plat->mode) {
1903 case MUSB_HOST:
1904#ifdef CONFIG_USB_MUSB_HDRC_HCD
1905 break;
1906#else
1907 goto bad_config;
1908#endif
1909 case MUSB_PERIPHERAL:
1910#ifdef CONFIG_USB_GADGET_MUSB_HDRC
1911 break;
1912#else
1913 goto bad_config;
1914#endif
1915 case MUSB_OTG:
1916#ifdef CONFIG_USB_MUSB_OTG
1917 break;
1918#else
1919bad_config:
1920#endif
1921 default:
1922 dev_err(dev, "incompatible Kconfig role setting\n");
1923 return -EINVAL;
1924 }
1925
1926 /* allocate */
1927 musb = allocate_instance(dev, plat->config, ctrl);
1928 if (!musb)
1929 return -ENOMEM;
1930
1931 spin_lock_init(&musb->lock);
1932 musb->board_mode = plat->mode;
1933 musb->board_set_power = plat->set_power;
1934 musb->set_clock = plat->set_clock;
1935 musb->min_power = plat->min_power;
1936
1937 /* Clock usage is chip-specific ... functional clock (DaVinci,
1938 * OMAP2430), or PHY ref (some TUSB6010 boards). All this core
1939 * code does is make sure a clock handle is available; platform
1940 * code manages it during start/stop and suspend/resume.
1941 */
1942 if (plat->clock) {
1943 musb->clock = clk_get(dev, plat->clock);
1944 if (IS_ERR(musb->clock)) {
1945 status = PTR_ERR(musb->clock);
1946 musb->clock = NULL;
1947 goto fail;
1948 }
1949 }
1950
1951 /* assume vbus is off */
1952
1953 /* platform adjusts musb->mregs and musb->isr if needed,
1954 * and activates clocks
1955 */
1956 musb->isr = generic_interrupt;
1957 status = musb_platform_init(musb);
1958
1959 if (status < 0)
1960 goto fail;
1961 if (!musb->isr) {
1962 status = -ENODEV;
1963 goto fail2;
1964 }
1965
1966#ifndef CONFIG_MUSB_PIO_ONLY
1967 if (use_dma && dev->dma_mask) {
1968 struct dma_controller *c;
1969
1970 c = dma_controller_create(musb, musb->mregs);
1971 musb->dma_controller = c;
1972 if (c)
1973 (void) c->start(c);
1974 }
1975#endif
1976 /* ideally this would be abstracted in platform setup */
1977 if (!is_dma_capable() || !musb->dma_controller)
1978 dev->dma_mask = NULL;
1979
1980 /* be sure interrupts are disabled before connecting ISR */
1981 musb_platform_disable(musb);
1982 musb_generic_disable(musb);
1983
1984 /* setup musb parts of the core (especially endpoints) */
1985 status = musb_core_init(plat->config->multipoint
1986 ? MUSB_CONTROLLER_MHDRC
1987 : MUSB_CONTROLLER_HDRC, musb);
1988 if (status < 0)
1989 goto fail2;
1990
1991 /* Init IRQ workqueue before request_irq */
1992 INIT_WORK(&musb->irq_work, musb_irq_work);
1993
1994 /* attach to the IRQ */
1995 if (request_irq(nIrq, musb->isr, 0, dev->bus_id, musb)) {
1996 dev_err(dev, "request_irq %d failed!\n", nIrq);
1997 status = -ENODEV;
1998 goto fail2;
1999 }
2000 musb->nIrq = nIrq;
2001/* FIXME this handles wakeup irqs wrong */
2002 if (enable_irq_wake(nIrq) == 0)
2003 device_init_wakeup(dev, 1);
2004
2005 pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n",
2006 musb_driver_name,
2007 ({char *s;
2008 switch (musb->board_mode) {
2009 case MUSB_HOST: s = "Host"; break;
2010 case MUSB_PERIPHERAL: s = "Peripheral"; break;
2011 default: s = "OTG"; break;
2012 }; s; }),
2013 ctrl,
2014 (is_dma_capable() && musb->dma_controller)
2015 ? "DMA" : "PIO",
2016 musb->nIrq);
2017
2018#ifdef CONFIG_USB_MUSB_HDRC_HCD
2019 /* host side needs more setup, except for no-host modes */
2020 if (musb->board_mode != MUSB_PERIPHERAL) {
2021 struct usb_hcd *hcd = musb_to_hcd(musb);
2022
2023 if (musb->board_mode == MUSB_OTG)
2024 hcd->self.otg_port = 1;
2025 musb->xceiv.host = &hcd->self;
2026 hcd->power_budget = 2 * (plat->power ? : 250);
2027 }
2028#endif /* CONFIG_USB_MUSB_HDRC_HCD */
2029
2030 /* For the host-only role, we can activate right away.
2031 * (We expect the ID pin to be forcibly grounded!!)
2032 * Otherwise, wait till the gadget driver hooks up.
2033 */
2034 if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
2035 MUSB_HST_MODE(musb);
2036 musb->xceiv.default_a = 1;
2037 musb->xceiv.state = OTG_STATE_A_IDLE;
2038
2039 status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
2040
2041 DBG(1, "%s mode, status %d, devctl %02x %c\n",
2042 "HOST", status,
2043 musb_readb(musb->mregs, MUSB_DEVCTL),
2044 (musb_readb(musb->mregs, MUSB_DEVCTL)
2045 & MUSB_DEVCTL_BDEVICE
2046 ? 'B' : 'A'));
2047
2048 } else /* peripheral is enabled */ {
2049 MUSB_DEV_MODE(musb);
2050 musb->xceiv.default_a = 0;
2051 musb->xceiv.state = OTG_STATE_B_IDLE;
2052
2053 status = musb_gadget_setup(musb);
2054
2055 DBG(1, "%s mode, status %d, dev%02x\n",
2056 is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
2057 status,
2058 musb_readb(musb->mregs, MUSB_DEVCTL));
2059
2060 }
2061
2062 if (status == 0)
2063 musb_debug_create("driver/musb_hdrc", musb);
2064 else {
2065fail:
2066 if (musb->clock)
2067 clk_put(musb->clock);
2068 device_init_wakeup(dev, 0);
2069 musb_free(musb);
2070 return status;
2071 }
2072
2073#ifdef CONFIG_SYSFS
2074 status = device_create_file(dev, &dev_attr_mode);
2075 status = device_create_file(dev, &dev_attr_vbus);
2076#ifdef CONFIG_USB_GADGET_MUSB_HDRC
2077 status = device_create_file(dev, &dev_attr_srp);
2078#endif /* CONFIG_USB_GADGET_MUSB_HDRC */
2079 status = 0;
2080#endif
2081
2082 return status;
2083
2084fail2:
2085 musb_platform_exit(musb);
2086 goto fail;
2087}
2088
2089/*-------------------------------------------------------------------------*/
2090
2091/* all implementations (PCI bridge to FPGA, VLYNQ, etc) should just
2092 * bridge to a platform device; this driver then suffices.
2093 */
2094
2095#ifndef CONFIG_MUSB_PIO_ONLY
2096static u64 *orig_dma_mask;
2097#endif
2098
2099static int __init musb_probe(struct platform_device *pdev)
2100{
2101 struct device *dev = &pdev->dev;
2102 int irq = platform_get_irq(pdev, 0);
2103 struct resource *iomem;
2104 void __iomem *base;
2105
2106 iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2107 if (!iomem || irq == 0)
2108 return -ENODEV;
2109
2110 base = ioremap(iomem->start, iomem->end - iomem->start + 1);
2111 if (!base) {
2112 dev_err(dev, "ioremap failed\n");
2113 return -ENOMEM;
2114 }
2115
2116#ifndef CONFIG_MUSB_PIO_ONLY
2117 /* clobbered by use_dma=n */
2118 orig_dma_mask = dev->dma_mask;
2119#endif
2120 return musb_init_controller(dev, irq, base);
2121}
2122
2123static int __devexit musb_remove(struct platform_device *pdev)
2124{
2125 struct musb *musb = dev_to_musb(&pdev->dev);
2126 void __iomem *ctrl_base = musb->ctrl_base;
2127
2128 /* this gets called on rmmod.
2129 * - Host mode: host may still be active
2130 * - Peripheral mode: peripheral is deactivated (or never-activated)
2131 * - OTG mode: both roles are deactivated (or never-activated)
2132 */
2133 musb_shutdown(pdev);
2134 musb_debug_delete("driver/musb_hdrc", musb);
2135#ifdef CONFIG_USB_MUSB_HDRC_HCD
2136 if (musb->board_mode == MUSB_HOST)
2137 usb_remove_hcd(musb_to_hcd(musb));
2138#endif
2139 musb_free(musb);
2140 iounmap(ctrl_base);
2141 device_init_wakeup(&pdev->dev, 0);
2142#ifndef CONFIG_MUSB_PIO_ONLY
2143 pdev->dev.dma_mask = orig_dma_mask;
2144#endif
2145 return 0;
2146}
2147
2148#ifdef CONFIG_PM
2149
2150static int musb_suspend(struct platform_device *pdev, pm_message_t message)
2151{
2152 unsigned long flags;
2153 struct musb *musb = dev_to_musb(&pdev->dev);
2154
2155 if (!musb->clock)
2156 return 0;
2157
2158 spin_lock_irqsave(&musb->lock, flags);
2159
2160 if (is_peripheral_active(musb)) {
2161 /* FIXME force disconnect unless we know USB will wake
2162 * the system up quickly enough to respond ...
2163 */
2164 } else if (is_host_active(musb)) {
2165 /* we know all the children are suspended; sometimes
2166 * they will even be wakeup-enabled.
2167 */
2168 }
2169
2170 if (musb->set_clock)
2171 musb->set_clock(musb->clock, 0);
2172 else
2173 clk_disable(musb->clock);
2174 spin_unlock_irqrestore(&musb->lock, flags);
2175 return 0;
2176}
2177
2178static int musb_resume(struct platform_device *pdev)
2179{
2180 unsigned long flags;
2181 struct musb *musb = dev_to_musb(&pdev->dev);
2182
2183 if (!musb->clock)
2184 return 0;
2185
2186 spin_lock_irqsave(&musb->lock, flags);
2187
2188 if (musb->set_clock)
2189 musb->set_clock(musb->clock, 1);
2190 else
2191 clk_enable(musb->clock);
2192
2193 /* for static cmos like DaVinci, register values were preserved
2194 * unless for some reason the whole soc powered down and we're
2195 * not treating that as a whole-system restart (e.g. swsusp)
2196 */
2197 spin_unlock_irqrestore(&musb->lock, flags);
2198 return 0;
2199}
2200
2201#else
2202#define musb_suspend NULL
2203#define musb_resume NULL
2204#endif
2205
2206static struct platform_driver musb_driver = {
2207 .driver = {
2208 .name = (char *)musb_driver_name,
2209 .bus = &platform_bus_type,
2210 .owner = THIS_MODULE,
2211 },
2212 .remove = __devexit_p(musb_remove),
2213 .shutdown = musb_shutdown,
2214 .suspend = musb_suspend,
2215 .resume = musb_resume,
2216};
2217
2218/*-------------------------------------------------------------------------*/
2219
2220static int __init musb_init(void)
2221{
2222#ifdef CONFIG_USB_MUSB_HDRC_HCD
2223 if (usb_disabled())
2224 return 0;
2225#endif
2226
2227 pr_info("%s: version " MUSB_VERSION ", "
2228#ifdef CONFIG_MUSB_PIO_ONLY
2229 "pio"
2230#elif defined(CONFIG_USB_TI_CPPI_DMA)
2231 "cppi-dma"
2232#elif defined(CONFIG_USB_INVENTRA_DMA)
2233 "musb-dma"
2234#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
2235 "tusb-omap-dma"
2236#else
2237 "?dma?"
2238#endif
2239 ", "
2240#ifdef CONFIG_USB_MUSB_OTG
2241 "otg (peripheral+host)"
2242#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
2243 "peripheral"
2244#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
2245 "host"
2246#endif
2247 ", debug=%d\n",
2248 musb_driver_name, debug);
2249 return platform_driver_probe(&musb_driver, musb_probe);
2250}
2251
2252/* make us init after usbcore and before usb
2253 * gadget and host-side drivers start to register
2254 */
2255subsys_initcall(musb_init);
2256
2257static void __exit musb_cleanup(void)
2258{
2259 platform_driver_unregister(&musb_driver);
2260}
2261module_exit(musb_cleanup);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
new file mode 100644
index 000000000000..eade46d81708
--- /dev/null
+++ b/drivers/usb/musb/musb_core.h
@@ -0,0 +1,507 @@
1/*
2 * MUSB OTG driver defines
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef __MUSB_CORE_H__
36#define __MUSB_CORE_H__
37
38#include <linux/slab.h>
39#include <linux/list.h>
40#include <linux/interrupt.h>
41#include <linux/smp_lock.h>
42#include <linux/errno.h>
43#include <linux/clk.h>
44#include <linux/device.h>
45#include <linux/usb/ch9.h>
46#include <linux/usb/gadget.h>
47#include <linux/usb.h>
48#include <linux/usb/otg.h>
49#include <linux/usb/musb.h>
50
51struct musb;
52struct musb_hw_ep;
53struct musb_ep;
54
55
56#include "musb_debug.h"
57#include "musb_dma.h"
58
59#include "musb_io.h"
60#include "musb_regs.h"
61
62#include "musb_gadget.h"
63#include "../core/hcd.h"
64#include "musb_host.h"
65
66
67
68#ifdef CONFIG_USB_MUSB_OTG
69
70#define is_peripheral_enabled(musb) ((musb)->board_mode != MUSB_HOST)
71#define is_host_enabled(musb) ((musb)->board_mode != MUSB_PERIPHERAL)
72#define is_otg_enabled(musb) ((musb)->board_mode == MUSB_OTG)
73
74/* NOTE: otg and peripheral-only state machines start at B_IDLE.
75 * OTG or host-only go to A_IDLE when ID is sensed.
76 */
77#define is_peripheral_active(m) (!(m)->is_host)
78#define is_host_active(m) ((m)->is_host)
79
80#else
81#define is_peripheral_enabled(musb) is_peripheral_capable()
82#define is_host_enabled(musb) is_host_capable()
83#define is_otg_enabled(musb) 0
84
85#define is_peripheral_active(musb) is_peripheral_capable()
86#define is_host_active(musb) is_host_capable()
87#endif
88
89#if defined(CONFIG_USB_MUSB_OTG) || defined(CONFIG_USB_MUSB_PERIPHERAL)
90/* for some reason, the "select USB_GADGET_MUSB_HDRC" doesn't always
91 * override that choice selection (often USB_GADGET_DUMMY_HCD).
92 */
93#ifndef CONFIG_USB_GADGET_MUSB_HDRC
94#error bogus Kconfig output ... select CONFIG_USB_GADGET_MUSB_HDRC
95#endif
96#endif /* need MUSB gadget selection */
97
98
99#ifdef CONFIG_PROC_FS
100#include <linux/fs.h>
101#define MUSB_CONFIG_PROC_FS
102#endif
103
104/****************************** PERIPHERAL ROLE *****************************/
105
106#ifdef CONFIG_USB_GADGET_MUSB_HDRC
107
108#define is_peripheral_capable() (1)
109
110extern irqreturn_t musb_g_ep0_irq(struct musb *);
111extern void musb_g_tx(struct musb *, u8);
112extern void musb_g_rx(struct musb *, u8);
113extern void musb_g_reset(struct musb *);
114extern void musb_g_suspend(struct musb *);
115extern void musb_g_resume(struct musb *);
116extern void musb_g_wakeup(struct musb *);
117extern void musb_g_disconnect(struct musb *);
118
119#else
120
121#define is_peripheral_capable() (0)
122
123static inline irqreturn_t musb_g_ep0_irq(struct musb *m) { return IRQ_NONE; }
124static inline void musb_g_reset(struct musb *m) {}
125static inline void musb_g_suspend(struct musb *m) {}
126static inline void musb_g_resume(struct musb *m) {}
127static inline void musb_g_wakeup(struct musb *m) {}
128static inline void musb_g_disconnect(struct musb *m) {}
129
130#endif
131
132/****************************** HOST ROLE ***********************************/
133
134#ifdef CONFIG_USB_MUSB_HDRC_HCD
135
136#define is_host_capable() (1)
137
138extern irqreturn_t musb_h_ep0_irq(struct musb *);
139extern void musb_host_tx(struct musb *, u8);
140extern void musb_host_rx(struct musb *, u8);
141
142#else
143
144#define is_host_capable() (0)
145
146static inline irqreturn_t musb_h_ep0_irq(struct musb *m) { return IRQ_NONE; }
147static inline void musb_host_tx(struct musb *m, u8 e) {}
148static inline void musb_host_rx(struct musb *m, u8 e) {}
149
150#endif
151
152
153/****************************** CONSTANTS ********************************/
154
155#ifndef MUSB_C_NUM_EPS
156#define MUSB_C_NUM_EPS ((u8)16)
157#endif
158
159#ifndef MUSB_MAX_END0_PACKET
160#define MUSB_MAX_END0_PACKET ((u16)MUSB_EP0_FIFOSIZE)
161#endif
162
163/* host side ep0 states */
164enum musb_h_ep0_state {
165 MUSB_EP0_IDLE,
166 MUSB_EP0_START, /* expect ack of setup */
167 MUSB_EP0_IN, /* expect IN DATA */
168 MUSB_EP0_OUT, /* expect ack of OUT DATA */
169 MUSB_EP0_STATUS, /* expect ack of STATUS */
170} __attribute__ ((packed));
171
172/* peripheral side ep0 states */
173enum musb_g_ep0_state {
174 MUSB_EP0_STAGE_SETUP, /* idle, waiting for setup */
175 MUSB_EP0_STAGE_TX, /* IN data */
176 MUSB_EP0_STAGE_RX, /* OUT data */
177 MUSB_EP0_STAGE_STATUSIN, /* (after OUT data) */
178 MUSB_EP0_STAGE_STATUSOUT, /* (after IN data) */
179 MUSB_EP0_STAGE_ACKWAIT, /* after zlp, before statusin */
180} __attribute__ ((packed));
181
182/* OTG protocol constants */
183#define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */
184#define OTG_TIME_A_WAIT_BCON 0 /* 0=infinite; min 1000 msec */
185#define OTG_TIME_A_IDLE_BDIS 200 /* msec (min) */
186
187/*************************** REGISTER ACCESS ********************************/
188
189/* Endpoint registers (other than dynfifo setup) can be accessed either
190 * directly with the "flat" model, or after setting up an index register.
191 */
192
193#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \
194 || defined(CONFIG_ARCH_OMAP3430)
195/* REVISIT indexed access seemed to
196 * misbehave (on DaVinci) for at least peripheral IN ...
197 */
198#define MUSB_FLAT_REG
199#endif
200
201/* TUSB mapping: "flat" plus ep0 special cases */
202#if defined(CONFIG_USB_TUSB6010)
203#define musb_ep_select(_mbase, _epnum) \
204 musb_writeb((_mbase), MUSB_INDEX, (_epnum))
205#define MUSB_EP_OFFSET MUSB_TUSB_OFFSET
206
207/* "flat" mapping: each endpoint has its own i/o address */
208#elif defined(MUSB_FLAT_REG)
209#define musb_ep_select(_mbase, _epnum) (((void)(_mbase)), ((void)(_epnum)))
210#define MUSB_EP_OFFSET MUSB_FLAT_OFFSET
211
212/* "indexed" mapping: INDEX register controls register bank select */
213#else
214#define musb_ep_select(_mbase, _epnum) \
215 musb_writeb((_mbase), MUSB_INDEX, (_epnum))
216#define MUSB_EP_OFFSET MUSB_INDEXED_OFFSET
217#endif
218
219/****************************** FUNCTIONS ********************************/
220
221#define MUSB_HST_MODE(_musb)\
222 { (_musb)->is_host = true; }
223#define MUSB_DEV_MODE(_musb) \
224 { (_musb)->is_host = false; }
225
226#define test_devctl_hst_mode(_x) \
227 (musb_readb((_x)->mregs, MUSB_DEVCTL)&MUSB_DEVCTL_HM)
228
229#define MUSB_MODE(musb) ((musb)->is_host ? "Host" : "Peripheral")
230
231/******************************** TYPES *************************************/
232
233/*
234 * struct musb_hw_ep - endpoint hardware (bidirectional)
235 *
236 * Ordered slightly for better cacheline locality.
237 */
238struct musb_hw_ep {
239 struct musb *musb;
240 void __iomem *fifo;
241 void __iomem *regs;
242
243#ifdef CONFIG_USB_TUSB6010
244 void __iomem *conf;
245#endif
246
247 /* index in musb->endpoints[] */
248 u8 epnum;
249
250 /* hardware configuration, possibly dynamic */
251 bool is_shared_fifo;
252 bool tx_double_buffered;
253 bool rx_double_buffered;
254 u16 max_packet_sz_tx;
255 u16 max_packet_sz_rx;
256
257 struct dma_channel *tx_channel;
258 struct dma_channel *rx_channel;
259
260#ifdef CONFIG_USB_TUSB6010
261 /* TUSB has "asynchronous" and "synchronous" dma modes */
262 dma_addr_t fifo_async;
263 dma_addr_t fifo_sync;
264 void __iomem *fifo_sync_va;
265#endif
266
267#ifdef CONFIG_USB_MUSB_HDRC_HCD
268 void __iomem *target_regs;
269
270 /* currently scheduled peripheral endpoint */
271 struct musb_qh *in_qh;
272 struct musb_qh *out_qh;
273
274 u8 rx_reinit;
275 u8 tx_reinit;
276#endif
277
278#ifdef CONFIG_USB_GADGET_MUSB_HDRC
279 /* peripheral side */
280 struct musb_ep ep_in; /* TX */
281 struct musb_ep ep_out; /* RX */
282#endif
283};
284
285static inline struct usb_request *next_in_request(struct musb_hw_ep *hw_ep)
286{
287#ifdef CONFIG_USB_GADGET_MUSB_HDRC
288 return next_request(&hw_ep->ep_in);
289#else
290 return NULL;
291#endif
292}
293
294static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep)
295{
296#ifdef CONFIG_USB_GADGET_MUSB_HDRC
297 return next_request(&hw_ep->ep_out);
298#else
299 return NULL;
300#endif
301}
302
303/*
304 * struct musb - Driver instance data.
305 */
306struct musb {
307 /* device lock */
308 spinlock_t lock;
309 struct clk *clock;
310 irqreturn_t (*isr)(int, void *);
311 struct work_struct irq_work;
312
313/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */
314#define MUSB_PORT_STAT_RESUME (1 << 31)
315
316 u32 port1_status;
317
318#ifdef CONFIG_USB_MUSB_HDRC_HCD
319 unsigned long rh_timer;
320
321 enum musb_h_ep0_state ep0_stage;
322
323 /* bulk traffic normally dedicates endpoint hardware, and each
324 * direction has its own ring of host side endpoints.
325 * we try to progress the transfer at the head of each endpoint's
326 * queue until it completes or NAKs too much; then we try the next
327 * endpoint.
328 */
329 struct musb_hw_ep *bulk_ep;
330
331 struct list_head control; /* of musb_qh */
332 struct list_head in_bulk; /* of musb_qh */
333 struct list_head out_bulk; /* of musb_qh */
334 struct musb_qh *periodic[32]; /* tree of interrupt+iso */
335#endif
336
337 /* called with IRQs blocked; ON/nonzero implies starting a session,
338 * and waiting at least a_wait_vrise_tmout.
339 */
340 void (*board_set_vbus)(struct musb *, int is_on);
341
342 struct dma_controller *dma_controller;
343
344 struct device *controller;
345 void __iomem *ctrl_base;
346 void __iomem *mregs;
347
348#ifdef CONFIG_USB_TUSB6010
349 dma_addr_t async;
350 dma_addr_t sync;
351 void __iomem *sync_va;
352#endif
353
354 /* passed down from chip/board specific irq handlers */
355 u8 int_usb;
356 u16 int_rx;
357 u16 int_tx;
358
359 struct otg_transceiver xceiv;
360
361 int nIrq;
362
363 struct musb_hw_ep endpoints[MUSB_C_NUM_EPS];
364#define control_ep endpoints
365
366#define VBUSERR_RETRY_COUNT 3
367 u16 vbuserr_retry;
368 u16 epmask;
369 u8 nr_endpoints;
370
371 u8 board_mode; /* enum musb_mode */
372 int (*board_set_power)(int state);
373
374 int (*set_clock)(struct clk *clk, int is_active);
375
376 u8 min_power; /* vbus for periph, in mA/2 */
377
378 bool is_host;
379
380 int a_wait_bcon; /* VBUS timeout in msecs */
381 unsigned long idle_timeout; /* Next timeout in jiffies */
382
383 /* active means connected and not suspended */
384 unsigned is_active:1;
385
386 unsigned is_multipoint:1;
387 unsigned ignore_disconnect:1; /* during bus resets */
388
389#ifdef C_MP_TX
390 unsigned bulk_split:1;
391#define can_bulk_split(musb,type) \
392 (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split)
393#else
394#define can_bulk_split(musb, type) 0
395#endif
396
397#ifdef C_MP_RX
398 unsigned bulk_combine:1;
399#define can_bulk_combine(musb,type) \
400 (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine)
401#else
402#define can_bulk_combine(musb, type) 0
403#endif
404
405#ifdef CONFIG_USB_GADGET_MUSB_HDRC
406 /* is_suspended means USB B_PERIPHERAL suspend */
407 unsigned is_suspended:1;
408
409 /* may_wakeup means remote wakeup is enabled */
410 unsigned may_wakeup:1;
411
412 /* is_self_powered is reported in device status and the
413 * config descriptor. is_bus_powered means B_PERIPHERAL
414 * draws some VBUS current; both can be true.
415 */
416 unsigned is_self_powered:1;
417 unsigned is_bus_powered:1;
418
419 unsigned set_address:1;
420 unsigned test_mode:1;
421 unsigned softconnect:1;
422
423 u8 address;
424 u8 test_mode_nr;
425 u16 ackpend; /* ep0 */
426 enum musb_g_ep0_state ep0_state;
427 struct usb_gadget g; /* the gadget */
428 struct usb_gadget_driver *gadget_driver; /* its driver */
429#endif
430
431 struct musb_hdrc_config *config;
432
433#ifdef MUSB_CONFIG_PROC_FS
434 struct proc_dir_entry *proc_entry;
435#endif
436};
437
438static inline void musb_set_vbus(struct musb *musb, int is_on)
439{
440 musb->board_set_vbus(musb, is_on);
441}
442
443#ifdef CONFIG_USB_GADGET_MUSB_HDRC
444static inline struct musb *gadget_to_musb(struct usb_gadget *g)
445{
446 return container_of(g, struct musb, g);
447}
448#endif
449
450
451/***************************** Glue it together *****************************/
452
453extern const char musb_driver_name[];
454
455extern void musb_start(struct musb *musb);
456extern void musb_stop(struct musb *musb);
457
458extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
459extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst);
460
461extern void musb_load_testpacket(struct musb *);
462
463extern irqreturn_t musb_interrupt(struct musb *);
464
465extern void musb_platform_enable(struct musb *musb);
466extern void musb_platform_disable(struct musb *musb);
467
468extern void musb_hnp_stop(struct musb *musb);
469
470extern void musb_platform_set_mode(struct musb *musb, u8 musb_mode);
471
472#if defined(CONFIG_USB_TUSB6010) || \
473 defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
474extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
475#else
476#define musb_platform_try_idle(x, y) do {} while (0)
477#endif
478
479#ifdef CONFIG_USB_TUSB6010
480extern int musb_platform_get_vbus_status(struct musb *musb);
481#else
482#define musb_platform_get_vbus_status(x) 0
483#endif
484
485extern int __init musb_platform_init(struct musb *musb);
486extern int musb_platform_exit(struct musb *musb);
487
488/*-------------------------- ProcFS definitions ---------------------*/
489
490struct proc_dir_entry;
491
492#if (MUSB_DEBUG > 0) && defined(MUSB_CONFIG_PROC_FS)
493extern struct proc_dir_entry *musb_debug_create(char *name, struct musb *data);
494extern void musb_debug_delete(char *name, struct musb *data);
495
496#else
497static inline struct proc_dir_entry *
498musb_debug_create(char *name, struct musb *data)
499{
500 return NULL;
501}
502static inline void musb_debug_delete(char *name, struct musb *data)
503{
504}
505#endif
506
507#endif /* __MUSB_CORE_H__ */
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h
new file mode 100644
index 000000000000..3bdb311e820d
--- /dev/null
+++ b/drivers/usb/musb/musb_debug.h
@@ -0,0 +1,66 @@
1/*
2 * MUSB OTG driver debug defines
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef __MUSB_LINUX_DEBUG_H__
36#define __MUSB_LINUX_DEBUG_H__
37
38#define yprintk(facility, format, args...) \
39 do { printk(facility "%s %d: " format , \
40 __func__, __LINE__ , ## args); } while (0)
41#define WARNING(fmt, args...) yprintk(KERN_WARNING, fmt, ## args)
42#define INFO(fmt, args...) yprintk(KERN_INFO, fmt, ## args)
43#define ERR(fmt, args...) yprintk(KERN_ERR, fmt, ## args)
44
45#define xprintk(level, facility, format, args...) do { \
46 if (_dbg_level(level)) { \
47 printk(facility "%s %d: " format , \
48 __func__, __LINE__ , ## args); \
49 } } while (0)
50
51#if MUSB_DEBUG > 0
52extern unsigned debug;
53#else
54#define debug 0
55#endif
56
57static inline int _dbg_level(unsigned l)
58{
59 return debug >= l;
60}
61
62#define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args)
63
64extern const char *otg_state_string(struct musb *);
65
66#endif /* __MUSB_LINUX_DEBUG_H__ */
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
new file mode 100644
index 000000000000..0a2c4e3602c1
--- /dev/null
+++ b/drivers/usb/musb/musb_dma.h
@@ -0,0 +1,172 @@
1/*
2 * MUSB OTG driver DMA controller abstraction
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef __MUSB_DMA_H__
36#define __MUSB_DMA_H__
37
38struct musb_hw_ep;
39
40/*
41 * DMA Controller Abstraction
42 *
43 * DMA Controllers are abstracted to allow use of a variety of different
44 * implementations of DMA, as allowed by the Inventra USB cores. On the
45 * host side, usbcore sets up the DMA mappings and flushes caches; on the
46 * peripheral side, the gadget controller driver does. Responsibilities
47 * of a DMA controller driver include:
48 *
49 * - Handling the details of moving multiple USB packets
50 * in cooperation with the Inventra USB core, including especially
51 * the correct RX side treatment of short packets and buffer-full
52 * states (both of which terminate transfers).
53 *
54 * - Knowing the correlation between dma channels and the
55 * Inventra core's local endpoint resources and data direction.
56 *
57 * - Maintaining a list of allocated/available channels.
58 *
59 * - Updating channel status on interrupts,
60 * whether shared with the Inventra core or separate.
61 */
62
63#define DMA_ADDR_INVALID (~(dma_addr_t)0)
64
65#ifndef CONFIG_MUSB_PIO_ONLY
66#define is_dma_capable() (1)
67#else
68#define is_dma_capable() (0)
69#endif
70
71#ifdef CONFIG_USB_TI_CPPI_DMA
72#define is_cppi_enabled() 1
73#else
74#define is_cppi_enabled() 0
75#endif
76
77#ifdef CONFIG_USB_TUSB_OMAP_DMA
78#define tusb_dma_omap() 1
79#else
80#define tusb_dma_omap() 0
81#endif
82
83/*
84 * DMA channel status ... updated by the dma controller driver whenever that
85 * status changes, and protected by the overall controller spinlock.
86 */
87enum dma_channel_status {
88 /* unallocated */
89 MUSB_DMA_STATUS_UNKNOWN,
90 /* allocated ... but not busy, no errors */
91 MUSB_DMA_STATUS_FREE,
92 /* busy ... transactions are active */
93 MUSB_DMA_STATUS_BUSY,
94 /* transaction(s) aborted due to ... dma or memory bus error */
95 MUSB_DMA_STATUS_BUS_ABORT,
96 /* transaction(s) aborted due to ... core error or USB fault */
97 MUSB_DMA_STATUS_CORE_ABORT
98};
99
100struct dma_controller;
101
102/**
103 * struct dma_channel - A DMA channel.
104 * @private_data: channel-private data
105 * @max_len: the maximum number of bytes the channel can move in one
106 * transaction (typically representing many USB maximum-sized packets)
107 * @actual_len: how many bytes have been transferred
108 * @status: current channel status (updated e.g. on interrupt)
109 * @desired_mode: true if mode 1 is desired; false if mode 0 is desired
110 *
111 * channels are associated with an endpoint for the duration of at least
112 * one usb transfer.
113 */
114struct dma_channel {
115 void *private_data;
116 /* FIXME not void* private_data, but a dma_controller * */
117 size_t max_len;
118 size_t actual_len;
119 enum dma_channel_status status;
120 bool desired_mode;
121};
122
123/*
124 * dma_channel_status - return status of dma channel
125 * @c: the channel
126 *
127 * Returns the software's view of the channel status. If that status is BUSY
128 * then it's possible that the hardware has completed (or aborted) a transfer,
129 * so the driver needs to update that status.
130 */
131static inline enum dma_channel_status
132dma_channel_status(struct dma_channel *c)
133{
134 return (is_dma_capable() && c) ? c->status : MUSB_DMA_STATUS_UNKNOWN;
135}
136
137/**
138 * struct dma_controller - A DMA Controller.
139 * @start: call this to start a DMA controller;
140 * return 0 on success, else negative errno
141 * @stop: call this to stop a DMA controller
142 * return 0 on success, else negative errno
143 * @channel_alloc: call this to allocate a DMA channel
144 * @channel_release: call this to release a DMA channel
145 * @channel_abort: call this to abort a pending DMA transaction,
146 * returning it to FREE (but allocated) state
147 *
148 * Controllers manage dma channels.
149 */
150struct dma_controller {
151 int (*start)(struct dma_controller *);
152 int (*stop)(struct dma_controller *);
153 struct dma_channel *(*channel_alloc)(struct dma_controller *,
154 struct musb_hw_ep *, u8 is_tx);
155 void (*channel_release)(struct dma_channel *);
156 int (*channel_program)(struct dma_channel *channel,
157 u16 maxpacket, u8 mode,
158 dma_addr_t dma_addr,
159 u32 length);
160 int (*channel_abort)(struct dma_channel *);
161};
162
163/* called after channel_program(), may indicate a fault */
164extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
165
166
167extern struct dma_controller *__init
168dma_controller_create(struct musb *, void __iomem *);
169
170extern void dma_controller_destroy(struct dma_controller *);
171
172#endif /* __MUSB_DMA_H__ */
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
new file mode 100644
index 000000000000..d6a802c224fa
--- /dev/null
+++ b/drivers/usb/musb/musb_gadget.c
@@ -0,0 +1,2031 @@
1/*
2 * MUSB OTG driver peripheral support
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#include <linux/kernel.h>
36#include <linux/list.h>
37#include <linux/timer.h>
38#include <linux/module.h>
39#include <linux/smp.h>
40#include <linux/spinlock.h>
41#include <linux/delay.h>
42#include <linux/moduleparam.h>
43#include <linux/stat.h>
44#include <linux/dma-mapping.h>
45
46#include "musb_core.h"
47
48
49/* MUSB PERIPHERAL status 3-mar-2006:
50 *
51 * - EP0 seems solid. It passes both USBCV and usbtest control cases.
52 * Minor glitches:
53 *
54 * + remote wakeup to Linux hosts work, but saw USBCV failures;
55 * in one test run (operator error?)
56 * + endpoint halt tests -- in both usbtest and usbcv -- seem
57 * to break when dma is enabled ... is something wrongly
58 * clearing SENDSTALL?
59 *
60 * - Mass storage behaved ok when last tested. Network traffic patterns
61 * (with lots of short transfers etc) need retesting; they turn up the
62 * worst cases of the DMA, since short packets are typical but are not
63 * required.
64 *
65 * - TX/IN
66 * + both pio and dma behave in with network and g_zero tests
67 * + no cppi throughput issues other than no-hw-queueing
68 * + failed with FLAT_REG (DaVinci)
69 * + seems to behave with double buffering, PIO -and- CPPI
70 * + with gadgetfs + AIO, requests got lost?
71 *
72 * - RX/OUT
73 * + both pio and dma behave in with network and g_zero tests
74 * + dma is slow in typical case (short_not_ok is clear)
75 * + double buffering ok with PIO
76 * + double buffering *FAILS* with CPPI, wrong data bytes sometimes
77 * + request lossage observed with gadgetfs
78 *
79 * - ISO not tested ... might work, but only weakly isochronous
80 *
81 * - Gadget driver disabling of softconnect during bind() is ignored; so
82 * drivers can't hold off host requests until userspace is ready.
83 * (Workaround: they can turn it off later.)
84 *
85 * - PORTABILITY (assumes PIO works):
86 * + DaVinci, basically works with cppi dma
87 * + OMAP 2430, ditto with mentor dma
88 * + TUSB 6010, platform-specific dma in the works
89 */
90
91/* ----------------------------------------------------------------------- */
92
93/*
94 * Immediately complete a request.
95 *
96 * @param request the request to complete
97 * @param status the status to complete the request with
98 * Context: controller locked, IRQs blocked.
99 */
100void musb_g_giveback(
101 struct musb_ep *ep,
102 struct usb_request *request,
103 int status)
104__releases(ep->musb->lock)
105__acquires(ep->musb->lock)
106{
107 struct musb_request *req;
108 struct musb *musb;
109 int busy = ep->busy;
110
111 req = to_musb_request(request);
112
113 list_del(&request->list);
114 if (req->request.status == -EINPROGRESS)
115 req->request.status = status;
116 musb = req->musb;
117
118 ep->busy = 1;
119 spin_unlock(&musb->lock);
120 if (is_dma_capable()) {
121 if (req->mapped) {
122 dma_unmap_single(musb->controller,
123 req->request.dma,
124 req->request.length,
125 req->tx
126 ? DMA_TO_DEVICE
127 : DMA_FROM_DEVICE);
128 req->request.dma = DMA_ADDR_INVALID;
129 req->mapped = 0;
130 } else if (req->request.dma != DMA_ADDR_INVALID)
131 dma_sync_single_for_cpu(musb->controller,
132 req->request.dma,
133 req->request.length,
134 req->tx
135 ? DMA_TO_DEVICE
136 : DMA_FROM_DEVICE);
137 }
138 if (request->status == 0)
139 DBG(5, "%s done request %p, %d/%d\n",
140 ep->end_point.name, request,
141 req->request.actual, req->request.length);
142 else
143 DBG(2, "%s request %p, %d/%d fault %d\n",
144 ep->end_point.name, request,
145 req->request.actual, req->request.length,
146 request->status);
147 req->request.complete(&req->ep->end_point, &req->request);
148 spin_lock(&musb->lock);
149 ep->busy = busy;
150}
151
152/* ----------------------------------------------------------------------- */
153
154/*
155 * Abort requests queued to an endpoint using the status. Synchronous.
156 * caller locked controller and blocked irqs, and selected this ep.
157 */
158static void nuke(struct musb_ep *ep, const int status)
159{
160 struct musb_request *req = NULL;
161 void __iomem *epio = ep->musb->endpoints[ep->current_epnum].regs;
162
163 ep->busy = 1;
164
165 if (is_dma_capable() && ep->dma) {
166 struct dma_controller *c = ep->musb->dma_controller;
167 int value;
168 if (ep->is_in) {
169 musb_writew(epio, MUSB_TXCSR,
170 0 | MUSB_TXCSR_FLUSHFIFO);
171 musb_writew(epio, MUSB_TXCSR,
172 0 | MUSB_TXCSR_FLUSHFIFO);
173 } else {
174 musb_writew(epio, MUSB_RXCSR,
175 0 | MUSB_RXCSR_FLUSHFIFO);
176 musb_writew(epio, MUSB_RXCSR,
177 0 | MUSB_RXCSR_FLUSHFIFO);
178 }
179
180 value = c->channel_abort(ep->dma);
181 DBG(value ? 1 : 6, "%s: abort DMA --> %d\n", ep->name, value);
182 c->channel_release(ep->dma);
183 ep->dma = NULL;
184 }
185
186 while (!list_empty(&(ep->req_list))) {
187 req = container_of(ep->req_list.next, struct musb_request,
188 request.list);
189 musb_g_giveback(ep, &req->request, status);
190 }
191}
192
193/* ----------------------------------------------------------------------- */
194
195/* Data transfers - pure PIO, pure DMA, or mixed mode */
196
197/*
198 * This assumes the separate CPPI engine is responding to DMA requests
199 * from the usb core ... sequenced a bit differently from mentor dma.
200 */
201
202static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep)
203{
204 if (can_bulk_split(musb, ep->type))
205 return ep->hw_ep->max_packet_sz_tx;
206 else
207 return ep->packet_sz;
208}
209
210
211#ifdef CONFIG_USB_INVENTRA_DMA
212
213/* Peripheral tx (IN) using Mentor DMA works as follows:
214 Only mode 0 is used for transfers <= wPktSize,
215 mode 1 is used for larger transfers,
216
217 One of the following happens:
218 - Host sends IN token which causes an endpoint interrupt
219 -> TxAvail
220 -> if DMA is currently busy, exit.
221 -> if queue is non-empty, txstate().
222
223 - Request is queued by the gadget driver.
224 -> if queue was previously empty, txstate()
225
226 txstate()
227 -> start
228 /\ -> setup DMA
229 | (data is transferred to the FIFO, then sent out when
230 | IN token(s) are recd from Host.
231 | -> DMA interrupt on completion
232 | calls TxAvail.
233 | -> stop DMA, ~DmaEenab,
234 | -> set TxPktRdy for last short pkt or zlp
235 | -> Complete Request
236 | -> Continue next request (call txstate)
237 |___________________________________|
238
239 * Non-Mentor DMA engines can of course work differently, such as by
240 * upleveling from irq-per-packet to irq-per-buffer.
241 */
242
243#endif
244
245/*
246 * An endpoint is transmitting data. This can be called either from
247 * the IRQ routine or from ep.queue() to kickstart a request on an
248 * endpoint.
249 *
250 * Context: controller locked, IRQs blocked, endpoint selected
251 */
252static void txstate(struct musb *musb, struct musb_request *req)
253{
254 u8 epnum = req->epnum;
255 struct musb_ep *musb_ep;
256 void __iomem *epio = musb->endpoints[epnum].regs;
257 struct usb_request *request;
258 u16 fifo_count = 0, csr;
259 int use_dma = 0;
260
261 musb_ep = req->ep;
262
263 /* we shouldn't get here while DMA is active ... but we do ... */
264 if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
265 DBG(4, "dma pending...\n");
266 return;
267 }
268
269 /* read TXCSR before */
270 csr = musb_readw(epio, MUSB_TXCSR);
271
272 request = &req->request;
273 fifo_count = min(max_ep_writesize(musb, musb_ep),
274 (int)(request->length - request->actual));
275
276 if (csr & MUSB_TXCSR_TXPKTRDY) {
277 DBG(5, "%s old packet still ready , txcsr %03x\n",
278 musb_ep->end_point.name, csr);
279 return;
280 }
281
282 if (csr & MUSB_TXCSR_P_SENDSTALL) {
283 DBG(5, "%s stalling, txcsr %03x\n",
284 musb_ep->end_point.name, csr);
285 return;
286 }
287
288 DBG(4, "hw_ep%d, maxpacket %d, fifo count %d, txcsr %03x\n",
289 epnum, musb_ep->packet_sz, fifo_count,
290 csr);
291
292#ifndef CONFIG_MUSB_PIO_ONLY
293 if (is_dma_capable() && musb_ep->dma) {
294 struct dma_controller *c = musb->dma_controller;
295
296 use_dma = (request->dma != DMA_ADDR_INVALID);
297
298 /* MUSB_TXCSR_P_ISO is still set correctly */
299
300#ifdef CONFIG_USB_INVENTRA_DMA
301 {
302 size_t request_size;
303
304 /* setup DMA, then program endpoint CSR */
305 request_size = min(request->length,
306 musb_ep->dma->max_len);
307 if (request_size <= musb_ep->packet_sz)
308 musb_ep->dma->desired_mode = 0;
309 else
310 musb_ep->dma->desired_mode = 1;
311
312 use_dma = use_dma && c->channel_program(
313 musb_ep->dma, musb_ep->packet_sz,
314 musb_ep->dma->desired_mode,
315 request->dma, request_size);
316 if (use_dma) {
317 if (musb_ep->dma->desired_mode == 0) {
318 /* ASSERT: DMAENAB is clear */
319 csr &= ~(MUSB_TXCSR_AUTOSET |
320 MUSB_TXCSR_DMAMODE);
321 csr |= (MUSB_TXCSR_DMAENAB |
322 MUSB_TXCSR_MODE);
323 /* against programming guide */
324 } else
325 csr |= (MUSB_TXCSR_AUTOSET
326 | MUSB_TXCSR_DMAENAB
327 | MUSB_TXCSR_DMAMODE
328 | MUSB_TXCSR_MODE);
329
330 csr &= ~MUSB_TXCSR_P_UNDERRUN;
331 musb_writew(epio, MUSB_TXCSR, csr);
332 }
333 }
334
335#elif defined(CONFIG_USB_TI_CPPI_DMA)
336 /* program endpoint CSR first, then setup DMA */
337 csr &= ~(MUSB_TXCSR_AUTOSET
338 | MUSB_TXCSR_DMAMODE
339 | MUSB_TXCSR_P_UNDERRUN
340 | MUSB_TXCSR_TXPKTRDY);
341 csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_DMAENAB;
342 musb_writew(epio, MUSB_TXCSR,
343 (MUSB_TXCSR_P_WZC_BITS & ~MUSB_TXCSR_P_UNDERRUN)
344 | csr);
345
346 /* ensure writebuffer is empty */
347 csr = musb_readw(epio, MUSB_TXCSR);
348
349 /* NOTE host side sets DMAENAB later than this; both are
350 * OK since the transfer dma glue (between CPPI and Mentor
351 * fifos) just tells CPPI it could start. Data only moves
352 * to the USB TX fifo when both fifos are ready.
353 */
354
355 /* "mode" is irrelevant here; handle terminating ZLPs like
356 * PIO does, since the hardware RNDIS mode seems unreliable
357 * except for the last-packet-is-already-short case.
358 */
359 use_dma = use_dma && c->channel_program(
360 musb_ep->dma, musb_ep->packet_sz,
361 0,
362 request->dma,
363 request->length);
364 if (!use_dma) {
365 c->channel_release(musb_ep->dma);
366 musb_ep->dma = NULL;
367 /* ASSERT: DMAENAB clear */
368 csr &= ~(MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
369 /* invariant: prequest->buf is non-null */
370 }
371#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
372 use_dma = use_dma && c->channel_program(
373 musb_ep->dma, musb_ep->packet_sz,
374 request->zero,
375 request->dma,
376 request->length);
377#endif
378 }
379#endif
380
381 if (!use_dma) {
382 musb_write_fifo(musb_ep->hw_ep, fifo_count,
383 (u8 *) (request->buf + request->actual));
384 request->actual += fifo_count;
385 csr |= MUSB_TXCSR_TXPKTRDY;
386 csr &= ~MUSB_TXCSR_P_UNDERRUN;
387 musb_writew(epio, MUSB_TXCSR, csr);
388 }
389
390 /* host may already have the data when this message shows... */
391 DBG(3, "%s TX/IN %s len %d/%d, txcsr %04x, fifo %d/%d\n",
392 musb_ep->end_point.name, use_dma ? "dma" : "pio",
393 request->actual, request->length,
394 musb_readw(epio, MUSB_TXCSR),
395 fifo_count,
396 musb_readw(epio, MUSB_TXMAXP));
397}
398
399/*
400 * FIFO state update (e.g. data ready).
401 * Called from IRQ, with controller locked.
402 */
403void musb_g_tx(struct musb *musb, u8 epnum)
404{
405 u16 csr;
406 struct usb_request *request;
407 u8 __iomem *mbase = musb->mregs;
408 struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_in;
409 void __iomem *epio = musb->endpoints[epnum].regs;
410 struct dma_channel *dma;
411
412 musb_ep_select(mbase, epnum);
413 request = next_request(musb_ep);
414
415 csr = musb_readw(epio, MUSB_TXCSR);
416 DBG(4, "<== %s, txcsr %04x\n", musb_ep->end_point.name, csr);
417
418 dma = is_dma_capable() ? musb_ep->dma : NULL;
419 do {
420 /* REVISIT for high bandwidth, MUSB_TXCSR_P_INCOMPTX
421 * probably rates reporting as a host error
422 */
423 if (csr & MUSB_TXCSR_P_SENTSTALL) {
424 csr |= MUSB_TXCSR_P_WZC_BITS;
425 csr &= ~MUSB_TXCSR_P_SENTSTALL;
426 musb_writew(epio, MUSB_TXCSR, csr);
427 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
428 dma->status = MUSB_DMA_STATUS_CORE_ABORT;
429 musb->dma_controller->channel_abort(dma);
430 }
431
432 if (request)
433 musb_g_giveback(musb_ep, request, -EPIPE);
434
435 break;
436 }
437
438 if (csr & MUSB_TXCSR_P_UNDERRUN) {
439 /* we NAKed, no big deal ... little reason to care */
440 csr |= MUSB_TXCSR_P_WZC_BITS;
441 csr &= ~(MUSB_TXCSR_P_UNDERRUN
442 | MUSB_TXCSR_TXPKTRDY);
443 musb_writew(epio, MUSB_TXCSR, csr);
444 DBG(20, "underrun on ep%d, req %p\n", epnum, request);
445 }
446
447 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
448 /* SHOULD NOT HAPPEN ... has with cppi though, after
449 * changing SENDSTALL (and other cases); harmless?
450 */
451 DBG(5, "%s dma still busy?\n", musb_ep->end_point.name);
452 break;
453 }
454
455 if (request) {
456 u8 is_dma = 0;
457
458 if (dma && (csr & MUSB_TXCSR_DMAENAB)) {
459 is_dma = 1;
460 csr |= MUSB_TXCSR_P_WZC_BITS;
461 csr &= ~(MUSB_TXCSR_DMAENAB
462 | MUSB_TXCSR_P_UNDERRUN
463 | MUSB_TXCSR_TXPKTRDY);
464 musb_writew(epio, MUSB_TXCSR, csr);
465 /* ensure writebuffer is empty */
466 csr = musb_readw(epio, MUSB_TXCSR);
467 request->actual += musb_ep->dma->actual_len;
468 DBG(4, "TXCSR%d %04x, dma off, "
469 "len %zu, req %p\n",
470 epnum, csr,
471 musb_ep->dma->actual_len,
472 request);
473 }
474
475 if (is_dma || request->actual == request->length) {
476
477 /* First, maybe a terminating short packet.
478 * Some DMA engines might handle this by
479 * themselves.
480 */
481 if ((request->zero
482 && request->length
483 && (request->length
484 % musb_ep->packet_sz)
485 == 0)
486#ifdef CONFIG_USB_INVENTRA_DMA
487 || (is_dma &&
488 ((!dma->desired_mode) ||
489 (request->actual &
490 (musb_ep->packet_sz - 1))))
491#endif
492 ) {
493 /* on dma completion, fifo may not
494 * be available yet ...
495 */
496 if (csr & MUSB_TXCSR_TXPKTRDY)
497 break;
498
499 DBG(4, "sending zero pkt\n");
500 musb_writew(epio, MUSB_TXCSR,
501 MUSB_TXCSR_MODE
502 | MUSB_TXCSR_TXPKTRDY);
503 request->zero = 0;
504 }
505
506 /* ... or if not, then complete it */
507 musb_g_giveback(musb_ep, request, 0);
508
509 /* kickstart next transfer if appropriate;
510 * the packet that just completed might not
511 * be transmitted for hours or days.
512 * REVISIT for double buffering...
513 * FIXME revisit for stalls too...
514 */
515 musb_ep_select(mbase, epnum);
516 csr = musb_readw(epio, MUSB_TXCSR);
517 if (csr & MUSB_TXCSR_FIFONOTEMPTY)
518 break;
519 request = musb_ep->desc
520 ? next_request(musb_ep)
521 : NULL;
522 if (!request) {
523 DBG(4, "%s idle now\n",
524 musb_ep->end_point.name);
525 break;
526 }
527 }
528
529 txstate(musb, to_musb_request(request));
530 }
531
532 } while (0);
533}
534
535/* ------------------------------------------------------------ */
536
537#ifdef CONFIG_USB_INVENTRA_DMA
538
539/* Peripheral rx (OUT) using Mentor DMA works as follows:
540 - Only mode 0 is used.
541
542 - Request is queued by the gadget class driver.
543 -> if queue was previously empty, rxstate()
544
545 - Host sends OUT token which causes an endpoint interrupt
546 /\ -> RxReady
547 | -> if request queued, call rxstate
548 | /\ -> setup DMA
549 | | -> DMA interrupt on completion
550 | | -> RxReady
551 | | -> stop DMA
552 | | -> ack the read
553 | | -> if data recd = max expected
554 | | by the request, or host
555 | | sent a short packet,
556 | | complete the request,
557 | | and start the next one.
558 | |_____________________________________|
559 | else just wait for the host
560 | to send the next OUT token.
561 |__________________________________________________|
562
563 * Non-Mentor DMA engines can of course work differently.
564 */
565
566#endif
567
568/*
569 * Context: controller locked, IRQs blocked, endpoint selected
570 */
571static void rxstate(struct musb *musb, struct musb_request *req)
572{
573 u16 csr = 0;
574 const u8 epnum = req->epnum;
575 struct usb_request *request = &req->request;
576 struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
577 void __iomem *epio = musb->endpoints[epnum].regs;
578 u16 fifo_count = 0;
579 u16 len = musb_ep->packet_sz;
580
581 csr = musb_readw(epio, MUSB_RXCSR);
582
583 if (is_cppi_enabled() && musb_ep->dma) {
584 struct dma_controller *c = musb->dma_controller;
585 struct dma_channel *channel = musb_ep->dma;
586
587 /* NOTE: CPPI won't actually stop advancing the DMA
588 * queue after short packet transfers, so this is almost
589 * always going to run as IRQ-per-packet DMA so that
590 * faults will be handled correctly.
591 */
592 if (c->channel_program(channel,
593 musb_ep->packet_sz,
594 !request->short_not_ok,
595 request->dma + request->actual,
596 request->length - request->actual)) {
597
598 /* make sure that if an rxpkt arrived after the irq,
599 * the cppi engine will be ready to take it as soon
600 * as DMA is enabled
601 */
602 csr &= ~(MUSB_RXCSR_AUTOCLEAR
603 | MUSB_RXCSR_DMAMODE);
604 csr |= MUSB_RXCSR_DMAENAB | MUSB_RXCSR_P_WZC_BITS;
605 musb_writew(epio, MUSB_RXCSR, csr);
606 return;
607 }
608 }
609
610 if (csr & MUSB_RXCSR_RXPKTRDY) {
611 len = musb_readw(epio, MUSB_RXCOUNT);
612 if (request->actual < request->length) {
613#ifdef CONFIG_USB_INVENTRA_DMA
614 if (is_dma_capable() && musb_ep->dma) {
615 struct dma_controller *c;
616 struct dma_channel *channel;
617 int use_dma = 0;
618
619 c = musb->dma_controller;
620 channel = musb_ep->dma;
621
622 /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
623 * mode 0 only. So we do not get endpoint interrupts due to DMA
624 * completion. We only get interrupts from DMA controller.
625 *
626 * We could operate in DMA mode 1 if we knew the size of the tranfer
627 * in advance. For mass storage class, request->length = what the host
628 * sends, so that'd work. But for pretty much everything else,
629 * request->length is routinely more than what the host sends. For
630 * most these gadgets, end of is signified either by a short packet,
631 * or filling the last byte of the buffer. (Sending extra data in
632 * that last pckate should trigger an overflow fault.) But in mode 1,
633 * we don't get DMA completion interrrupt for short packets.
634 *
635 * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
636 * to get endpoint interrupt on every DMA req, but that didn't seem
637 * to work reliably.
638 *
639 * REVISIT an updated g_file_storage can set req->short_not_ok, which
640 * then becomes usable as a runtime "use mode 1" hint...
641 */
642
643 csr |= MUSB_RXCSR_DMAENAB;
644#ifdef USE_MODE1
645 csr |= MUSB_RXCSR_AUTOCLEAR;
646 /* csr |= MUSB_RXCSR_DMAMODE; */
647
648 /* this special sequence (enabling and then
649 * disabling MUSB_RXCSR_DMAMODE) is required
650 * to get DMAReq to activate
651 */
652 musb_writew(epio, MUSB_RXCSR,
653 csr | MUSB_RXCSR_DMAMODE);
654#endif
655 musb_writew(epio, MUSB_RXCSR, csr);
656
657 if (request->actual < request->length) {
658 int transfer_size = 0;
659#ifdef USE_MODE1
660 transfer_size = min(request->length,
661 channel->max_len);
662#else
663 transfer_size = len;
664#endif
665 if (transfer_size <= musb_ep->packet_sz)
666 musb_ep->dma->desired_mode = 0;
667 else
668 musb_ep->dma->desired_mode = 1;
669
670 use_dma = c->channel_program(
671 channel,
672 musb_ep->packet_sz,
673 channel->desired_mode,
674 request->dma
675 + request->actual,
676 transfer_size);
677 }
678
679 if (use_dma)
680 return;
681 }
682#endif /* Mentor's DMA */
683
684 fifo_count = request->length - request->actual;
685 DBG(3, "%s OUT/RX pio fifo %d/%d, maxpacket %d\n",
686 musb_ep->end_point.name,
687 len, fifo_count,
688 musb_ep->packet_sz);
689
690 fifo_count = min(len, fifo_count);
691
692#ifdef CONFIG_USB_TUSB_OMAP_DMA
693 if (tusb_dma_omap() && musb_ep->dma) {
694 struct dma_controller *c = musb->dma_controller;
695 struct dma_channel *channel = musb_ep->dma;
696 u32 dma_addr = request->dma + request->actual;
697 int ret;
698
699 ret = c->channel_program(channel,
700 musb_ep->packet_sz,
701 channel->desired_mode,
702 dma_addr,
703 fifo_count);
704 if (ret)
705 return;
706 }
707#endif
708
709 musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
710 (request->buf + request->actual));
711 request->actual += fifo_count;
712
713 /* REVISIT if we left anything in the fifo, flush
714 * it and report -EOVERFLOW
715 */
716
717 /* ack the read! */
718 csr |= MUSB_RXCSR_P_WZC_BITS;
719 csr &= ~MUSB_RXCSR_RXPKTRDY;
720 musb_writew(epio, MUSB_RXCSR, csr);
721 }
722 }
723
724 /* reach the end or short packet detected */
725 if (request->actual == request->length || len < musb_ep->packet_sz)
726 musb_g_giveback(musb_ep, request, 0);
727}
728
729/*
730 * Data ready for a request; called from IRQ
731 */
732void musb_g_rx(struct musb *musb, u8 epnum)
733{
734 u16 csr;
735 struct usb_request *request;
736 void __iomem *mbase = musb->mregs;
737 struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
738 void __iomem *epio = musb->endpoints[epnum].regs;
739 struct dma_channel *dma;
740
741 musb_ep_select(mbase, epnum);
742
743 request = next_request(musb_ep);
744
745 csr = musb_readw(epio, MUSB_RXCSR);
746 dma = is_dma_capable() ? musb_ep->dma : NULL;
747
748 DBG(4, "<== %s, rxcsr %04x%s %p\n", musb_ep->end_point.name,
749 csr, dma ? " (dma)" : "", request);
750
751 if (csr & MUSB_RXCSR_P_SENTSTALL) {
752 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
753 dma->status = MUSB_DMA_STATUS_CORE_ABORT;
754 (void) musb->dma_controller->channel_abort(dma);
755 request->actual += musb_ep->dma->actual_len;
756 }
757
758 csr |= MUSB_RXCSR_P_WZC_BITS;
759 csr &= ~MUSB_RXCSR_P_SENTSTALL;
760 musb_writew(epio, MUSB_RXCSR, csr);
761
762 if (request)
763 musb_g_giveback(musb_ep, request, -EPIPE);
764 goto done;
765 }
766
767 if (csr & MUSB_RXCSR_P_OVERRUN) {
768 /* csr |= MUSB_RXCSR_P_WZC_BITS; */
769 csr &= ~MUSB_RXCSR_P_OVERRUN;
770 musb_writew(epio, MUSB_RXCSR, csr);
771
772 DBG(3, "%s iso overrun on %p\n", musb_ep->name, request);
773 if (request && request->status == -EINPROGRESS)
774 request->status = -EOVERFLOW;
775 }
776 if (csr & MUSB_RXCSR_INCOMPRX) {
777 /* REVISIT not necessarily an error */
778 DBG(4, "%s, incomprx\n", musb_ep->end_point.name);
779 }
780
781 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
782 /* "should not happen"; likely RXPKTRDY pending for DMA */
783 DBG((csr & MUSB_RXCSR_DMAENAB) ? 4 : 1,
784 "%s busy, csr %04x\n",
785 musb_ep->end_point.name, csr);
786 goto done;
787 }
788
789 if (dma && (csr & MUSB_RXCSR_DMAENAB)) {
790 csr &= ~(MUSB_RXCSR_AUTOCLEAR
791 | MUSB_RXCSR_DMAENAB
792 | MUSB_RXCSR_DMAMODE);
793 musb_writew(epio, MUSB_RXCSR,
794 MUSB_RXCSR_P_WZC_BITS | csr);
795
796 request->actual += musb_ep->dma->actual_len;
797
798 DBG(4, "RXCSR%d %04x, dma off, %04x, len %zu, req %p\n",
799 epnum, csr,
800 musb_readw(epio, MUSB_RXCSR),
801 musb_ep->dma->actual_len, request);
802
803#if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA)
804 /* Autoclear doesn't clear RxPktRdy for short packets */
805 if ((dma->desired_mode == 0)
806 || (dma->actual_len
807 & (musb_ep->packet_sz - 1))) {
808 /* ack the read! */
809 csr &= ~MUSB_RXCSR_RXPKTRDY;
810 musb_writew(epio, MUSB_RXCSR, csr);
811 }
812
813 /* incomplete, and not short? wait for next IN packet */
814 if ((request->actual < request->length)
815 && (musb_ep->dma->actual_len
816 == musb_ep->packet_sz))
817 goto done;
818#endif
819 musb_g_giveback(musb_ep, request, 0);
820
821 request = next_request(musb_ep);
822 if (!request)
823 goto done;
824
825 /* don't start more i/o till the stall clears */
826 musb_ep_select(mbase, epnum);
827 csr = musb_readw(epio, MUSB_RXCSR);
828 if (csr & MUSB_RXCSR_P_SENDSTALL)
829 goto done;
830 }
831
832
833 /* analyze request if the ep is hot */
834 if (request)
835 rxstate(musb, to_musb_request(request));
836 else
837 DBG(3, "packet waiting for %s%s request\n",
838 musb_ep->desc ? "" : "inactive ",
839 musb_ep->end_point.name);
840
841done:
842 return;
843}
844
845/* ------------------------------------------------------------ */
846
847static int musb_gadget_enable(struct usb_ep *ep,
848 const struct usb_endpoint_descriptor *desc)
849{
850 unsigned long flags;
851 struct musb_ep *musb_ep;
852 struct musb_hw_ep *hw_ep;
853 void __iomem *regs;
854 struct musb *musb;
855 void __iomem *mbase;
856 u8 epnum;
857 u16 csr;
858 unsigned tmp;
859 int status = -EINVAL;
860
861 if (!ep || !desc)
862 return -EINVAL;
863
864 musb_ep = to_musb_ep(ep);
865 hw_ep = musb_ep->hw_ep;
866 regs = hw_ep->regs;
867 musb = musb_ep->musb;
868 mbase = musb->mregs;
869 epnum = musb_ep->current_epnum;
870
871 spin_lock_irqsave(&musb->lock, flags);
872
873 if (musb_ep->desc) {
874 status = -EBUSY;
875 goto fail;
876 }
877 musb_ep->type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
878
879 /* check direction and (later) maxpacket size against endpoint */
880 if ((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != epnum)
881 goto fail;
882
883 /* REVISIT this rules out high bandwidth periodic transfers */
884 tmp = le16_to_cpu(desc->wMaxPacketSize);
885 if (tmp & ~0x07ff)
886 goto fail;
887 musb_ep->packet_sz = tmp;
888
889 /* enable the interrupts for the endpoint, set the endpoint
890 * packet size (or fail), set the mode, clear the fifo
891 */
892 musb_ep_select(mbase, epnum);
893 if (desc->bEndpointAddress & USB_DIR_IN) {
894 u16 int_txe = musb_readw(mbase, MUSB_INTRTXE);
895
896 if (hw_ep->is_shared_fifo)
897 musb_ep->is_in = 1;
898 if (!musb_ep->is_in)
899 goto fail;
900 if (tmp > hw_ep->max_packet_sz_tx)
901 goto fail;
902
903 int_txe |= (1 << epnum);
904 musb_writew(mbase, MUSB_INTRTXE, int_txe);
905
906 /* REVISIT if can_bulk_split(), use by updating "tmp";
907 * likewise high bandwidth periodic tx
908 */
909 musb_writew(regs, MUSB_TXMAXP, tmp);
910
911 csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
912 if (musb_readw(regs, MUSB_TXCSR)
913 & MUSB_TXCSR_FIFONOTEMPTY)
914 csr |= MUSB_TXCSR_FLUSHFIFO;
915 if (musb_ep->type == USB_ENDPOINT_XFER_ISOC)
916 csr |= MUSB_TXCSR_P_ISO;
917
918 /* set twice in case of double buffering */
919 musb_writew(regs, MUSB_TXCSR, csr);
920 /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
921 musb_writew(regs, MUSB_TXCSR, csr);
922
923 } else {
924 u16 int_rxe = musb_readw(mbase, MUSB_INTRRXE);
925
926 if (hw_ep->is_shared_fifo)
927 musb_ep->is_in = 0;
928 if (musb_ep->is_in)
929 goto fail;
930 if (tmp > hw_ep->max_packet_sz_rx)
931 goto fail;
932
933 int_rxe |= (1 << epnum);
934 musb_writew(mbase, MUSB_INTRRXE, int_rxe);
935
936 /* REVISIT if can_bulk_combine() use by updating "tmp"
937 * likewise high bandwidth periodic rx
938 */
939 musb_writew(regs, MUSB_RXMAXP, tmp);
940
941 /* force shared fifo to OUT-only mode */
942 if (hw_ep->is_shared_fifo) {
943 csr = musb_readw(regs, MUSB_TXCSR);
944 csr &= ~(MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY);
945 musb_writew(regs, MUSB_TXCSR, csr);
946 }
947
948 csr = MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_CLRDATATOG;
949 if (musb_ep->type == USB_ENDPOINT_XFER_ISOC)
950 csr |= MUSB_RXCSR_P_ISO;
951 else if (musb_ep->type == USB_ENDPOINT_XFER_INT)
952 csr |= MUSB_RXCSR_DISNYET;
953
954 /* set twice in case of double buffering */
955 musb_writew(regs, MUSB_RXCSR, csr);
956 musb_writew(regs, MUSB_RXCSR, csr);
957 }
958
959 /* NOTE: all the I/O code _should_ work fine without DMA, in case
960 * for some reason you run out of channels here.
961 */
962 if (is_dma_capable() && musb->dma_controller) {
963 struct dma_controller *c = musb->dma_controller;
964
965 musb_ep->dma = c->channel_alloc(c, hw_ep,
966 (desc->bEndpointAddress & USB_DIR_IN));
967 } else
968 musb_ep->dma = NULL;
969
970 musb_ep->desc = desc;
971 musb_ep->busy = 0;
972 status = 0;
973
974 pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n",
975 musb_driver_name, musb_ep->end_point.name,
976 ({ char *s; switch (musb_ep->type) {
977 case USB_ENDPOINT_XFER_BULK: s = "bulk"; break;
978 case USB_ENDPOINT_XFER_INT: s = "int"; break;
979 default: s = "iso"; break;
980 }; s; }),
981 musb_ep->is_in ? "IN" : "OUT",
982 musb_ep->dma ? "dma, " : "",
983 musb_ep->packet_sz);
984
985 schedule_work(&musb->irq_work);
986
987fail:
988 spin_unlock_irqrestore(&musb->lock, flags);
989 return status;
990}
991
992/*
993 * Disable an endpoint flushing all requests queued.
994 */
995static int musb_gadget_disable(struct usb_ep *ep)
996{
997 unsigned long flags;
998 struct musb *musb;
999 u8 epnum;
1000 struct musb_ep *musb_ep;
1001 void __iomem *epio;
1002 int status = 0;
1003
1004 musb_ep = to_musb_ep(ep);
1005 musb = musb_ep->musb;
1006 epnum = musb_ep->current_epnum;
1007 epio = musb->endpoints[epnum].regs;
1008
1009 spin_lock_irqsave(&musb->lock, flags);
1010 musb_ep_select(musb->mregs, epnum);
1011
1012 /* zero the endpoint sizes */
1013 if (musb_ep->is_in) {
1014 u16 int_txe = musb_readw(musb->mregs, MUSB_INTRTXE);
1015 int_txe &= ~(1 << epnum);
1016 musb_writew(musb->mregs, MUSB_INTRTXE, int_txe);
1017 musb_writew(epio, MUSB_TXMAXP, 0);
1018 } else {
1019 u16 int_rxe = musb_readw(musb->mregs, MUSB_INTRRXE);
1020 int_rxe &= ~(1 << epnum);
1021 musb_writew(musb->mregs, MUSB_INTRRXE, int_rxe);
1022 musb_writew(epio, MUSB_RXMAXP, 0);
1023 }
1024
1025 musb_ep->desc = NULL;
1026
1027 /* abort all pending DMA and requests */
1028 nuke(musb_ep, -ESHUTDOWN);
1029
1030 schedule_work(&musb->irq_work);
1031
1032 spin_unlock_irqrestore(&(musb->lock), flags);
1033
1034 DBG(2, "%s\n", musb_ep->end_point.name);
1035
1036 return status;
1037}
1038
1039/*
1040 * Allocate a request for an endpoint.
1041 * Reused by ep0 code.
1042 */
1043struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
1044{
1045 struct musb_ep *musb_ep = to_musb_ep(ep);
1046 struct musb_request *request = NULL;
1047
1048 request = kzalloc(sizeof *request, gfp_flags);
1049 if (request) {
1050 INIT_LIST_HEAD(&request->request.list);
1051 request->request.dma = DMA_ADDR_INVALID;
1052 request->epnum = musb_ep->current_epnum;
1053 request->ep = musb_ep;
1054 }
1055
1056 return &request->request;
1057}
1058
1059/*
1060 * Free a request
1061 * Reused by ep0 code.
1062 */
1063void musb_free_request(struct usb_ep *ep, struct usb_request *req)
1064{
1065 kfree(to_musb_request(req));
1066}
1067
1068static LIST_HEAD(buffers);
1069
1070struct free_record {
1071 struct list_head list;
1072 struct device *dev;
1073 unsigned bytes;
1074 dma_addr_t dma;
1075};
1076
1077/*
1078 * Context: controller locked, IRQs blocked.
1079 */
1080static void musb_ep_restart(struct musb *musb, struct musb_request *req)
1081{
1082 DBG(3, "<== %s request %p len %u on hw_ep%d\n",
1083 req->tx ? "TX/IN" : "RX/OUT",
1084 &req->request, req->request.length, req->epnum);
1085
1086 musb_ep_select(musb->mregs, req->epnum);
1087 if (req->tx)
1088 txstate(musb, req);
1089 else
1090 rxstate(musb, req);
1091}
1092
1093static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
1094 gfp_t gfp_flags)
1095{
1096 struct musb_ep *musb_ep;
1097 struct musb_request *request;
1098 struct musb *musb;
1099 int status = 0;
1100 unsigned long lockflags;
1101
1102 if (!ep || !req)
1103 return -EINVAL;
1104 if (!req->buf)
1105 return -ENODATA;
1106
1107 musb_ep = to_musb_ep(ep);
1108 musb = musb_ep->musb;
1109
1110 request = to_musb_request(req);
1111 request->musb = musb;
1112
1113 if (request->ep != musb_ep)
1114 return -EINVAL;
1115
1116 DBG(4, "<== to %s request=%p\n", ep->name, req);
1117
1118 /* request is mine now... */
1119 request->request.actual = 0;
1120 request->request.status = -EINPROGRESS;
1121 request->epnum = musb_ep->current_epnum;
1122 request->tx = musb_ep->is_in;
1123
1124 if (is_dma_capable() && musb_ep->dma) {
1125 if (request->request.dma == DMA_ADDR_INVALID) {
1126 request->request.dma = dma_map_single(
1127 musb->controller,
1128 request->request.buf,
1129 request->request.length,
1130 request->tx
1131 ? DMA_TO_DEVICE
1132 : DMA_FROM_DEVICE);
1133 request->mapped = 1;
1134 } else {
1135 dma_sync_single_for_device(musb->controller,
1136 request->request.dma,
1137 request->request.length,
1138 request->tx
1139 ? DMA_TO_DEVICE
1140 : DMA_FROM_DEVICE);
1141 request->mapped = 0;
1142 }
1143 } else if (!req->buf) {
1144 return -ENODATA;
1145 } else
1146 request->mapped = 0;
1147
1148 spin_lock_irqsave(&musb->lock, lockflags);
1149
1150 /* don't queue if the ep is down */
1151 if (!musb_ep->desc) {
1152 DBG(4, "req %p queued to %s while ep %s\n",
1153 req, ep->name, "disabled");
1154 status = -ESHUTDOWN;
1155 goto cleanup;
1156 }
1157
1158 /* add request to the list */
1159 list_add_tail(&(request->request.list), &(musb_ep->req_list));
1160
1161 /* it this is the head of the queue, start i/o ... */
1162 if (!musb_ep->busy && &request->request.list == musb_ep->req_list.next)
1163 musb_ep_restart(musb, request);
1164
1165cleanup:
1166 spin_unlock_irqrestore(&musb->lock, lockflags);
1167 return status;
1168}
1169
1170static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request)
1171{
1172 struct musb_ep *musb_ep = to_musb_ep(ep);
1173 struct usb_request *r;
1174 unsigned long flags;
1175 int status = 0;
1176 struct musb *musb = musb_ep->musb;
1177
1178 if (!ep || !request || to_musb_request(request)->ep != musb_ep)
1179 return -EINVAL;
1180
1181 spin_lock_irqsave(&musb->lock, flags);
1182
1183 list_for_each_entry(r, &musb_ep->req_list, list) {
1184 if (r == request)
1185 break;
1186 }
1187 if (r != request) {
1188 DBG(3, "request %p not queued to %s\n", request, ep->name);
1189 status = -EINVAL;
1190 goto done;
1191 }
1192
1193 /* if the hardware doesn't have the request, easy ... */
1194 if (musb_ep->req_list.next != &request->list || musb_ep->busy)
1195 musb_g_giveback(musb_ep, request, -ECONNRESET);
1196
1197 /* ... else abort the dma transfer ... */
1198 else if (is_dma_capable() && musb_ep->dma) {
1199 struct dma_controller *c = musb->dma_controller;
1200
1201 musb_ep_select(musb->mregs, musb_ep->current_epnum);
1202 if (c->channel_abort)
1203 status = c->channel_abort(musb_ep->dma);
1204 else
1205 status = -EBUSY;
1206 if (status == 0)
1207 musb_g_giveback(musb_ep, request, -ECONNRESET);
1208 } else {
1209 /* NOTE: by sticking to easily tested hardware/driver states,
1210 * we leave counting of in-flight packets imprecise.
1211 */
1212 musb_g_giveback(musb_ep, request, -ECONNRESET);
1213 }
1214
1215done:
1216 spin_unlock_irqrestore(&musb->lock, flags);
1217 return status;
1218}
1219
1220/*
1221 * Set or clear the halt bit of an endpoint. A halted enpoint won't tx/rx any
1222 * data but will queue requests.
1223 *
1224 * exported to ep0 code
1225 */
1226int musb_gadget_set_halt(struct usb_ep *ep, int value)
1227{
1228 struct musb_ep *musb_ep = to_musb_ep(ep);
1229 u8 epnum = musb_ep->current_epnum;
1230 struct musb *musb = musb_ep->musb;
1231 void __iomem *epio = musb->endpoints[epnum].regs;
1232 void __iomem *mbase;
1233 unsigned long flags;
1234 u16 csr;
1235 struct musb_request *request = NULL;
1236 int status = 0;
1237
1238 if (!ep)
1239 return -EINVAL;
1240 mbase = musb->mregs;
1241
1242 spin_lock_irqsave(&musb->lock, flags);
1243
1244 if ((USB_ENDPOINT_XFER_ISOC == musb_ep->type)) {
1245 status = -EINVAL;
1246 goto done;
1247 }
1248
1249 musb_ep_select(mbase, epnum);
1250
1251 /* cannot portably stall with non-empty FIFO */
1252 request = to_musb_request(next_request(musb_ep));
1253 if (value && musb_ep->is_in) {
1254 csr = musb_readw(epio, MUSB_TXCSR);
1255 if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
1256 DBG(3, "%s fifo busy, cannot halt\n", ep->name);
1257 spin_unlock_irqrestore(&musb->lock, flags);
1258 return -EAGAIN;
1259 }
1260
1261 }
1262
1263 /* set/clear the stall and toggle bits */
1264 DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear");
1265 if (musb_ep->is_in) {
1266 csr = musb_readw(epio, MUSB_TXCSR);
1267 if (csr & MUSB_TXCSR_FIFONOTEMPTY)
1268 csr |= MUSB_TXCSR_FLUSHFIFO;
1269 csr |= MUSB_TXCSR_P_WZC_BITS
1270 | MUSB_TXCSR_CLRDATATOG;
1271 if (value)
1272 csr |= MUSB_TXCSR_P_SENDSTALL;
1273 else
1274 csr &= ~(MUSB_TXCSR_P_SENDSTALL
1275 | MUSB_TXCSR_P_SENTSTALL);
1276 csr &= ~MUSB_TXCSR_TXPKTRDY;
1277 musb_writew(epio, MUSB_TXCSR, csr);
1278 } else {
1279 csr = musb_readw(epio, MUSB_RXCSR);
1280 csr |= MUSB_RXCSR_P_WZC_BITS
1281 | MUSB_RXCSR_FLUSHFIFO
1282 | MUSB_RXCSR_CLRDATATOG;
1283 if (value)
1284 csr |= MUSB_RXCSR_P_SENDSTALL;
1285 else
1286 csr &= ~(MUSB_RXCSR_P_SENDSTALL
1287 | MUSB_RXCSR_P_SENTSTALL);
1288 musb_writew(epio, MUSB_RXCSR, csr);
1289 }
1290
1291done:
1292
1293 /* maybe start the first request in the queue */
1294 if (!musb_ep->busy && !value && request) {
1295 DBG(3, "restarting the request\n");
1296 musb_ep_restart(musb, request);
1297 }
1298
1299 spin_unlock_irqrestore(&musb->lock, flags);
1300 return status;
1301}
1302
1303static int musb_gadget_fifo_status(struct usb_ep *ep)
1304{
1305 struct musb_ep *musb_ep = to_musb_ep(ep);
1306 void __iomem *epio = musb_ep->hw_ep->regs;
1307 int retval = -EINVAL;
1308
1309 if (musb_ep->desc && !musb_ep->is_in) {
1310 struct musb *musb = musb_ep->musb;
1311 int epnum = musb_ep->current_epnum;
1312 void __iomem *mbase = musb->mregs;
1313 unsigned long flags;
1314
1315 spin_lock_irqsave(&musb->lock, flags);
1316
1317 musb_ep_select(mbase, epnum);
1318 /* FIXME return zero unless RXPKTRDY is set */
1319 retval = musb_readw(epio, MUSB_RXCOUNT);
1320
1321 spin_unlock_irqrestore(&musb->lock, flags);
1322 }
1323 return retval;
1324}
1325
1326static void musb_gadget_fifo_flush(struct usb_ep *ep)
1327{
1328 struct musb_ep *musb_ep = to_musb_ep(ep);
1329 struct musb *musb = musb_ep->musb;
1330 u8 epnum = musb_ep->current_epnum;
1331 void __iomem *epio = musb->endpoints[epnum].regs;
1332 void __iomem *mbase;
1333 unsigned long flags;
1334 u16 csr, int_txe;
1335
1336 mbase = musb->mregs;
1337
1338 spin_lock_irqsave(&musb->lock, flags);
1339 musb_ep_select(mbase, (u8) epnum);
1340
1341 /* disable interrupts */
1342 int_txe = musb_readw(mbase, MUSB_INTRTXE);
1343 musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));
1344
1345 if (musb_ep->is_in) {
1346 csr = musb_readw(epio, MUSB_TXCSR);
1347 if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
1348 csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS;
1349 musb_writew(epio, MUSB_TXCSR, csr);
1350 /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
1351 musb_writew(epio, MUSB_TXCSR, csr);
1352 }
1353 } else {
1354 csr = musb_readw(epio, MUSB_RXCSR);
1355 csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_P_WZC_BITS;
1356 musb_writew(epio, MUSB_RXCSR, csr);
1357 musb_writew(epio, MUSB_RXCSR, csr);
1358 }
1359
1360 /* re-enable interrupt */
1361 musb_writew(mbase, MUSB_INTRTXE, int_txe);
1362 spin_unlock_irqrestore(&musb->lock, flags);
1363}
1364
1365static const struct usb_ep_ops musb_ep_ops = {
1366 .enable = musb_gadget_enable,
1367 .disable = musb_gadget_disable,
1368 .alloc_request = musb_alloc_request,
1369 .free_request = musb_free_request,
1370 .queue = musb_gadget_queue,
1371 .dequeue = musb_gadget_dequeue,
1372 .set_halt = musb_gadget_set_halt,
1373 .fifo_status = musb_gadget_fifo_status,
1374 .fifo_flush = musb_gadget_fifo_flush
1375};
1376
1377/* ----------------------------------------------------------------------- */
1378
1379static int musb_gadget_get_frame(struct usb_gadget *gadget)
1380{
1381 struct musb *musb = gadget_to_musb(gadget);
1382
1383 return (int)musb_readw(musb->mregs, MUSB_FRAME);
1384}
1385
1386static int musb_gadget_wakeup(struct usb_gadget *gadget)
1387{
1388 struct musb *musb = gadget_to_musb(gadget);
1389 void __iomem *mregs = musb->mregs;
1390 unsigned long flags;
1391 int status = -EINVAL;
1392 u8 power, devctl;
1393 int retries;
1394
1395 spin_lock_irqsave(&musb->lock, flags);
1396
1397 switch (musb->xceiv.state) {
1398 case OTG_STATE_B_PERIPHERAL:
1399 /* NOTE: OTG state machine doesn't include B_SUSPENDED;
1400 * that's part of the standard usb 1.1 state machine, and
1401 * doesn't affect OTG transitions.
1402 */
1403 if (musb->may_wakeup && musb->is_suspended)
1404 break;
1405 goto done;
1406 case OTG_STATE_B_IDLE:
1407 /* Start SRP ... OTG not required. */
1408 devctl = musb_readb(mregs, MUSB_DEVCTL);
1409 DBG(2, "Sending SRP: devctl: %02x\n", devctl);
1410 devctl |= MUSB_DEVCTL_SESSION;
1411 musb_writeb(mregs, MUSB_DEVCTL, devctl);
1412 devctl = musb_readb(mregs, MUSB_DEVCTL);
1413 retries = 100;
1414 while (!(devctl & MUSB_DEVCTL_SESSION)) {
1415 devctl = musb_readb(mregs, MUSB_DEVCTL);
1416 if (retries-- < 1)
1417 break;
1418 }
1419 retries = 10000;
1420 while (devctl & MUSB_DEVCTL_SESSION) {
1421 devctl = musb_readb(mregs, MUSB_DEVCTL);
1422 if (retries-- < 1)
1423 break;
1424 }
1425
1426 /* Block idling for at least 1s */
1427 musb_platform_try_idle(musb,
1428 jiffies + msecs_to_jiffies(1 * HZ));
1429
1430 status = 0;
1431 goto done;
1432 default:
1433 DBG(2, "Unhandled wake: %s\n", otg_state_string(musb));
1434 goto done;
1435 }
1436
1437 status = 0;
1438
1439 power = musb_readb(mregs, MUSB_POWER);
1440 power |= MUSB_POWER_RESUME;
1441 musb_writeb(mregs, MUSB_POWER, power);
1442 DBG(2, "issue wakeup\n");
1443
1444 /* FIXME do this next chunk in a timer callback, no udelay */
1445 mdelay(2);
1446
1447 power = musb_readb(mregs, MUSB_POWER);
1448 power &= ~MUSB_POWER_RESUME;
1449 musb_writeb(mregs, MUSB_POWER, power);
1450done:
1451 spin_unlock_irqrestore(&musb->lock, flags);
1452 return status;
1453}
1454
1455static int
1456musb_gadget_set_self_powered(struct usb_gadget *gadget, int is_selfpowered)
1457{
1458 struct musb *musb = gadget_to_musb(gadget);
1459
1460 musb->is_self_powered = !!is_selfpowered;
1461 return 0;
1462}
1463
1464static void musb_pullup(struct musb *musb, int is_on)
1465{
1466 u8 power;
1467
1468 power = musb_readb(musb->mregs, MUSB_POWER);
1469 if (is_on)
1470 power |= MUSB_POWER_SOFTCONN;
1471 else
1472 power &= ~MUSB_POWER_SOFTCONN;
1473
1474 /* FIXME if on, HdrcStart; if off, HdrcStop */
1475
1476 DBG(3, "gadget %s D+ pullup %s\n",
1477 musb->gadget_driver->function, is_on ? "on" : "off");
1478 musb_writeb(musb->mregs, MUSB_POWER, power);
1479}
1480
1481#if 0
1482static int musb_gadget_vbus_session(struct usb_gadget *gadget, int is_active)
1483{
1484 DBG(2, "<= %s =>\n", __func__);
1485
1486 /*
1487 * FIXME iff driver's softconnect flag is set (as it is during probe,
1488 * though that can clear it), just musb_pullup().
1489 */
1490
1491 return -EINVAL;
1492}
1493#endif
1494
1495static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
1496{
1497 struct musb *musb = gadget_to_musb(gadget);
1498
1499 if (!musb->xceiv.set_power)
1500 return -EOPNOTSUPP;
1501 return otg_set_power(&musb->xceiv, mA);
1502}
1503
1504static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on)
1505{
1506 struct musb *musb = gadget_to_musb(gadget);
1507 unsigned long flags;
1508
1509 is_on = !!is_on;
1510
1511 /* NOTE: this assumes we are sensing vbus; we'd rather
1512 * not pullup unless the B-session is active.
1513 */
1514 spin_lock_irqsave(&musb->lock, flags);
1515 if (is_on != musb->softconnect) {
1516 musb->softconnect = is_on;
1517 musb_pullup(musb, is_on);
1518 }
1519 spin_unlock_irqrestore(&musb->lock, flags);
1520 return 0;
1521}
1522
1523static const struct usb_gadget_ops musb_gadget_operations = {
1524 .get_frame = musb_gadget_get_frame,
1525 .wakeup = musb_gadget_wakeup,
1526 .set_selfpowered = musb_gadget_set_self_powered,
1527 /* .vbus_session = musb_gadget_vbus_session, */
1528 .vbus_draw = musb_gadget_vbus_draw,
1529 .pullup = musb_gadget_pullup,
1530};
1531
1532/* ----------------------------------------------------------------------- */
1533
1534/* Registration */
1535
1536/* Only this registration code "knows" the rule (from USB standards)
1537 * about there being only one external upstream port. It assumes
1538 * all peripheral ports are external...
1539 */
1540static struct musb *the_gadget;
1541
1542static void musb_gadget_release(struct device *dev)
1543{
1544 /* kref_put(WHAT) */
1545 dev_dbg(dev, "%s\n", __func__);
1546}
1547
1548
1549static void __init
1550init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in)
1551{
1552 struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
1553
1554 memset(ep, 0, sizeof *ep);
1555
1556 ep->current_epnum = epnum;
1557 ep->musb = musb;
1558 ep->hw_ep = hw_ep;
1559 ep->is_in = is_in;
1560
1561 INIT_LIST_HEAD(&ep->req_list);
1562
1563 sprintf(ep->name, "ep%d%s", epnum,
1564 (!epnum || hw_ep->is_shared_fifo) ? "" : (
1565 is_in ? "in" : "out"));
1566 ep->end_point.name = ep->name;
1567 INIT_LIST_HEAD(&ep->end_point.ep_list);
1568 if (!epnum) {
1569 ep->end_point.maxpacket = 64;
1570 ep->end_point.ops = &musb_g_ep0_ops;
1571 musb->g.ep0 = &ep->end_point;
1572 } else {
1573 if (is_in)
1574 ep->end_point.maxpacket = hw_ep->max_packet_sz_tx;
1575 else
1576 ep->end_point.maxpacket = hw_ep->max_packet_sz_rx;
1577 ep->end_point.ops = &musb_ep_ops;
1578 list_add_tail(&ep->end_point.ep_list, &musb->g.ep_list);
1579 }
1580}
1581
1582/*
1583 * Initialize the endpoints exposed to peripheral drivers, with backlinks
1584 * to the rest of the driver state.
1585 */
1586static inline void __init musb_g_init_endpoints(struct musb *musb)
1587{
1588 u8 epnum;
1589 struct musb_hw_ep *hw_ep;
1590 unsigned count = 0;
1591
1592 /* intialize endpoint list just once */
1593 INIT_LIST_HEAD(&(musb->g.ep_list));
1594
1595 for (epnum = 0, hw_ep = musb->endpoints;
1596 epnum < musb->nr_endpoints;
1597 epnum++, hw_ep++) {
1598 if (hw_ep->is_shared_fifo /* || !epnum */) {
1599 init_peripheral_ep(musb, &hw_ep->ep_in, epnum, 0);
1600 count++;
1601 } else {
1602 if (hw_ep->max_packet_sz_tx) {
1603 init_peripheral_ep(musb, &hw_ep->ep_in,
1604 epnum, 1);
1605 count++;
1606 }
1607 if (hw_ep->max_packet_sz_rx) {
1608 init_peripheral_ep(musb, &hw_ep->ep_out,
1609 epnum, 0);
1610 count++;
1611 }
1612 }
1613 }
1614}
1615
1616/* called once during driver setup to initialize and link into
1617 * the driver model; memory is zeroed.
1618 */
1619int __init musb_gadget_setup(struct musb *musb)
1620{
1621 int status;
1622
1623 /* REVISIT minor race: if (erroneously) setting up two
1624 * musb peripherals at the same time, only the bus lock
1625 * is probably held.
1626 */
1627 if (the_gadget)
1628 return -EBUSY;
1629 the_gadget = musb;
1630
1631 musb->g.ops = &musb_gadget_operations;
1632 musb->g.is_dualspeed = 1;
1633 musb->g.speed = USB_SPEED_UNKNOWN;
1634
1635 /* this "gadget" abstracts/virtualizes the controller */
1636 strcpy(musb->g.dev.bus_id, "gadget");
1637 musb->g.dev.parent = musb->controller;
1638 musb->g.dev.dma_mask = musb->controller->dma_mask;
1639 musb->g.dev.release = musb_gadget_release;
1640 musb->g.name = musb_driver_name;
1641
1642 if (is_otg_enabled(musb))
1643 musb->g.is_otg = 1;
1644
1645 musb_g_init_endpoints(musb);
1646
1647 musb->is_active = 0;
1648 musb_platform_try_idle(musb, 0);
1649
1650 status = device_register(&musb->g.dev);
1651 if (status != 0)
1652 the_gadget = NULL;
1653 return status;
1654}
1655
1656void musb_gadget_cleanup(struct musb *musb)
1657{
1658 if (musb != the_gadget)
1659 return;
1660
1661 device_unregister(&musb->g.dev);
1662 the_gadget = NULL;
1663}
1664
1665/*
1666 * Register the gadget driver. Used by gadget drivers when
1667 * registering themselves with the controller.
1668 *
1669 * -EINVAL something went wrong (not driver)
1670 * -EBUSY another gadget is already using the controller
1671 * -ENOMEM no memeory to perform the operation
1672 *
1673 * @param driver the gadget driver
1674 * @return <0 if error, 0 if everything is fine
1675 */
1676int usb_gadget_register_driver(struct usb_gadget_driver *driver)
1677{
1678 int retval;
1679 unsigned long flags;
1680 struct musb *musb = the_gadget;
1681
1682 if (!driver
1683 || driver->speed != USB_SPEED_HIGH
1684 || !driver->bind
1685 || !driver->setup)
1686 return -EINVAL;
1687
1688 /* driver must be initialized to support peripheral mode */
1689 if (!musb || !(musb->board_mode == MUSB_OTG
1690 || musb->board_mode != MUSB_OTG)) {
1691 DBG(1, "%s, no dev??\n", __func__);
1692 return -ENODEV;
1693 }
1694
1695 DBG(3, "registering driver %s\n", driver->function);
1696 spin_lock_irqsave(&musb->lock, flags);
1697
1698 if (musb->gadget_driver) {
1699 DBG(1, "%s is already bound to %s\n",
1700 musb_driver_name,
1701 musb->gadget_driver->driver.name);
1702 retval = -EBUSY;
1703 } else {
1704 musb->gadget_driver = driver;
1705 musb->g.dev.driver = &driver->driver;
1706 driver->driver.bus = NULL;
1707 musb->softconnect = 1;
1708 retval = 0;
1709 }
1710
1711 spin_unlock_irqrestore(&musb->lock, flags);
1712
1713 if (retval == 0) {
1714 retval = driver->bind(&musb->g);
1715 if (retval != 0) {
1716 DBG(3, "bind to driver %s failed --> %d\n",
1717 driver->driver.name, retval);
1718 musb->gadget_driver = NULL;
1719 musb->g.dev.driver = NULL;
1720 }
1721
1722 spin_lock_irqsave(&musb->lock, flags);
1723
1724 /* REVISIT always use otg_set_peripheral(), handling
1725 * issues including the root hub one below ...
1726 */
1727 musb->xceiv.gadget = &musb->g;
1728 musb->xceiv.state = OTG_STATE_B_IDLE;
1729 musb->is_active = 1;
1730
1731 /* FIXME this ignores the softconnect flag. Drivers are
1732 * allowed hold the peripheral inactive until for example
1733 * userspace hooks up printer hardware or DSP codecs, so
1734 * hosts only see fully functional devices.
1735 */
1736
1737 if (!is_otg_enabled(musb))
1738 musb_start(musb);
1739
1740 spin_unlock_irqrestore(&musb->lock, flags);
1741
1742 if (is_otg_enabled(musb)) {
1743 DBG(3, "OTG startup...\n");
1744
1745 /* REVISIT: funcall to other code, which also
1746 * handles power budgeting ... this way also
1747 * ensures HdrcStart is indirectly called.
1748 */
1749 retval = usb_add_hcd(musb_to_hcd(musb), -1, 0);
1750 if (retval < 0) {
1751 DBG(1, "add_hcd failed, %d\n", retval);
1752 spin_lock_irqsave(&musb->lock, flags);
1753 musb->xceiv.gadget = NULL;
1754 musb->xceiv.state = OTG_STATE_UNDEFINED;
1755 musb->gadget_driver = NULL;
1756 musb->g.dev.driver = NULL;
1757 spin_unlock_irqrestore(&musb->lock, flags);
1758 }
1759 }
1760 }
1761
1762 return retval;
1763}
1764EXPORT_SYMBOL(usb_gadget_register_driver);
1765
1766static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
1767{
1768 int i;
1769 struct musb_hw_ep *hw_ep;
1770
1771 /* don't disconnect if it's not connected */
1772 if (musb->g.speed == USB_SPEED_UNKNOWN)
1773 driver = NULL;
1774 else
1775 musb->g.speed = USB_SPEED_UNKNOWN;
1776
1777 /* deactivate the hardware */
1778 if (musb->softconnect) {
1779 musb->softconnect = 0;
1780 musb_pullup(musb, 0);
1781 }
1782 musb_stop(musb);
1783
1784 /* killing any outstanding requests will quiesce the driver;
1785 * then report disconnect
1786 */
1787 if (driver) {
1788 for (i = 0, hw_ep = musb->endpoints;
1789 i < musb->nr_endpoints;
1790 i++, hw_ep++) {
1791 musb_ep_select(musb->mregs, i);
1792 if (hw_ep->is_shared_fifo /* || !epnum */) {
1793 nuke(&hw_ep->ep_in, -ESHUTDOWN);
1794 } else {
1795 if (hw_ep->max_packet_sz_tx)
1796 nuke(&hw_ep->ep_in, -ESHUTDOWN);
1797 if (hw_ep->max_packet_sz_rx)
1798 nuke(&hw_ep->ep_out, -ESHUTDOWN);
1799 }
1800 }
1801
1802 spin_unlock(&musb->lock);
1803 driver->disconnect(&musb->g);
1804 spin_lock(&musb->lock);
1805 }
1806}
1807
1808/*
1809 * Unregister the gadget driver. Used by gadget drivers when
1810 * unregistering themselves from the controller.
1811 *
1812 * @param driver the gadget driver to unregister
1813 */
1814int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
1815{
1816 unsigned long flags;
1817 int retval = 0;
1818 struct musb *musb = the_gadget;
1819
1820 if (!driver || !driver->unbind || !musb)
1821 return -EINVAL;
1822
1823 /* REVISIT always use otg_set_peripheral() here too;
1824 * this needs to shut down the OTG engine.
1825 */
1826
1827 spin_lock_irqsave(&musb->lock, flags);
1828
1829#ifdef CONFIG_USB_MUSB_OTG
1830 musb_hnp_stop(musb);
1831#endif
1832
1833 if (musb->gadget_driver == driver) {
1834
1835 (void) musb_gadget_vbus_draw(&musb->g, 0);
1836
1837 musb->xceiv.state = OTG_STATE_UNDEFINED;
1838 stop_activity(musb, driver);
1839
1840 DBG(3, "unregistering driver %s\n", driver->function);
1841 spin_unlock_irqrestore(&musb->lock, flags);
1842 driver->unbind(&musb->g);
1843 spin_lock_irqsave(&musb->lock, flags);
1844
1845 musb->gadget_driver = NULL;
1846 musb->g.dev.driver = NULL;
1847
1848 musb->is_active = 0;
1849 musb_platform_try_idle(musb, 0);
1850 } else
1851 retval = -EINVAL;
1852 spin_unlock_irqrestore(&musb->lock, flags);
1853
1854 if (is_otg_enabled(musb) && retval == 0) {
1855 usb_remove_hcd(musb_to_hcd(musb));
1856 /* FIXME we need to be able to register another
1857 * gadget driver here and have everything work;
1858 * that currently misbehaves.
1859 */
1860 }
1861
1862 return retval;
1863}
1864EXPORT_SYMBOL(usb_gadget_unregister_driver);
1865
1866
1867/* ----------------------------------------------------------------------- */
1868
1869/* lifecycle operations called through plat_uds.c */
1870
1871void musb_g_resume(struct musb *musb)
1872{
1873 musb->is_suspended = 0;
1874 switch (musb->xceiv.state) {
1875 case OTG_STATE_B_IDLE:
1876 break;
1877 case OTG_STATE_B_WAIT_ACON:
1878 case OTG_STATE_B_PERIPHERAL:
1879 musb->is_active = 1;
1880 if (musb->gadget_driver && musb->gadget_driver->resume) {
1881 spin_unlock(&musb->lock);
1882 musb->gadget_driver->resume(&musb->g);
1883 spin_lock(&musb->lock);
1884 }
1885 break;
1886 default:
1887 WARNING("unhandled RESUME transition (%s)\n",
1888 otg_state_string(musb));
1889 }
1890}
1891
1892/* called when SOF packets stop for 3+ msec */
1893void musb_g_suspend(struct musb *musb)
1894{
1895 u8 devctl;
1896
1897 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
1898 DBG(3, "devctl %02x\n", devctl);
1899
1900 switch (musb->xceiv.state) {
1901 case OTG_STATE_B_IDLE:
1902 if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
1903 musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
1904 break;
1905 case OTG_STATE_B_PERIPHERAL:
1906 musb->is_suspended = 1;
1907 if (musb->gadget_driver && musb->gadget_driver->suspend) {
1908 spin_unlock(&musb->lock);
1909 musb->gadget_driver->suspend(&musb->g);
1910 spin_lock(&musb->lock);
1911 }
1912 break;
1913 default:
1914 /* REVISIT if B_HOST, clear DEVCTL.HOSTREQ;
1915 * A_PERIPHERAL may need care too
1916 */
1917 WARNING("unhandled SUSPEND transition (%s)\n",
1918 otg_state_string(musb));
1919 }
1920}
1921
1922/* Called during SRP */
1923void musb_g_wakeup(struct musb *musb)
1924{
1925 musb_gadget_wakeup(&musb->g);
1926}
1927
1928/* called when VBUS drops below session threshold, and in other cases */
1929void musb_g_disconnect(struct musb *musb)
1930{
1931 void __iomem *mregs = musb->mregs;
1932 u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
1933
1934 DBG(3, "devctl %02x\n", devctl);
1935
1936 /* clear HR */
1937 musb_writeb(mregs, MUSB_DEVCTL, devctl & MUSB_DEVCTL_SESSION);
1938
1939 /* don't draw vbus until new b-default session */
1940 (void) musb_gadget_vbus_draw(&musb->g, 0);
1941
1942 musb->g.speed = USB_SPEED_UNKNOWN;
1943 if (musb->gadget_driver && musb->gadget_driver->disconnect) {
1944 spin_unlock(&musb->lock);
1945 musb->gadget_driver->disconnect(&musb->g);
1946 spin_lock(&musb->lock);
1947 }
1948
1949 switch (musb->xceiv.state) {
1950 default:
1951#ifdef CONFIG_USB_MUSB_OTG
1952 DBG(2, "Unhandled disconnect %s, setting a_idle\n",
1953 otg_state_string(musb));
1954 musb->xceiv.state = OTG_STATE_A_IDLE;
1955 break;
1956 case OTG_STATE_A_PERIPHERAL:
1957 musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
1958 break;
1959 case OTG_STATE_B_WAIT_ACON:
1960 case OTG_STATE_B_HOST:
1961#endif
1962 case OTG_STATE_B_PERIPHERAL:
1963 case OTG_STATE_B_IDLE:
1964 musb->xceiv.state = OTG_STATE_B_IDLE;
1965 break;
1966 case OTG_STATE_B_SRP_INIT:
1967 break;
1968 }
1969
1970 musb->is_active = 0;
1971}
1972
1973void musb_g_reset(struct musb *musb)
1974__releases(musb->lock)
1975__acquires(musb->lock)
1976{
1977 void __iomem *mbase = musb->mregs;
1978 u8 devctl = musb_readb(mbase, MUSB_DEVCTL);
1979 u8 power;
1980
1981 DBG(3, "<== %s addr=%x driver '%s'\n",
1982 (devctl & MUSB_DEVCTL_BDEVICE)
1983 ? "B-Device" : "A-Device",
1984 musb_readb(mbase, MUSB_FADDR),
1985 musb->gadget_driver
1986 ? musb->gadget_driver->driver.name
1987 : NULL
1988 );
1989
1990 /* report disconnect, if we didn't already (flushing EP state) */
1991 if (musb->g.speed != USB_SPEED_UNKNOWN)
1992 musb_g_disconnect(musb);
1993
1994 /* clear HR */
1995 else if (devctl & MUSB_DEVCTL_HR)
1996 musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
1997
1998
1999 /* what speed did we negotiate? */
2000 power = musb_readb(mbase, MUSB_POWER);
2001 musb->g.speed = (power & MUSB_POWER_HSMODE)
2002 ? USB_SPEED_HIGH : USB_SPEED_FULL;
2003
2004 /* start in USB_STATE_DEFAULT */
2005 musb->is_active = 1;
2006 musb->is_suspended = 0;
2007 MUSB_DEV_MODE(musb);
2008 musb->address = 0;
2009 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
2010
2011 musb->may_wakeup = 0;
2012 musb->g.b_hnp_enable = 0;
2013 musb->g.a_alt_hnp_support = 0;
2014 musb->g.a_hnp_support = 0;
2015
2016 /* Normal reset, as B-Device;
2017 * or else after HNP, as A-Device
2018 */
2019 if (devctl & MUSB_DEVCTL_BDEVICE) {
2020 musb->xceiv.state = OTG_STATE_B_PERIPHERAL;
2021 musb->g.is_a_peripheral = 0;
2022 } else if (is_otg_enabled(musb)) {
2023 musb->xceiv.state = OTG_STATE_A_PERIPHERAL;
2024 musb->g.is_a_peripheral = 1;
2025 } else
2026 WARN_ON(1);
2027
2028 /* start with default limits on VBUS power draw */
2029 (void) musb_gadget_vbus_draw(&musb->g,
2030 is_otg_enabled(musb) ? 8 : 100);
2031}
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h
new file mode 100644
index 000000000000..59502da9f739
--- /dev/null
+++ b/drivers/usb/musb/musb_gadget.h
@@ -0,0 +1,108 @@
1/*
2 * MUSB OTG driver peripheral defines
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef __MUSB_GADGET_H
36#define __MUSB_GADGET_H
37
38struct musb_request {
39 struct usb_request request;
40 struct musb_ep *ep;
41 struct musb *musb;
42 u8 tx; /* endpoint direction */
43 u8 epnum;
44 u8 mapped;
45};
46
47static inline struct musb_request *to_musb_request(struct usb_request *req)
48{
49 return req ? container_of(req, struct musb_request, request) : NULL;
50}
51
52extern struct usb_request *
53musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
54extern void musb_free_request(struct usb_ep *ep, struct usb_request *req);
55
56
57/*
58 * struct musb_ep - peripheral side view of endpoint rx or tx side
59 */
60struct musb_ep {
61 /* stuff towards the head is basically write-once. */
62 struct usb_ep end_point;
63 char name[12];
64 struct musb_hw_ep *hw_ep;
65 struct musb *musb;
66 u8 current_epnum;
67
68 /* ... when enabled/disabled ... */
69 u8 type;
70 u8 is_in;
71 u16 packet_sz;
72 const struct usb_endpoint_descriptor *desc;
73 struct dma_channel *dma;
74
75 /* later things are modified based on usage */
76 struct list_head req_list;
77
78 /* true if lock must be dropped but req_list may not be advanced */
79 u8 busy;
80};
81
82static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
83{
84 return ep ? container_of(ep, struct musb_ep, end_point) : NULL;
85}
86
87static inline struct usb_request *next_request(struct musb_ep *ep)
88{
89 struct list_head *queue = &ep->req_list;
90
91 if (list_empty(queue))
92 return NULL;
93 return container_of(queue->next, struct usb_request, list);
94}
95
96extern void musb_g_tx(struct musb *musb, u8 epnum);
97extern void musb_g_rx(struct musb *musb, u8 epnum);
98
99extern const struct usb_ep_ops musb_g_ep0_ops;
100
101extern int musb_gadget_setup(struct musb *);
102extern void musb_gadget_cleanup(struct musb *);
103
104extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
105
106extern int musb_gadget_set_halt(struct usb_ep *ep, int value);
107
108#endif /* __MUSB_GADGET_H */
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
new file mode 100644
index 000000000000..48d7d3ccb243
--- /dev/null
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -0,0 +1,981 @@
1/*
2 * MUSB OTG peripheral driver ep0 handling
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#include <linux/kernel.h>
36#include <linux/list.h>
37#include <linux/timer.h>
38#include <linux/spinlock.h>
39#include <linux/init.h>
40#include <linux/device.h>
41#include <linux/interrupt.h>
42
43#include "musb_core.h"
44
45/* ep0 is always musb->endpoints[0].ep_in */
46#define next_ep0_request(musb) next_in_request(&(musb)->endpoints[0])
47
48/*
49 * locking note: we use only the controller lock, for simpler correctness.
50 * It's always held with IRQs blocked.
51 *
52 * It protects the ep0 request queue as well as ep0_state, not just the
53 * controller and indexed registers. And that lock stays held unless it
54 * needs to be dropped to allow reentering this driver ... like upcalls to
55 * the gadget driver, or adjusting endpoint halt status.
56 */
57
58static char *decode_ep0stage(u8 stage)
59{
60 switch (stage) {
61 case MUSB_EP0_STAGE_SETUP: return "idle";
62 case MUSB_EP0_STAGE_TX: return "in";
63 case MUSB_EP0_STAGE_RX: return "out";
64 case MUSB_EP0_STAGE_ACKWAIT: return "wait";
65 case MUSB_EP0_STAGE_STATUSIN: return "in/status";
66 case MUSB_EP0_STAGE_STATUSOUT: return "out/status";
67 default: return "?";
68 }
69}
70
71/* handle a standard GET_STATUS request
72 * Context: caller holds controller lock
73 */
74static int service_tx_status_request(
75 struct musb *musb,
76 const struct usb_ctrlrequest *ctrlrequest)
77{
78 void __iomem *mbase = musb->mregs;
79 int handled = 1;
80 u8 result[2], epnum = 0;
81 const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK;
82
83 result[1] = 0;
84
85 switch (recip) {
86 case USB_RECIP_DEVICE:
87 result[0] = musb->is_self_powered << USB_DEVICE_SELF_POWERED;
88 result[0] |= musb->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;
89#ifdef CONFIG_USB_MUSB_OTG
90 if (musb->g.is_otg) {
91 result[0] |= musb->g.b_hnp_enable
92 << USB_DEVICE_B_HNP_ENABLE;
93 result[0] |= musb->g.a_alt_hnp_support
94 << USB_DEVICE_A_ALT_HNP_SUPPORT;
95 result[0] |= musb->g.a_hnp_support
96 << USB_DEVICE_A_HNP_SUPPORT;
97 }
98#endif
99 break;
100
101 case USB_RECIP_INTERFACE:
102 result[0] = 0;
103 break;
104
105 case USB_RECIP_ENDPOINT: {
106 int is_in;
107 struct musb_ep *ep;
108 u16 tmp;
109 void __iomem *regs;
110
111 epnum = (u8) ctrlrequest->wIndex;
112 if (!epnum) {
113 result[0] = 0;
114 break;
115 }
116
117 is_in = epnum & USB_DIR_IN;
118 if (is_in) {
119 epnum &= 0x0f;
120 ep = &musb->endpoints[epnum].ep_in;
121 } else {
122 ep = &musb->endpoints[epnum].ep_out;
123 }
124 regs = musb->endpoints[epnum].regs;
125
126 if (epnum >= MUSB_C_NUM_EPS || !ep->desc) {
127 handled = -EINVAL;
128 break;
129 }
130
131 musb_ep_select(mbase, epnum);
132 if (is_in)
133 tmp = musb_readw(regs, MUSB_TXCSR)
134 & MUSB_TXCSR_P_SENDSTALL;
135 else
136 tmp = musb_readw(regs, MUSB_RXCSR)
137 & MUSB_RXCSR_P_SENDSTALL;
138 musb_ep_select(mbase, 0);
139
140 result[0] = tmp ? 1 : 0;
141 } break;
142
143 default:
144 /* class, vendor, etc ... delegate */
145 handled = 0;
146 break;
147 }
148
149 /* fill up the fifo; caller updates csr0 */
150 if (handled > 0) {
151 u16 len = le16_to_cpu(ctrlrequest->wLength);
152
153 if (len > 2)
154 len = 2;
155 musb_write_fifo(&musb->endpoints[0], len, result);
156 }
157
158 return handled;
159}
160
161/*
162 * handle a control-IN request, the end0 buffer contains the current request
163 * that is supposed to be a standard control request. Assumes the fifo to
164 * be at least 2 bytes long.
165 *
166 * @return 0 if the request was NOT HANDLED,
167 * < 0 when error
168 * > 0 when the request is processed
169 *
170 * Context: caller holds controller lock
171 */
172static int
173service_in_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest)
174{
175 int handled = 0; /* not handled */
176
177 if ((ctrlrequest->bRequestType & USB_TYPE_MASK)
178 == USB_TYPE_STANDARD) {
179 switch (ctrlrequest->bRequest) {
180 case USB_REQ_GET_STATUS:
181 handled = service_tx_status_request(musb,
182 ctrlrequest);
183 break;
184
185 /* case USB_REQ_SYNC_FRAME: */
186
187 default:
188 break;
189 }
190 }
191 return handled;
192}
193
194/*
195 * Context: caller holds controller lock
196 */
197static void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req)
198{
199 musb_g_giveback(&musb->endpoints[0].ep_in, req, 0);
200 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
201}
202
203/*
204 * Tries to start B-device HNP negotiation if enabled via sysfs
205 */
206static inline void musb_try_b_hnp_enable(struct musb *musb)
207{
208 void __iomem *mbase = musb->mregs;
209 u8 devctl;
210
211 DBG(1, "HNP: Setting HR\n");
212 devctl = musb_readb(mbase, MUSB_DEVCTL);
213 musb_writeb(mbase, MUSB_DEVCTL, devctl | MUSB_DEVCTL_HR);
214}
215
216/*
217 * Handle all control requests with no DATA stage, including standard
218 * requests such as:
219 * USB_REQ_SET_CONFIGURATION, USB_REQ_SET_INTERFACE, unrecognized
220 * always delegated to the gadget driver
221 * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE
222 * always handled here, except for class/vendor/... features
223 *
224 * Context: caller holds controller lock
225 */
226static int
227service_zero_data_request(struct musb *musb,
228 struct usb_ctrlrequest *ctrlrequest)
229__releases(musb->lock)
230__acquires(musb->lock)
231{
232 int handled = -EINVAL;
233 void __iomem *mbase = musb->mregs;
234 const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK;
235
236 /* the gadget driver handles everything except what we MUST handle */
237 if ((ctrlrequest->bRequestType & USB_TYPE_MASK)
238 == USB_TYPE_STANDARD) {
239 switch (ctrlrequest->bRequest) {
240 case USB_REQ_SET_ADDRESS:
241 /* change it after the status stage */
242 musb->set_address = true;
243 musb->address = (u8) (ctrlrequest->wValue & 0x7f);
244 handled = 1;
245 break;
246
247 case USB_REQ_CLEAR_FEATURE:
248 switch (recip) {
249 case USB_RECIP_DEVICE:
250 if (ctrlrequest->wValue
251 != USB_DEVICE_REMOTE_WAKEUP)
252 break;
253 musb->may_wakeup = 0;
254 handled = 1;
255 break;
256 case USB_RECIP_INTERFACE:
257 break;
258 case USB_RECIP_ENDPOINT:{
259 const u8 num = ctrlrequest->wIndex & 0x0f;
260 struct musb_ep *musb_ep;
261
262 if (num == 0
263 || num >= MUSB_C_NUM_EPS
264 || ctrlrequest->wValue
265 != USB_ENDPOINT_HALT)
266 break;
267
268 if (ctrlrequest->wIndex & USB_DIR_IN)
269 musb_ep = &musb->endpoints[num].ep_in;
270 else
271 musb_ep = &musb->endpoints[num].ep_out;
272 if (!musb_ep->desc)
273 break;
274
275 /* REVISIT do it directly, no locking games */
276 spin_unlock(&musb->lock);
277 musb_gadget_set_halt(&musb_ep->end_point, 0);
278 spin_lock(&musb->lock);
279
280 /* select ep0 again */
281 musb_ep_select(mbase, 0);
282 handled = 1;
283 } break;
284 default:
285 /* class, vendor, etc ... delegate */
286 handled = 0;
287 break;
288 }
289 break;
290
291 case USB_REQ_SET_FEATURE:
292 switch (recip) {
293 case USB_RECIP_DEVICE:
294 handled = 1;
295 switch (ctrlrequest->wValue) {
296 case USB_DEVICE_REMOTE_WAKEUP:
297 musb->may_wakeup = 1;
298 break;
299 case USB_DEVICE_TEST_MODE:
300 if (musb->g.speed != USB_SPEED_HIGH)
301 goto stall;
302 if (ctrlrequest->wIndex & 0xff)
303 goto stall;
304
305 switch (ctrlrequest->wIndex >> 8) {
306 case 1:
307 pr_debug("TEST_J\n");
308 /* TEST_J */
309 musb->test_mode_nr =
310 MUSB_TEST_J;
311 break;
312 case 2:
313 /* TEST_K */
314 pr_debug("TEST_K\n");
315 musb->test_mode_nr =
316 MUSB_TEST_K;
317 break;
318 case 3:
319 /* TEST_SE0_NAK */
320 pr_debug("TEST_SE0_NAK\n");
321 musb->test_mode_nr =
322 MUSB_TEST_SE0_NAK;
323 break;
324 case 4:
325 /* TEST_PACKET */
326 pr_debug("TEST_PACKET\n");
327 musb->test_mode_nr =
328 MUSB_TEST_PACKET;
329 break;
330 default:
331 goto stall;
332 }
333
334 /* enter test mode after irq */
335 if (handled > 0)
336 musb->test_mode = true;
337 break;
338#ifdef CONFIG_USB_MUSB_OTG
339 case USB_DEVICE_B_HNP_ENABLE:
340 if (!musb->g.is_otg)
341 goto stall;
342 musb->g.b_hnp_enable = 1;
343 musb_try_b_hnp_enable(musb);
344 break;
345 case USB_DEVICE_A_HNP_SUPPORT:
346 if (!musb->g.is_otg)
347 goto stall;
348 musb->g.a_hnp_support = 1;
349 break;
350 case USB_DEVICE_A_ALT_HNP_SUPPORT:
351 if (!musb->g.is_otg)
352 goto stall;
353 musb->g.a_alt_hnp_support = 1;
354 break;
355#endif
356stall:
357 default:
358 handled = -EINVAL;
359 break;
360 }
361 break;
362
363 case USB_RECIP_INTERFACE:
364 break;
365
366 case USB_RECIP_ENDPOINT:{
367 const u8 epnum =
368 ctrlrequest->wIndex & 0x0f;
369 struct musb_ep *musb_ep;
370 struct musb_hw_ep *ep;
371 void __iomem *regs;
372 int is_in;
373 u16 csr;
374
375 if (epnum == 0
376 || epnum >= MUSB_C_NUM_EPS
377 || ctrlrequest->wValue
378 != USB_ENDPOINT_HALT)
379 break;
380
381 ep = musb->endpoints + epnum;
382 regs = ep->regs;
383 is_in = ctrlrequest->wIndex & USB_DIR_IN;
384 if (is_in)
385 musb_ep = &ep->ep_in;
386 else
387 musb_ep = &ep->ep_out;
388 if (!musb_ep->desc)
389 break;
390
391 musb_ep_select(mbase, epnum);
392 if (is_in) {
393 csr = musb_readw(regs,
394 MUSB_TXCSR);
395 if (csr & MUSB_TXCSR_FIFONOTEMPTY)
396 csr |= MUSB_TXCSR_FLUSHFIFO;
397 csr |= MUSB_TXCSR_P_SENDSTALL
398 | MUSB_TXCSR_CLRDATATOG
399 | MUSB_TXCSR_P_WZC_BITS;
400 musb_writew(regs, MUSB_TXCSR,
401 csr);
402 } else {
403 csr = musb_readw(regs,
404 MUSB_RXCSR);
405 csr |= MUSB_RXCSR_P_SENDSTALL
406 | MUSB_RXCSR_FLUSHFIFO
407 | MUSB_RXCSR_CLRDATATOG
408 | MUSB_TXCSR_P_WZC_BITS;
409 musb_writew(regs, MUSB_RXCSR,
410 csr);
411 }
412
413 /* select ep0 again */
414 musb_ep_select(mbase, 0);
415 handled = 1;
416 } break;
417
418 default:
419 /* class, vendor, etc ... delegate */
420 handled = 0;
421 break;
422 }
423 break;
424 default:
425 /* delegate SET_CONFIGURATION, etc */
426 handled = 0;
427 }
428 } else
429 handled = 0;
430 return handled;
431}
432
433/* we have an ep0out data packet
434 * Context: caller holds controller lock
435 */
436static void ep0_rxstate(struct musb *musb)
437{
438 void __iomem *regs = musb->control_ep->regs;
439 struct usb_request *req;
440 u16 tmp;
441
442 req = next_ep0_request(musb);
443
444 /* read packet and ack; or stall because of gadget driver bug:
445 * should have provided the rx buffer before setup() returned.
446 */
447 if (req) {
448 void *buf = req->buf + req->actual;
449 unsigned len = req->length - req->actual;
450
451 /* read the buffer */
452 tmp = musb_readb(regs, MUSB_COUNT0);
453 if (tmp > len) {
454 req->status = -EOVERFLOW;
455 tmp = len;
456 }
457 musb_read_fifo(&musb->endpoints[0], tmp, buf);
458 req->actual += tmp;
459 tmp = MUSB_CSR0_P_SVDRXPKTRDY;
460 if (tmp < 64 || req->actual == req->length) {
461 musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
462 tmp |= MUSB_CSR0_P_DATAEND;
463 } else
464 req = NULL;
465 } else
466 tmp = MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_SENDSTALL;
467
468
469 /* Completion handler may choose to stall, e.g. because the
470 * message just received holds invalid data.
471 */
472 if (req) {
473 musb->ackpend = tmp;
474 musb_g_ep0_giveback(musb, req);
475 if (!musb->ackpend)
476 return;
477 musb->ackpend = 0;
478 }
479 musb_writew(regs, MUSB_CSR0, tmp);
480}
481
482/*
483 * transmitting to the host (IN), this code might be called from IRQ
484 * and from kernel thread.
485 *
486 * Context: caller holds controller lock
487 */
488static void ep0_txstate(struct musb *musb)
489{
490 void __iomem *regs = musb->control_ep->regs;
491 struct usb_request *request = next_ep0_request(musb);
492 u16 csr = MUSB_CSR0_TXPKTRDY;
493 u8 *fifo_src;
494 u8 fifo_count;
495
496 if (!request) {
497 /* WARN_ON(1); */
498 DBG(2, "odd; csr0 %04x\n", musb_readw(regs, MUSB_CSR0));
499 return;
500 }
501
502 /* load the data */
503 fifo_src = (u8 *) request->buf + request->actual;
504 fifo_count = min((unsigned) MUSB_EP0_FIFOSIZE,
505 request->length - request->actual);
506 musb_write_fifo(&musb->endpoints[0], fifo_count, fifo_src);
507 request->actual += fifo_count;
508
509 /* update the flags */
510 if (fifo_count < MUSB_MAX_END0_PACKET
511 || request->actual == request->length) {
512 musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
513 csr |= MUSB_CSR0_P_DATAEND;
514 } else
515 request = NULL;
516
517 /* report completions as soon as the fifo's loaded; there's no
518 * win in waiting till this last packet gets acked. (other than
519 * very precise fault reporting, needed by USB TMC; possible with
520 * this hardware, but not usable from portable gadget drivers.)
521 */
522 if (request) {
523 musb->ackpend = csr;
524 musb_g_ep0_giveback(musb, request);
525 if (!musb->ackpend)
526 return;
527 musb->ackpend = 0;
528 }
529
530 /* send it out, triggering a "txpktrdy cleared" irq */
531 musb_writew(regs, MUSB_CSR0, csr);
532}
533
534/*
535 * Read a SETUP packet (struct usb_ctrlrequest) from the hardware.
536 * Fields are left in USB byte-order.
537 *
538 * Context: caller holds controller lock.
539 */
540static void
541musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req)
542{
543 struct usb_request *r;
544 void __iomem *regs = musb->control_ep->regs;
545
546 musb_read_fifo(&musb->endpoints[0], sizeof *req, (u8 *)req);
547
548 /* NOTE: earlier 2.6 versions changed setup packets to host
549 * order, but now USB packets always stay in USB byte order.
550 */
551 DBG(3, "SETUP req%02x.%02x v%04x i%04x l%d\n",
552 req->bRequestType,
553 req->bRequest,
554 le16_to_cpu(req->wValue),
555 le16_to_cpu(req->wIndex),
556 le16_to_cpu(req->wLength));
557
558 /* clean up any leftover transfers */
559 r = next_ep0_request(musb);
560 if (r)
561 musb_g_ep0_giveback(musb, r);
562
563 /* For zero-data requests we want to delay the STATUS stage to
564 * avoid SETUPEND errors. If we read data (OUT), delay accepting
565 * packets until there's a buffer to store them in.
566 *
567 * If we write data, the controller acts happier if we enable
568 * the TX FIFO right away, and give the controller a moment
569 * to switch modes...
570 */
571 musb->set_address = false;
572 musb->ackpend = MUSB_CSR0_P_SVDRXPKTRDY;
573 if (req->wLength == 0) {
574 if (req->bRequestType & USB_DIR_IN)
575 musb->ackpend |= MUSB_CSR0_TXPKTRDY;
576 musb->ep0_state = MUSB_EP0_STAGE_ACKWAIT;
577 } else if (req->bRequestType & USB_DIR_IN) {
578 musb->ep0_state = MUSB_EP0_STAGE_TX;
579 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDRXPKTRDY);
580 while ((musb_readw(regs, MUSB_CSR0)
581 & MUSB_CSR0_RXPKTRDY) != 0)
582 cpu_relax();
583 musb->ackpend = 0;
584 } else
585 musb->ep0_state = MUSB_EP0_STAGE_RX;
586}
587
588static int
589forward_to_driver(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest)
590__releases(musb->lock)
591__acquires(musb->lock)
592{
593 int retval;
594 if (!musb->gadget_driver)
595 return -EOPNOTSUPP;
596 spin_unlock(&musb->lock);
597 retval = musb->gadget_driver->setup(&musb->g, ctrlrequest);
598 spin_lock(&musb->lock);
599 return retval;
600}
601
602/*
603 * Handle peripheral ep0 interrupt
604 *
605 * Context: irq handler; we won't re-enter the driver that way.
606 */
607irqreturn_t musb_g_ep0_irq(struct musb *musb)
608{
609 u16 csr;
610 u16 len;
611 void __iomem *mbase = musb->mregs;
612 void __iomem *regs = musb->endpoints[0].regs;
613 irqreturn_t retval = IRQ_NONE;
614
615 musb_ep_select(mbase, 0); /* select ep0 */
616 csr = musb_readw(regs, MUSB_CSR0);
617 len = musb_readb(regs, MUSB_COUNT0);
618
619 DBG(4, "csr %04x, count %d, myaddr %d, ep0stage %s\n",
620 csr, len,
621 musb_readb(mbase, MUSB_FADDR),
622 decode_ep0stage(musb->ep0_state));
623
624 /* I sent a stall.. need to acknowledge it now.. */
625 if (csr & MUSB_CSR0_P_SENTSTALL) {
626 musb_writew(regs, MUSB_CSR0,
627 csr & ~MUSB_CSR0_P_SENTSTALL);
628 retval = IRQ_HANDLED;
629 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
630 csr = musb_readw(regs, MUSB_CSR0);
631 }
632
633 /* request ended "early" */
634 if (csr & MUSB_CSR0_P_SETUPEND) {
635 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDSETUPEND);
636 retval = IRQ_HANDLED;
637 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
638 csr = musb_readw(regs, MUSB_CSR0);
639 /* NOTE: request may need completion */
640 }
641
642 /* docs from Mentor only describe tx, rx, and idle/setup states.
643 * we need to handle nuances around status stages, and also the
644 * case where status and setup stages come back-to-back ...
645 */
646 switch (musb->ep0_state) {
647
648 case MUSB_EP0_STAGE_TX:
649 /* irq on clearing txpktrdy */
650 if ((csr & MUSB_CSR0_TXPKTRDY) == 0) {
651 ep0_txstate(musb);
652 retval = IRQ_HANDLED;
653 }
654 break;
655
656 case MUSB_EP0_STAGE_RX:
657 /* irq on set rxpktrdy */
658 if (csr & MUSB_CSR0_RXPKTRDY) {
659 ep0_rxstate(musb);
660 retval = IRQ_HANDLED;
661 }
662 break;
663
664 case MUSB_EP0_STAGE_STATUSIN:
665 /* end of sequence #2 (OUT/RX state) or #3 (no data) */
666
667 /* update address (if needed) only @ the end of the
668 * status phase per usb spec, which also guarantees
669 * we get 10 msec to receive this irq... until this
670 * is done we won't see the next packet.
671 */
672 if (musb->set_address) {
673 musb->set_address = false;
674 musb_writeb(mbase, MUSB_FADDR, musb->address);
675 }
676
677 /* enter test mode if needed (exit by reset) */
678 else if (musb->test_mode) {
679 DBG(1, "entering TESTMODE\n");
680
681 if (MUSB_TEST_PACKET == musb->test_mode_nr)
682 musb_load_testpacket(musb);
683
684 musb_writeb(mbase, MUSB_TESTMODE,
685 musb->test_mode_nr);
686 }
687 /* FALLTHROUGH */
688
689 case MUSB_EP0_STAGE_STATUSOUT:
690 /* end of sequence #1: write to host (TX state) */
691 {
692 struct usb_request *req;
693
694 req = next_ep0_request(musb);
695 if (req)
696 musb_g_ep0_giveback(musb, req);
697 }
698 retval = IRQ_HANDLED;
699 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
700 /* FALLTHROUGH */
701
702 case MUSB_EP0_STAGE_SETUP:
703 if (csr & MUSB_CSR0_RXPKTRDY) {
704 struct usb_ctrlrequest setup;
705 int handled = 0;
706
707 if (len != 8) {
708 ERR("SETUP packet len %d != 8 ?\n", len);
709 break;
710 }
711 musb_read_setup(musb, &setup);
712 retval = IRQ_HANDLED;
713
714 /* sometimes the RESET won't be reported */
715 if (unlikely(musb->g.speed == USB_SPEED_UNKNOWN)) {
716 u8 power;
717
718 printk(KERN_NOTICE "%s: peripheral reset "
719 "irq lost!\n",
720 musb_driver_name);
721 power = musb_readb(mbase, MUSB_POWER);
722 musb->g.speed = (power & MUSB_POWER_HSMODE)
723 ? USB_SPEED_HIGH : USB_SPEED_FULL;
724
725 }
726
727 switch (musb->ep0_state) {
728
729 /* sequence #3 (no data stage), includes requests
730 * we can't forward (notably SET_ADDRESS and the
731 * device/endpoint feature set/clear operations)
732 * plus SET_CONFIGURATION and others we must
733 */
734 case MUSB_EP0_STAGE_ACKWAIT:
735 handled = service_zero_data_request(
736 musb, &setup);
737
738 /* status stage might be immediate */
739 if (handled > 0) {
740 musb->ackpend |= MUSB_CSR0_P_DATAEND;
741 musb->ep0_state =
742 MUSB_EP0_STAGE_STATUSIN;
743 }
744 break;
745
746 /* sequence #1 (IN to host), includes GET_STATUS
747 * requests that we can't forward, GET_DESCRIPTOR
748 * and others that we must
749 */
750 case MUSB_EP0_STAGE_TX:
751 handled = service_in_request(musb, &setup);
752 if (handled > 0) {
753 musb->ackpend = MUSB_CSR0_TXPKTRDY
754 | MUSB_CSR0_P_DATAEND;
755 musb->ep0_state =
756 MUSB_EP0_STAGE_STATUSOUT;
757 }
758 break;
759
760 /* sequence #2 (OUT from host), always forward */
761 default: /* MUSB_EP0_STAGE_RX */
762 break;
763 }
764
765 DBG(3, "handled %d, csr %04x, ep0stage %s\n",
766 handled, csr,
767 decode_ep0stage(musb->ep0_state));
768
769 /* unless we need to delegate this to the gadget
770 * driver, we know how to wrap this up: csr0 has
771 * not yet been written.
772 */
773 if (handled < 0)
774 goto stall;
775 else if (handled > 0)
776 goto finish;
777
778 handled = forward_to_driver(musb, &setup);
779 if (handled < 0) {
780 musb_ep_select(mbase, 0);
781stall:
782 DBG(3, "stall (%d)\n", handled);
783 musb->ackpend |= MUSB_CSR0_P_SENDSTALL;
784 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
785finish:
786 musb_writew(regs, MUSB_CSR0,
787 musb->ackpend);
788 musb->ackpend = 0;
789 }
790 }
791 break;
792
793 case MUSB_EP0_STAGE_ACKWAIT:
794 /* This should not happen. But happens with tusb6010 with
795 * g_file_storage and high speed. Do nothing.
796 */
797 retval = IRQ_HANDLED;
798 break;
799
800 default:
801 /* "can't happen" */
802 WARN_ON(1);
803 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SENDSTALL);
804 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
805 break;
806 }
807
808 return retval;
809}
810
811
812static int
813musb_g_ep0_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc)
814{
815 /* always enabled */
816 return -EINVAL;
817}
818
819static int musb_g_ep0_disable(struct usb_ep *e)
820{
821 /* always enabled */
822 return -EINVAL;
823}
824
825static int
826musb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags)
827{
828 struct musb_ep *ep;
829 struct musb_request *req;
830 struct musb *musb;
831 int status;
832 unsigned long lockflags;
833 void __iomem *regs;
834
835 if (!e || !r)
836 return -EINVAL;
837
838 ep = to_musb_ep(e);
839 musb = ep->musb;
840 regs = musb->control_ep->regs;
841
842 req = to_musb_request(r);
843 req->musb = musb;
844 req->request.actual = 0;
845 req->request.status = -EINPROGRESS;
846 req->tx = ep->is_in;
847
848 spin_lock_irqsave(&musb->lock, lockflags);
849
850 if (!list_empty(&ep->req_list)) {
851 status = -EBUSY;
852 goto cleanup;
853 }
854
855 switch (musb->ep0_state) {
856 case MUSB_EP0_STAGE_RX: /* control-OUT data */
857 case MUSB_EP0_STAGE_TX: /* control-IN data */
858 case MUSB_EP0_STAGE_ACKWAIT: /* zero-length data */
859 status = 0;
860 break;
861 default:
862 DBG(1, "ep0 request queued in state %d\n",
863 musb->ep0_state);
864 status = -EINVAL;
865 goto cleanup;
866 }
867
868 /* add request to the list */
869 list_add_tail(&(req->request.list), &(ep->req_list));
870
871 DBG(3, "queue to %s (%s), length=%d\n",
872 ep->name, ep->is_in ? "IN/TX" : "OUT/RX",
873 req->request.length);
874
875 musb_ep_select(musb->mregs, 0);
876
877 /* sequence #1, IN ... start writing the data */
878 if (musb->ep0_state == MUSB_EP0_STAGE_TX)
879 ep0_txstate(musb);
880
881 /* sequence #3, no-data ... issue IN status */
882 else if (musb->ep0_state == MUSB_EP0_STAGE_ACKWAIT) {
883 if (req->request.length)
884 status = -EINVAL;
885 else {
886 musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
887 musb_writew(regs, MUSB_CSR0,
888 musb->ackpend | MUSB_CSR0_P_DATAEND);
889 musb->ackpend = 0;
890 musb_g_ep0_giveback(ep->musb, r);
891 }
892
893 /* else for sequence #2 (OUT), caller provides a buffer
894 * before the next packet arrives. deferred responses
895 * (after SETUP is acked) are racey.
896 */
897 } else if (musb->ackpend) {
898 musb_writew(regs, MUSB_CSR0, musb->ackpend);
899 musb->ackpend = 0;
900 }
901
902cleanup:
903 spin_unlock_irqrestore(&musb->lock, lockflags);
904 return status;
905}
906
907static int musb_g_ep0_dequeue(struct usb_ep *ep, struct usb_request *req)
908{
909 /* we just won't support this */
910 return -EINVAL;
911}
912
913static int musb_g_ep0_halt(struct usb_ep *e, int value)
914{
915 struct musb_ep *ep;
916 struct musb *musb;
917 void __iomem *base, *regs;
918 unsigned long flags;
919 int status;
920 u16 csr;
921
922 if (!e || !value)
923 return -EINVAL;
924
925 ep = to_musb_ep(e);
926 musb = ep->musb;
927 base = musb->mregs;
928 regs = musb->control_ep->regs;
929 status = 0;
930
931 spin_lock_irqsave(&musb->lock, flags);
932
933 if (!list_empty(&ep->req_list)) {
934 status = -EBUSY;
935 goto cleanup;
936 }
937
938 musb_ep_select(base, 0);
939 csr = musb->ackpend;
940
941 switch (musb->ep0_state) {
942
943 /* Stalls are usually issued after parsing SETUP packet, either
944 * directly in irq context from setup() or else later.
945 */
946 case MUSB_EP0_STAGE_TX: /* control-IN data */
947 case MUSB_EP0_STAGE_ACKWAIT: /* STALL for zero-length data */
948 case MUSB_EP0_STAGE_RX: /* control-OUT data */
949 csr = musb_readw(regs, MUSB_CSR0);
950 /* FALLTHROUGH */
951
952 /* It's also OK to issue stalls during callbacks when a non-empty
953 * DATA stage buffer has been read (or even written).
954 */
955 case MUSB_EP0_STAGE_STATUSIN: /* control-OUT status */
956 case MUSB_EP0_STAGE_STATUSOUT: /* control-IN status */
957
958 csr |= MUSB_CSR0_P_SENDSTALL;
959 musb_writew(regs, MUSB_CSR0, csr);
960 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
961 musb->ackpend = 0;
962 break;
963 default:
964 DBG(1, "ep0 can't halt in state %d\n", musb->ep0_state);
965 status = -EINVAL;
966 }
967
968cleanup:
969 spin_unlock_irqrestore(&musb->lock, flags);
970 return status;
971}
972
973const struct usb_ep_ops musb_g_ep0_ops = {
974 .enable = musb_g_ep0_enable,
975 .disable = musb_g_ep0_disable,
976 .alloc_request = musb_alloc_request,
977 .free_request = musb_free_request,
978 .queue = musb_g_ep0_queue,
979 .dequeue = musb_g_ep0_dequeue,
980 .set_halt = musb_g_ep0_halt,
981};
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
new file mode 100644
index 000000000000..8b4be012669a
--- /dev/null
+++ b/drivers/usb/musb/musb_host.c
@@ -0,0 +1,2170 @@
1/*
2 * MUSB OTG driver host support
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/delay.h>
38#include <linux/sched.h>
39#include <linux/slab.h>
40#include <linux/errno.h>
41#include <linux/init.h>
42#include <linux/list.h>
43
44#include "musb_core.h"
45#include "musb_host.h"
46
47
48/* MUSB HOST status 22-mar-2006
49 *
50 * - There's still lots of partial code duplication for fault paths, so
51 * they aren't handled as consistently as they need to be.
52 *
53 * - PIO mostly behaved when last tested.
54 * + including ep0, with all usbtest cases 9, 10
55 * + usbtest 14 (ep0out) doesn't seem to run at all
56 * + double buffered OUT/TX endpoints saw stalls(!) with certain usbtest
57 * configurations, but otherwise double buffering passes basic tests.
58 * + for 2.6.N, for N > ~10, needs API changes for hcd framework.
59 *
60 * - DMA (CPPI) ... partially behaves, not currently recommended
61 * + about 1/15 the speed of typical EHCI implementations (PCI)
62 * + RX, all too often reqpkt seems to misbehave after tx
63 * + TX, no known issues (other than evident silicon issue)
64 *
65 * - DMA (Mentor/OMAP) ...has at least toggle update problems
66 *
67 * - Still no traffic scheduling code to make NAKing for bulk or control
68 * transfers unable to starve other requests; or to make efficient use
69 * of hardware with periodic transfers. (Note that network drivers
70 * commonly post bulk reads that stay pending for a long time; these
71 * would make very visible trouble.)
72 *
73 * - Not tested with HNP, but some SRP paths seem to behave.
74 *
75 * NOTE 24-August-2006:
76 *
77 * - Bulk traffic finally uses both sides of hardware ep1, freeing up an
78 * extra endpoint for periodic use enabling hub + keybd + mouse. That
79 * mostly works, except that with "usbnet" it's easy to trigger cases
80 * with "ping" where RX loses. (a) ping to davinci, even "ping -f",
81 * fine; but (b) ping _from_ davinci, even "ping -c 1", ICMP RX loses
82 * although ARP RX wins. (That test was done with a full speed link.)
83 */
84
85
86/*
87 * NOTE on endpoint usage:
88 *
89 * CONTROL transfers all go through ep0. BULK ones go through dedicated IN
90 * and OUT endpoints ... hardware is dedicated for those "async" queue(s).
91 *
92 * (Yes, bulk _could_ use more of the endpoints than that, and would even
93 * benefit from it ... one remote device may easily be NAKing while others
94 * need to perform transfers in that same direction. The same thing could
95 * be done in software though, assuming dma cooperates.)
96 *
97 * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints.
98 * So far that scheduling is both dumb and optimistic: the endpoint will be
99 * "claimed" until its software queue is no longer refilled. No multiplexing
100 * of transfers between endpoints, or anything clever.
101 */
102
103
104static void musb_ep_program(struct musb *musb, u8 epnum,
105 struct urb *urb, unsigned int nOut,
106 u8 *buf, u32 len);
107
108/*
109 * Clear TX fifo. Needed to avoid BABBLE errors.
110 */
111static inline void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
112{
113 void __iomem *epio = ep->regs;
114 u16 csr;
115 int retries = 1000;
116
117 csr = musb_readw(epio, MUSB_TXCSR);
118 while (csr & MUSB_TXCSR_FIFONOTEMPTY) {
119 DBG(5, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
120 csr |= MUSB_TXCSR_FLUSHFIFO;
121 musb_writew(epio, MUSB_TXCSR, csr);
122 csr = musb_readw(epio, MUSB_TXCSR);
123 if (retries-- < 1) {
124 ERR("Could not flush host TX fifo: csr: %04x\n", csr);
125 return;
126 }
127 mdelay(1);
128 }
129}
130
131/*
132 * Start transmit. Caller is responsible for locking shared resources.
133 * musb must be locked.
134 */
135static inline void musb_h_tx_start(struct musb_hw_ep *ep)
136{
137 u16 txcsr;
138
139 /* NOTE: no locks here; caller should lock and select EP */
140 if (ep->epnum) {
141 txcsr = musb_readw(ep->regs, MUSB_TXCSR);
142 txcsr |= MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_H_WZC_BITS;
143 musb_writew(ep->regs, MUSB_TXCSR, txcsr);
144 } else {
145 txcsr = MUSB_CSR0_H_SETUPPKT | MUSB_CSR0_TXPKTRDY;
146 musb_writew(ep->regs, MUSB_CSR0, txcsr);
147 }
148
149}
150
151static inline void cppi_host_txdma_start(struct musb_hw_ep *ep)
152{
153 u16 txcsr;
154
155 /* NOTE: no locks here; caller should lock and select EP */
156 txcsr = musb_readw(ep->regs, MUSB_TXCSR);
157 txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS;
158 musb_writew(ep->regs, MUSB_TXCSR, txcsr);
159}
160
161/*
162 * Start the URB at the front of an endpoint's queue
163 * end must be claimed from the caller.
164 *
165 * Context: controller locked, irqs blocked
166 */
167static void
168musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
169{
170 u16 frame;
171 u32 len;
172 void *buf;
173 void __iomem *mbase = musb->mregs;
174 struct urb *urb = next_urb(qh);
175 struct musb_hw_ep *hw_ep = qh->hw_ep;
176 unsigned pipe = urb->pipe;
177 u8 address = usb_pipedevice(pipe);
178 int epnum = hw_ep->epnum;
179
180 /* initialize software qh state */
181 qh->offset = 0;
182 qh->segsize = 0;
183
184 /* gather right source of data */
185 switch (qh->type) {
186 case USB_ENDPOINT_XFER_CONTROL:
187 /* control transfers always start with SETUP */
188 is_in = 0;
189 hw_ep->out_qh = qh;
190 musb->ep0_stage = MUSB_EP0_START;
191 buf = urb->setup_packet;
192 len = 8;
193 break;
194 case USB_ENDPOINT_XFER_ISOC:
195 qh->iso_idx = 0;
196 qh->frame = 0;
197 buf = urb->transfer_buffer + urb->iso_frame_desc[0].offset;
198 len = urb->iso_frame_desc[0].length;
199 break;
200 default: /* bulk, interrupt */
201 buf = urb->transfer_buffer;
202 len = urb->transfer_buffer_length;
203 }
204
205 DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
206 qh, urb, address, qh->epnum,
207 is_in ? "in" : "out",
208 ({char *s; switch (qh->type) {
209 case USB_ENDPOINT_XFER_CONTROL: s = ""; break;
210 case USB_ENDPOINT_XFER_BULK: s = "-bulk"; break;
211 case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break;
212 default: s = "-intr"; break;
213 }; s; }),
214 epnum, buf, len);
215
216 /* Configure endpoint */
217 if (is_in || hw_ep->is_shared_fifo)
218 hw_ep->in_qh = qh;
219 else
220 hw_ep->out_qh = qh;
221 musb_ep_program(musb, epnum, urb, !is_in, buf, len);
222
223 /* transmit may have more work: start it when it is time */
224 if (is_in)
225 return;
226
227 /* determine if the time is right for a periodic transfer */
228 switch (qh->type) {
229 case USB_ENDPOINT_XFER_ISOC:
230 case USB_ENDPOINT_XFER_INT:
231 DBG(3, "check whether there's still time for periodic Tx\n");
232 qh->iso_idx = 0;
233 frame = musb_readw(mbase, MUSB_FRAME);
234 /* FIXME this doesn't implement that scheduling policy ...
235 * or handle framecounter wrapping
236 */
237 if ((urb->transfer_flags & URB_ISO_ASAP)
238 || (frame >= urb->start_frame)) {
239 /* REVISIT the SOF irq handler shouldn't duplicate
240 * this code; and we don't init urb->start_frame...
241 */
242 qh->frame = 0;
243 goto start;
244 } else {
245 qh->frame = urb->start_frame;
246 /* enable SOF interrupt so we can count down */
247 DBG(1, "SOF for %d\n", epnum);
248#if 1 /* ifndef CONFIG_ARCH_DAVINCI */
249 musb_writeb(mbase, MUSB_INTRUSBE, 0xff);
250#endif
251 }
252 break;
253 default:
254start:
255 DBG(4, "Start TX%d %s\n", epnum,
256 hw_ep->tx_channel ? "dma" : "pio");
257
258 if (!hw_ep->tx_channel)
259 musb_h_tx_start(hw_ep);
260 else if (is_cppi_enabled() || tusb_dma_omap())
261 cppi_host_txdma_start(hw_ep);
262 }
263}
264
265/* caller owns controller lock, irqs are blocked */
266static void
267__musb_giveback(struct musb *musb, struct urb *urb, int status)
268__releases(musb->lock)
269__acquires(musb->lock)
270{
271 DBG(({ int level; switch (urb->status) {
272 case 0:
273 level = 4;
274 break;
275 /* common/boring faults */
276 case -EREMOTEIO:
277 case -ESHUTDOWN:
278 case -ECONNRESET:
279 case -EPIPE:
280 level = 3;
281 break;
282 default:
283 level = 2;
284 break;
285 }; level; }),
286 "complete %p (%d), dev%d ep%d%s, %d/%d\n",
287 urb, urb->status,
288 usb_pipedevice(urb->pipe),
289 usb_pipeendpoint(urb->pipe),
290 usb_pipein(urb->pipe) ? "in" : "out",
291 urb->actual_length, urb->transfer_buffer_length
292 );
293
294 spin_unlock(&musb->lock);
295 usb_hcd_giveback_urb(musb_to_hcd(musb), urb, status);
296 spin_lock(&musb->lock);
297}
298
299/* for bulk/interrupt endpoints only */
300static inline void
301musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb)
302{
303 struct usb_device *udev = urb->dev;
304 u16 csr;
305 void __iomem *epio = ep->regs;
306 struct musb_qh *qh;
307
308 /* FIXME: the current Mentor DMA code seems to have
309 * problems getting toggle correct.
310 */
311
312 if (is_in || ep->is_shared_fifo)
313 qh = ep->in_qh;
314 else
315 qh = ep->out_qh;
316
317 if (!is_in) {
318 csr = musb_readw(epio, MUSB_TXCSR);
319 usb_settoggle(udev, qh->epnum, 1,
320 (csr & MUSB_TXCSR_H_DATATOGGLE)
321 ? 1 : 0);
322 } else {
323 csr = musb_readw(epio, MUSB_RXCSR);
324 usb_settoggle(udev, qh->epnum, 0,
325 (csr & MUSB_RXCSR_H_DATATOGGLE)
326 ? 1 : 0);
327 }
328}
329
330/* caller owns controller lock, irqs are blocked */
331static struct musb_qh *
332musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
333{
334 int is_in;
335 struct musb_hw_ep *ep = qh->hw_ep;
336 struct musb *musb = ep->musb;
337 int ready = qh->is_ready;
338
339 if (ep->is_shared_fifo)
340 is_in = 1;
341 else
342 is_in = usb_pipein(urb->pipe);
343
344 /* save toggle eagerly, for paranoia */
345 switch (qh->type) {
346 case USB_ENDPOINT_XFER_BULK:
347 case USB_ENDPOINT_XFER_INT:
348 musb_save_toggle(ep, is_in, urb);
349 break;
350 case USB_ENDPOINT_XFER_ISOC:
351 if (status == 0 && urb->error_count)
352 status = -EXDEV;
353 break;
354 }
355
356 usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb);
357
358 qh->is_ready = 0;
359 __musb_giveback(musb, urb, status);
360 qh->is_ready = ready;
361
362 /* reclaim resources (and bandwidth) ASAP; deschedule it, and
363 * invalidate qh as soon as list_empty(&hep->urb_list)
364 */
365 if (list_empty(&qh->hep->urb_list)) {
366 struct list_head *head;
367
368 if (is_in)
369 ep->rx_reinit = 1;
370 else
371 ep->tx_reinit = 1;
372
373 /* clobber old pointers to this qh */
374 if (is_in || ep->is_shared_fifo)
375 ep->in_qh = NULL;
376 else
377 ep->out_qh = NULL;
378 qh->hep->hcpriv = NULL;
379
380 switch (qh->type) {
381
382 case USB_ENDPOINT_XFER_ISOC:
383 case USB_ENDPOINT_XFER_INT:
384 /* this is where periodic bandwidth should be
385 * de-allocated if it's tracked and allocated;
386 * and where we'd update the schedule tree...
387 */
388 musb->periodic[ep->epnum] = NULL;
389 kfree(qh);
390 qh = NULL;
391 break;
392
393 case USB_ENDPOINT_XFER_CONTROL:
394 case USB_ENDPOINT_XFER_BULK:
395 /* fifo policy for these lists, except that NAKing
396 * should rotate a qh to the end (for fairness).
397 */
398 head = qh->ring.prev;
399 list_del(&qh->ring);
400 kfree(qh);
401 qh = first_qh(head);
402 break;
403 }
404 }
405 return qh;
406}
407
408/*
409 * Advance this hardware endpoint's queue, completing the specified urb and
410 * advancing to either the next urb queued to that qh, or else invalidating
411 * that qh and advancing to the next qh scheduled after the current one.
412 *
413 * Context: caller owns controller lock, irqs are blocked
414 */
415static void
416musb_advance_schedule(struct musb *musb, struct urb *urb,
417 struct musb_hw_ep *hw_ep, int is_in)
418{
419 struct musb_qh *qh;
420
421 if (is_in || hw_ep->is_shared_fifo)
422 qh = hw_ep->in_qh;
423 else
424 qh = hw_ep->out_qh;
425
426 if (urb->status == -EINPROGRESS)
427 qh = musb_giveback(qh, urb, 0);
428 else
429 qh = musb_giveback(qh, urb, urb->status);
430
431 if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) {
432 DBG(4, "... next ep%d %cX urb %p\n",
433 hw_ep->epnum, is_in ? 'R' : 'T',
434 next_urb(qh));
435 musb_start_urb(musb, is_in, qh);
436 }
437}
438
439static inline u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
440{
441 /* we don't want fifo to fill itself again;
442 * ignore dma (various models),
443 * leave toggle alone (may not have been saved yet)
444 */
445 csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_RXPKTRDY;
446 csr &= ~(MUSB_RXCSR_H_REQPKT
447 | MUSB_RXCSR_H_AUTOREQ
448 | MUSB_RXCSR_AUTOCLEAR);
449
450 /* write 2x to allow double buffering */
451 musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
452 musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
453
454 /* flush writebuffer */
455 return musb_readw(hw_ep->regs, MUSB_RXCSR);
456}
457
458/*
459 * PIO RX for a packet (or part of it).
460 */
461static bool
462musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err)
463{
464 u16 rx_count;
465 u8 *buf;
466 u16 csr;
467 bool done = false;
468 u32 length;
469 int do_flush = 0;
470 struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
471 void __iomem *epio = hw_ep->regs;
472 struct musb_qh *qh = hw_ep->in_qh;
473 int pipe = urb->pipe;
474 void *buffer = urb->transfer_buffer;
475
476 /* musb_ep_select(mbase, epnum); */
477 rx_count = musb_readw(epio, MUSB_RXCOUNT);
478 DBG(3, "RX%d count %d, buffer %p len %d/%d\n", epnum, rx_count,
479 urb->transfer_buffer, qh->offset,
480 urb->transfer_buffer_length);
481
482 /* unload FIFO */
483 if (usb_pipeisoc(pipe)) {
484 int status = 0;
485 struct usb_iso_packet_descriptor *d;
486
487 if (iso_err) {
488 status = -EILSEQ;
489 urb->error_count++;
490 }
491
492 d = urb->iso_frame_desc + qh->iso_idx;
493 buf = buffer + d->offset;
494 length = d->length;
495 if (rx_count > length) {
496 if (status == 0) {
497 status = -EOVERFLOW;
498 urb->error_count++;
499 }
500 DBG(2, "** OVERFLOW %d into %d\n", rx_count, length);
501 do_flush = 1;
502 } else
503 length = rx_count;
504 urb->actual_length += length;
505 d->actual_length = length;
506
507 d->status = status;
508
509 /* see if we are done */
510 done = (++qh->iso_idx >= urb->number_of_packets);
511 } else {
512 /* non-isoch */
513 buf = buffer + qh->offset;
514 length = urb->transfer_buffer_length - qh->offset;
515 if (rx_count > length) {
516 if (urb->status == -EINPROGRESS)
517 urb->status = -EOVERFLOW;
518 DBG(2, "** OVERFLOW %d into %d\n", rx_count, length);
519 do_flush = 1;
520 } else
521 length = rx_count;
522 urb->actual_length += length;
523 qh->offset += length;
524
525 /* see if we are done */
526 done = (urb->actual_length == urb->transfer_buffer_length)
527 || (rx_count < qh->maxpacket)
528 || (urb->status != -EINPROGRESS);
529 if (done
530 && (urb->status == -EINPROGRESS)
531 && (urb->transfer_flags & URB_SHORT_NOT_OK)
532 && (urb->actual_length
533 < urb->transfer_buffer_length))
534 urb->status = -EREMOTEIO;
535 }
536
537 musb_read_fifo(hw_ep, length, buf);
538
539 csr = musb_readw(epio, MUSB_RXCSR);
540 csr |= MUSB_RXCSR_H_WZC_BITS;
541 if (unlikely(do_flush))
542 musb_h_flush_rxfifo(hw_ep, csr);
543 else {
544 /* REVISIT this assumes AUTOCLEAR is never set */
545 csr &= ~(MUSB_RXCSR_RXPKTRDY | MUSB_RXCSR_H_REQPKT);
546 if (!done)
547 csr |= MUSB_RXCSR_H_REQPKT;
548 musb_writew(epio, MUSB_RXCSR, csr);
549 }
550
551 return done;
552}
553
554/* we don't always need to reinit a given side of an endpoint...
555 * when we do, use tx/rx reinit routine and then construct a new CSR
556 * to address data toggle, NYET, and DMA or PIO.
557 *
558 * it's possible that driver bugs (especially for DMA) or aborting a
559 * transfer might have left the endpoint busier than it should be.
560 * the busy/not-empty tests are basically paranoia.
561 */
562static void
563musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
564{
565 u16 csr;
566
567 /* NOTE: we know the "rx" fifo reinit never triggers for ep0.
568 * That always uses tx_reinit since ep0 repurposes TX register
569 * offsets; the initial SETUP packet is also a kind of OUT.
570 */
571
572 /* if programmed for Tx, put it in RX mode */
573 if (ep->is_shared_fifo) {
574 csr = musb_readw(ep->regs, MUSB_TXCSR);
575 if (csr & MUSB_TXCSR_MODE) {
576 musb_h_tx_flush_fifo(ep);
577 musb_writew(ep->regs, MUSB_TXCSR,
578 MUSB_TXCSR_FRCDATATOG);
579 }
580 /* clear mode (and everything else) to enable Rx */
581 musb_writew(ep->regs, MUSB_TXCSR, 0);
582
583 /* scrub all previous state, clearing toggle */
584 } else {
585 csr = musb_readw(ep->regs, MUSB_RXCSR);
586 if (csr & MUSB_RXCSR_RXPKTRDY)
587 WARNING("rx%d, packet/%d ready?\n", ep->epnum,
588 musb_readw(ep->regs, MUSB_RXCOUNT));
589
590 musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
591 }
592
593 /* target addr and (for multipoint) hub addr/port */
594 if (musb->is_multipoint) {
595 musb_writeb(ep->target_regs, MUSB_RXFUNCADDR,
596 qh->addr_reg);
597 musb_writeb(ep->target_regs, MUSB_RXHUBADDR,
598 qh->h_addr_reg);
599 musb_writeb(ep->target_regs, MUSB_RXHUBPORT,
600 qh->h_port_reg);
601 } else
602 musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
603
604 /* protocol/endpoint, interval/NAKlimit, i/o size */
605 musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg);
606 musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg);
607 /* NOTE: bulk combining rewrites high bits of maxpacket */
608 musb_writew(ep->regs, MUSB_RXMAXP, qh->maxpacket);
609
610 ep->rx_reinit = 0;
611}
612
613
614/*
615 * Program an HDRC endpoint as per the given URB
616 * Context: irqs blocked, controller lock held
617 */
618static void musb_ep_program(struct musb *musb, u8 epnum,
619 struct urb *urb, unsigned int is_out,
620 u8 *buf, u32 len)
621{
622 struct dma_controller *dma_controller;
623 struct dma_channel *dma_channel;
624 u8 dma_ok;
625 void __iomem *mbase = musb->mregs;
626 struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
627 void __iomem *epio = hw_ep->regs;
628 struct musb_qh *qh;
629 u16 packet_sz;
630
631 if (!is_out || hw_ep->is_shared_fifo)
632 qh = hw_ep->in_qh;
633 else
634 qh = hw_ep->out_qh;
635
636 packet_sz = qh->maxpacket;
637
638 DBG(3, "%s hw%d urb %p spd%d dev%d ep%d%s "
639 "h_addr%02x h_port%02x bytes %d\n",
640 is_out ? "-->" : "<--",
641 epnum, urb, urb->dev->speed,
642 qh->addr_reg, qh->epnum, is_out ? "out" : "in",
643 qh->h_addr_reg, qh->h_port_reg,
644 len);
645
646 musb_ep_select(mbase, epnum);
647
648 /* candidate for DMA? */
649 dma_controller = musb->dma_controller;
650 if (is_dma_capable() && epnum && dma_controller) {
651 dma_channel = is_out ? hw_ep->tx_channel : hw_ep->rx_channel;
652 if (!dma_channel) {
653 dma_channel = dma_controller->channel_alloc(
654 dma_controller, hw_ep, is_out);
655 if (is_out)
656 hw_ep->tx_channel = dma_channel;
657 else
658 hw_ep->rx_channel = dma_channel;
659 }
660 } else
661 dma_channel = NULL;
662
663 /* make sure we clear DMAEnab, autoSet bits from previous run */
664
665 /* OUT/transmit/EP0 or IN/receive? */
666 if (is_out) {
667 u16 csr;
668 u16 int_txe;
669 u16 load_count;
670
671 csr = musb_readw(epio, MUSB_TXCSR);
672
673 /* disable interrupt in case we flush */
674 int_txe = musb_readw(mbase, MUSB_INTRTXE);
675 musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum));
676
677 /* general endpoint setup */
678 if (epnum) {
679 /* ASSERT: TXCSR_DMAENAB was already cleared */
680
681 /* flush all old state, set default */
682 musb_h_tx_flush_fifo(hw_ep);
683 csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT
684 | MUSB_TXCSR_DMAMODE
685 | MUSB_TXCSR_FRCDATATOG
686 | MUSB_TXCSR_H_RXSTALL
687 | MUSB_TXCSR_H_ERROR
688 | MUSB_TXCSR_TXPKTRDY
689 );
690 csr |= MUSB_TXCSR_MODE;
691
692 if (usb_gettoggle(urb->dev,
693 qh->epnum, 1))
694 csr |= MUSB_TXCSR_H_WR_DATATOGGLE
695 | MUSB_TXCSR_H_DATATOGGLE;
696 else
697 csr |= MUSB_TXCSR_CLRDATATOG;
698
699 /* twice in case of double packet buffering */
700 musb_writew(epio, MUSB_TXCSR, csr);
701 /* REVISIT may need to clear FLUSHFIFO ... */
702 musb_writew(epio, MUSB_TXCSR, csr);
703 csr = musb_readw(epio, MUSB_TXCSR);
704 } else {
705 /* endpoint 0: just flush */
706 musb_writew(epio, MUSB_CSR0,
707 csr | MUSB_CSR0_FLUSHFIFO);
708 musb_writew(epio, MUSB_CSR0,
709 csr | MUSB_CSR0_FLUSHFIFO);
710 }
711
712 /* target addr and (for multipoint) hub addr/port */
713 if (musb->is_multipoint) {
714 musb_writeb(mbase,
715 MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR),
716 qh->addr_reg);
717 musb_writeb(mbase,
718 MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR),
719 qh->h_addr_reg);
720 musb_writeb(mbase,
721 MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT),
722 qh->h_port_reg);
723/* FIXME if !epnum, do the same for RX ... */
724 } else
725 musb_writeb(mbase, MUSB_FADDR, qh->addr_reg);
726
727 /* protocol/endpoint/interval/NAKlimit */
728 if (epnum) {
729 musb_writeb(epio, MUSB_TXTYPE, qh->type_reg);
730 if (can_bulk_split(musb, qh->type))
731 musb_writew(epio, MUSB_TXMAXP,
732 packet_sz
733 | ((hw_ep->max_packet_sz_tx /
734 packet_sz) - 1) << 11);
735 else
736 musb_writew(epio, MUSB_TXMAXP,
737 packet_sz);
738 musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg);
739 } else {
740 musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg);
741 if (musb->is_multipoint)
742 musb_writeb(epio, MUSB_TYPE0,
743 qh->type_reg);
744 }
745
746 if (can_bulk_split(musb, qh->type))
747 load_count = min((u32) hw_ep->max_packet_sz_tx,
748 len);
749 else
750 load_count = min((u32) packet_sz, len);
751
752#ifdef CONFIG_USB_INVENTRA_DMA
753 if (dma_channel) {
754
755 /* clear previous state */
756 csr = musb_readw(epio, MUSB_TXCSR);
757 csr &= ~(MUSB_TXCSR_AUTOSET
758 | MUSB_TXCSR_DMAMODE
759 | MUSB_TXCSR_DMAENAB);
760 csr |= MUSB_TXCSR_MODE;
761 musb_writew(epio, MUSB_TXCSR,
762 csr | MUSB_TXCSR_MODE);
763
764 qh->segsize = min(len, dma_channel->max_len);
765
766 if (qh->segsize <= packet_sz)
767 dma_channel->desired_mode = 0;
768 else
769 dma_channel->desired_mode = 1;
770
771
772 if (dma_channel->desired_mode == 0) {
773 csr &= ~(MUSB_TXCSR_AUTOSET
774 | MUSB_TXCSR_DMAMODE);
775 csr |= (MUSB_TXCSR_DMAENAB);
776 /* against programming guide */
777 } else
778 csr |= (MUSB_TXCSR_AUTOSET
779 | MUSB_TXCSR_DMAENAB
780 | MUSB_TXCSR_DMAMODE);
781
782 musb_writew(epio, MUSB_TXCSR, csr);
783
784 dma_ok = dma_controller->channel_program(
785 dma_channel, packet_sz,
786 dma_channel->desired_mode,
787 urb->transfer_dma,
788 qh->segsize);
789 if (dma_ok) {
790 load_count = 0;
791 } else {
792 dma_controller->channel_release(dma_channel);
793 if (is_out)
794 hw_ep->tx_channel = NULL;
795 else
796 hw_ep->rx_channel = NULL;
797 dma_channel = NULL;
798 }
799 }
800#endif
801
802 /* candidate for DMA */
803 if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
804
805 /* program endpoint CSRs first, then setup DMA.
806 * assume CPPI setup succeeds.
807 * defer enabling dma.
808 */
809 csr = musb_readw(epio, MUSB_TXCSR);
810 csr &= ~(MUSB_TXCSR_AUTOSET
811 | MUSB_TXCSR_DMAMODE
812 | MUSB_TXCSR_DMAENAB);
813 csr |= MUSB_TXCSR_MODE;
814 musb_writew(epio, MUSB_TXCSR,
815 csr | MUSB_TXCSR_MODE);
816
817 dma_channel->actual_len = 0L;
818 qh->segsize = len;
819
820 /* TX uses "rndis" mode automatically, but needs help
821 * to identify the zero-length-final-packet case.
822 */
823 dma_ok = dma_controller->channel_program(
824 dma_channel, packet_sz,
825 (urb->transfer_flags
826 & URB_ZERO_PACKET)
827 == URB_ZERO_PACKET,
828 urb->transfer_dma,
829 qh->segsize);
830 if (dma_ok) {
831 load_count = 0;
832 } else {
833 dma_controller->channel_release(dma_channel);
834 hw_ep->tx_channel = NULL;
835 dma_channel = NULL;
836
837 /* REVISIT there's an error path here that
838 * needs handling: can't do dma, but
839 * there's no pio buffer address...
840 */
841 }
842 }
843
844 if (load_count) {
845 /* ASSERT: TXCSR_DMAENAB was already cleared */
846
847 /* PIO to load FIFO */
848 qh->segsize = load_count;
849 musb_write_fifo(hw_ep, load_count, buf);
850 csr = musb_readw(epio, MUSB_TXCSR);
851 csr &= ~(MUSB_TXCSR_DMAENAB
852 | MUSB_TXCSR_DMAMODE
853 | MUSB_TXCSR_AUTOSET);
854 /* write CSR */
855 csr |= MUSB_TXCSR_MODE;
856
857 if (epnum)
858 musb_writew(epio, MUSB_TXCSR, csr);
859 }
860
861 /* re-enable interrupt */
862 musb_writew(mbase, MUSB_INTRTXE, int_txe);
863
864 /* IN/receive */
865 } else {
866 u16 csr;
867
868 if (hw_ep->rx_reinit) {
869 musb_rx_reinit(musb, qh, hw_ep);
870
871 /* init new state: toggle and NYET, maybe DMA later */
872 if (usb_gettoggle(urb->dev, qh->epnum, 0))
873 csr = MUSB_RXCSR_H_WR_DATATOGGLE
874 | MUSB_RXCSR_H_DATATOGGLE;
875 else
876 csr = 0;
877 if (qh->type == USB_ENDPOINT_XFER_INT)
878 csr |= MUSB_RXCSR_DISNYET;
879
880 } else {
881 csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
882
883 if (csr & (MUSB_RXCSR_RXPKTRDY
884 | MUSB_RXCSR_DMAENAB
885 | MUSB_RXCSR_H_REQPKT))
886 ERR("broken !rx_reinit, ep%d csr %04x\n",
887 hw_ep->epnum, csr);
888
889 /* scrub any stale state, leaving toggle alone */
890 csr &= MUSB_RXCSR_DISNYET;
891 }
892
893 /* kick things off */
894
895 if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
896 /* candidate for DMA */
897 if (dma_channel) {
898 dma_channel->actual_len = 0L;
899 qh->segsize = len;
900
901 /* AUTOREQ is in a DMA register */
902 musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
903 csr = musb_readw(hw_ep->regs,
904 MUSB_RXCSR);
905
906 /* unless caller treats short rx transfers as
907 * errors, we dare not queue multiple transfers.
908 */
909 dma_ok = dma_controller->channel_program(
910 dma_channel, packet_sz,
911 !(urb->transfer_flags
912 & URB_SHORT_NOT_OK),
913 urb->transfer_dma,
914 qh->segsize);
915 if (!dma_ok) {
916 dma_controller->channel_release(
917 dma_channel);
918 hw_ep->rx_channel = NULL;
919 dma_channel = NULL;
920 } else
921 csr |= MUSB_RXCSR_DMAENAB;
922 }
923 }
924
925 csr |= MUSB_RXCSR_H_REQPKT;
926 DBG(7, "RXCSR%d := %04x\n", epnum, csr);
927 musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
928 csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
929 }
930}
931
932
933/*
934 * Service the default endpoint (ep0) as host.
935 * Return true until it's time to start the status stage.
936 */
937static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
938{
939 bool more = false;
940 u8 *fifo_dest = NULL;
941 u16 fifo_count = 0;
942 struct musb_hw_ep *hw_ep = musb->control_ep;
943 struct musb_qh *qh = hw_ep->in_qh;
944 struct usb_ctrlrequest *request;
945
946 switch (musb->ep0_stage) {
947 case MUSB_EP0_IN:
948 fifo_dest = urb->transfer_buffer + urb->actual_length;
949 fifo_count = min(len, ((u16) (urb->transfer_buffer_length
950 - urb->actual_length)));
951 if (fifo_count < len)
952 urb->status = -EOVERFLOW;
953
954 musb_read_fifo(hw_ep, fifo_count, fifo_dest);
955
956 urb->actual_length += fifo_count;
957 if (len < qh->maxpacket) {
958 /* always terminate on short read; it's
959 * rarely reported as an error.
960 */
961 } else if (urb->actual_length <
962 urb->transfer_buffer_length)
963 more = true;
964 break;
965 case MUSB_EP0_START:
966 request = (struct usb_ctrlrequest *) urb->setup_packet;
967
968 if (!request->wLength) {
969 DBG(4, "start no-DATA\n");
970 break;
971 } else if (request->bRequestType & USB_DIR_IN) {
972 DBG(4, "start IN-DATA\n");
973 musb->ep0_stage = MUSB_EP0_IN;
974 more = true;
975 break;
976 } else {
977 DBG(4, "start OUT-DATA\n");
978 musb->ep0_stage = MUSB_EP0_OUT;
979 more = true;
980 }
981 /* FALLTHROUGH */
982 case MUSB_EP0_OUT:
983 fifo_count = min(qh->maxpacket, ((u16)
984 (urb->transfer_buffer_length
985 - urb->actual_length)));
986
987 if (fifo_count) {
988 fifo_dest = (u8 *) (urb->transfer_buffer
989 + urb->actual_length);
990 DBG(3, "Sending %d bytes to %p\n",
991 fifo_count, fifo_dest);
992 musb_write_fifo(hw_ep, fifo_count, fifo_dest);
993
994 urb->actual_length += fifo_count;
995 more = true;
996 }
997 break;
998 default:
999 ERR("bogus ep0 stage %d\n", musb->ep0_stage);
1000 break;
1001 }
1002
1003 return more;
1004}
1005
1006/*
1007 * Handle default endpoint interrupt as host. Only called in IRQ time
1008 * from the LinuxIsr() interrupt service routine.
1009 *
1010 * called with controller irqlocked
1011 */
1012irqreturn_t musb_h_ep0_irq(struct musb *musb)
1013{
1014 struct urb *urb;
1015 u16 csr, len;
1016 int status = 0;
1017 void __iomem *mbase = musb->mregs;
1018 struct musb_hw_ep *hw_ep = musb->control_ep;
1019 void __iomem *epio = hw_ep->regs;
1020 struct musb_qh *qh = hw_ep->in_qh;
1021 bool complete = false;
1022 irqreturn_t retval = IRQ_NONE;
1023
1024 /* ep0 only has one queue, "in" */
1025 urb = next_urb(qh);
1026
1027 musb_ep_select(mbase, 0);
1028 csr = musb_readw(epio, MUSB_CSR0);
1029 len = (csr & MUSB_CSR0_RXPKTRDY)
1030 ? musb_readb(epio, MUSB_COUNT0)
1031 : 0;
1032
1033 DBG(4, "<== csr0 %04x, qh %p, count %d, urb %p, stage %d\n",
1034 csr, qh, len, urb, musb->ep0_stage);
1035
1036 /* if we just did status stage, we are done */
1037 if (MUSB_EP0_STATUS == musb->ep0_stage) {
1038 retval = IRQ_HANDLED;
1039 complete = true;
1040 }
1041
1042 /* prepare status */
1043 if (csr & MUSB_CSR0_H_RXSTALL) {
1044 DBG(6, "STALLING ENDPOINT\n");
1045 status = -EPIPE;
1046
1047 } else if (csr & MUSB_CSR0_H_ERROR) {
1048 DBG(2, "no response, csr0 %04x\n", csr);
1049 status = -EPROTO;
1050
1051 } else if (csr & MUSB_CSR0_H_NAKTIMEOUT) {
1052 DBG(2, "control NAK timeout\n");
1053
1054 /* NOTE: this code path would be a good place to PAUSE a
1055 * control transfer, if another one is queued, so that
1056 * ep0 is more likely to stay busy.
1057 *
1058 * if (qh->ring.next != &musb->control), then
1059 * we have a candidate... NAKing is *NOT* an error
1060 */
1061 musb_writew(epio, MUSB_CSR0, 0);
1062 retval = IRQ_HANDLED;
1063 }
1064
1065 if (status) {
1066 DBG(6, "aborting\n");
1067 retval = IRQ_HANDLED;
1068 if (urb)
1069 urb->status = status;
1070 complete = true;
1071
1072 /* use the proper sequence to abort the transfer */
1073 if (csr & MUSB_CSR0_H_REQPKT) {
1074 csr &= ~MUSB_CSR0_H_REQPKT;
1075 musb_writew(epio, MUSB_CSR0, csr);
1076 csr &= ~MUSB_CSR0_H_NAKTIMEOUT;
1077 musb_writew(epio, MUSB_CSR0, csr);
1078 } else {
1079 csr |= MUSB_CSR0_FLUSHFIFO;
1080 musb_writew(epio, MUSB_CSR0, csr);
1081 musb_writew(epio, MUSB_CSR0, csr);
1082 csr &= ~MUSB_CSR0_H_NAKTIMEOUT;
1083 musb_writew(epio, MUSB_CSR0, csr);
1084 }
1085
1086 musb_writeb(epio, MUSB_NAKLIMIT0, 0);
1087
1088 /* clear it */
1089 musb_writew(epio, MUSB_CSR0, 0);
1090 }
1091
1092 if (unlikely(!urb)) {
1093 /* stop endpoint since we have no place for its data, this
1094 * SHOULD NEVER HAPPEN! */
1095 ERR("no URB for end 0\n");
1096
1097 musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO);
1098 musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO);
1099 musb_writew(epio, MUSB_CSR0, 0);
1100
1101 goto done;
1102 }
1103
1104 if (!complete) {
1105 /* call common logic and prepare response */
1106 if (musb_h_ep0_continue(musb, len, urb)) {
1107 /* more packets required */
1108 csr = (MUSB_EP0_IN == musb->ep0_stage)
1109 ? MUSB_CSR0_H_REQPKT : MUSB_CSR0_TXPKTRDY;
1110 } else {
1111 /* data transfer complete; perform status phase */
1112 if (usb_pipeout(urb->pipe)
1113 || !urb->transfer_buffer_length)
1114 csr = MUSB_CSR0_H_STATUSPKT
1115 | MUSB_CSR0_H_REQPKT;
1116 else
1117 csr = MUSB_CSR0_H_STATUSPKT
1118 | MUSB_CSR0_TXPKTRDY;
1119
1120 /* flag status stage */
1121 musb->ep0_stage = MUSB_EP0_STATUS;
1122
1123 DBG(5, "ep0 STATUS, csr %04x\n", csr);
1124
1125 }
1126 musb_writew(epio, MUSB_CSR0, csr);
1127 retval = IRQ_HANDLED;
1128 } else
1129 musb->ep0_stage = MUSB_EP0_IDLE;
1130
1131 /* call completion handler if done */
1132 if (complete)
1133 musb_advance_schedule(musb, urb, hw_ep, 1);
1134done:
1135 return retval;
1136}
1137
1138
1139#ifdef CONFIG_USB_INVENTRA_DMA
1140
1141/* Host side TX (OUT) using Mentor DMA works as follows:
1142 submit_urb ->
1143 - if queue was empty, Program Endpoint
1144 - ... which starts DMA to fifo in mode 1 or 0
1145
1146 DMA Isr (transfer complete) -> TxAvail()
1147 - Stop DMA (~DmaEnab) (<--- Alert ... currently happens
1148 only in musb_cleanup_urb)
1149 - TxPktRdy has to be set in mode 0 or for
1150 short packets in mode 1.
1151*/
1152
1153#endif
1154
1155/* Service a Tx-Available or dma completion irq for the endpoint */
1156void musb_host_tx(struct musb *musb, u8 epnum)
1157{
1158 int pipe;
1159 bool done = false;
1160 u16 tx_csr;
1161 size_t wLength = 0;
1162 u8 *buf = NULL;
1163 struct urb *urb;
1164 struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
1165 void __iomem *epio = hw_ep->regs;
1166 struct musb_qh *qh = hw_ep->out_qh;
1167 u32 status = 0;
1168 void __iomem *mbase = musb->mregs;
1169 struct dma_channel *dma;
1170
1171 urb = next_urb(qh);
1172
1173 musb_ep_select(mbase, epnum);
1174 tx_csr = musb_readw(epio, MUSB_TXCSR);
1175
1176 /* with CPPI, DMA sometimes triggers "extra" irqs */
1177 if (!urb) {
1178 DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr);
1179 goto finish;
1180 }
1181
1182 pipe = urb->pipe;
1183 dma = is_dma_capable() ? hw_ep->tx_channel : NULL;
1184 DBG(4, "OUT/TX%d end, csr %04x%s\n", epnum, tx_csr,
1185 dma ? ", dma" : "");
1186
1187 /* check for errors */
1188 if (tx_csr & MUSB_TXCSR_H_RXSTALL) {
1189 /* dma was disabled, fifo flushed */
1190 DBG(3, "TX end %d stall\n", epnum);
1191
1192 /* stall; record URB status */
1193 status = -EPIPE;
1194
1195 } else if (tx_csr & MUSB_TXCSR_H_ERROR) {
1196 /* (NON-ISO) dma was disabled, fifo flushed */
1197 DBG(3, "TX 3strikes on ep=%d\n", epnum);
1198
1199 status = -ETIMEDOUT;
1200
1201 } else if (tx_csr & MUSB_TXCSR_H_NAKTIMEOUT) {
1202 DBG(6, "TX end=%d device not responding\n", epnum);
1203
1204 /* NOTE: this code path would be a good place to PAUSE a
1205 * transfer, if there's some other (nonperiodic) tx urb
1206 * that could use this fifo. (dma complicates it...)
1207 *
1208 * if (bulk && qh->ring.next != &musb->out_bulk), then
1209 * we have a candidate... NAKing is *NOT* an error
1210 */
1211 musb_ep_select(mbase, epnum);
1212 musb_writew(epio, MUSB_TXCSR,
1213 MUSB_TXCSR_H_WZC_BITS
1214 | MUSB_TXCSR_TXPKTRDY);
1215 goto finish;
1216 }
1217
1218 if (status) {
1219 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
1220 dma->status = MUSB_DMA_STATUS_CORE_ABORT;
1221 (void) musb->dma_controller->channel_abort(dma);
1222 }
1223
1224 /* do the proper sequence to abort the transfer in the
1225 * usb core; the dma engine should already be stopped.
1226 */
1227 musb_h_tx_flush_fifo(hw_ep);
1228 tx_csr &= ~(MUSB_TXCSR_AUTOSET
1229 | MUSB_TXCSR_DMAENAB
1230 | MUSB_TXCSR_H_ERROR
1231 | MUSB_TXCSR_H_RXSTALL
1232 | MUSB_TXCSR_H_NAKTIMEOUT
1233 );
1234
1235 musb_ep_select(mbase, epnum);
1236 musb_writew(epio, MUSB_TXCSR, tx_csr);
1237 /* REVISIT may need to clear FLUSHFIFO ... */
1238 musb_writew(epio, MUSB_TXCSR, tx_csr);
1239 musb_writeb(epio, MUSB_TXINTERVAL, 0);
1240
1241 done = true;
1242 }
1243
1244 /* second cppi case */
1245 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
1246 DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr);
1247 goto finish;
1248
1249 }
1250
1251 /* REVISIT this looks wrong... */
1252 if (!status || dma || usb_pipeisoc(pipe)) {
1253 if (dma)
1254 wLength = dma->actual_len;
1255 else
1256 wLength = qh->segsize;
1257 qh->offset += wLength;
1258
1259 if (usb_pipeisoc(pipe)) {
1260 struct usb_iso_packet_descriptor *d;
1261
1262 d = urb->iso_frame_desc + qh->iso_idx;
1263 d->actual_length = qh->segsize;
1264 if (++qh->iso_idx >= urb->number_of_packets) {
1265 done = true;
1266 } else {
1267 d++;
1268 buf = urb->transfer_buffer + d->offset;
1269 wLength = d->length;
1270 }
1271 } else if (dma) {
1272 done = true;
1273 } else {
1274 /* see if we need to send more data, or ZLP */
1275 if (qh->segsize < qh->maxpacket)
1276 done = true;
1277 else if (qh->offset == urb->transfer_buffer_length
1278 && !(urb->transfer_flags
1279 & URB_ZERO_PACKET))
1280 done = true;
1281 if (!done) {
1282 buf = urb->transfer_buffer
1283 + qh->offset;
1284 wLength = urb->transfer_buffer_length
1285 - qh->offset;
1286 }
1287 }
1288 }
1289
1290 /* urb->status != -EINPROGRESS means request has been faulted,
1291 * so we must abort this transfer after cleanup
1292 */
1293 if (urb->status != -EINPROGRESS) {
1294 done = true;
1295 if (status == 0)
1296 status = urb->status;
1297 }
1298
1299 if (done) {
1300 /* set status */
1301 urb->status = status;
1302 urb->actual_length = qh->offset;
1303 musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT);
1304
1305 } else if (!(tx_csr & MUSB_TXCSR_DMAENAB)) {
1306 /* WARN_ON(!buf); */
1307
1308 /* REVISIT: some docs say that when hw_ep->tx_double_buffered,
1309 * (and presumably, fifo is not half-full) we should write TWO
1310 * packets before updating TXCSR ... other docs disagree ...
1311 */
1312 /* PIO: start next packet in this URB */
1313 wLength = min(qh->maxpacket, (u16) wLength);
1314 musb_write_fifo(hw_ep, wLength, buf);
1315 qh->segsize = wLength;
1316
1317 musb_ep_select(mbase, epnum);
1318 musb_writew(epio, MUSB_TXCSR,
1319 MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
1320 } else
1321 DBG(1, "not complete, but dma enabled?\n");
1322
1323finish:
1324 return;
1325}
1326
1327
1328#ifdef CONFIG_USB_INVENTRA_DMA
1329
1330/* Host side RX (IN) using Mentor DMA works as follows:
1331 submit_urb ->
1332 - if queue was empty, ProgramEndpoint
1333 - first IN token is sent out (by setting ReqPkt)
1334 LinuxIsr -> RxReady()
1335 /\ => first packet is received
1336 | - Set in mode 0 (DmaEnab, ~ReqPkt)
1337 | -> DMA Isr (transfer complete) -> RxReady()
1338 | - Ack receive (~RxPktRdy), turn off DMA (~DmaEnab)
1339 | - if urb not complete, send next IN token (ReqPkt)
1340 | | else complete urb.
1341 | |
1342 ---------------------------
1343 *
1344 * Nuances of mode 1:
1345 * For short packets, no ack (+RxPktRdy) is sent automatically
1346 * (even if AutoClear is ON)
1347 * For full packets, ack (~RxPktRdy) and next IN token (+ReqPkt) is sent
1348 * automatically => major problem, as collecting the next packet becomes
1349 * difficult. Hence mode 1 is not used.
1350 *
1351 * REVISIT
1352 * All we care about at this driver level is that
1353 * (a) all URBs terminate with REQPKT cleared and fifo(s) empty;
1354 * (b) termination conditions are: short RX, or buffer full;
1355 * (c) fault modes include
1356 * - iff URB_SHORT_NOT_OK, short RX status is -EREMOTEIO.
1357 * (and that endpoint's dma queue stops immediately)
1358 * - overflow (full, PLUS more bytes in the terminal packet)
1359 *
1360 * So for example, usb-storage sets URB_SHORT_NOT_OK, and would
1361 * thus be a great candidate for using mode 1 ... for all but the
1362 * last packet of one URB's transfer.
1363 */
1364
1365#endif
1366
1367/*
1368 * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
1369 * and high-bandwidth IN transfer cases.
1370 */
1371void musb_host_rx(struct musb *musb, u8 epnum)
1372{
1373 struct urb *urb;
1374 struct musb_hw_ep *hw_ep = musb->endpoints + epnum;
1375 void __iomem *epio = hw_ep->regs;
1376 struct musb_qh *qh = hw_ep->in_qh;
1377 size_t xfer_len;
1378 void __iomem *mbase = musb->mregs;
1379 int pipe;
1380 u16 rx_csr, val;
1381 bool iso_err = false;
1382 bool done = false;
1383 u32 status;
1384 struct dma_channel *dma;
1385
1386 musb_ep_select(mbase, epnum);
1387
1388 urb = next_urb(qh);
1389 dma = is_dma_capable() ? hw_ep->rx_channel : NULL;
1390 status = 0;
1391 xfer_len = 0;
1392
1393 rx_csr = musb_readw(epio, MUSB_RXCSR);
1394 val = rx_csr;
1395
1396 if (unlikely(!urb)) {
1397 /* REVISIT -- THIS SHOULD NEVER HAPPEN ... but, at least
1398 * usbtest #11 (unlinks) triggers it regularly, sometimes
1399 * with fifo full. (Only with DMA??)
1400 */
1401 DBG(3, "BOGUS RX%d ready, csr %04x, count %d\n", epnum, val,
1402 musb_readw(epio, MUSB_RXCOUNT));
1403 musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
1404 return;
1405 }
1406
1407 pipe = urb->pipe;
1408
1409 DBG(5, "<== hw %d rxcsr %04x, urb actual %d (+dma %zu)\n",
1410 epnum, rx_csr, urb->actual_length,
1411 dma ? dma->actual_len : 0);
1412
1413 /* check for errors, concurrent stall & unlink is not really
1414 * handled yet! */
1415 if (rx_csr & MUSB_RXCSR_H_RXSTALL) {
1416 DBG(3, "RX end %d STALL\n", epnum);
1417
1418 /* stall; record URB status */
1419 status = -EPIPE;
1420
1421 } else if (rx_csr & MUSB_RXCSR_H_ERROR) {
1422 DBG(3, "end %d RX proto error\n", epnum);
1423
1424 status = -EPROTO;
1425 musb_writeb(epio, MUSB_RXINTERVAL, 0);
1426
1427 } else if (rx_csr & MUSB_RXCSR_DATAERROR) {
1428
1429 if (USB_ENDPOINT_XFER_ISOC != qh->type) {
1430 /* NOTE this code path would be a good place to PAUSE a
1431 * transfer, if there's some other (nonperiodic) rx urb
1432 * that could use this fifo. (dma complicates it...)
1433 *
1434 * if (bulk && qh->ring.next != &musb->in_bulk), then
1435 * we have a candidate... NAKing is *NOT* an error
1436 */
1437 DBG(6, "RX end %d NAK timeout\n", epnum);
1438 musb_ep_select(mbase, epnum);
1439 musb_writew(epio, MUSB_RXCSR,
1440 MUSB_RXCSR_H_WZC_BITS
1441 | MUSB_RXCSR_H_REQPKT);
1442
1443 goto finish;
1444 } else {
1445 DBG(4, "RX end %d ISO data error\n", epnum);
1446 /* packet error reported later */
1447 iso_err = true;
1448 }
1449 }
1450
1451 /* faults abort the transfer */
1452 if (status) {
1453 /* clean up dma and collect transfer count */
1454 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
1455 dma->status = MUSB_DMA_STATUS_CORE_ABORT;
1456 (void) musb->dma_controller->channel_abort(dma);
1457 xfer_len = dma->actual_len;
1458 }
1459 musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
1460 musb_writeb(epio, MUSB_RXINTERVAL, 0);
1461 done = true;
1462 goto finish;
1463 }
1464
1465 if (unlikely(dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY)) {
1466 /* SHOULD NEVER HAPPEN ... but at least DaVinci has done it */
1467 ERR("RX%d dma busy, csr %04x\n", epnum, rx_csr);
1468 goto finish;
1469 }
1470
1471 /* thorough shutdown for now ... given more precise fault handling
1472 * and better queueing support, we might keep a DMA pipeline going
1473 * while processing this irq for earlier completions.
1474 */
1475
1476 /* FIXME this is _way_ too much in-line logic for Mentor DMA */
1477
1478#ifndef CONFIG_USB_INVENTRA_DMA
1479 if (rx_csr & MUSB_RXCSR_H_REQPKT) {
1480 /* REVISIT this happened for a while on some short reads...
1481 * the cleanup still needs investigation... looks bad...
1482 * and also duplicates dma cleanup code above ... plus,
1483 * shouldn't this be the "half full" double buffer case?
1484 */
1485 if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
1486 dma->status = MUSB_DMA_STATUS_CORE_ABORT;
1487 (void) musb->dma_controller->channel_abort(dma);
1488 xfer_len = dma->actual_len;
1489 done = true;
1490 }
1491
1492 DBG(2, "RXCSR%d %04x, reqpkt, len %zu%s\n", epnum, rx_csr,
1493 xfer_len, dma ? ", dma" : "");
1494 rx_csr &= ~MUSB_RXCSR_H_REQPKT;
1495
1496 musb_ep_select(mbase, epnum);
1497 musb_writew(epio, MUSB_RXCSR,
1498 MUSB_RXCSR_H_WZC_BITS | rx_csr);
1499 }
1500#endif
1501 if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
1502 xfer_len = dma->actual_len;
1503
1504 val &= ~(MUSB_RXCSR_DMAENAB
1505 | MUSB_RXCSR_H_AUTOREQ
1506 | MUSB_RXCSR_AUTOCLEAR
1507 | MUSB_RXCSR_RXPKTRDY);
1508 musb_writew(hw_ep->regs, MUSB_RXCSR, val);
1509
1510#ifdef CONFIG_USB_INVENTRA_DMA
1511 /* done if urb buffer is full or short packet is recd */
1512 done = (urb->actual_length + xfer_len >=
1513 urb->transfer_buffer_length
1514 || dma->actual_len < qh->maxpacket);
1515
1516 /* send IN token for next packet, without AUTOREQ */
1517 if (!done) {
1518 val |= MUSB_RXCSR_H_REQPKT;
1519 musb_writew(epio, MUSB_RXCSR,
1520 MUSB_RXCSR_H_WZC_BITS | val);
1521 }
1522
1523 DBG(4, "ep %d dma %s, rxcsr %04x, rxcount %d\n", epnum,
1524 done ? "off" : "reset",
1525 musb_readw(epio, MUSB_RXCSR),
1526 musb_readw(epio, MUSB_RXCOUNT));
1527#else
1528 done = true;
1529#endif
1530 } else if (urb->status == -EINPROGRESS) {
1531 /* if no errors, be sure a packet is ready for unloading */
1532 if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) {
1533 status = -EPROTO;
1534 ERR("Rx interrupt with no errors or packet!\n");
1535
1536 /* FIXME this is another "SHOULD NEVER HAPPEN" */
1537
1538/* SCRUB (RX) */
1539 /* do the proper sequence to abort the transfer */
1540 musb_ep_select(mbase, epnum);
1541 val &= ~MUSB_RXCSR_H_REQPKT;
1542 musb_writew(epio, MUSB_RXCSR, val);
1543 goto finish;
1544 }
1545
1546 /* we are expecting IN packets */
1547#ifdef CONFIG_USB_INVENTRA_DMA
1548 if (dma) {
1549 struct dma_controller *c;
1550 u16 rx_count;
1551 int ret;
1552
1553 rx_count = musb_readw(epio, MUSB_RXCOUNT);
1554
1555 DBG(2, "RX%d count %d, buffer 0x%x len %d/%d\n",
1556 epnum, rx_count,
1557 urb->transfer_dma
1558 + urb->actual_length,
1559 qh->offset,
1560 urb->transfer_buffer_length);
1561
1562 c = musb->dma_controller;
1563
1564 dma->desired_mode = 0;
1565#ifdef USE_MODE1
1566 /* because of the issue below, mode 1 will
1567 * only rarely behave with correct semantics.
1568 */
1569 if ((urb->transfer_flags &
1570 URB_SHORT_NOT_OK)
1571 && (urb->transfer_buffer_length -
1572 urb->actual_length)
1573 > qh->maxpacket)
1574 dma->desired_mode = 1;
1575#endif
1576
1577/* Disadvantage of using mode 1:
1578 * It's basically usable only for mass storage class; essentially all
1579 * other protocols also terminate transfers on short packets.
1580 *
1581 * Details:
1582 * An extra IN token is sent at the end of the transfer (due to AUTOREQ)
1583 * If you try to use mode 1 for (transfer_buffer_length - 512), and try
1584 * to use the extra IN token to grab the last packet using mode 0, then
1585 * the problem is that you cannot be sure when the device will send the
1586 * last packet and RxPktRdy set. Sometimes the packet is recd too soon
1587 * such that it gets lost when RxCSR is re-set at the end of the mode 1
1588 * transfer, while sometimes it is recd just a little late so that if you
1589 * try to configure for mode 0 soon after the mode 1 transfer is
1590 * completed, you will find rxcount 0. Okay, so you might think why not
1591 * wait for an interrupt when the pkt is recd. Well, you won't get any!
1592 */
1593
1594 val = musb_readw(epio, MUSB_RXCSR);
1595 val &= ~MUSB_RXCSR_H_REQPKT;
1596
1597 if (dma->desired_mode == 0)
1598 val &= ~MUSB_RXCSR_H_AUTOREQ;
1599 else
1600 val |= MUSB_RXCSR_H_AUTOREQ;
1601 val |= MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAENAB;
1602
1603 musb_writew(epio, MUSB_RXCSR,
1604 MUSB_RXCSR_H_WZC_BITS | val);
1605
1606 /* REVISIT if when actual_length != 0,
1607 * transfer_buffer_length needs to be
1608 * adjusted first...
1609 */
1610 ret = c->channel_program(
1611 dma, qh->maxpacket,
1612 dma->desired_mode,
1613 urb->transfer_dma
1614 + urb->actual_length,
1615 (dma->desired_mode == 0)
1616 ? rx_count
1617 : urb->transfer_buffer_length);
1618
1619 if (!ret) {
1620 c->channel_release(dma);
1621 hw_ep->rx_channel = NULL;
1622 dma = NULL;
1623 /* REVISIT reset CSR */
1624 }
1625 }
1626#endif /* Mentor DMA */
1627
1628 if (!dma) {
1629 done = musb_host_packet_rx(musb, urb,
1630 epnum, iso_err);
1631 DBG(6, "read %spacket\n", done ? "last " : "");
1632 }
1633 }
1634
1635 if (dma && usb_pipeisoc(pipe)) {
1636 struct usb_iso_packet_descriptor *d;
1637 int iso_stat = status;
1638
1639 d = urb->iso_frame_desc + qh->iso_idx;
1640 d->actual_length += xfer_len;
1641 if (iso_err) {
1642 iso_stat = -EILSEQ;
1643 urb->error_count++;
1644 }
1645 d->status = iso_stat;
1646 }
1647
1648finish:
1649 urb->actual_length += xfer_len;
1650 qh->offset += xfer_len;
1651 if (done) {
1652 if (urb->status == -EINPROGRESS)
1653 urb->status = status;
1654 musb_advance_schedule(musb, urb, hw_ep, USB_DIR_IN);
1655 }
1656}
1657
1658/* schedule nodes correspond to peripheral endpoints, like an OHCI QH.
1659 * the software schedule associates multiple such nodes with a given
1660 * host side hardware endpoint + direction; scheduling may activate
1661 * that hardware endpoint.
1662 */
1663static int musb_schedule(
1664 struct musb *musb,
1665 struct musb_qh *qh,
1666 int is_in)
1667{
1668 int idle;
1669 int best_diff;
1670 int best_end, epnum;
1671 struct musb_hw_ep *hw_ep = NULL;
1672 struct list_head *head = NULL;
1673
1674 /* use fixed hardware for control and bulk */
1675 switch (qh->type) {
1676 case USB_ENDPOINT_XFER_CONTROL:
1677 head = &musb->control;
1678 hw_ep = musb->control_ep;
1679 break;
1680 case USB_ENDPOINT_XFER_BULK:
1681 hw_ep = musb->bulk_ep;
1682 if (is_in)
1683 head = &musb->in_bulk;
1684 else
1685 head = &musb->out_bulk;
1686 break;
1687 }
1688 if (head) {
1689 idle = list_empty(head);
1690 list_add_tail(&qh->ring, head);
1691 goto success;
1692 }
1693
1694 /* else, periodic transfers get muxed to other endpoints */
1695
1696 /* FIXME this doesn't consider direction, so it can only
1697 * work for one half of the endpoint hardware, and assumes
1698 * the previous cases handled all non-shared endpoints...
1699 */
1700
1701 /* we know this qh hasn't been scheduled, so all we need to do
1702 * is choose which hardware endpoint to put it on ...
1703 *
1704 * REVISIT what we really want here is a regular schedule tree
1705 * like e.g. OHCI uses, but for now musb->periodic is just an
1706 * array of the _single_ logical endpoint associated with a
1707 * given physical one (identity mapping logical->physical).
1708 *
1709 * that simplistic approach makes TT scheduling a lot simpler;
1710 * there is none, and thus none of its complexity...
1711 */
1712 best_diff = 4096;
1713 best_end = -1;
1714
1715 for (epnum = 1; epnum < musb->nr_endpoints; epnum++) {
1716 int diff;
1717
1718 if (musb->periodic[epnum])
1719 continue;
1720 hw_ep = &musb->endpoints[epnum];
1721 if (hw_ep == musb->bulk_ep)
1722 continue;
1723
1724 if (is_in)
1725 diff = hw_ep->max_packet_sz_rx - qh->maxpacket;
1726 else
1727 diff = hw_ep->max_packet_sz_tx - qh->maxpacket;
1728
1729 if (diff > 0 && best_diff > diff) {
1730 best_diff = diff;
1731 best_end = epnum;
1732 }
1733 }
1734 if (best_end < 0)
1735 return -ENOSPC;
1736
1737 idle = 1;
1738 hw_ep = musb->endpoints + best_end;
1739 musb->periodic[best_end] = qh;
1740 DBG(4, "qh %p periodic slot %d\n", qh, best_end);
1741success:
1742 qh->hw_ep = hw_ep;
1743 qh->hep->hcpriv = qh;
1744 if (idle)
1745 musb_start_urb(musb, is_in, qh);
1746 return 0;
1747}
1748
1749static int musb_urb_enqueue(
1750 struct usb_hcd *hcd,
1751 struct urb *urb,
1752 gfp_t mem_flags)
1753{
1754 unsigned long flags;
1755 struct musb *musb = hcd_to_musb(hcd);
1756 struct usb_host_endpoint *hep = urb->ep;
1757 struct musb_qh *qh = hep->hcpriv;
1758 struct usb_endpoint_descriptor *epd = &hep->desc;
1759 int ret;
1760 unsigned type_reg;
1761 unsigned interval;
1762
1763 /* host role must be active */
1764 if (!is_host_active(musb) || !musb->is_active)
1765 return -ENODEV;
1766
1767 spin_lock_irqsave(&musb->lock, flags);
1768 ret = usb_hcd_link_urb_to_ep(hcd, urb);
1769 spin_unlock_irqrestore(&musb->lock, flags);
1770 if (ret)
1771 return ret;
1772
1773 /* DMA mapping was already done, if needed, and this urb is on
1774 * hep->urb_list ... so there's little to do unless hep wasn't
1775 * yet scheduled onto a live qh.
1776 *
1777 * REVISIT best to keep hep->hcpriv valid until the endpoint gets
1778 * disabled, testing for empty qh->ring and avoiding qh setup costs
1779 * except for the first urb queued after a config change.
1780 */
1781 if (qh) {
1782 urb->hcpriv = qh;
1783 return 0;
1784 }
1785
1786 /* Allocate and initialize qh, minimizing the work done each time
1787 * hw_ep gets reprogrammed, or with irqs blocked. Then schedule it.
1788 *
1789 * REVISIT consider a dedicated qh kmem_cache, so it's harder
1790 * for bugs in other kernel code to break this driver...
1791 */
1792 qh = kzalloc(sizeof *qh, mem_flags);
1793 if (!qh) {
1794 usb_hcd_unlink_urb_from_ep(hcd, urb);
1795 return -ENOMEM;
1796 }
1797
1798 qh->hep = hep;
1799 qh->dev = urb->dev;
1800 INIT_LIST_HEAD(&qh->ring);
1801 qh->is_ready = 1;
1802
1803 qh->maxpacket = le16_to_cpu(epd->wMaxPacketSize);
1804
1805 /* no high bandwidth support yet */
1806 if (qh->maxpacket & ~0x7ff) {
1807 ret = -EMSGSIZE;
1808 goto done;
1809 }
1810
1811 qh->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
1812 qh->type = epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
1813
1814 /* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */
1815 qh->addr_reg = (u8) usb_pipedevice(urb->pipe);
1816
1817 /* precompute rxtype/txtype/type0 register */
1818 type_reg = (qh->type << 4) | qh->epnum;
1819 switch (urb->dev->speed) {
1820 case USB_SPEED_LOW:
1821 type_reg |= 0xc0;
1822 break;
1823 case USB_SPEED_FULL:
1824 type_reg |= 0x80;
1825 break;
1826 default:
1827 type_reg |= 0x40;
1828 }
1829 qh->type_reg = type_reg;
1830
1831 /* precompute rxinterval/txinterval register */
1832 interval = min((u8)16, epd->bInterval); /* log encoding */
1833 switch (qh->type) {
1834 case USB_ENDPOINT_XFER_INT:
1835 /* fullspeed uses linear encoding */
1836 if (USB_SPEED_FULL == urb->dev->speed) {
1837 interval = epd->bInterval;
1838 if (!interval)
1839 interval = 1;
1840 }
1841 /* FALLTHROUGH */
1842 case USB_ENDPOINT_XFER_ISOC:
1843 /* iso always uses log encoding */
1844 break;
1845 default:
1846 /* REVISIT we actually want to use NAK limits, hinting to the
1847 * transfer scheduling logic to try some other qh, e.g. try
1848 * for 2 msec first:
1849 *
1850 * interval = (USB_SPEED_HIGH == urb->dev->speed) ? 16 : 2;
1851 *
1852 * The downside of disabling this is that transfer scheduling
1853 * gets VERY unfair for nonperiodic transfers; a misbehaving
1854 * peripheral could make that hurt. Or for reads, one that's
1855 * perfectly normal: network and other drivers keep reads
1856 * posted at all times, having one pending for a week should
1857 * be perfectly safe.
1858 *
1859 * The upside of disabling it is avoidng transfer scheduling
1860 * code to put this aside for while.
1861 */
1862 interval = 0;
1863 }
1864 qh->intv_reg = interval;
1865
1866 /* precompute addressing for external hub/tt ports */
1867 if (musb->is_multipoint) {
1868 struct usb_device *parent = urb->dev->parent;
1869
1870 if (parent != hcd->self.root_hub) {
1871 qh->h_addr_reg = (u8) parent->devnum;
1872
1873 /* set up tt info if needed */
1874 if (urb->dev->tt) {
1875 qh->h_port_reg = (u8) urb->dev->ttport;
1876 qh->h_addr_reg |= 0x80;
1877 }
1878 }
1879 }
1880
1881 /* invariant: hep->hcpriv is null OR the qh that's already scheduled.
1882 * until we get real dma queues (with an entry for each urb/buffer),
1883 * we only have work to do in the former case.
1884 */
1885 spin_lock_irqsave(&musb->lock, flags);
1886 if (hep->hcpriv) {
1887 /* some concurrent activity submitted another urb to hep...
1888 * odd, rare, error prone, but legal.
1889 */
1890 kfree(qh);
1891 ret = 0;
1892 } else
1893 ret = musb_schedule(musb, qh,
1894 epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK);
1895
1896 if (ret == 0) {
1897 urb->hcpriv = qh;
1898 /* FIXME set urb->start_frame for iso/intr, it's tested in
1899 * musb_start_urb(), but otherwise only konicawc cares ...
1900 */
1901 }
1902 spin_unlock_irqrestore(&musb->lock, flags);
1903
1904done:
1905 if (ret != 0) {
1906 usb_hcd_unlink_urb_from_ep(hcd, urb);
1907 kfree(qh);
1908 }
1909 return ret;
1910}
1911
1912
1913/*
1914 * abort a transfer that's at the head of a hardware queue.
1915 * called with controller locked, irqs blocked
1916 * that hardware queue advances to the next transfer, unless prevented
1917 */
1918static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in)
1919{
1920 struct musb_hw_ep *ep = qh->hw_ep;
1921 void __iomem *epio = ep->regs;
1922 unsigned hw_end = ep->epnum;
1923 void __iomem *regs = ep->musb->mregs;
1924 u16 csr;
1925 int status = 0;
1926
1927 musb_ep_select(regs, hw_end);
1928
1929 if (is_dma_capable()) {
1930 struct dma_channel *dma;
1931
1932 dma = is_in ? ep->rx_channel : ep->tx_channel;
1933 if (dma) {
1934 status = ep->musb->dma_controller->channel_abort(dma);
1935 DBG(status ? 1 : 3,
1936 "abort %cX%d DMA for urb %p --> %d\n",
1937 is_in ? 'R' : 'T', ep->epnum,
1938 urb, status);
1939 urb->actual_length += dma->actual_len;
1940 }
1941 }
1942
1943 /* turn off DMA requests, discard state, stop polling ... */
1944 if (is_in) {
1945 /* giveback saves bulk toggle */
1946 csr = musb_h_flush_rxfifo(ep, 0);
1947
1948 /* REVISIT we still get an irq; should likely clear the
1949 * endpoint's irq status here to avoid bogus irqs.
1950 * clearing that status is platform-specific...
1951 */
1952 } else {
1953 musb_h_tx_flush_fifo(ep);
1954 csr = musb_readw(epio, MUSB_TXCSR);
1955 csr &= ~(MUSB_TXCSR_AUTOSET
1956 | MUSB_TXCSR_DMAENAB
1957 | MUSB_TXCSR_H_RXSTALL
1958 | MUSB_TXCSR_H_NAKTIMEOUT
1959 | MUSB_TXCSR_H_ERROR
1960 | MUSB_TXCSR_TXPKTRDY);
1961 musb_writew(epio, MUSB_TXCSR, csr);
1962 /* REVISIT may need to clear FLUSHFIFO ... */
1963 musb_writew(epio, MUSB_TXCSR, csr);
1964 /* flush cpu writebuffer */
1965 csr = musb_readw(epio, MUSB_TXCSR);
1966 }
1967 if (status == 0)
1968 musb_advance_schedule(ep->musb, urb, ep, is_in);
1969 return status;
1970}
1971
1972static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
1973{
1974 struct musb *musb = hcd_to_musb(hcd);
1975 struct musb_qh *qh;
1976 struct list_head *sched;
1977 unsigned long flags;
1978 int ret;
1979
1980 DBG(4, "urb=%p, dev%d ep%d%s\n", urb,
1981 usb_pipedevice(urb->pipe),
1982 usb_pipeendpoint(urb->pipe),
1983 usb_pipein(urb->pipe) ? "in" : "out");
1984
1985 spin_lock_irqsave(&musb->lock, flags);
1986 ret = usb_hcd_check_unlink_urb(hcd, urb, status);
1987 if (ret)
1988 goto done;
1989
1990 qh = urb->hcpriv;
1991 if (!qh)
1992 goto done;
1993
1994 /* Any URB not actively programmed into endpoint hardware can be
1995 * immediately given back. Such an URB must be at the head of its
1996 * endpoint queue, unless someday we get real DMA queues. And even
1997 * then, it might not be known to the hardware...
1998 *
1999 * Otherwise abort current transfer, pending dma, etc.; urb->status
2000 * has already been updated. This is a synchronous abort; it'd be
2001 * OK to hold off until after some IRQ, though.
2002 */
2003 if (!qh->is_ready || urb->urb_list.prev != &qh->hep->urb_list)
2004 ret = -EINPROGRESS;
2005 else {
2006 switch (qh->type) {
2007 case USB_ENDPOINT_XFER_CONTROL:
2008 sched = &musb->control;
2009 break;
2010 case USB_ENDPOINT_XFER_BULK:
2011 if (usb_pipein(urb->pipe))
2012 sched = &musb->in_bulk;
2013 else
2014 sched = &musb->out_bulk;
2015 break;
2016 default:
2017 /* REVISIT when we get a schedule tree, periodic
2018 * transfers won't always be at the head of a
2019 * singleton queue...
2020 */
2021 sched = NULL;
2022 break;
2023 }
2024 }
2025
2026 /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */
2027 if (ret < 0 || (sched && qh != first_qh(sched))) {
2028 int ready = qh->is_ready;
2029
2030 ret = 0;
2031 qh->is_ready = 0;
2032 __musb_giveback(musb, urb, 0);
2033 qh->is_ready = ready;
2034 } else
2035 ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
2036done:
2037 spin_unlock_irqrestore(&musb->lock, flags);
2038 return ret;
2039}
2040
2041/* disable an endpoint */
2042static void
2043musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
2044{
2045 u8 epnum = hep->desc.bEndpointAddress;
2046 unsigned long flags;
2047 struct musb *musb = hcd_to_musb(hcd);
2048 u8 is_in = epnum & USB_DIR_IN;
2049 struct musb_qh *qh = hep->hcpriv;
2050 struct urb *urb, *tmp;
2051 struct list_head *sched;
2052
2053 if (!qh)
2054 return;
2055
2056 spin_lock_irqsave(&musb->lock, flags);
2057
2058 switch (qh->type) {
2059 case USB_ENDPOINT_XFER_CONTROL:
2060 sched = &musb->control;
2061 break;
2062 case USB_ENDPOINT_XFER_BULK:
2063 if (is_in)
2064 sched = &musb->in_bulk;
2065 else
2066 sched = &musb->out_bulk;
2067 break;
2068 default:
2069 /* REVISIT when we get a schedule tree, periodic transfers
2070 * won't always be at the head of a singleton queue...
2071 */
2072 sched = NULL;
2073 break;
2074 }
2075
2076 /* NOTE: qh is invalid unless !list_empty(&hep->urb_list) */
2077
2078 /* kick first urb off the hardware, if needed */
2079 qh->is_ready = 0;
2080 if (!sched || qh == first_qh(sched)) {
2081 urb = next_urb(qh);
2082
2083 /* make software (then hardware) stop ASAP */
2084 if (!urb->unlinked)
2085 urb->status = -ESHUTDOWN;
2086
2087 /* cleanup */
2088 musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN);
2089 } else
2090 urb = NULL;
2091
2092 /* then just nuke all the others */
2093 list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list)
2094 musb_giveback(qh, urb, -ESHUTDOWN);
2095
2096 spin_unlock_irqrestore(&musb->lock, flags);
2097}
2098
2099static int musb_h_get_frame_number(struct usb_hcd *hcd)
2100{
2101 struct musb *musb = hcd_to_musb(hcd);
2102
2103 return musb_readw(musb->mregs, MUSB_FRAME);
2104}
2105
2106static int musb_h_start(struct usb_hcd *hcd)
2107{
2108 struct musb *musb = hcd_to_musb(hcd);
2109
2110 /* NOTE: musb_start() is called when the hub driver turns
2111 * on port power, or when (OTG) peripheral starts.
2112 */
2113 hcd->state = HC_STATE_RUNNING;
2114 musb->port1_status = 0;
2115 return 0;
2116}
2117
2118static void musb_h_stop(struct usb_hcd *hcd)
2119{
2120 musb_stop(hcd_to_musb(hcd));
2121 hcd->state = HC_STATE_HALT;
2122}
2123
2124static int musb_bus_suspend(struct usb_hcd *hcd)
2125{
2126 struct musb *musb = hcd_to_musb(hcd);
2127
2128 if (musb->xceiv.state == OTG_STATE_A_SUSPEND)
2129 return 0;
2130
2131 if (is_host_active(musb) && musb->is_active) {
2132 WARNING("trying to suspend as %s is_active=%i\n",
2133 otg_state_string(musb), musb->is_active);
2134 return -EBUSY;
2135 } else
2136 return 0;
2137}
2138
2139static int musb_bus_resume(struct usb_hcd *hcd)
2140{
2141 /* resuming child port does the work */
2142 return 0;
2143}
2144
2145const struct hc_driver musb_hc_driver = {
2146 .description = "musb-hcd",
2147 .product_desc = "MUSB HDRC host driver",
2148 .hcd_priv_size = sizeof(struct musb),
2149 .flags = HCD_USB2 | HCD_MEMORY,
2150
2151 /* not using irq handler or reset hooks from usbcore, since
2152 * those must be shared with peripheral code for OTG configs
2153 */
2154
2155 .start = musb_h_start,
2156 .stop = musb_h_stop,
2157
2158 .get_frame_number = musb_h_get_frame_number,
2159
2160 .urb_enqueue = musb_urb_enqueue,
2161 .urb_dequeue = musb_urb_dequeue,
2162 .endpoint_disable = musb_h_disable,
2163
2164 .hub_status_data = musb_hub_status_data,
2165 .hub_control = musb_hub_control,
2166 .bus_suspend = musb_bus_suspend,
2167 .bus_resume = musb_bus_resume,
2168 /* .start_port_reset = NULL, */
2169 /* .hub_irq_enable = NULL, */
2170};
diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h
new file mode 100644
index 000000000000..77bcdb9d5b32
--- /dev/null
+++ b/drivers/usb/musb/musb_host.h
@@ -0,0 +1,110 @@
1/*
2 * MUSB OTG driver host defines
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef _MUSB_HOST_H
36#define _MUSB_HOST_H
37
38static inline struct usb_hcd *musb_to_hcd(struct musb *musb)
39{
40 return container_of((void *) musb, struct usb_hcd, hcd_priv);
41}
42
43static inline struct musb *hcd_to_musb(struct usb_hcd *hcd)
44{
45 return (struct musb *) (hcd->hcd_priv);
46}
47
48/* stored in "usb_host_endpoint.hcpriv" for scheduled endpoints */
49struct musb_qh {
50 struct usb_host_endpoint *hep; /* usbcore info */
51 struct usb_device *dev;
52 struct musb_hw_ep *hw_ep; /* current binding */
53
54 struct list_head ring; /* of musb_qh */
55 /* struct musb_qh *next; */ /* for periodic tree */
56
57 unsigned offset; /* in urb->transfer_buffer */
58 unsigned segsize; /* current xfer fragment */
59
60 u8 type_reg; /* {rx,tx} type register */
61 u8 intv_reg; /* {rx,tx} interval register */
62 u8 addr_reg; /* device address register */
63 u8 h_addr_reg; /* hub address register */
64 u8 h_port_reg; /* hub port register */
65
66 u8 is_ready; /* safe to modify hw_ep */
67 u8 type; /* XFERTYPE_* */
68 u8 epnum;
69 u16 maxpacket;
70 u16 frame; /* for periodic schedule */
71 unsigned iso_idx; /* in urb->iso_frame_desc[] */
72};
73
74/* map from control or bulk queue head to the first qh on that ring */
75static inline struct musb_qh *first_qh(struct list_head *q)
76{
77 if (list_empty(q))
78 return NULL;
79 return list_entry(q->next, struct musb_qh, ring);
80}
81
82
83extern void musb_root_disconnect(struct musb *musb);
84
85struct usb_hcd;
86
87extern int musb_hub_status_data(struct usb_hcd *hcd, char *buf);
88extern int musb_hub_control(struct usb_hcd *hcd,
89 u16 typeReq, u16 wValue, u16 wIndex,
90 char *buf, u16 wLength);
91
92extern const struct hc_driver musb_hc_driver;
93
94static inline struct urb *next_urb(struct musb_qh *qh)
95{
96#ifdef CONFIG_USB_MUSB_HDRC_HCD
97 struct list_head *queue;
98
99 if (!qh)
100 return NULL;
101 queue = &qh->hep->urb_list;
102 if (list_empty(queue))
103 return NULL;
104 return list_entry(queue->next, struct urb, urb_list);
105#else
106 return NULL;
107#endif
108}
109
110#endif /* _MUSB_HOST_H */
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
new file mode 100644
index 000000000000..6bbedae83af8
--- /dev/null
+++ b/drivers/usb/musb/musb_io.h
@@ -0,0 +1,115 @@
1/*
2 * MUSB OTG driver register I/O
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef __MUSB_LINUX_PLATFORM_ARCH_H__
36#define __MUSB_LINUX_PLATFORM_ARCH_H__
37
38#include <linux/io.h>
39
40#ifndef CONFIG_ARM
41static inline void readsl(const void __iomem *addr, void *buf, int len)
42 { insl((unsigned long)addr, buf, len); }
43static inline void readsw(const void __iomem *addr, void *buf, int len)
44 { insw((unsigned long)addr, buf, len); }
45static inline void readsb(const void __iomem *addr, void *buf, int len)
46 { insb((unsigned long)addr, buf, len); }
47
48static inline void writesl(const void __iomem *addr, const void *buf, int len)
49 { outsl((unsigned long)addr, buf, len); }
50static inline void writesw(const void __iomem *addr, const void *buf, int len)
51 { outsw((unsigned long)addr, buf, len); }
52static inline void writesb(const void __iomem *addr, const void *buf, int len)
53 { outsb((unsigned long)addr, buf, len); }
54
55#endif
56
57/* NOTE: these offsets are all in bytes */
58
59static inline u16 musb_readw(const void __iomem *addr, unsigned offset)
60 { return __raw_readw(addr + offset); }
61
62static inline u32 musb_readl(const void __iomem *addr, unsigned offset)
63 { return __raw_readl(addr + offset); }
64
65
66static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data)
67 { __raw_writew(data, addr + offset); }
68
69static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data)
70 { __raw_writel(data, addr + offset); }
71
72
73#ifdef CONFIG_USB_TUSB6010
74
75/*
76 * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum.
77 */
78static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
79{
80 u16 tmp;
81 u8 val;
82
83 tmp = __raw_readw(addr + (offset & ~1));
84 if (offset & 1)
85 val = (tmp >> 8);
86 else
87 val = tmp & 0xff;
88
89 return val;
90}
91
92static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
93{
94 u16 tmp;
95
96 tmp = __raw_readw(addr + (offset & ~1));
97 if (offset & 1)
98 tmp = (data << 8) | (tmp & 0xff);
99 else
100 tmp = (tmp & 0xff00) | data;
101
102 __raw_writew(tmp, addr + (offset & ~1));
103}
104
105#else
106
107static inline u8 musb_readb(const void __iomem *addr, unsigned offset)
108 { return __raw_readb(addr + offset); }
109
110static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data)
111 { __raw_writeb(data, addr + offset); }
112
113#endif /* CONFIG_USB_TUSB6010 */
114
115#endif
diff --git a/drivers/usb/musb/musb_procfs.c b/drivers/usb/musb/musb_procfs.c
new file mode 100644
index 000000000000..55e6b78bdccc
--- /dev/null
+++ b/drivers/usb/musb/musb_procfs.c
@@ -0,0 +1,830 @@
1/*
2 * MUSB OTG driver debug support
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#include <linux/kernel.h>
36#include <linux/proc_fs.h>
37#include <linux/seq_file.h>
38#include <linux/uaccess.h> /* FIXME remove procfs writes */
39#include <asm/arch/hardware.h>
40
41#include "musb_core.h"
42
43#include "davinci.h"
44
45#ifdef CONFIG_USB_MUSB_HDRC_HCD
46
47static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
48{
49 int count;
50 int tmp;
51 struct usb_host_endpoint *hep = qh->hep;
52 struct urb *urb;
53
54 count = snprintf(buf, max, " qh %p dev%d ep%d%s max%d\n",
55 qh, qh->dev->devnum, qh->epnum,
56 ({ char *s; switch (qh->type) {
57 case USB_ENDPOINT_XFER_BULK:
58 s = "-bulk"; break;
59 case USB_ENDPOINT_XFER_INT:
60 s = "-int"; break;
61 case USB_ENDPOINT_XFER_CONTROL:
62 s = ""; break;
63 default:
64 s = "iso"; break;
65 }; s; }),
66 qh->maxpacket);
67 if (count <= 0)
68 return 0;
69 buf += count;
70 max -= count;
71
72 list_for_each_entry(urb, &hep->urb_list, urb_list) {
73 tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
74 usb_pipein(urb->pipe) ? "in" : "out",
75 urb, urb->actual_length,
76 urb->transfer_buffer_length);
77 if (tmp <= 0)
78 break;
79 tmp = min(tmp, (int)max);
80 count += tmp;
81 buf += tmp;
82 max -= tmp;
83 }
84 return count;
85}
86
87static int
88dump_queue(struct list_head *q, char *buf, unsigned max)
89{
90 int count = 0;
91 struct musb_qh *qh;
92
93 list_for_each_entry(qh, q, ring) {
94 int tmp;
95
96 tmp = dump_qh(qh, buf, max);
97 if (tmp <= 0)
98 break;
99 tmp = min(tmp, (int)max);
100 count += tmp;
101 buf += tmp;
102 max -= tmp;
103 }
104 return count;
105}
106
107#endif /* HCD */
108
109#ifdef CONFIG_USB_GADGET_MUSB_HDRC
110static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
111{
112 char *buf = buffer;
113 int code = 0;
114 void __iomem *regs = ep->hw_ep->regs;
115 char *mode = "1buf";
116
117 if (ep->is_in) {
118 if (ep->hw_ep->tx_double_buffered)
119 mode = "2buf";
120 } else {
121 if (ep->hw_ep->rx_double_buffered)
122 mode = "2buf";
123 }
124
125 do {
126 struct usb_request *req;
127
128 code = snprintf(buf, max,
129 "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
130 ep->name, ep->current_epnum,
131 mode, ep->dma ? " dma" : "",
132 musb_readw(regs,
133 (ep->is_in || !ep->current_epnum)
134 ? MUSB_TXCSR
135 : MUSB_RXCSR),
136 musb_readw(regs, ep->is_in
137 ? MUSB_TXMAXP
138 : MUSB_RXMAXP)
139 );
140 if (code <= 0)
141 break;
142 code = min(code, (int) max);
143 buf += code;
144 max -= code;
145
146 if (is_cppi_enabled() && ep->current_epnum) {
147 unsigned cppi = ep->current_epnum - 1;
148 void __iomem *base = ep->musb->ctrl_base;
149 unsigned off1 = cppi << 2;
150 void __iomem *ram = base;
151 char tmp[16];
152
153 if (ep->is_in) {
154 ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
155 tmp[0] = 0;
156 } else {
157 ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
158 snprintf(tmp, sizeof tmp, "%d left, ",
159 musb_readl(base,
160 DAVINCI_RXCPPI_BUFCNT0_REG + off1));
161 }
162
163 code = snprintf(buf, max, "%cX DMA%d: %s"
164 "%08x %08x, %08x %08x; "
165 "%08x %08x %08x .. %08x\n",
166 ep->is_in ? 'T' : 'R',
167 ep->current_epnum - 1, tmp,
168 musb_readl(ram, 0 * 4),
169 musb_readl(ram, 1 * 4),
170 musb_readl(ram, 2 * 4),
171 musb_readl(ram, 3 * 4),
172 musb_readl(ram, 4 * 4),
173 musb_readl(ram, 5 * 4),
174 musb_readl(ram, 6 * 4),
175 musb_readl(ram, 7 * 4));
176 if (code <= 0)
177 break;
178 code = min(code, (int) max);
179 buf += code;
180 max -= code;
181 }
182
183 if (list_empty(&ep->req_list)) {
184 code = snprintf(buf, max, "\t(queue empty)\n");
185 if (code <= 0)
186 break;
187 code = min(code, (int) max);
188 buf += code;
189 max -= code;
190 break;
191 }
192 list_for_each_entry(req, &ep->req_list, list) {
193 code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
194 req,
195 req->zero ? "zero, " : "",
196 req->short_not_ok ? "!short, " : "",
197 req->actual, req->length);
198 if (code <= 0)
199 break;
200 code = min(code, (int) max);
201 buf += code;
202 max -= code;
203 }
204 } while (0);
205 return buf - buffer;
206}
207#endif
208
209static int
210dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
211{
212 int code = 0;
213 char *buf = aBuffer;
214 struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
215
216 do {
217 musb_ep_select(musb->mregs, epnum);
218#ifdef CONFIG_USB_MUSB_HDRC_HCD
219 if (is_host_active(musb)) {
220 int dump_rx, dump_tx;
221 void __iomem *regs = hw_ep->regs;
222
223 /* TEMPORARY (!) until we have a real periodic
224 * schedule tree ...
225 */
226 if (!epnum) {
227 /* control is shared, uses RX queue
228 * but (mostly) shadowed tx registers
229 */
230 dump_tx = !list_empty(&musb->control);
231 dump_rx = 0;
232 } else if (hw_ep == musb->bulk_ep) {
233 dump_tx = !list_empty(&musb->out_bulk);
234 dump_rx = !list_empty(&musb->in_bulk);
235 } else if (musb->periodic[epnum]) {
236 struct usb_host_endpoint *hep;
237
238 hep = musb->periodic[epnum]->hep;
239 dump_rx = hep->desc.bEndpointAddress
240 & USB_ENDPOINT_DIR_MASK;
241 dump_tx = !dump_rx;
242 } else
243 break;
244 /* END TEMPORARY */
245
246
247 if (dump_rx) {
248 code = snprintf(buf, max,
249 "\nRX%d: %s rxcsr %04x interval %02x "
250 "max %04x type %02x; "
251 "dev %d hub %d port %d"
252 "\n",
253 epnum,
254 hw_ep->rx_double_buffered
255 ? "2buf" : "1buf",
256 musb_readw(regs, MUSB_RXCSR),
257 musb_readb(regs, MUSB_RXINTERVAL),
258 musb_readw(regs, MUSB_RXMAXP),
259 musb_readb(regs, MUSB_RXTYPE),
260 /* FIXME: assumes multipoint */
261 musb_readb(musb->mregs,
262 MUSB_BUSCTL_OFFSET(epnum,
263 MUSB_RXFUNCADDR)),
264 musb_readb(musb->mregs,
265 MUSB_BUSCTL_OFFSET(epnum,
266 MUSB_RXHUBADDR)),
267 musb_readb(musb->mregs,
268 MUSB_BUSCTL_OFFSET(epnum,
269 MUSB_RXHUBPORT))
270 );
271 if (code <= 0)
272 break;
273 code = min(code, (int) max);
274 buf += code;
275 max -= code;
276
277 if (is_cppi_enabled()
278 && epnum
279 && hw_ep->rx_channel) {
280 unsigned cppi = epnum - 1;
281 unsigned off1 = cppi << 2;
282 void __iomem *base;
283 void __iomem *ram;
284 char tmp[16];
285
286 base = musb->ctrl_base;
287 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
288 cppi) + base;
289 snprintf(tmp, sizeof tmp, "%d left, ",
290 musb_readl(base,
291 DAVINCI_RXCPPI_BUFCNT0_REG
292 + off1));
293
294 code = snprintf(buf, max,
295 " rx dma%d: %s"
296 "%08x %08x, %08x %08x; "
297 "%08x %08x %08x .. %08x\n",
298 cppi, tmp,
299 musb_readl(ram, 0 * 4),
300 musb_readl(ram, 1 * 4),
301 musb_readl(ram, 2 * 4),
302 musb_readl(ram, 3 * 4),
303 musb_readl(ram, 4 * 4),
304 musb_readl(ram, 5 * 4),
305 musb_readl(ram, 6 * 4),
306 musb_readl(ram, 7 * 4));
307 if (code <= 0)
308 break;
309 code = min(code, (int) max);
310 buf += code;
311 max -= code;
312 }
313
314 if (hw_ep == musb->bulk_ep
315 && !list_empty(
316 &musb->in_bulk)) {
317 code = dump_queue(&musb->in_bulk,
318 buf, max);
319 if (code <= 0)
320 break;
321 code = min(code, (int) max);
322 buf += code;
323 max -= code;
324 } else if (musb->periodic[epnum]) {
325 code = dump_qh(musb->periodic[epnum],
326 buf, max);
327 if (code <= 0)
328 break;
329 code = min(code, (int) max);
330 buf += code;
331 max -= code;
332 }
333 }
334
335 if (dump_tx) {
336 code = snprintf(buf, max,
337 "\nTX%d: %s txcsr %04x interval %02x "
338 "max %04x type %02x; "
339 "dev %d hub %d port %d"
340 "\n",
341 epnum,
342 hw_ep->tx_double_buffered
343 ? "2buf" : "1buf",
344 musb_readw(regs, MUSB_TXCSR),
345 musb_readb(regs, MUSB_TXINTERVAL),
346 musb_readw(regs, MUSB_TXMAXP),
347 musb_readb(regs, MUSB_TXTYPE),
348 /* FIXME: assumes multipoint */
349 musb_readb(musb->mregs,
350 MUSB_BUSCTL_OFFSET(epnum,
351 MUSB_TXFUNCADDR)),
352 musb_readb(musb->mregs,
353 MUSB_BUSCTL_OFFSET(epnum,
354 MUSB_TXHUBADDR)),
355 musb_readb(musb->mregs,
356 MUSB_BUSCTL_OFFSET(epnum,
357 MUSB_TXHUBPORT))
358 );
359 if (code <= 0)
360 break;
361 code = min(code, (int) max);
362 buf += code;
363 max -= code;
364
365 if (is_cppi_enabled()
366 && epnum
367 && hw_ep->tx_channel) {
368 unsigned cppi = epnum - 1;
369 void __iomem *base;
370 void __iomem *ram;
371
372 base = musb->ctrl_base;
373 ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
374 cppi) + base;
375 code = snprintf(buf, max,
376 " tx dma%d: "
377 "%08x %08x, %08x %08x; "
378 "%08x %08x %08x .. %08x\n",
379 cppi,
380 musb_readl(ram, 0 * 4),
381 musb_readl(ram, 1 * 4),
382 musb_readl(ram, 2 * 4),
383 musb_readl(ram, 3 * 4),
384 musb_readl(ram, 4 * 4),
385 musb_readl(ram, 5 * 4),
386 musb_readl(ram, 6 * 4),
387 musb_readl(ram, 7 * 4));
388 if (code <= 0)
389 break;
390 code = min(code, (int) max);
391 buf += code;
392 max -= code;
393 }
394
395 if (hw_ep == musb->control_ep
396 && !list_empty(
397 &musb->control)) {
398 code = dump_queue(&musb->control,
399 buf, max);
400 if (code <= 0)
401 break;
402 code = min(code, (int) max);
403 buf += code;
404 max -= code;
405 } else if (hw_ep == musb->bulk_ep
406 && !list_empty(
407 &musb->out_bulk)) {
408 code = dump_queue(&musb->out_bulk,
409 buf, max);
410 if (code <= 0)
411 break;
412 code = min(code, (int) max);
413 buf += code;
414 max -= code;
415 } else if (musb->periodic[epnum]) {
416 code = dump_qh(musb->periodic[epnum],
417 buf, max);
418 if (code <= 0)
419 break;
420 code = min(code, (int) max);
421 buf += code;
422 max -= code;
423 }
424 }
425 }
426#endif
427#ifdef CONFIG_USB_GADGET_MUSB_HDRC
428 if (is_peripheral_active(musb)) {
429 code = 0;
430
431 if (hw_ep->ep_in.desc || !epnum) {
432 code = dump_ep(&hw_ep->ep_in, buf, max);
433 if (code <= 0)
434 break;
435 code = min(code, (int) max);
436 buf += code;
437 max -= code;
438 }
439 if (hw_ep->ep_out.desc) {
440 code = dump_ep(&hw_ep->ep_out, buf, max);
441 if (code <= 0)
442 break;
443 code = min(code, (int) max);
444 buf += code;
445 max -= code;
446 }
447 }
448#endif
449 } while (0);
450
451 return buf - aBuffer;
452}
453
454/* Dump the current status and compile options.
455 * @param musb the device driver instance
456 * @param buffer where to dump the status; it must be big enough to hold the
457 * result otherwise "BAD THINGS HAPPENS(TM)".
458 */
459static int dump_header_stats(struct musb *musb, char *buffer)
460{
461 int code, count = 0;
462 const void __iomem *mbase = musb->mregs;
463
464 *buffer = 0;
465 count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
466 "(Power=%02x, DevCtl=%02x)\n",
467 (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
468 musb_readb(mbase, MUSB_POWER),
469 musb_readb(mbase, MUSB_DEVCTL));
470 if (count <= 0)
471 return 0;
472 buffer += count;
473
474 code = sprintf(buffer, "OTG state: %s; %sactive\n",
475 otg_state_string(musb),
476 musb->is_active ? "" : "in");
477 if (code <= 0)
478 goto done;
479 buffer += code;
480 count += code;
481
482 code = sprintf(buffer,
483 "Options: "
484#ifdef CONFIG_MUSB_PIO_ONLY
485 "pio"
486#elif defined(CONFIG_USB_TI_CPPI_DMA)
487 "cppi-dma"
488#elif defined(CONFIG_USB_INVENTRA_DMA)
489 "musb-dma"
490#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
491 "tusb-omap-dma"
492#else
493 "?dma?"
494#endif
495 ", "
496#ifdef CONFIG_USB_MUSB_OTG
497 "otg (peripheral+host)"
498#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
499 "peripheral"
500#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
501 "host"
502#endif
503 ", debug=%d [eps=%d]\n",
504 debug,
505 musb->nr_endpoints);
506 if (code <= 0)
507 goto done;
508 count += code;
509 buffer += code;
510
511#ifdef CONFIG_USB_GADGET_MUSB_HDRC
512 code = sprintf(buffer, "Peripheral address: %02x\n",
513 musb_readb(musb->ctrl_base, MUSB_FADDR));
514 if (code <= 0)
515 goto done;
516 buffer += code;
517 count += code;
518#endif
519
520#ifdef CONFIG_USB_MUSB_HDRC_HCD
521 code = sprintf(buffer, "Root port status: %08x\n",
522 musb->port1_status);
523 if (code <= 0)
524 goto done;
525 buffer += code;
526 count += code;
527#endif
528
529#ifdef CONFIG_ARCH_DAVINCI
530 code = sprintf(buffer,
531 "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
532 "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
533 "\n",
534 musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
535 musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
536 __raw_readl((void __force __iomem *)
537 IO_ADDRESS(USBPHY_CTL_PADDR)),
538 musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
539 musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
540 musb_readl(musb->ctrl_base,
541 DAVINCI_USB_INT_SOURCE_REG),
542 musb_readl(musb->ctrl_base,
543 DAVINCI_USB_INT_MASK_REG));
544 if (code <= 0)
545 goto done;
546 count += code;
547 buffer += code;
548#endif /* DAVINCI */
549
550#ifdef CONFIG_USB_TUSB6010
551 code = sprintf(buffer,
552 "TUSB6010: devconf %08x, phy enable %08x drive %08x"
553 "\n\totg %03x timer %08x"
554 "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
555 "\n",
556 musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
557 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
558 musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
559 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
560 musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
561 musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
562 musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
563 musb_readl(musb->ctrl_base, TUSB_INT_SRC),
564 musb_readl(musb->ctrl_base, TUSB_INT_MASK));
565 if (code <= 0)
566 goto done;
567 count += code;
568 buffer += code;
569#endif /* DAVINCI */
570
571 if (is_cppi_enabled() && musb->dma_controller) {
572 code = sprintf(buffer,
573 "CPPI: txcr=%d txsrc=%01x txena=%01x; "
574 "rxcr=%d rxsrc=%01x rxena=%01x "
575 "\n",
576 musb_readl(musb->ctrl_base,
577 DAVINCI_TXCPPI_CTRL_REG),
578 musb_readl(musb->ctrl_base,
579 DAVINCI_TXCPPI_RAW_REG),
580 musb_readl(musb->ctrl_base,
581 DAVINCI_TXCPPI_INTENAB_REG),
582 musb_readl(musb->ctrl_base,
583 DAVINCI_RXCPPI_CTRL_REG),
584 musb_readl(musb->ctrl_base,
585 DAVINCI_RXCPPI_RAW_REG),
586 musb_readl(musb->ctrl_base,
587 DAVINCI_RXCPPI_INTENAB_REG));
588 if (code <= 0)
589 goto done;
590 count += code;
591 buffer += code;
592 }
593
594#ifdef CONFIG_USB_GADGET_MUSB_HDRC
595 if (is_peripheral_enabled(musb)) {
596 code = sprintf(buffer, "Gadget driver: %s\n",
597 musb->gadget_driver
598 ? musb->gadget_driver->driver.name
599 : "(none)");
600 if (code <= 0)
601 goto done;
602 count += code;
603 buffer += code;
604 }
605#endif
606
607done:
608 return count;
609}
610
611/* Write to ProcFS
612 *
613 * C soft-connect
614 * c soft-disconnect
615 * I enable HS
616 * i disable HS
617 * s stop session
618 * F force session (OTG-unfriendly)
619 * E rElinquish bus (OTG)
620 * H request host mode
621 * h cancel host request
622 * T start sending TEST_PACKET
623 * D<num> set/query the debug level
624 */
625static int musb_proc_write(struct file *file, const char __user *buffer,
626 unsigned long count, void *data)
627{
628 char cmd;
629 u8 reg;
630 struct musb *musb = (struct musb *)data;
631 void __iomem *mbase = musb->mregs;
632
633 /* MOD_INC_USE_COUNT; */
634
635 if (unlikely(copy_from_user(&cmd, buffer, 1)))
636 return -EFAULT;
637
638 switch (cmd) {
639 case 'C':
640 if (mbase) {
641 reg = musb_readb(mbase, MUSB_POWER)
642 | MUSB_POWER_SOFTCONN;
643 musb_writeb(mbase, MUSB_POWER, reg);
644 }
645 break;
646
647 case 'c':
648 if (mbase) {
649 reg = musb_readb(mbase, MUSB_POWER)
650 & ~MUSB_POWER_SOFTCONN;
651 musb_writeb(mbase, MUSB_POWER, reg);
652 }
653 break;
654
655 case 'I':
656 if (mbase) {
657 reg = musb_readb(mbase, MUSB_POWER)
658 | MUSB_POWER_HSENAB;
659 musb_writeb(mbase, MUSB_POWER, reg);
660 }
661 break;
662
663 case 'i':
664 if (mbase) {
665 reg = musb_readb(mbase, MUSB_POWER)
666 & ~MUSB_POWER_HSENAB;
667 musb_writeb(mbase, MUSB_POWER, reg);
668 }
669 break;
670
671 case 'F':
672 reg = musb_readb(mbase, MUSB_DEVCTL);
673 reg |= MUSB_DEVCTL_SESSION;
674 musb_writeb(mbase, MUSB_DEVCTL, reg);
675 break;
676
677 case 'H':
678 if (mbase) {
679 reg = musb_readb(mbase, MUSB_DEVCTL);
680 reg |= MUSB_DEVCTL_HR;
681 musb_writeb(mbase, MUSB_DEVCTL, reg);
682 /* MUSB_HST_MODE( ((struct musb*)data) ); */
683 /* WARNING("Host Mode\n"); */
684 }
685 break;
686
687 case 'h':
688 if (mbase) {
689 reg = musb_readb(mbase, MUSB_DEVCTL);
690 reg &= ~MUSB_DEVCTL_HR;
691 musb_writeb(mbase, MUSB_DEVCTL, reg);
692 }
693 break;
694
695 case 'T':
696 if (mbase) {
697 musb_load_testpacket(musb);
698 musb_writeb(mbase, MUSB_TESTMODE,
699 MUSB_TEST_PACKET);
700 }
701 break;
702
703#if (MUSB_DEBUG > 0)
704 /* set/read debug level */
705 case 'D':{
706 if (count > 1) {
707 char digits[8], *p = digits;
708 int i = 0, level = 0, sign = 1;
709 int len = min(count - 1, (unsigned long)8);
710
711 if (copy_from_user(&digits, &buffer[1], len))
712 return -EFAULT;
713
714 /* optional sign */
715 if (*p == '-') {
716 len -= 1;
717 sign = -sign;
718 p++;
719 }
720
721 /* read it */
722 while (i++ < len && *p > '0' && *p < '9') {
723 level = level * 10 + (*p - '0');
724 p++;
725 }
726
727 level *= sign;
728 DBG(1, "debug level %d\n", level);
729 debug = level;
730 }
731 }
732 break;
733
734
735 case '?':
736 INFO("?: you are seeing it\n");
737 INFO("C/c: soft connect enable/disable\n");
738 INFO("I/i: hispeed enable/disable\n");
739 INFO("F: force session start\n");
740 INFO("H: host mode\n");
741 INFO("T: start sending TEST_PACKET\n");
742 INFO("D: set/read dbug level\n");
743 break;
744#endif
745
746 default:
747 ERR("Command %c not implemented\n", cmd);
748 break;
749 }
750
751 musb_platform_try_idle(musb, 0);
752
753 return count;
754}
755
756static int musb_proc_read(char *page, char **start,
757 off_t off, int count, int *eof, void *data)
758{
759 char *buffer = page;
760 int code = 0;
761 unsigned long flags;
762 struct musb *musb = data;
763 unsigned epnum;
764
765 count -= off;
766 count -= 1; /* for NUL at end */
767 if (count <= 0)
768 return -EINVAL;
769
770 spin_lock_irqsave(&musb->lock, flags);
771
772 code = dump_header_stats(musb, buffer);
773 if (code > 0) {
774 buffer += code;
775 count -= code;
776 }
777
778 /* generate the report for the end points */
779 /* REVISIT ... not unless something's connected! */
780 for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
781 epnum++) {
782 code = dump_end_info(musb, epnum, buffer, count);
783 if (code > 0) {
784 buffer += code;
785 count -= code;
786 }
787 }
788
789 musb_platform_try_idle(musb, 0);
790
791 spin_unlock_irqrestore(&musb->lock, flags);
792 *eof = 1;
793
794 return buffer - page;
795}
796
797void __devexit musb_debug_delete(char *name, struct musb *musb)
798{
799 if (musb->proc_entry)
800 remove_proc_entry(name, NULL);
801}
802
803struct proc_dir_entry *__init
804musb_debug_create(char *name, struct musb *data)
805{
806 struct proc_dir_entry *pde;
807
808 /* FIXME convert everything to seq_file; then later, debugfs */
809
810 if (!name)
811 return NULL;
812
813 pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL);
814 data->proc_entry = pde;
815 if (pde) {
816 pde->data = data;
817 /* pde->owner = THIS_MODULE; */
818
819 pde->read_proc = musb_proc_read;
820 pde->write_proc = musb_proc_write;
821
822 pde->size = 0;
823
824 pr_debug("Registered /proc/%s\n", name);
825 } else {
826 pr_debug("Cannot create a valid proc file entry");
827 }
828
829 return pde;
830}
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
new file mode 100644
index 000000000000..9c228661aa5a
--- /dev/null
+++ b/drivers/usb/musb/musb_regs.h
@@ -0,0 +1,300 @@
1/*
2 * MUSB OTG driver register defines
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#ifndef __MUSB_REGS_H__
36#define __MUSB_REGS_H__
37
38#define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */
39
40/*
41 * Common USB registers
42 */
43
44#define MUSB_FADDR 0x00 /* 8-bit */
45#define MUSB_POWER 0x01 /* 8-bit */
46
47#define MUSB_INTRTX 0x02 /* 16-bit */
48#define MUSB_INTRRX 0x04
49#define MUSB_INTRTXE 0x06
50#define MUSB_INTRRXE 0x08
51#define MUSB_INTRUSB 0x0A /* 8 bit */
52#define MUSB_INTRUSBE 0x0B /* 8 bit */
53#define MUSB_FRAME 0x0C
54#define MUSB_INDEX 0x0E /* 8 bit */
55#define MUSB_TESTMODE 0x0F /* 8 bit */
56
57/* Get offset for a given FIFO from musb->mregs */
58#ifdef CONFIG_USB_TUSB6010
59#define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20))
60#else
61#define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4))
62#endif
63
64/*
65 * Additional Control Registers
66 */
67
68#define MUSB_DEVCTL 0x60 /* 8 bit */
69
70/* These are always controlled through the INDEX register */
71#define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */
72#define MUSB_RXFIFOSZ 0x63 /* 8-bit (see masks) */
73#define MUSB_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */
74#define MUSB_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */
75
76/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */
77#define MUSB_HWVERS 0x6C /* 8 bit */
78
79#define MUSB_EPINFO 0x78 /* 8 bit */
80#define MUSB_RAMINFO 0x79 /* 8 bit */
81#define MUSB_LINKINFO 0x7a /* 8 bit */
82#define MUSB_VPLEN 0x7b /* 8 bit */
83#define MUSB_HS_EOF1 0x7c /* 8 bit */
84#define MUSB_FS_EOF1 0x7d /* 8 bit */
85#define MUSB_LS_EOF1 0x7e /* 8 bit */
86
87/* Offsets to endpoint registers */
88#define MUSB_TXMAXP 0x00
89#define MUSB_TXCSR 0x02
90#define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */
91#define MUSB_RXMAXP 0x04
92#define MUSB_RXCSR 0x06
93#define MUSB_RXCOUNT 0x08
94#define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */
95#define MUSB_TXTYPE 0x0A
96#define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */
97#define MUSB_TXINTERVAL 0x0B
98#define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */
99#define MUSB_RXTYPE 0x0C
100#define MUSB_RXINTERVAL 0x0D
101#define MUSB_FIFOSIZE 0x0F
102#define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */
103
104/* Offsets to endpoint registers in indexed model (using INDEX register) */
105#define MUSB_INDEXED_OFFSET(_epnum, _offset) \
106 (0x10 + (_offset))
107
108/* Offsets to endpoint registers in flat models */
109#define MUSB_FLAT_OFFSET(_epnum, _offset) \
110 (0x100 + (0x10*(_epnum)) + (_offset))
111
112#ifdef CONFIG_USB_TUSB6010
113/* TUSB6010 EP0 configuration register is special */
114#define MUSB_TUSB_OFFSET(_epnum, _offset) \
115 (0x10 + _offset)
116#include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */
117#endif
118
119/* "bus control"/target registers, for host side multipoint (external hubs) */
120#define MUSB_TXFUNCADDR 0x00
121#define MUSB_TXHUBADDR 0x02
122#define MUSB_TXHUBPORT 0x03
123
124#define MUSB_RXFUNCADDR 0x04
125#define MUSB_RXHUBADDR 0x06
126#define MUSB_RXHUBPORT 0x07
127
128#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
129 (0x80 + (8*(_epnum)) + (_offset))
130
131/*
132 * MUSB Register bits
133 */
134
135/* POWER */
136#define MUSB_POWER_ISOUPDATE 0x80
137#define MUSB_POWER_SOFTCONN 0x40
138#define MUSB_POWER_HSENAB 0x20
139#define MUSB_POWER_HSMODE 0x10
140#define MUSB_POWER_RESET 0x08
141#define MUSB_POWER_RESUME 0x04
142#define MUSB_POWER_SUSPENDM 0x02
143#define MUSB_POWER_ENSUSPEND 0x01
144
145/* INTRUSB */
146#define MUSB_INTR_SUSPEND 0x01
147#define MUSB_INTR_RESUME 0x02
148#define MUSB_INTR_RESET 0x04
149#define MUSB_INTR_BABBLE 0x04
150#define MUSB_INTR_SOF 0x08
151#define MUSB_INTR_CONNECT 0x10
152#define MUSB_INTR_DISCONNECT 0x20
153#define MUSB_INTR_SESSREQ 0x40
154#define MUSB_INTR_VBUSERROR 0x80 /* For SESSION end */
155
156/* DEVCTL */
157#define MUSB_DEVCTL_BDEVICE 0x80
158#define MUSB_DEVCTL_FSDEV 0x40
159#define MUSB_DEVCTL_LSDEV 0x20
160#define MUSB_DEVCTL_VBUS 0x18
161#define MUSB_DEVCTL_VBUS_SHIFT 3
162#define MUSB_DEVCTL_HM 0x04
163#define MUSB_DEVCTL_HR 0x02
164#define MUSB_DEVCTL_SESSION 0x01
165
166/* TESTMODE */
167#define MUSB_TEST_FORCE_HOST 0x80
168#define MUSB_TEST_FIFO_ACCESS 0x40
169#define MUSB_TEST_FORCE_FS 0x20
170#define MUSB_TEST_FORCE_HS 0x10
171#define MUSB_TEST_PACKET 0x08
172#define MUSB_TEST_K 0x04
173#define MUSB_TEST_J 0x02
174#define MUSB_TEST_SE0_NAK 0x01
175
176/* Allocate for double-packet buffering (effectively doubles assigned _SIZE) */
177#define MUSB_FIFOSZ_DPB 0x10
178/* Allocation size (8, 16, 32, ... 4096) */
179#define MUSB_FIFOSZ_SIZE 0x0f
180
181/* CSR0 */
182#define MUSB_CSR0_FLUSHFIFO 0x0100
183#define MUSB_CSR0_TXPKTRDY 0x0002
184#define MUSB_CSR0_RXPKTRDY 0x0001
185
186/* CSR0 in Peripheral mode */
187#define MUSB_CSR0_P_SVDSETUPEND 0x0080
188#define MUSB_CSR0_P_SVDRXPKTRDY 0x0040
189#define MUSB_CSR0_P_SENDSTALL 0x0020
190#define MUSB_CSR0_P_SETUPEND 0x0010
191#define MUSB_CSR0_P_DATAEND 0x0008
192#define MUSB_CSR0_P_SENTSTALL 0x0004
193
194/* CSR0 in Host mode */
195#define MUSB_CSR0_H_DIS_PING 0x0800
196#define MUSB_CSR0_H_WR_DATATOGGLE 0x0400 /* Set to allow setting: */
197#define MUSB_CSR0_H_DATATOGGLE 0x0200 /* Data toggle control */
198#define MUSB_CSR0_H_NAKTIMEOUT 0x0080
199#define MUSB_CSR0_H_STATUSPKT 0x0040
200#define MUSB_CSR0_H_REQPKT 0x0020
201#define MUSB_CSR0_H_ERROR 0x0010
202#define MUSB_CSR0_H_SETUPPKT 0x0008
203#define MUSB_CSR0_H_RXSTALL 0x0004
204
205/* CSR0 bits to avoid zeroing (write zero clears, write 1 ignored) */
206#define MUSB_CSR0_P_WZC_BITS \
207 (MUSB_CSR0_P_SENTSTALL)
208#define MUSB_CSR0_H_WZC_BITS \
209 (MUSB_CSR0_H_NAKTIMEOUT | MUSB_CSR0_H_RXSTALL \
210 | MUSB_CSR0_RXPKTRDY)
211
212/* TxType/RxType */
213#define MUSB_TYPE_SPEED 0xc0
214#define MUSB_TYPE_SPEED_SHIFT 6
215#define MUSB_TYPE_PROTO 0x30 /* Implicitly zero for ep0 */
216#define MUSB_TYPE_PROTO_SHIFT 4
217#define MUSB_TYPE_REMOTE_END 0xf /* Implicitly zero for ep0 */
218
219/* CONFIGDATA */
220#define MUSB_CONFIGDATA_MPRXE 0x80 /* Auto bulk pkt combining */
221#define MUSB_CONFIGDATA_MPTXE 0x40 /* Auto bulk pkt splitting */
222#define MUSB_CONFIGDATA_BIGENDIAN 0x20
223#define MUSB_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */
224#define MUSB_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */
225#define MUSB_CONFIGDATA_DYNFIFO 0x04 /* Dynamic FIFO sizing */
226#define MUSB_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */
227#define MUSB_CONFIGDATA_UTMIDW 0x01 /* Data width 0/1 => 8/16bits */
228
229/* TXCSR in Peripheral and Host mode */
230#define MUSB_TXCSR_AUTOSET 0x8000
231#define MUSB_TXCSR_MODE 0x2000
232#define MUSB_TXCSR_DMAENAB 0x1000
233#define MUSB_TXCSR_FRCDATATOG 0x0800
234#define MUSB_TXCSR_DMAMODE 0x0400
235#define MUSB_TXCSR_CLRDATATOG 0x0040
236#define MUSB_TXCSR_FLUSHFIFO 0x0008
237#define MUSB_TXCSR_FIFONOTEMPTY 0x0002
238#define MUSB_TXCSR_TXPKTRDY 0x0001
239
240/* TXCSR in Peripheral mode */
241#define MUSB_TXCSR_P_ISO 0x4000
242#define MUSB_TXCSR_P_INCOMPTX 0x0080
243#define MUSB_TXCSR_P_SENTSTALL 0x0020
244#define MUSB_TXCSR_P_SENDSTALL 0x0010
245#define MUSB_TXCSR_P_UNDERRUN 0x0004
246
247/* TXCSR in Host mode */
248#define MUSB_TXCSR_H_WR_DATATOGGLE 0x0200
249#define MUSB_TXCSR_H_DATATOGGLE 0x0100
250#define MUSB_TXCSR_H_NAKTIMEOUT 0x0080
251#define MUSB_TXCSR_H_RXSTALL 0x0020
252#define MUSB_TXCSR_H_ERROR 0x0004
253
254/* TXCSR bits to avoid zeroing (write zero clears, write 1 ignored) */
255#define MUSB_TXCSR_P_WZC_BITS \
256 (MUSB_TXCSR_P_INCOMPTX | MUSB_TXCSR_P_SENTSTALL \
257 | MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_FIFONOTEMPTY)
258#define MUSB_TXCSR_H_WZC_BITS \
259 (MUSB_TXCSR_H_NAKTIMEOUT | MUSB_TXCSR_H_RXSTALL \
260 | MUSB_TXCSR_H_ERROR | MUSB_TXCSR_FIFONOTEMPTY)
261
262/* RXCSR in Peripheral and Host mode */
263#define MUSB_RXCSR_AUTOCLEAR 0x8000
264#define MUSB_RXCSR_DMAENAB 0x2000
265#define MUSB_RXCSR_DISNYET 0x1000
266#define MUSB_RXCSR_PID_ERR 0x1000
267#define MUSB_RXCSR_DMAMODE 0x0800
268#define MUSB_RXCSR_INCOMPRX 0x0100
269#define MUSB_RXCSR_CLRDATATOG 0x0080
270#define MUSB_RXCSR_FLUSHFIFO 0x0010
271#define MUSB_RXCSR_DATAERROR 0x0008
272#define MUSB_RXCSR_FIFOFULL 0x0002
273#define MUSB_RXCSR_RXPKTRDY 0x0001
274
275/* RXCSR in Peripheral mode */
276#define MUSB_RXCSR_P_ISO 0x4000
277#define MUSB_RXCSR_P_SENTSTALL 0x0040
278#define MUSB_RXCSR_P_SENDSTALL 0x0020
279#define MUSB_RXCSR_P_OVERRUN 0x0004
280
281/* RXCSR in Host mode */
282#define MUSB_RXCSR_H_AUTOREQ 0x4000
283#define MUSB_RXCSR_H_WR_DATATOGGLE 0x0400
284#define MUSB_RXCSR_H_DATATOGGLE 0x0200
285#define MUSB_RXCSR_H_RXSTALL 0x0040
286#define MUSB_RXCSR_H_REQPKT 0x0020
287#define MUSB_RXCSR_H_ERROR 0x0004
288
289/* RXCSR bits to avoid zeroing (write zero clears, write 1 ignored) */
290#define MUSB_RXCSR_P_WZC_BITS \
291 (MUSB_RXCSR_P_SENTSTALL | MUSB_RXCSR_P_OVERRUN \
292 | MUSB_RXCSR_RXPKTRDY)
293#define MUSB_RXCSR_H_WZC_BITS \
294 (MUSB_RXCSR_H_RXSTALL | MUSB_RXCSR_H_ERROR \
295 | MUSB_RXCSR_DATAERROR | MUSB_RXCSR_RXPKTRDY)
296
297/* HUBADDR */
298#define MUSB_HUBADDR_MULTI_TT 0x80
299
300#endif /* __MUSB_REGS_H__ */
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
new file mode 100644
index 000000000000..e0e9ce584175
--- /dev/null
+++ b/drivers/usb/musb/musb_virthub.c
@@ -0,0 +1,425 @@
1/*
2 * MUSB OTG driver virtual root hub support
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/sched.h>
38#include <linux/slab.h>
39#include <linux/errno.h>
40#include <linux/init.h>
41#include <linux/time.h>
42#include <linux/timer.h>
43
44#include <asm/unaligned.h>
45
46#include "musb_core.h"
47
48
49static void musb_port_suspend(struct musb *musb, bool do_suspend)
50{
51 u8 power;
52 void __iomem *mbase = musb->mregs;
53
54 if (!is_host_active(musb))
55 return;
56
57 /* NOTE: this doesn't necessarily put PHY into low power mode,
58 * turning off its clock; that's a function of PHY integration and
59 * MUSB_POWER_ENSUSPEND. PHY may need a clock (sigh) to detect
60 * SE0 changing to connect (J) or wakeup (K) states.
61 */
62 power = musb_readb(mbase, MUSB_POWER);
63 if (do_suspend) {
64 int retries = 10000;
65
66 power &= ~MUSB_POWER_RESUME;
67 power |= MUSB_POWER_SUSPENDM;
68 musb_writeb(mbase, MUSB_POWER, power);
69
70 /* Needed for OPT A tests */
71 power = musb_readb(mbase, MUSB_POWER);
72 while (power & MUSB_POWER_SUSPENDM) {
73 power = musb_readb(mbase, MUSB_POWER);
74 if (retries-- < 1)
75 break;
76 }
77
78 DBG(3, "Root port suspended, power %02x\n", power);
79
80 musb->port1_status |= USB_PORT_STAT_SUSPEND;
81 switch (musb->xceiv.state) {
82 case OTG_STATE_A_HOST:
83 musb->xceiv.state = OTG_STATE_A_SUSPEND;
84 musb->is_active = is_otg_enabled(musb)
85 && musb->xceiv.host->b_hnp_enable;
86 musb_platform_try_idle(musb, 0);
87 break;
88#ifdef CONFIG_USB_MUSB_OTG
89 case OTG_STATE_B_HOST:
90 musb->xceiv.state = OTG_STATE_B_WAIT_ACON;
91 musb->is_active = is_otg_enabled(musb)
92 && musb->xceiv.host->b_hnp_enable;
93 musb_platform_try_idle(musb, 0);
94 break;
95#endif
96 default:
97 DBG(1, "bogus rh suspend? %s\n",
98 otg_state_string(musb));
99 }
100 } else if (power & MUSB_POWER_SUSPENDM) {
101 power &= ~MUSB_POWER_SUSPENDM;
102 power |= MUSB_POWER_RESUME;
103 musb_writeb(mbase, MUSB_POWER, power);
104
105 DBG(3, "Root port resuming, power %02x\n", power);
106
107 /* later, GetPortStatus will stop RESUME signaling */
108 musb->port1_status |= MUSB_PORT_STAT_RESUME;
109 musb->rh_timer = jiffies + msecs_to_jiffies(20);
110 }
111}
112
113static void musb_port_reset(struct musb *musb, bool do_reset)
114{
115 u8 power;
116 void __iomem *mbase = musb->mregs;
117
118#ifdef CONFIG_USB_MUSB_OTG
119 if (musb->xceiv.state == OTG_STATE_B_IDLE) {
120 DBG(2, "HNP: Returning from HNP; no hub reset from b_idle\n");
121 musb->port1_status &= ~USB_PORT_STAT_RESET;
122 return;
123 }
124#endif
125
126 if (!is_host_active(musb))
127 return;
128
129 /* NOTE: caller guarantees it will turn off the reset when
130 * the appropriate amount of time has passed
131 */
132 power = musb_readb(mbase, MUSB_POWER);
133 if (do_reset) {
134
135 /*
136 * If RESUME is set, we must make sure it stays minimum 20 ms.
137 * Then we must clear RESUME and wait a bit to let musb start
138 * generating SOFs. If we don't do this, OPT HS A 6.8 tests
139 * fail with "Error! Did not receive an SOF before suspend
140 * detected".
141 */
142 if (power & MUSB_POWER_RESUME) {
143 while (time_before(jiffies, musb->rh_timer))
144 msleep(1);
145 musb_writeb(mbase, MUSB_POWER,
146 power & ~MUSB_POWER_RESUME);
147 msleep(1);
148 }
149
150 musb->ignore_disconnect = true;
151 power &= 0xf0;
152 musb_writeb(mbase, MUSB_POWER,
153 power | MUSB_POWER_RESET);
154
155 musb->port1_status |= USB_PORT_STAT_RESET;
156 musb->port1_status &= ~USB_PORT_STAT_ENABLE;
157 musb->rh_timer = jiffies + msecs_to_jiffies(50);
158 } else {
159 DBG(4, "root port reset stopped\n");
160 musb_writeb(mbase, MUSB_POWER,
161 power & ~MUSB_POWER_RESET);
162
163 musb->ignore_disconnect = false;
164
165 power = musb_readb(mbase, MUSB_POWER);
166 if (power & MUSB_POWER_HSMODE) {
167 DBG(4, "high-speed device connected\n");
168 musb->port1_status |= USB_PORT_STAT_HIGH_SPEED;
169 }
170
171 musb->port1_status &= ~USB_PORT_STAT_RESET;
172 musb->port1_status |= USB_PORT_STAT_ENABLE
173 | (USB_PORT_STAT_C_RESET << 16)
174 | (USB_PORT_STAT_C_ENABLE << 16);
175 usb_hcd_poll_rh_status(musb_to_hcd(musb));
176
177 musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
178 }
179}
180
181void musb_root_disconnect(struct musb *musb)
182{
183 musb->port1_status = (1 << USB_PORT_FEAT_POWER)
184 | (1 << USB_PORT_FEAT_C_CONNECTION);
185
186 usb_hcd_poll_rh_status(musb_to_hcd(musb));
187 musb->is_active = 0;
188
189 switch (musb->xceiv.state) {
190 case OTG_STATE_A_HOST:
191 case OTG_STATE_A_SUSPEND:
192 musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
193 musb->is_active = 0;
194 break;
195 case OTG_STATE_A_WAIT_VFALL:
196 musb->xceiv.state = OTG_STATE_B_IDLE;
197 break;
198 default:
199 DBG(1, "host disconnect (%s)\n", otg_state_string(musb));
200 }
201}
202
203
204/*---------------------------------------------------------------------*/
205
206/* Caller may or may not hold musb->lock */
207int musb_hub_status_data(struct usb_hcd *hcd, char *buf)
208{
209 struct musb *musb = hcd_to_musb(hcd);
210 int retval = 0;
211
212 /* called in_irq() via usb_hcd_poll_rh_status() */
213 if (musb->port1_status & 0xffff0000) {
214 *buf = 0x02;
215 retval = 1;
216 }
217 return retval;
218}
219
220int musb_hub_control(
221 struct usb_hcd *hcd,
222 u16 typeReq,
223 u16 wValue,
224 u16 wIndex,
225 char *buf,
226 u16 wLength)
227{
228 struct musb *musb = hcd_to_musb(hcd);
229 u32 temp;
230 int retval = 0;
231 unsigned long flags;
232
233 spin_lock_irqsave(&musb->lock, flags);
234
235 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
236 spin_unlock_irqrestore(&musb->lock, flags);
237 return -ESHUTDOWN;
238 }
239
240 /* hub features: always zero, setting is a NOP
241 * port features: reported, sometimes updated when host is active
242 * no indicators
243 */
244 switch (typeReq) {
245 case ClearHubFeature:
246 case SetHubFeature:
247 switch (wValue) {
248 case C_HUB_OVER_CURRENT:
249 case C_HUB_LOCAL_POWER:
250 break;
251 default:
252 goto error;
253 }
254 break;
255 case ClearPortFeature:
256 if ((wIndex & 0xff) != 1)
257 goto error;
258
259 switch (wValue) {
260 case USB_PORT_FEAT_ENABLE:
261 break;
262 case USB_PORT_FEAT_SUSPEND:
263 musb_port_suspend(musb, false);
264 break;
265 case USB_PORT_FEAT_POWER:
266 if (!(is_otg_enabled(musb) && hcd->self.is_b_host))
267 musb_set_vbus(musb, 0);
268 break;
269 case USB_PORT_FEAT_C_CONNECTION:
270 case USB_PORT_FEAT_C_ENABLE:
271 case USB_PORT_FEAT_C_OVER_CURRENT:
272 case USB_PORT_FEAT_C_RESET:
273 case USB_PORT_FEAT_C_SUSPEND:
274 break;
275 default:
276 goto error;
277 }
278 DBG(5, "clear feature %d\n", wValue);
279 musb->port1_status &= ~(1 << wValue);
280 break;
281 case GetHubDescriptor:
282 {
283 struct usb_hub_descriptor *desc = (void *)buf;
284
285 desc->bDescLength = 9;
286 desc->bDescriptorType = 0x29;
287 desc->bNbrPorts = 1;
288 desc->wHubCharacteristics = __constant_cpu_to_le16(
289 0x0001 /* per-port power switching */
290 | 0x0010 /* no overcurrent reporting */
291 );
292 desc->bPwrOn2PwrGood = 5; /* msec/2 */
293 desc->bHubContrCurrent = 0;
294
295 /* workaround bogus struct definition */
296 desc->DeviceRemovable[0] = 0x02; /* port 1 */
297 desc->DeviceRemovable[1] = 0xff;
298 }
299 break;
300 case GetHubStatus:
301 temp = 0;
302 *(__le32 *) buf = cpu_to_le32(temp);
303 break;
304 case GetPortStatus:
305 if (wIndex != 1)
306 goto error;
307
308 /* finish RESET signaling? */
309 if ((musb->port1_status & USB_PORT_STAT_RESET)
310 && time_after_eq(jiffies, musb->rh_timer))
311 musb_port_reset(musb, false);
312
313 /* finish RESUME signaling? */
314 if ((musb->port1_status & MUSB_PORT_STAT_RESUME)
315 && time_after_eq(jiffies, musb->rh_timer)) {
316 u8 power;
317
318 power = musb_readb(musb->mregs, MUSB_POWER);
319 power &= ~MUSB_POWER_RESUME;
320 DBG(4, "root port resume stopped, power %02x\n",
321 power);
322 musb_writeb(musb->mregs, MUSB_POWER, power);
323
324 /* ISSUE: DaVinci (RTL 1.300) disconnects after
325 * resume of high speed peripherals (but not full
326 * speed ones).
327 */
328
329 musb->is_active = 1;
330 musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
331 | MUSB_PORT_STAT_RESUME);
332 musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
333 usb_hcd_poll_rh_status(musb_to_hcd(musb));
334 /* NOTE: it might really be A_WAIT_BCON ... */
335 musb->xceiv.state = OTG_STATE_A_HOST;
336 }
337
338 put_unaligned(cpu_to_le32(musb->port1_status
339 & ~MUSB_PORT_STAT_RESUME),
340 (__le32 *) buf);
341
342 /* port change status is more interesting */
343 DBG(get_unaligned((u16 *)(buf+2)) ? 2 : 5, "port status %08x\n",
344 musb->port1_status);
345 break;
346 case SetPortFeature:
347 if ((wIndex & 0xff) != 1)
348 goto error;
349
350 switch (wValue) {
351 case USB_PORT_FEAT_POWER:
352 /* NOTE: this controller has a strange state machine
353 * that involves "requesting sessions" according to
354 * magic side effects from incompletely-described
355 * rules about startup...
356 *
357 * This call is what really starts the host mode; be
358 * very careful about side effects if you reorder any
359 * initialization logic, e.g. for OTG, or change any
360 * logic relating to VBUS power-up.
361 */
362 if (!(is_otg_enabled(musb) && hcd->self.is_b_host))
363 musb_start(musb);
364 break;
365 case USB_PORT_FEAT_RESET:
366 musb_port_reset(musb, true);
367 break;
368 case USB_PORT_FEAT_SUSPEND:
369 musb_port_suspend(musb, true);
370 break;
371 case USB_PORT_FEAT_TEST:
372 if (unlikely(is_host_active(musb)))
373 goto error;
374
375 wIndex >>= 8;
376 switch (wIndex) {
377 case 1:
378 pr_debug("TEST_J\n");
379 temp = MUSB_TEST_J;
380 break;
381 case 2:
382 pr_debug("TEST_K\n");
383 temp = MUSB_TEST_K;
384 break;
385 case 3:
386 pr_debug("TEST_SE0_NAK\n");
387 temp = MUSB_TEST_SE0_NAK;
388 break;
389 case 4:
390 pr_debug("TEST_PACKET\n");
391 temp = MUSB_TEST_PACKET;
392 musb_load_testpacket(musb);
393 break;
394 case 5:
395 pr_debug("TEST_FORCE_ENABLE\n");
396 temp = MUSB_TEST_FORCE_HOST
397 | MUSB_TEST_FORCE_HS;
398
399 musb_writeb(musb->mregs, MUSB_DEVCTL,
400 MUSB_DEVCTL_SESSION);
401 break;
402 case 6:
403 pr_debug("TEST_FIFO_ACCESS\n");
404 temp = MUSB_TEST_FIFO_ACCESS;
405 break;
406 default:
407 goto error;
408 }
409 musb_writeb(musb->mregs, MUSB_TESTMODE, temp);
410 break;
411 default:
412 goto error;
413 }
414 DBG(5, "set feature %d\n", wValue);
415 musb->port1_status |= 1 << wValue;
416 break;
417
418 default:
419error:
420 /* "protocol stall" on error */
421 retval = -EPIPE;
422 }
423 spin_unlock_irqrestore(&musb->lock, flags);
424 return retval;
425}
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
new file mode 100644
index 000000000000..9ba8fb7fcd24
--- /dev/null
+++ b/drivers/usb/musb/musbhsdma.c
@@ -0,0 +1,433 @@
1/*
2 * MUSB OTG driver - support for Mentor's DMA controller
3 *
4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2007 by Texas Instruments
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
24 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33#include <linux/device.h>
34#include <linux/interrupt.h>
35#include <linux/platform_device.h>
36#include "musb_core.h"
37
38#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
39#include "omap2430.h"
40#endif
41
42#define MUSB_HSDMA_BASE 0x200
43#define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0)
44#define MUSB_HSDMA_CONTROL 0x4
45#define MUSB_HSDMA_ADDRESS 0x8
46#define MUSB_HSDMA_COUNT 0xc
47
48#define MUSB_HSDMA_CHANNEL_OFFSET(_bChannel, _offset) \
49 (MUSB_HSDMA_BASE + (_bChannel << 4) + _offset)
50
51/* control register (16-bit): */
52#define MUSB_HSDMA_ENABLE_SHIFT 0
53#define MUSB_HSDMA_TRANSMIT_SHIFT 1
54#define MUSB_HSDMA_MODE1_SHIFT 2
55#define MUSB_HSDMA_IRQENABLE_SHIFT 3
56#define MUSB_HSDMA_ENDPOINT_SHIFT 4
57#define MUSB_HSDMA_BUSERROR_SHIFT 8
58#define MUSB_HSDMA_BURSTMODE_SHIFT 9
59#define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
60#define MUSB_HSDMA_BURSTMODE_UNSPEC 0
61#define MUSB_HSDMA_BURSTMODE_INCR4 1
62#define MUSB_HSDMA_BURSTMODE_INCR8 2
63#define MUSB_HSDMA_BURSTMODE_INCR16 3
64
65#define MUSB_HSDMA_CHANNELS 8
66
67struct musb_dma_controller;
68
69struct musb_dma_channel {
70 struct dma_channel Channel;
71 struct musb_dma_controller *controller;
72 u32 dwStartAddress;
73 u32 len;
74 u16 wMaxPacketSize;
75 u8 bIndex;
76 u8 epnum;
77 u8 transmit;
78};
79
80struct musb_dma_controller {
81 struct dma_controller Controller;
82 struct musb_dma_channel aChannel[MUSB_HSDMA_CHANNELS];
83 void *pDmaPrivate;
84 void __iomem *pCoreBase;
85 u8 bChannelCount;
86 u8 bmUsedChannels;
87 u8 irq;
88};
89
90static int dma_controller_start(struct dma_controller *c)
91{
92 /* nothing to do */
93 return 0;
94}
95
96static void dma_channel_release(struct dma_channel *pChannel);
97
98static int dma_controller_stop(struct dma_controller *c)
99{
100 struct musb_dma_controller *controller =
101 container_of(c, struct musb_dma_controller, Controller);
102 struct musb *musb = (struct musb *) controller->pDmaPrivate;
103 struct dma_channel *pChannel;
104 u8 bBit;
105
106 if (controller->bmUsedChannels != 0) {
107 dev_err(musb->controller,
108 "Stopping DMA controller while channel active\n");
109
110 for (bBit = 0; bBit < MUSB_HSDMA_CHANNELS; bBit++) {
111 if (controller->bmUsedChannels & (1 << bBit)) {
112 pChannel = &controller->aChannel[bBit].Channel;
113 dma_channel_release(pChannel);
114
115 if (!controller->bmUsedChannels)
116 break;
117 }
118 }
119 }
120 return 0;
121}
122
123static struct dma_channel *dma_channel_allocate(struct dma_controller *c,
124 struct musb_hw_ep *hw_ep, u8 transmit)
125{
126 u8 bBit;
127 struct dma_channel *pChannel = NULL;
128 struct musb_dma_channel *pImplChannel = NULL;
129 struct musb_dma_controller *controller =
130 container_of(c, struct musb_dma_controller, Controller);
131
132 for (bBit = 0; bBit < MUSB_HSDMA_CHANNELS; bBit++) {
133 if (!(controller->bmUsedChannels & (1 << bBit))) {
134 controller->bmUsedChannels |= (1 << bBit);
135 pImplChannel = &(controller->aChannel[bBit]);
136 pImplChannel->controller = controller;
137 pImplChannel->bIndex = bBit;
138 pImplChannel->epnum = hw_ep->epnum;
139 pImplChannel->transmit = transmit;
140 pChannel = &(pImplChannel->Channel);
141 pChannel->private_data = pImplChannel;
142 pChannel->status = MUSB_DMA_STATUS_FREE;
143 pChannel->max_len = 0x10000;
144 /* Tx => mode 1; Rx => mode 0 */
145 pChannel->desired_mode = transmit;
146 pChannel->actual_len = 0;
147 break;
148 }
149 }
150 return pChannel;
151}
152
153static void dma_channel_release(struct dma_channel *pChannel)
154{
155 struct musb_dma_channel *pImplChannel =
156 (struct musb_dma_channel *) pChannel->private_data;
157
158 pChannel->actual_len = 0;
159 pImplChannel->dwStartAddress = 0;
160 pImplChannel->len = 0;
161
162 pImplChannel->controller->bmUsedChannels &=
163 ~(1 << pImplChannel->bIndex);
164
165 pChannel->status = MUSB_DMA_STATUS_UNKNOWN;
166}
167
168static void configure_channel(struct dma_channel *pChannel,
169 u16 packet_sz, u8 mode,
170 dma_addr_t dma_addr, u32 len)
171{
172 struct musb_dma_channel *pImplChannel =
173 (struct musb_dma_channel *) pChannel->private_data;
174 struct musb_dma_controller *controller = pImplChannel->controller;
175 void __iomem *mbase = controller->pCoreBase;
176 u8 bChannel = pImplChannel->bIndex;
177 u16 csr = 0;
178
179 DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
180 pChannel, packet_sz, dma_addr, len, mode);
181
182 if (mode) {
183 csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
184 BUG_ON(len < packet_sz);
185
186 if (packet_sz >= 64) {
187 csr |= MUSB_HSDMA_BURSTMODE_INCR16
188 << MUSB_HSDMA_BURSTMODE_SHIFT;
189 } else if (packet_sz >= 32) {
190 csr |= MUSB_HSDMA_BURSTMODE_INCR8
191 << MUSB_HSDMA_BURSTMODE_SHIFT;
192 } else if (packet_sz >= 16) {
193 csr |= MUSB_HSDMA_BURSTMODE_INCR4
194 << MUSB_HSDMA_BURSTMODE_SHIFT;
195 }
196 }
197
198 csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
199 | (1 << MUSB_HSDMA_ENABLE_SHIFT)
200 | (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
201 | (pImplChannel->transmit
202 ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
203 : 0);
204
205 /* address/count */
206 musb_writel(mbase,
207 MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS),
208 dma_addr);
209 musb_writel(mbase,
210 MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT),
211 len);
212
213 /* control (this should start things) */
214 musb_writew(mbase,
215 MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL),
216 csr);
217}
218
219static int dma_channel_program(struct dma_channel *pChannel,
220 u16 packet_sz, u8 mode,
221 dma_addr_t dma_addr, u32 len)
222{
223 struct musb_dma_channel *pImplChannel =
224 (struct musb_dma_channel *) pChannel->private_data;
225
226 DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
227 pImplChannel->epnum,
228 pImplChannel->transmit ? "Tx" : "Rx",
229 packet_sz, dma_addr, len, mode);
230
231 BUG_ON(pChannel->status == MUSB_DMA_STATUS_UNKNOWN ||
232 pChannel->status == MUSB_DMA_STATUS_BUSY);
233
234 pChannel->actual_len = 0;
235 pImplChannel->dwStartAddress = dma_addr;
236 pImplChannel->len = len;
237 pImplChannel->wMaxPacketSize = packet_sz;
238 pChannel->status = MUSB_DMA_STATUS_BUSY;
239
240 if ((mode == 1) && (len >= packet_sz))
241 configure_channel(pChannel, packet_sz, 1, dma_addr, len);
242 else
243 configure_channel(pChannel, packet_sz, 0, dma_addr, len);
244
245 return true;
246}
247
248static int dma_channel_abort(struct dma_channel *pChannel)
249{
250 struct musb_dma_channel *pImplChannel =
251 (struct musb_dma_channel *) pChannel->private_data;
252 u8 bChannel = pImplChannel->bIndex;
253 void __iomem *mbase = pImplChannel->controller->pCoreBase;
254 u16 csr;
255
256 if (pChannel->status == MUSB_DMA_STATUS_BUSY) {
257 if (pImplChannel->transmit) {
258
259 csr = musb_readw(mbase,
260 MUSB_EP_OFFSET(pImplChannel->epnum,
261 MUSB_TXCSR));
262 csr &= ~(MUSB_TXCSR_AUTOSET |
263 MUSB_TXCSR_DMAENAB |
264 MUSB_TXCSR_DMAMODE);
265 musb_writew(mbase,
266 MUSB_EP_OFFSET(pImplChannel->epnum,
267 MUSB_TXCSR),
268 csr);
269 } else {
270 csr = musb_readw(mbase,
271 MUSB_EP_OFFSET(pImplChannel->epnum,
272 MUSB_RXCSR));
273 csr &= ~(MUSB_RXCSR_AUTOCLEAR |
274 MUSB_RXCSR_DMAENAB |
275 MUSB_RXCSR_DMAMODE);
276 musb_writew(mbase,
277 MUSB_EP_OFFSET(pImplChannel->epnum,
278 MUSB_RXCSR),
279 csr);
280 }
281
282 musb_writew(mbase,
283 MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL),
284 0);
285 musb_writel(mbase,
286 MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS),
287 0);
288 musb_writel(mbase,
289 MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT),
290 0);
291
292 pChannel->status = MUSB_DMA_STATUS_FREE;
293 }
294 return 0;
295}
296
297static irqreturn_t dma_controller_irq(int irq, void *private_data)
298{
299 struct musb_dma_controller *controller =
300 (struct musb_dma_controller *)private_data;
301 struct musb_dma_channel *pImplChannel;
302 struct musb *musb = controller->pDmaPrivate;
303 void __iomem *mbase = controller->pCoreBase;
304 struct dma_channel *pChannel;
305 u8 bChannel;
306 u16 csr;
307 u32 dwAddress;
308 u8 int_hsdma;
309 irqreturn_t retval = IRQ_NONE;
310 unsigned long flags;
311
312 spin_lock_irqsave(&musb->lock, flags);
313
314 int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
315 if (!int_hsdma)
316 goto done;
317
318 for (bChannel = 0; bChannel < MUSB_HSDMA_CHANNELS; bChannel++) {
319 if (int_hsdma & (1 << bChannel)) {
320 pImplChannel = (struct musb_dma_channel *)
321 &(controller->aChannel[bChannel]);
322 pChannel = &pImplChannel->Channel;
323
324 csr = musb_readw(mbase,
325 MUSB_HSDMA_CHANNEL_OFFSET(bChannel,
326 MUSB_HSDMA_CONTROL));
327
328 if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT))
329 pImplChannel->Channel.status =
330 MUSB_DMA_STATUS_BUS_ABORT;
331 else {
332 u8 devctl;
333
334 dwAddress = musb_readl(mbase,
335 MUSB_HSDMA_CHANNEL_OFFSET(
336 bChannel,
337 MUSB_HSDMA_ADDRESS));
338 pChannel->actual_len = dwAddress
339 - pImplChannel->dwStartAddress;
340
341 DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
342 pChannel, pImplChannel->dwStartAddress,
343 dwAddress, pChannel->actual_len,
344 pImplChannel->len,
345 (pChannel->actual_len
346 < pImplChannel->len) ?
347 "=> reconfig 0" : "=> complete");
348
349 devctl = musb_readb(mbase, MUSB_DEVCTL);
350
351 pChannel->status = MUSB_DMA_STATUS_FREE;
352
353 /* completed */
354 if ((devctl & MUSB_DEVCTL_HM)
355 && (pImplChannel->transmit)
356 && ((pChannel->desired_mode == 0)
357 || (pChannel->actual_len &
358 (pImplChannel->wMaxPacketSize - 1)))
359 ) {
360 /* Send out the packet */
361 musb_ep_select(mbase,
362 pImplChannel->epnum);
363 musb_writew(mbase, MUSB_EP_OFFSET(
364 pImplChannel->epnum,
365 MUSB_TXCSR),
366 MUSB_TXCSR_TXPKTRDY);
367 } else
368 musb_dma_completion(
369 musb,
370 pImplChannel->epnum,
371 pImplChannel->transmit);
372 }
373 }
374 }
375 retval = IRQ_HANDLED;
376done:
377 spin_unlock_irqrestore(&musb->lock, flags);
378 return retval;
379}
380
381void dma_controller_destroy(struct dma_controller *c)
382{
383 struct musb_dma_controller *controller;
384
385 controller = container_of(c, struct musb_dma_controller, Controller);
386 if (!controller)
387 return;
388
389 if (controller->irq)
390 free_irq(controller->irq, c);
391
392 kfree(controller);
393}
394
395struct dma_controller *__init
396dma_controller_create(struct musb *musb, void __iomem *pCoreBase)
397{
398 struct musb_dma_controller *controller;
399 struct device *dev = musb->controller;
400 struct platform_device *pdev = to_platform_device(dev);
401 int irq = platform_get_irq(pdev, 1);
402
403 if (irq == 0) {
404 dev_err(dev, "No DMA interrupt line!\n");
405 return NULL;
406 }
407
408 controller = kzalloc(sizeof(struct musb_dma_controller), GFP_KERNEL);
409 if (!controller)
410 return NULL;
411
412 controller->bChannelCount = MUSB_HSDMA_CHANNELS;
413 controller->pDmaPrivate = musb;
414 controller->pCoreBase = pCoreBase;
415
416 controller->Controller.start = dma_controller_start;
417 controller->Controller.stop = dma_controller_stop;
418 controller->Controller.channel_alloc = dma_channel_allocate;
419 controller->Controller.channel_release = dma_channel_release;
420 controller->Controller.channel_program = dma_channel_program;
421 controller->Controller.channel_abort = dma_channel_abort;
422
423 if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
424 musb->controller->bus_id, &controller->Controller)) {
425 dev_err(dev, "request_irq %d failed!\n", irq);
426 dma_controller_destroy(&controller->Controller);
427 return NULL;
428 }
429
430 controller->irq = irq;
431
432 return &controller->Controller;
433}
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
new file mode 100644
index 000000000000..298b22e6ad0d
--- /dev/null
+++ b/drivers/usb/musb/omap2430.c
@@ -0,0 +1,324 @@
1/*
2 * Copyright (C) 2005-2007 by Texas Instruments
3 * Some code has been taken from tusb6010.c
4 * Copyrights for that are attributable to:
5 * Copyright (C) 2006 Nokia Corporation
6 * Jarkko Nikula <jarkko.nikula@nokia.com>
7 * Tony Lindgren <tony@atomide.com>
8 *
9 * This file is part of the Inventra Controller Driver for Linux.
10 *
11 * The Inventra Controller Driver for Linux is free software; you
12 * can redistribute it and/or modify it under the terms of the GNU
13 * General Public License version 2 as published by the Free Software
14 * Foundation.
15 *
16 * The Inventra Controller Driver for Linux is distributed in
17 * the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20 * License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with The Inventra Controller Driver for Linux ; if not,
24 * write to the Free Software Foundation, Inc., 59 Temple Place,
25 * Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/sched.h>
31#include <linux/slab.h>
32#include <linux/init.h>
33#include <linux/list.h>
34#include <linux/clk.h>
35#include <linux/io.h>
36
37#include <asm/mach-types.h>
38#include <asm/arch/hardware.h>
39#include <asm/arch/mux.h>
40
41#include "musb_core.h"
42#include "omap2430.h"
43
44#ifdef CONFIG_ARCH_OMAP3430
45#define get_cpu_rev() 2
46#endif
47
48#define MUSB_TIMEOUT_A_WAIT_BCON 1100
49
50static struct timer_list musb_idle_timer;
51
52static void musb_do_idle(unsigned long _musb)
53{
54 struct musb *musb = (void *)_musb;
55 unsigned long flags;
56 u8 power;
57 u8 devctl;
58
59 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
60
61 spin_lock_irqsave(&musb->lock, flags);
62
63 switch (musb->xceiv.state) {
64 case OTG_STATE_A_WAIT_BCON:
65 devctl &= ~MUSB_DEVCTL_SESSION;
66 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
67
68 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
69 if (devctl & MUSB_DEVCTL_BDEVICE) {
70 musb->xceiv.state = OTG_STATE_B_IDLE;
71 MUSB_DEV_MODE(musb);
72 } else {
73 musb->xceiv.state = OTG_STATE_A_IDLE;
74 MUSB_HST_MODE(musb);
75 }
76 break;
77#ifdef CONFIG_USB_MUSB_HDRC_HCD
78 case OTG_STATE_A_SUSPEND:
79 /* finish RESUME signaling? */
80 if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
81 power = musb_readb(musb->mregs, MUSB_POWER);
82 power &= ~MUSB_POWER_RESUME;
83 DBG(1, "root port resume stopped, power %02x\n", power);
84 musb_writeb(musb->mregs, MUSB_POWER, power);
85 musb->is_active = 1;
86 musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
87 | MUSB_PORT_STAT_RESUME);
88 musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
89 usb_hcd_poll_rh_status(musb_to_hcd(musb));
90 /* NOTE: it might really be A_WAIT_BCON ... */
91 musb->xceiv.state = OTG_STATE_A_HOST;
92 }
93 break;
94#endif
95#ifdef CONFIG_USB_MUSB_HDRC_HCD
96 case OTG_STATE_A_HOST:
97 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
98 if (devctl & MUSB_DEVCTL_BDEVICE)
99 musb->xceiv.state = OTG_STATE_B_IDLE;
100 else
101 musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
102#endif
103 default:
104 break;
105 }
106 spin_unlock_irqrestore(&musb->lock, flags);
107}
108
109
110void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
111{
112 unsigned long default_timeout = jiffies + msecs_to_jiffies(3);
113 static unsigned long last_timer;
114
115 if (timeout == 0)
116 timeout = default_timeout;
117
118 /* Never idle if active, or when VBUS timeout is not set as host */
119 if (musb->is_active || ((musb->a_wait_bcon == 0)
120 && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) {
121 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
122 del_timer(&musb_idle_timer);
123 last_timer = jiffies;
124 return;
125 }
126
127 if (time_after(last_timer, timeout)) {
128 if (!timer_pending(&musb_idle_timer))
129 last_timer = timeout;
130 else {
131 DBG(4, "Longer idle timer already pending, ignoring\n");
132 return;
133 }
134 }
135 last_timer = timeout;
136
137 DBG(4, "%s inactive, for idle timer for %lu ms\n",
138 otg_state_string(musb),
139 (unsigned long)jiffies_to_msecs(timeout - jiffies));
140 mod_timer(&musb_idle_timer, timeout);
141}
142
143void musb_platform_enable(struct musb *musb)
144{
145}
146void musb_platform_disable(struct musb *musb)
147{
148}
149static void omap_vbus_power(struct musb *musb, int is_on, int sleeping)
150{
151}
152
153static void omap_set_vbus(struct musb *musb, int is_on)
154{
155 u8 devctl;
156 /* HDRC controls CPEN, but beware current surges during device
157 * connect. They can trigger transient overcurrent conditions
158 * that must be ignored.
159 */
160
161 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
162
163 if (is_on) {
164 musb->is_active = 1;
165 musb->xceiv.default_a = 1;
166 musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
167 devctl |= MUSB_DEVCTL_SESSION;
168
169 MUSB_HST_MODE(musb);
170 } else {
171 musb->is_active = 0;
172
173 /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
174 * jumping right to B_IDLE...
175 */
176
177 musb->xceiv.default_a = 0;
178 musb->xceiv.state = OTG_STATE_B_IDLE;
179 devctl &= ~MUSB_DEVCTL_SESSION;
180
181 MUSB_DEV_MODE(musb);
182 }
183 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
184
185 DBG(1, "VBUS %s, devctl %02x "
186 /* otg %3x conf %08x prcm %08x */ "\n",
187 otg_state_string(musb),
188 musb_readb(musb->mregs, MUSB_DEVCTL));
189}
190static int omap_set_power(struct otg_transceiver *x, unsigned mA)
191{
192 return 0;
193}
194
195static int musb_platform_resume(struct musb *musb);
196
197void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
198{
199 u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
200
201 devctl |= MUSB_DEVCTL_SESSION;
202 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
203
204 switch (musb_mode) {
205 case MUSB_HOST:
206 otg_set_host(&musb->xceiv, musb->xceiv.host);
207 break;
208 case MUSB_PERIPHERAL:
209 otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget);
210 break;
211 case MUSB_OTG:
212 break;
213 }
214}
215
216int __init musb_platform_init(struct musb *musb)
217{
218 u32 l;
219
220#if defined(CONFIG_ARCH_OMAP2430)
221 omap_cfg_reg(AE5_2430_USB0HS_STP);
222#endif
223
224 musb_platform_resume(musb);
225
226 l = omap_readl(OTG_SYSCONFIG);
227 l &= ~ENABLEWAKEUP; /* disable wakeup */
228 l &= ~NOSTDBY; /* remove possible nostdby */
229 l |= SMARTSTDBY; /* enable smart standby */
230 l &= ~AUTOIDLE; /* disable auto idle */
231 l &= ~NOIDLE; /* remove possible noidle */
232 l |= SMARTIDLE; /* enable smart idle */
233 l |= AUTOIDLE; /* enable auto idle */
234 omap_writel(l, OTG_SYSCONFIG);
235
236 l = omap_readl(OTG_INTERFSEL);
237 l |= ULPI_12PIN;
238 omap_writel(l, OTG_INTERFSEL);
239
240 pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, "
241 "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n",
242 omap_readl(OTG_REVISION), omap_readl(OTG_SYSCONFIG),
243 omap_readl(OTG_SYSSTATUS), omap_readl(OTG_INTERFSEL),
244 omap_readl(OTG_SIMENABLE));
245
246 omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
247
248 if (is_host_enabled(musb))
249 musb->board_set_vbus = omap_set_vbus;
250 if (is_peripheral_enabled(musb))
251 musb->xceiv.set_power = omap_set_power;
252 musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON;
253
254 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
255
256 return 0;
257}
258
259int musb_platform_suspend(struct musb *musb)
260{
261 u32 l;
262
263 if (!musb->clock)
264 return 0;
265
266 /* in any role */
267 l = omap_readl(OTG_FORCESTDBY);
268 l |= ENABLEFORCE; /* enable MSTANDBY */
269 omap_writel(l, OTG_FORCESTDBY);
270
271 l = omap_readl(OTG_SYSCONFIG);
272 l |= ENABLEWAKEUP; /* enable wakeup */
273 omap_writel(l, OTG_SYSCONFIG);
274
275 if (musb->xceiv.set_suspend)
276 musb->xceiv.set_suspend(&musb->xceiv, 1);
277
278 if (musb->set_clock)
279 musb->set_clock(musb->clock, 0);
280 else
281 clk_disable(musb->clock);
282
283 return 0;
284}
285
286static int musb_platform_resume(struct musb *musb)
287{
288 u32 l;
289
290 if (!musb->clock)
291 return 0;
292
293 if (musb->xceiv.set_suspend)
294 musb->xceiv.set_suspend(&musb->xceiv, 0);
295
296 if (musb->set_clock)
297 musb->set_clock(musb->clock, 1);
298 else
299 clk_enable(musb->clock);
300
301 l = omap_readl(OTG_SYSCONFIG);
302 l &= ~ENABLEWAKEUP; /* disable wakeup */
303 omap_writel(l, OTG_SYSCONFIG);
304
305 l = omap_readl(OTG_FORCESTDBY);
306 l &= ~ENABLEFORCE; /* disable MSTANDBY */
307 omap_writel(l, OTG_FORCESTDBY);
308
309 return 0;
310}
311
312
313int musb_platform_exit(struct musb *musb)
314{
315
316 omap_vbus_power(musb, 0 /*off*/, 1);
317
318 musb_platform_suspend(musb);
319
320 clk_put(musb->clock);
321 musb->clock = 0;
322
323 return 0;
324}
diff --git a/drivers/usb/musb/omap2430.h b/drivers/usb/musb/omap2430.h
new file mode 100644
index 000000000000..786a62071f72
--- /dev/null
+++ b/drivers/usb/musb/omap2430.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright (C) 2005-2006 by Texas Instruments
3 *
4 * The Inventra Controller Driver for Linux is free software; you
5 * can redistribute it and/or modify it under the terms of the GNU
6 * General Public License version 2 as published by the Free Software
7 * Foundation.
8 */
9
10#ifndef __MUSB_OMAP243X_H__
11#define __MUSB_OMAP243X_H__
12
13#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
14#include <asm/arch/hardware.h>
15#include <asm/arch/usb.h>
16
17/*
18 * OMAP2430-specific definitions
19 */
20
21#define MENTOR_BASE_OFFSET 0
22#if defined(CONFIG_ARCH_OMAP2430)
23#define OMAP_HSOTG_BASE (OMAP243X_HS_BASE)
24#elif defined(CONFIG_ARCH_OMAP3430)
25#define OMAP_HSOTG_BASE (OMAP34XX_HSUSB_OTG_BASE)
26#endif
27#define OMAP_HSOTG(offset) (OMAP_HSOTG_BASE + 0x400 + (offset))
28#define OTG_REVISION OMAP_HSOTG(0x0)
29#define OTG_SYSCONFIG OMAP_HSOTG(0x4)
30# define MIDLEMODE 12 /* bit position */
31# define FORCESTDBY (0 << MIDLEMODE)
32# define NOSTDBY (1 << MIDLEMODE)
33# define SMARTSTDBY (2 << MIDLEMODE)
34# define SIDLEMODE 3 /* bit position */
35# define FORCEIDLE (0 << SIDLEMODE)
36# define NOIDLE (1 << SIDLEMODE)
37# define SMARTIDLE (2 << SIDLEMODE)
38# define ENABLEWAKEUP (1 << 2)
39# define SOFTRST (1 << 1)
40# define AUTOIDLE (1 << 0)
41#define OTG_SYSSTATUS OMAP_HSOTG(0x8)
42# define RESETDONE (1 << 0)
43#define OTG_INTERFSEL OMAP_HSOTG(0xc)
44# define EXTCP (1 << 2)
45# define PHYSEL 0 /* bit position */
46# define UTMI_8BIT (0 << PHYSEL)
47# define ULPI_12PIN (1 << PHYSEL)
48# define ULPI_8PIN (2 << PHYSEL)
49#define OTG_SIMENABLE OMAP_HSOTG(0x10)
50# define TM1 (1 << 0)
51#define OTG_FORCESTDBY OMAP_HSOTG(0x14)
52# define ENABLEFORCE (1 << 0)
53
54#endif /* CONFIG_ARCH_OMAP2430 */
55
56#endif /* __MUSB_OMAP243X_H__ */
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
new file mode 100644
index 000000000000..b73b036f3d77
--- /dev/null
+++ b/drivers/usb/musb/tusb6010.c
@@ -0,0 +1,1151 @@
1/*
2 * TUSB6010 USB 2.0 OTG Dual Role controller
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 * Jarkko Nikula <jarkko.nikula@nokia.com>
6 * Tony Lindgren <tony@atomide.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Notes:
13 * - Driver assumes that interface to external host (main CPU) is
14 * configured for NOR FLASH interface instead of VLYNQ serial
15 * interface.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/usb.h>
23#include <linux/irq.h>
24#include <linux/platform_device.h>
25
26#include "musb_core.h"
27
28static void tusb_source_power(struct musb *musb, int is_on);
29
30#define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf)
31#define TUSB_REV_MINOR(reg_val) (reg_val & 0xf)
32
33/*
34 * Checks the revision. We need to use the DMA register as 3.0 does not
35 * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
36 */
37u8 tusb_get_revision(struct musb *musb)
38{
39 void __iomem *tbase = musb->ctrl_base;
40 u32 die_id;
41 u8 rev;
42
43 rev = musb_readl(tbase, TUSB_DMA_CTRL_REV) & 0xff;
44 if (TUSB_REV_MAJOR(rev) == 3) {
45 die_id = TUSB_DIDR1_HI_CHIP_REV(musb_readl(tbase,
46 TUSB_DIDR1_HI));
47 if (die_id >= TUSB_DIDR1_HI_REV_31)
48 rev |= 1;
49 }
50
51 return rev;
52}
53
54static int __init tusb_print_revision(struct musb *musb)
55{
56 void __iomem *tbase = musb->ctrl_base;
57 u8 rev;
58
59 rev = tusb_get_revision(musb);
60
61 pr_info("tusb: %s%i.%i %s%i.%i %s%i.%i %s%i.%i %s%i %s%i.%i\n",
62 "prcm",
63 TUSB_REV_MAJOR(musb_readl(tbase, TUSB_PRCM_REV)),
64 TUSB_REV_MINOR(musb_readl(tbase, TUSB_PRCM_REV)),
65 "int",
66 TUSB_REV_MAJOR(musb_readl(tbase, TUSB_INT_CTRL_REV)),
67 TUSB_REV_MINOR(musb_readl(tbase, TUSB_INT_CTRL_REV)),
68 "gpio",
69 TUSB_REV_MAJOR(musb_readl(tbase, TUSB_GPIO_REV)),
70 TUSB_REV_MINOR(musb_readl(tbase, TUSB_GPIO_REV)),
71 "dma",
72 TUSB_REV_MAJOR(musb_readl(tbase, TUSB_DMA_CTRL_REV)),
73 TUSB_REV_MINOR(musb_readl(tbase, TUSB_DMA_CTRL_REV)),
74 "dieid",
75 TUSB_DIDR1_HI_CHIP_REV(musb_readl(tbase, TUSB_DIDR1_HI)),
76 "rev",
77 TUSB_REV_MAJOR(rev), TUSB_REV_MINOR(rev));
78
79 return tusb_get_revision(musb);
80}
81
82#define WBUS_QUIRK_MASK (TUSB_PHY_OTG_CTRL_TESTM2 | TUSB_PHY_OTG_CTRL_TESTM1 \
83 | TUSB_PHY_OTG_CTRL_TESTM0)
84
85/*
86 * Workaround for spontaneous WBUS wake-up issue #2 for tusb3.0.
87 * Disables power detection in PHY for the duration of idle.
88 */
89static void tusb_wbus_quirk(struct musb *musb, int enabled)
90{
91 void __iomem *tbase = musb->ctrl_base;
92 static u32 phy_otg_ctrl, phy_otg_ena;
93 u32 tmp;
94
95 if (enabled) {
96 phy_otg_ctrl = musb_readl(tbase, TUSB_PHY_OTG_CTRL);
97 phy_otg_ena = musb_readl(tbase, TUSB_PHY_OTG_CTRL_ENABLE);
98 tmp = TUSB_PHY_OTG_CTRL_WRPROTECT
99 | phy_otg_ena | WBUS_QUIRK_MASK;
100 musb_writel(tbase, TUSB_PHY_OTG_CTRL, tmp);
101 tmp = phy_otg_ena & ~WBUS_QUIRK_MASK;
102 tmp |= TUSB_PHY_OTG_CTRL_WRPROTECT | TUSB_PHY_OTG_CTRL_TESTM2;
103 musb_writel(tbase, TUSB_PHY_OTG_CTRL_ENABLE, tmp);
104 DBG(2, "Enabled tusb wbus quirk ctrl %08x ena %08x\n",
105 musb_readl(tbase, TUSB_PHY_OTG_CTRL),
106 musb_readl(tbase, TUSB_PHY_OTG_CTRL_ENABLE));
107 } else if (musb_readl(tbase, TUSB_PHY_OTG_CTRL_ENABLE)
108 & TUSB_PHY_OTG_CTRL_TESTM2) {
109 tmp = TUSB_PHY_OTG_CTRL_WRPROTECT | phy_otg_ctrl;
110 musb_writel(tbase, TUSB_PHY_OTG_CTRL, tmp);
111 tmp = TUSB_PHY_OTG_CTRL_WRPROTECT | phy_otg_ena;
112 musb_writel(tbase, TUSB_PHY_OTG_CTRL_ENABLE, tmp);
113 DBG(2, "Disabled tusb wbus quirk ctrl %08x ena %08x\n",
114 musb_readl(tbase, TUSB_PHY_OTG_CTRL),
115 musb_readl(tbase, TUSB_PHY_OTG_CTRL_ENABLE));
116 phy_otg_ctrl = 0;
117 phy_otg_ena = 0;
118 }
119}
120
121/*
122 * TUSB 6010 may use a parallel bus that doesn't support byte ops;
123 * so both loading and unloading FIFOs need explicit byte counts.
124 */
125
126static inline void
127tusb_fifo_write_unaligned(void __iomem *fifo, const u8 *buf, u16 len)
128{
129 u32 val;
130 int i;
131
132 if (len > 4) {
133 for (i = 0; i < (len >> 2); i++) {
134 memcpy(&val, buf, 4);
135 musb_writel(fifo, 0, val);
136 buf += 4;
137 }
138 len %= 4;
139 }
140 if (len > 0) {
141 /* Write the rest 1 - 3 bytes to FIFO */
142 memcpy(&val, buf, len);
143 musb_writel(fifo, 0, val);
144 }
145}
146
147static inline void tusb_fifo_read_unaligned(void __iomem *fifo,
148 void __iomem *buf, u16 len)
149{
150 u32 val;
151 int i;
152
153 if (len > 4) {
154 for (i = 0; i < (len >> 2); i++) {
155 val = musb_readl(fifo, 0);
156 memcpy(buf, &val, 4);
157 buf += 4;
158 }
159 len %= 4;
160 }
161 if (len > 0) {
162 /* Read the rest 1 - 3 bytes from FIFO */
163 val = musb_readl(fifo, 0);
164 memcpy(buf, &val, len);
165 }
166}
167
168void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf)
169{
170 void __iomem *ep_conf = hw_ep->conf;
171 void __iomem *fifo = hw_ep->fifo;
172 u8 epnum = hw_ep->epnum;
173
174 prefetch(buf);
175
176 DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
177 'T', epnum, fifo, len, buf);
178
179 if (epnum)
180 musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
181 TUSB_EP_CONFIG_XFR_SIZE(len));
182 else
183 musb_writel(ep_conf, 0, TUSB_EP0_CONFIG_DIR_TX |
184 TUSB_EP0_CONFIG_XFR_SIZE(len));
185
186 if (likely((0x01 & (unsigned long) buf) == 0)) {
187
188 /* Best case is 32bit-aligned destination address */
189 if ((0x02 & (unsigned long) buf) == 0) {
190 if (len >= 4) {
191 writesl(fifo, buf, len >> 2);
192 buf += (len & ~0x03);
193 len &= 0x03;
194 }
195 } else {
196 if (len >= 2) {
197 u32 val;
198 int i;
199
200 /* Cannot use writesw, fifo is 32-bit */
201 for (i = 0; i < (len >> 2); i++) {
202 val = (u32)(*(u16 *)buf);
203 buf += 2;
204 val |= (*(u16 *)buf) << 16;
205 buf += 2;
206 musb_writel(fifo, 0, val);
207 }
208 len &= 0x03;
209 }
210 }
211 }
212
213 if (len > 0)
214 tusb_fifo_write_unaligned(fifo, buf, len);
215}
216
217void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf)
218{
219 void __iomem *ep_conf = hw_ep->conf;
220 void __iomem *fifo = hw_ep->fifo;
221 u8 epnum = hw_ep->epnum;
222
223 DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
224 'R', epnum, fifo, len, buf);
225
226 if (epnum)
227 musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
228 TUSB_EP_CONFIG_XFR_SIZE(len));
229 else
230 musb_writel(ep_conf, 0, TUSB_EP0_CONFIG_XFR_SIZE(len));
231
232 if (likely((0x01 & (unsigned long) buf) == 0)) {
233
234 /* Best case is 32bit-aligned destination address */
235 if ((0x02 & (unsigned long) buf) == 0) {
236 if (len >= 4) {
237 readsl(fifo, buf, len >> 2);
238 buf += (len & ~0x03);
239 len &= 0x03;
240 }
241 } else {
242 if (len >= 2) {
243 u32 val;
244 int i;
245
246 /* Cannot use readsw, fifo is 32-bit */
247 for (i = 0; i < (len >> 2); i++) {
248 val = musb_readl(fifo, 0);
249 *(u16 *)buf = (u16)(val & 0xffff);
250 buf += 2;
251 *(u16 *)buf = (u16)(val >> 16);
252 buf += 2;
253 }
254 len &= 0x03;
255 }
256 }
257 }
258
259 if (len > 0)
260 tusb_fifo_read_unaligned(fifo, buf, len);
261}
262
263#ifdef CONFIG_USB_GADGET_MUSB_HDRC
264
265/* This is used by gadget drivers, and OTG transceiver logic, allowing
266 * at most mA current to be drawn from VBUS during a Default-B session
267 * (that is, while VBUS exceeds 4.4V). In Default-A (including pure host
268 * mode), or low power Default-B sessions, something else supplies power.
269 * Caller must take care of locking.
270 */
271static int tusb_draw_power(struct otg_transceiver *x, unsigned mA)
272{
273 struct musb *musb = container_of(x, struct musb, xceiv);
274 void __iomem *tbase = musb->ctrl_base;
275 u32 reg;
276
277 /*
278 * Keep clock active when enabled. Note that this is not tied to
279 * drawing VBUS, as with OTG mA can be less than musb->min_power.
280 */
281 if (musb->set_clock) {
282 if (mA)
283 musb->set_clock(musb->clock, 1);
284 else
285 musb->set_clock(musb->clock, 0);
286 }
287
288 /* tps65030 seems to consume max 100mA, with maybe 60mA available
289 * (measured on one board) for things other than tps and tusb.
290 *
291 * Boards sharing the CPU clock with CLKIN will need to prevent
292 * certain idle sleep states while the USB link is active.
293 *
294 * REVISIT we could use VBUS to supply only _one_ of { 1.5V, 3.3V }.
295 * The actual current usage would be very board-specific. For now,
296 * it's simpler to just use an aggregate (also board-specific).
297 */
298 if (x->default_a || mA < (musb->min_power << 1))
299 mA = 0;
300
301 reg = musb_readl(tbase, TUSB_PRCM_MNGMT);
302 if (mA) {
303 musb->is_bus_powered = 1;
304 reg |= TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN;
305 } else {
306 musb->is_bus_powered = 0;
307 reg &= ~(TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN);
308 }
309 musb_writel(tbase, TUSB_PRCM_MNGMT, reg);
310
311 DBG(2, "draw max %d mA VBUS\n", mA);
312 return 0;
313}
314
315#else
316#define tusb_draw_power NULL
317#endif
318
319/* workaround for issue 13: change clock during chip idle
320 * (to be fixed in rev3 silicon) ... symptoms include disconnect
321 * or looping suspend/resume cycles
322 */
323static void tusb_set_clock_source(struct musb *musb, unsigned mode)
324{
325 void __iomem *tbase = musb->ctrl_base;
326 u32 reg;
327
328 reg = musb_readl(tbase, TUSB_PRCM_CONF);
329 reg &= ~TUSB_PRCM_CONF_SYS_CLKSEL(0x3);
330
331 /* 0 = refclk (clkin, XI)
332 * 1 = PHY 60 MHz (internal PLL)
333 * 2 = not supported
334 * 3 = what?
335 */
336 if (mode > 0)
337 reg |= TUSB_PRCM_CONF_SYS_CLKSEL(mode & 0x3);
338
339 musb_writel(tbase, TUSB_PRCM_CONF, reg);
340
341 /* FIXME tusb6010_platform_retime(mode == 0); */
342}
343
344/*
345 * Idle TUSB6010 until next wake-up event; NOR access always wakes.
346 * Other code ensures that we idle unless we're connected _and_ the
347 * USB link is not suspended ... and tells us the relevant wakeup
348 * events. SW_EN for voltage is handled separately.
349 */
350void tusb_allow_idle(struct musb *musb, u32 wakeup_enables)
351{
352 void __iomem *tbase = musb->ctrl_base;
353 u32 reg;
354
355 if ((wakeup_enables & TUSB_PRCM_WBUS)
356 && (tusb_get_revision(musb) == TUSB_REV_30))
357 tusb_wbus_quirk(musb, 1);
358
359 tusb_set_clock_source(musb, 0);
360
361 wakeup_enables |= TUSB_PRCM_WNORCS;
362 musb_writel(tbase, TUSB_PRCM_WAKEUP_MASK, ~wakeup_enables);
363
364 /* REVISIT writeup of WID implies that if WID set and ID is grounded,
365 * TUSB_PHY_OTG_CTRL.TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP must be cleared.
366 * Presumably that's mostly to save power, hence WID is immaterial ...
367 */
368
369 reg = musb_readl(tbase, TUSB_PRCM_MNGMT);
370 /* issue 4: when driving vbus, use hipower (vbus_det) comparator */
371 if (is_host_active(musb)) {
372 reg |= TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN;
373 reg &= ~TUSB_PRCM_MNGMT_OTG_SESS_END_EN;
374 } else {
375 reg |= TUSB_PRCM_MNGMT_OTG_SESS_END_EN;
376 reg &= ~TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN;
377 }
378 reg |= TUSB_PRCM_MNGMT_PM_IDLE | TUSB_PRCM_MNGMT_DEV_IDLE;
379 musb_writel(tbase, TUSB_PRCM_MNGMT, reg);
380
381 DBG(6, "idle, wake on %02x\n", wakeup_enables);
382}
383
384/*
385 * Updates cable VBUS status. Caller must take care of locking.
386 */
387int musb_platform_get_vbus_status(struct musb *musb)
388{
389 void __iomem *tbase = musb->ctrl_base;
390 u32 otg_stat, prcm_mngmt;
391 int ret = 0;
392
393 otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
394 prcm_mngmt = musb_readl(tbase, TUSB_PRCM_MNGMT);
395
396 /* Temporarily enable VBUS detection if it was disabled for
397 * suspend mode. Unless it's enabled otg_stat and devctl will
398 * not show correct VBUS state.
399 */
400 if (!(prcm_mngmt & TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN)) {
401 u32 tmp = prcm_mngmt;
402 tmp |= TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN;
403 musb_writel(tbase, TUSB_PRCM_MNGMT, tmp);
404 otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
405 musb_writel(tbase, TUSB_PRCM_MNGMT, prcm_mngmt);
406 }
407
408 if (otg_stat & TUSB_DEV_OTG_STAT_VBUS_VALID)
409 ret = 1;
410
411 return ret;
412}
413
414static struct timer_list musb_idle_timer;
415
416static void musb_do_idle(unsigned long _musb)
417{
418 struct musb *musb = (void *)_musb;
419 unsigned long flags;
420
421 spin_lock_irqsave(&musb->lock, flags);
422
423 switch (musb->xceiv.state) {
424 case OTG_STATE_A_WAIT_BCON:
425 if ((musb->a_wait_bcon != 0)
426 && (musb->idle_timeout == 0
427 || time_after(jiffies, musb->idle_timeout))) {
428 DBG(4, "Nothing connected %s, turning off VBUS\n",
429 otg_state_string(musb));
430 }
431 /* FALLTHROUGH */
432 case OTG_STATE_A_IDLE:
433 tusb_source_power(musb, 0);
434 default:
435 break;
436 }
437
438 if (!musb->is_active) {
439 u32 wakeups;
440
441 /* wait until khubd handles port change status */
442 if (is_host_active(musb) && (musb->port1_status >> 16))
443 goto done;
444
445#ifdef CONFIG_USB_GADGET_MUSB_HDRC
446 if (is_peripheral_enabled(musb) && !musb->gadget_driver)
447 wakeups = 0;
448 else {
449 wakeups = TUSB_PRCM_WHOSTDISCON
450 | TUSB_PRCM_WBUS
451 | TUSB_PRCM_WVBUS;
452 if (is_otg_enabled(musb))
453 wakeups |= TUSB_PRCM_WID;
454 }
455#else
456 wakeups = TUSB_PRCM_WHOSTDISCON | TUSB_PRCM_WBUS;
457#endif
458 tusb_allow_idle(musb, wakeups);
459 }
460done:
461 spin_unlock_irqrestore(&musb->lock, flags);
462}
463
464/*
465 * Maybe put TUSB6010 into idle mode mode depending on USB link status,
466 * like "disconnected" or "suspended". We'll be woken out of it by
467 * connect, resume, or disconnect.
468 *
469 * Needs to be called as the last function everywhere where there is
470 * register access to TUSB6010 because of NOR flash wake-up.
471 * Caller should own controller spinlock.
472 *
473 * Delay because peripheral enables D+ pullup 3msec after SE0, and
474 * we don't want to treat that full speed J as a wakeup event.
475 * ... peripherals must draw only suspend current after 10 msec.
476 */
477void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
478{
479 unsigned long default_timeout = jiffies + msecs_to_jiffies(3);
480 static unsigned long last_timer;
481
482 if (timeout == 0)
483 timeout = default_timeout;
484
485 /* Never idle if active, or when VBUS timeout is not set as host */
486 if (musb->is_active || ((musb->a_wait_bcon == 0)
487 && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) {
488 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
489 del_timer(&musb_idle_timer);
490 last_timer = jiffies;
491 return;
492 }
493
494 if (time_after(last_timer, timeout)) {
495 if (!timer_pending(&musb_idle_timer))
496 last_timer = timeout;
497 else {
498 DBG(4, "Longer idle timer already pending, ignoring\n");
499 return;
500 }
501 }
502 last_timer = timeout;
503
504 DBG(4, "%s inactive, for idle timer for %lu ms\n",
505 otg_state_string(musb),
506 (unsigned long)jiffies_to_msecs(timeout - jiffies));
507 mod_timer(&musb_idle_timer, timeout);
508}
509
510/* ticks of 60 MHz clock */
511#define DEVCLOCK 60000000
512#define OTG_TIMER_MS(msecs) ((msecs) \
513 ? (TUSB_DEV_OTG_TIMER_VAL((DEVCLOCK/1000)*(msecs)) \
514 | TUSB_DEV_OTG_TIMER_ENABLE) \
515 : 0)
516
517static void tusb_source_power(struct musb *musb, int is_on)
518{
519 void __iomem *tbase = musb->ctrl_base;
520 u32 conf, prcm, timer;
521 u8 devctl;
522
523 /* HDRC controls CPEN, but beware current surges during device
524 * connect. They can trigger transient overcurrent conditions
525 * that must be ignored.
526 */
527
528 prcm = musb_readl(tbase, TUSB_PRCM_MNGMT);
529 conf = musb_readl(tbase, TUSB_DEV_CONF);
530 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
531
532 if (is_on) {
533 if (musb->set_clock)
534 musb->set_clock(musb->clock, 1);
535 timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE);
536 musb->xceiv.default_a = 1;
537 musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
538 devctl |= MUSB_DEVCTL_SESSION;
539
540 conf |= TUSB_DEV_CONF_USB_HOST_MODE;
541 MUSB_HST_MODE(musb);
542 } else {
543 u32 otg_stat;
544
545 timer = 0;
546
547 /* If ID pin is grounded, we want to be a_idle */
548 otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
549 if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) {
550 switch (musb->xceiv.state) {
551 case OTG_STATE_A_WAIT_VRISE:
552 case OTG_STATE_A_WAIT_BCON:
553 musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
554 break;
555 case OTG_STATE_A_WAIT_VFALL:
556 musb->xceiv.state = OTG_STATE_A_IDLE;
557 break;
558 default:
559 musb->xceiv.state = OTG_STATE_A_IDLE;
560 }
561 musb->is_active = 0;
562 musb->xceiv.default_a = 1;
563 MUSB_HST_MODE(musb);
564 } else {
565 musb->is_active = 0;
566 musb->xceiv.default_a = 0;
567 musb->xceiv.state = OTG_STATE_B_IDLE;
568 MUSB_DEV_MODE(musb);
569 }
570
571 devctl &= ~MUSB_DEVCTL_SESSION;
572 conf &= ~TUSB_DEV_CONF_USB_HOST_MODE;
573 if (musb->set_clock)
574 musb->set_clock(musb->clock, 0);
575 }
576 prcm &= ~(TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN);
577
578 musb_writel(tbase, TUSB_PRCM_MNGMT, prcm);
579 musb_writel(tbase, TUSB_DEV_OTG_TIMER, timer);
580 musb_writel(tbase, TUSB_DEV_CONF, conf);
581 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
582
583 DBG(1, "VBUS %s, devctl %02x otg %3x conf %08x prcm %08x\n",
584 otg_state_string(musb),
585 musb_readb(musb->mregs, MUSB_DEVCTL),
586 musb_readl(tbase, TUSB_DEV_OTG_STAT),
587 conf, prcm);
588}
589
590/*
591 * Sets the mode to OTG, peripheral or host by changing the ID detection.
592 * Caller must take care of locking.
593 *
594 * Note that if a mini-A cable is plugged in the ID line will stay down as
595 * the weak ID pull-up is not able to pull the ID up.
596 *
597 * REVISIT: It would be possible to add support for changing between host
598 * and peripheral modes in non-OTG configurations by reconfiguring hardware
599 * and then setting musb->board_mode. For now, only support OTG mode.
600 */
601void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
602{
603 void __iomem *tbase = musb->ctrl_base;
604 u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf;
605
606 if (musb->board_mode != MUSB_OTG) {
607 ERR("Changing mode currently only supported in OTG mode\n");
608 return;
609 }
610
611 otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
612 phy_otg_ctrl = musb_readl(tbase, TUSB_PHY_OTG_CTRL);
613 phy_otg_ena = musb_readl(tbase, TUSB_PHY_OTG_CTRL_ENABLE);
614 dev_conf = musb_readl(tbase, TUSB_DEV_CONF);
615
616 switch (musb_mode) {
617
618#ifdef CONFIG_USB_MUSB_HDRC_HCD
619 case MUSB_HOST: /* Disable PHY ID detect, ground ID */
620 phy_otg_ctrl &= ~TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
621 phy_otg_ena |= TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
622 dev_conf |= TUSB_DEV_CONF_ID_SEL;
623 dev_conf &= ~TUSB_DEV_CONF_SOFT_ID;
624 break;
625#endif
626
627#ifdef CONFIG_USB_GADGET_MUSB_HDRC
628 case MUSB_PERIPHERAL: /* Disable PHY ID detect, keep ID pull-up on */
629 phy_otg_ctrl |= TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
630 phy_otg_ena |= TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
631 dev_conf |= (TUSB_DEV_CONF_ID_SEL | TUSB_DEV_CONF_SOFT_ID);
632 break;
633#endif
634
635#ifdef CONFIG_USB_MUSB_OTG
636 case MUSB_OTG: /* Use PHY ID detection */
637 phy_otg_ctrl |= TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
638 phy_otg_ena |= TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
639 dev_conf &= ~(TUSB_DEV_CONF_ID_SEL | TUSB_DEV_CONF_SOFT_ID);
640 break;
641#endif
642
643 default:
644 DBG(2, "Trying to set unknown mode %i\n", musb_mode);
645 }
646
647 musb_writel(tbase, TUSB_PHY_OTG_CTRL,
648 TUSB_PHY_OTG_CTRL_WRPROTECT | phy_otg_ctrl);
649 musb_writel(tbase, TUSB_PHY_OTG_CTRL_ENABLE,
650 TUSB_PHY_OTG_CTRL_WRPROTECT | phy_otg_ena);
651 musb_writel(tbase, TUSB_DEV_CONF, dev_conf);
652
653 otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
654 if ((musb_mode == MUSB_PERIPHERAL) &&
655 !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS))
656 INFO("Cannot be peripheral with mini-A cable "
657 "otg_stat: %08x\n", otg_stat);
658}
659
660static inline unsigned long
661tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase)
662{
663 u32 otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
664 unsigned long idle_timeout = 0;
665
666 /* ID pin */
667 if ((int_src & TUSB_INT_SRC_ID_STATUS_CHNG)) {
668 int default_a;
669
670 if (is_otg_enabled(musb))
671 default_a = !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS);
672 else
673 default_a = is_host_enabled(musb);
674 DBG(2, "Default-%c\n", default_a ? 'A' : 'B');
675 musb->xceiv.default_a = default_a;
676 tusb_source_power(musb, default_a);
677
678 /* Don't allow idling immediately */
679 if (default_a)
680 idle_timeout = jiffies + (HZ * 3);
681 }
682
683 /* VBUS state change */
684 if (int_src & TUSB_INT_SRC_VBUS_SENSE_CHNG) {
685
686 /* B-dev state machine: no vbus ~= disconnect */
687 if ((is_otg_enabled(musb) && !musb->xceiv.default_a)
688 || !is_host_enabled(musb)) {
689#ifdef CONFIG_USB_MUSB_HDRC_HCD
690 /* ? musb_root_disconnect(musb); */
691 musb->port1_status &=
692 ~(USB_PORT_STAT_CONNECTION
693 | USB_PORT_STAT_ENABLE
694 | USB_PORT_STAT_LOW_SPEED
695 | USB_PORT_STAT_HIGH_SPEED
696 | USB_PORT_STAT_TEST
697 );
698#endif
699
700 if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) {
701 DBG(1, "Forcing disconnect (no interrupt)\n");
702 if (musb->xceiv.state != OTG_STATE_B_IDLE) {
703 /* INTR_DISCONNECT can hide... */
704 musb->xceiv.state = OTG_STATE_B_IDLE;
705 musb->int_usb |= MUSB_INTR_DISCONNECT;
706 }
707 musb->is_active = 0;
708 }
709 DBG(2, "vbus change, %s, otg %03x\n",
710 otg_state_string(musb), otg_stat);
711 idle_timeout = jiffies + (1 * HZ);
712 schedule_work(&musb->irq_work);
713
714 } else /* A-dev state machine */ {
715 DBG(2, "vbus change, %s, otg %03x\n",
716 otg_state_string(musb), otg_stat);
717
718 switch (musb->xceiv.state) {
719 case OTG_STATE_A_IDLE:
720 DBG(2, "Got SRP, turning on VBUS\n");
721 musb_set_vbus(musb, 1);
722
723 /* CONNECT can wake if a_wait_bcon is set */
724 if (musb->a_wait_bcon != 0)
725 musb->is_active = 0;
726 else
727 musb->is_active = 1;
728
729 /*
730 * OPT FS A TD.4.6 needs few seconds for
731 * A_WAIT_VRISE
732 */
733 idle_timeout = jiffies + (2 * HZ);
734
735 break;
736 case OTG_STATE_A_WAIT_VRISE:
737 /* ignore; A-session-valid < VBUS_VALID/2,
738 * we monitor this with the timer
739 */
740 break;
741 case OTG_STATE_A_WAIT_VFALL:
742 /* REVISIT this irq triggers during short
743 * spikes caused by enumeration ...
744 */
745 if (musb->vbuserr_retry) {
746 musb->vbuserr_retry--;
747 tusb_source_power(musb, 1);
748 } else {
749 musb->vbuserr_retry
750 = VBUSERR_RETRY_COUNT;
751 tusb_source_power(musb, 0);
752 }
753 break;
754 default:
755 break;
756 }
757 }
758 }
759
760 /* OTG timer expiration */
761 if (int_src & TUSB_INT_SRC_OTG_TIMEOUT) {
762 u8 devctl;
763
764 DBG(4, "%s timer, %03x\n", otg_state_string(musb), otg_stat);
765
766 switch (musb->xceiv.state) {
767 case OTG_STATE_A_WAIT_VRISE:
768 /* VBUS has probably been valid for a while now,
769 * but may well have bounced out of range a bit
770 */
771 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
772 if (otg_stat & TUSB_DEV_OTG_STAT_VBUS_VALID) {
773 if ((devctl & MUSB_DEVCTL_VBUS)
774 != MUSB_DEVCTL_VBUS) {
775 DBG(2, "devctl %02x\n", devctl);
776 break;
777 }
778 musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
779 musb->is_active = 0;
780 idle_timeout = jiffies
781 + msecs_to_jiffies(musb->a_wait_bcon);
782 } else {
783 /* REVISIT report overcurrent to hub? */
784 ERR("vbus too slow, devctl %02x\n", devctl);
785 tusb_source_power(musb, 0);
786 }
787 break;
788 case OTG_STATE_A_WAIT_BCON:
789 if (musb->a_wait_bcon != 0)
790 idle_timeout = jiffies
791 + msecs_to_jiffies(musb->a_wait_bcon);
792 break;
793 case OTG_STATE_A_SUSPEND:
794 break;
795 case OTG_STATE_B_WAIT_ACON:
796 break;
797 default:
798 break;
799 }
800 }
801 schedule_work(&musb->irq_work);
802
803 return idle_timeout;
804}
805
806static irqreturn_t tusb_interrupt(int irq, void *__hci)
807{
808 struct musb *musb = __hci;
809 void __iomem *tbase = musb->ctrl_base;
810 unsigned long flags, idle_timeout = 0;
811 u32 int_mask, int_src;
812
813 spin_lock_irqsave(&musb->lock, flags);
814
815 /* Mask all interrupts to allow using both edge and level GPIO irq */
816 int_mask = musb_readl(tbase, TUSB_INT_MASK);
817 musb_writel(tbase, TUSB_INT_MASK, ~TUSB_INT_MASK_RESERVED_BITS);
818
819 int_src = musb_readl(tbase, TUSB_INT_SRC) & ~TUSB_INT_SRC_RESERVED_BITS;
820 DBG(3, "TUSB IRQ %08x\n", int_src);
821
822 musb->int_usb = (u8) int_src;
823
824 /* Acknowledge wake-up source interrupts */
825 if (int_src & TUSB_INT_SRC_DEV_WAKEUP) {
826 u32 reg;
827 u32 i;
828
829 if (tusb_get_revision(musb) == TUSB_REV_30)
830 tusb_wbus_quirk(musb, 0);
831
832 /* there are issues re-locking the PLL on wakeup ... */
833
834 /* work around issue 8 */
835 for (i = 0xf7f7f7; i > 0xf7f7f7 - 1000; i--) {
836 musb_writel(tbase, TUSB_SCRATCH_PAD, 0);
837 musb_writel(tbase, TUSB_SCRATCH_PAD, i);
838 reg = musb_readl(tbase, TUSB_SCRATCH_PAD);
839 if (reg == i)
840 break;
841 DBG(6, "TUSB NOR not ready\n");
842 }
843
844 /* work around issue 13 (2nd half) */
845 tusb_set_clock_source(musb, 1);
846
847 reg = musb_readl(tbase, TUSB_PRCM_WAKEUP_SOURCE);
848 musb_writel(tbase, TUSB_PRCM_WAKEUP_CLEAR, reg);
849 if (reg & ~TUSB_PRCM_WNORCS) {
850 musb->is_active = 1;
851 schedule_work(&musb->irq_work);
852 }
853 DBG(3, "wake %sactive %02x\n",
854 musb->is_active ? "" : "in", reg);
855
856 /* REVISIT host side TUSB_PRCM_WHOSTDISCON, TUSB_PRCM_WBUS */
857 }
858
859 if (int_src & TUSB_INT_SRC_USB_IP_CONN)
860 del_timer(&musb_idle_timer);
861
862 /* OTG state change reports (annoyingly) not issued by Mentor core */
863 if (int_src & (TUSB_INT_SRC_VBUS_SENSE_CHNG
864 | TUSB_INT_SRC_OTG_TIMEOUT
865 | TUSB_INT_SRC_ID_STATUS_CHNG))
866 idle_timeout = tusb_otg_ints(musb, int_src, tbase);
867
868 /* TX dma callback must be handled here, RX dma callback is
869 * handled in tusb_omap_dma_cb.
870 */
871 if ((int_src & TUSB_INT_SRC_TXRX_DMA_DONE)) {
872 u32 dma_src = musb_readl(tbase, TUSB_DMA_INT_SRC);
873 u32 real_dma_src = musb_readl(tbase, TUSB_DMA_INT_MASK);
874
875 DBG(3, "DMA IRQ %08x\n", dma_src);
876 real_dma_src = ~real_dma_src & dma_src;
877 if (tusb_dma_omap() && real_dma_src) {
878 int tx_source = (real_dma_src & 0xffff);
879 int i;
880
881 for (i = 1; i <= 15; i++) {
882 if (tx_source & (1 << i)) {
883 DBG(3, "completing ep%i %s\n", i, "tx");
884 musb_dma_completion(musb, i, 1);
885 }
886 }
887 }
888 musb_writel(tbase, TUSB_DMA_INT_CLEAR, dma_src);
889 }
890
891 /* EP interrupts. In OCP mode tusb6010 mirrors the MUSB interrupts */
892 if (int_src & (TUSB_INT_SRC_USB_IP_TX | TUSB_INT_SRC_USB_IP_RX)) {
893 u32 musb_src = musb_readl(tbase, TUSB_USBIP_INT_SRC);
894
895 musb_writel(tbase, TUSB_USBIP_INT_CLEAR, musb_src);
896 musb->int_rx = (((musb_src >> 16) & 0xffff) << 1);
897 musb->int_tx = (musb_src & 0xffff);
898 } else {
899 musb->int_rx = 0;
900 musb->int_tx = 0;
901 }
902
903 if (int_src & (TUSB_INT_SRC_USB_IP_TX | TUSB_INT_SRC_USB_IP_RX | 0xff))
904 musb_interrupt(musb);
905
906 /* Acknowledge TUSB interrupts. Clear only non-reserved bits */
907 musb_writel(tbase, TUSB_INT_SRC_CLEAR,
908 int_src & ~TUSB_INT_MASK_RESERVED_BITS);
909
910 musb_platform_try_idle(musb, idle_timeout);
911
912 musb_writel(tbase, TUSB_INT_MASK, int_mask);
913 spin_unlock_irqrestore(&musb->lock, flags);
914
915 return IRQ_HANDLED;
916}
917
918static int dma_off;
919
920/*
921 * Enables TUSB6010. Caller must take care of locking.
922 * REVISIT:
923 * - Check what is unnecessary in MGC_HdrcStart()
924 */
925void musb_platform_enable(struct musb *musb)
926{
927 void __iomem *tbase = musb->ctrl_base;
928
929 /* Setup TUSB6010 main interrupt mask. Enable all interrupts except SOF.
930 * REVISIT: Enable and deal with TUSB_INT_SRC_USB_IP_SOF */
931 musb_writel(tbase, TUSB_INT_MASK, TUSB_INT_SRC_USB_IP_SOF);
932
933 /* Setup TUSB interrupt, disable DMA and GPIO interrupts */
934 musb_writel(tbase, TUSB_USBIP_INT_MASK, 0);
935 musb_writel(tbase, TUSB_DMA_INT_MASK, 0x7fffffff);
936 musb_writel(tbase, TUSB_GPIO_INT_MASK, 0x1ff);
937
938 /* Clear all subsystem interrups */
939 musb_writel(tbase, TUSB_USBIP_INT_CLEAR, 0x7fffffff);
940 musb_writel(tbase, TUSB_DMA_INT_CLEAR, 0x7fffffff);
941 musb_writel(tbase, TUSB_GPIO_INT_CLEAR, 0x1ff);
942
943 /* Acknowledge pending interrupt(s) */
944 musb_writel(tbase, TUSB_INT_SRC_CLEAR, ~TUSB_INT_MASK_RESERVED_BITS);
945
946 /* Only 0 clock cycles for minimum interrupt de-assertion time and
947 * interrupt polarity active low seems to work reliably here */
948 musb_writel(tbase, TUSB_INT_CTRL_CONF,
949 TUSB_INT_CTRL_CONF_INT_RELCYC(0));
950
951 set_irq_type(musb->nIrq, IRQ_TYPE_LEVEL_LOW);
952
953 /* maybe force into the Default-A OTG state machine */
954 if (!(musb_readl(tbase, TUSB_DEV_OTG_STAT)
955 & TUSB_DEV_OTG_STAT_ID_STATUS))
956 musb_writel(tbase, TUSB_INT_SRC_SET,
957 TUSB_INT_SRC_ID_STATUS_CHNG);
958
959 if (is_dma_capable() && dma_off)
960 printk(KERN_WARNING "%s %s: dma not reactivated\n",
961 __FILE__, __func__);
962 else
963 dma_off = 1;
964}
965
966/*
967 * Disables TUSB6010. Caller must take care of locking.
968 */
969void musb_platform_disable(struct musb *musb)
970{
971 void __iomem *tbase = musb->ctrl_base;
972
973 /* FIXME stop DMA, IRQs, timers, ... */
974
975 /* disable all IRQs */
976 musb_writel(tbase, TUSB_INT_MASK, ~TUSB_INT_MASK_RESERVED_BITS);
977 musb_writel(tbase, TUSB_USBIP_INT_MASK, 0x7fffffff);
978 musb_writel(tbase, TUSB_DMA_INT_MASK, 0x7fffffff);
979 musb_writel(tbase, TUSB_GPIO_INT_MASK, 0x1ff);
980
981 del_timer(&musb_idle_timer);
982
983 if (is_dma_capable() && !dma_off) {
984 printk(KERN_WARNING "%s %s: dma still active\n",
985 __FILE__, __func__);
986 dma_off = 1;
987 }
988}
989
990/*
991 * Sets up TUSB6010 CPU interface specific signals and registers
992 * Note: Settings optimized for OMAP24xx
993 */
994static void __init tusb_setup_cpu_interface(struct musb *musb)
995{
996 void __iomem *tbase = musb->ctrl_base;
997
998 /*
999 * Disable GPIO[5:0] pullups (used as output DMA requests)
1000 * Don't disable GPIO[7:6] as they are needed for wake-up.
1001 */
1002 musb_writel(tbase, TUSB_PULLUP_1_CTRL, 0x0000003F);
1003
1004 /* Disable all pullups on NOR IF, DMAREQ0 and DMAREQ1 */
1005 musb_writel(tbase, TUSB_PULLUP_2_CTRL, 0x01FFFFFF);
1006
1007 /* Turn GPIO[5:0] to DMAREQ[5:0] signals */
1008 musb_writel(tbase, TUSB_GPIO_CONF, TUSB_GPIO_CONF_DMAREQ(0x3f));
1009
1010 /* Burst size 16x16 bits, all six DMA requests enabled, DMA request
1011 * de-assertion time 2 system clocks p 62 */
1012 musb_writel(tbase, TUSB_DMA_REQ_CONF,
1013 TUSB_DMA_REQ_CONF_BURST_SIZE(2) |
1014 TUSB_DMA_REQ_CONF_DMA_REQ_EN(0x3f) |
1015 TUSB_DMA_REQ_CONF_DMA_REQ_ASSER(2));
1016
1017 /* Set 0 wait count for synchronous burst access */
1018 musb_writel(tbase, TUSB_WAIT_COUNT, 1);
1019}
1020
1021static int __init tusb_start(struct musb *musb)
1022{
1023 void __iomem *tbase = musb->ctrl_base;
1024 int ret = 0;
1025 unsigned long flags;
1026 u32 reg;
1027
1028 if (musb->board_set_power)
1029 ret = musb->board_set_power(1);
1030 if (ret != 0) {
1031 printk(KERN_ERR "tusb: Cannot enable TUSB6010\n");
1032 return ret;
1033 }
1034
1035 spin_lock_irqsave(&musb->lock, flags);
1036
1037 if (musb_readl(tbase, TUSB_PROD_TEST_RESET) !=
1038 TUSB_PROD_TEST_RESET_VAL) {
1039 printk(KERN_ERR "tusb: Unable to detect TUSB6010\n");
1040 goto err;
1041 }
1042
1043 ret = tusb_print_revision(musb);
1044 if (ret < 2) {
1045 printk(KERN_ERR "tusb: Unsupported TUSB6010 revision %i\n",
1046 ret);
1047 goto err;
1048 }
1049
1050 /* The uint bit for "USB non-PDR interrupt enable" has to be 1 when
1051 * NOR FLASH interface is used */
1052 musb_writel(tbase, TUSB_VLYNQ_CTRL, 8);
1053
1054 /* Select PHY free running 60MHz as a system clock */
1055 tusb_set_clock_source(musb, 1);
1056
1057 /* VBus valid timer 1us, disable DFT/Debug and VLYNQ clocks for
1058 * power saving, enable VBus detect and session end comparators,
1059 * enable IDpullup, enable VBus charging */
1060 musb_writel(tbase, TUSB_PRCM_MNGMT,
1061 TUSB_PRCM_MNGMT_VBUS_VALID_TIMER(0xa) |
1062 TUSB_PRCM_MNGMT_VBUS_VALID_FLT_EN |
1063 TUSB_PRCM_MNGMT_OTG_SESS_END_EN |
1064 TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN |
1065 TUSB_PRCM_MNGMT_OTG_ID_PULLUP);
1066 tusb_setup_cpu_interface(musb);
1067
1068 /* simplify: always sense/pullup ID pins, as if in OTG mode */
1069 reg = musb_readl(tbase, TUSB_PHY_OTG_CTRL_ENABLE);
1070 reg |= TUSB_PHY_OTG_CTRL_WRPROTECT | TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
1071 musb_writel(tbase, TUSB_PHY_OTG_CTRL_ENABLE, reg);
1072
1073 reg = musb_readl(tbase, TUSB_PHY_OTG_CTRL);
1074 reg |= TUSB_PHY_OTG_CTRL_WRPROTECT | TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP;
1075 musb_writel(tbase, TUSB_PHY_OTG_CTRL, reg);
1076
1077 spin_unlock_irqrestore(&musb->lock, flags);
1078
1079 return 0;
1080
1081err:
1082 spin_unlock_irqrestore(&musb->lock, flags);
1083
1084 if (musb->board_set_power)
1085 musb->board_set_power(0);
1086
1087 return -ENODEV;
1088}
1089
1090int __init musb_platform_init(struct musb *musb)
1091{
1092 struct platform_device *pdev;
1093 struct resource *mem;
1094 void __iomem *sync;
1095 int ret;
1096
1097 pdev = to_platform_device(musb->controller);
1098
1099 /* dma address for async dma */
1100 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1101 musb->async = mem->start;
1102
1103 /* dma address for sync dma */
1104 mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1105 if (!mem) {
1106 pr_debug("no sync dma resource?\n");
1107 return -ENODEV;
1108 }
1109 musb->sync = mem->start;
1110
1111 sync = ioremap(mem->start, mem->end - mem->start + 1);
1112 if (!sync) {
1113 pr_debug("ioremap for sync failed\n");
1114 return -ENOMEM;
1115 }
1116 musb->sync_va = sync;
1117
1118 /* Offsets from base: VLYNQ at 0x000, MUSB regs at 0x400,
1119 * FIFOs at 0x600, TUSB at 0x800
1120 */
1121 musb->mregs += TUSB_BASE_OFFSET;
1122
1123 ret = tusb_start(musb);
1124 if (ret) {
1125 printk(KERN_ERR "Could not start tusb6010 (%d)\n",
1126 ret);
1127 return -ENODEV;
1128 }
1129 musb->isr = tusb_interrupt;
1130
1131 if (is_host_enabled(musb))
1132 musb->board_set_vbus = tusb_source_power;
1133 if (is_peripheral_enabled(musb))
1134 musb->xceiv.set_power = tusb_draw_power;
1135
1136 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
1137
1138 return ret;
1139}
1140
1141int musb_platform_exit(struct musb *musb)
1142{
1143 del_timer_sync(&musb_idle_timer);
1144
1145 if (musb->board_set_power)
1146 musb->board_set_power(0);
1147
1148 iounmap(musb->sync_va);
1149
1150 return 0;
1151}
diff --git a/drivers/usb/musb/tusb6010.h b/drivers/usb/musb/tusb6010.h
new file mode 100644
index 000000000000..ab8c96286ce6
--- /dev/null
+++ b/drivers/usb/musb/tusb6010.h
@@ -0,0 +1,233 @@
1/*
2 * Definitions for TUSB6010 USB 2.0 OTG Dual Role controller
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 * Jarkko Nikula <jarkko.nikula@nokia.com>
6 * Tony Lindgren <tony@atomide.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __TUSB6010_H__
14#define __TUSB6010_H__
15
16extern u8 tusb_get_revision(struct musb *musb);
17
18#ifdef CONFIG_USB_TUSB6010
19#define musb_in_tusb() 1
20#else
21#define musb_in_tusb() 0
22#endif
23
24#ifdef CONFIG_USB_TUSB_OMAP_DMA
25#define tusb_dma_omap() 1
26#else
27#define tusb_dma_omap() 0
28#endif
29
30/* VLYNQ control register. 32-bit at offset 0x000 */
31#define TUSB_VLYNQ_CTRL 0x004
32
33/* Mentor Graphics OTG core registers. 8,- 16- and 32-bit at offset 0x400 */
34#define TUSB_BASE_OFFSET 0x400
35
36/* FIFO registers 32-bit at offset 0x600 */
37#define TUSB_FIFO_BASE 0x600
38
39/* Device System & Control registers. 32-bit at offset 0x800 */
40#define TUSB_SYS_REG_BASE 0x800
41
42#define TUSB_DEV_CONF (TUSB_SYS_REG_BASE + 0x000)
43#define TUSB_DEV_CONF_USB_HOST_MODE (1 << 16)
44#define TUSB_DEV_CONF_PROD_TEST_MODE (1 << 15)
45#define TUSB_DEV_CONF_SOFT_ID (1 << 1)
46#define TUSB_DEV_CONF_ID_SEL (1 << 0)
47
48#define TUSB_PHY_OTG_CTRL_ENABLE (TUSB_SYS_REG_BASE + 0x004)
49#define TUSB_PHY_OTG_CTRL (TUSB_SYS_REG_BASE + 0x008)
50#define TUSB_PHY_OTG_CTRL_WRPROTECT (0xa5 << 24)
51#define TUSB_PHY_OTG_CTRL_OTG_ID_PULLUP (1 << 23)
52#define TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN (1 << 19)
53#define TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN (1 << 18)
54#define TUSB_PHY_OTG_CTRL_TESTM2 (1 << 17)
55#define TUSB_PHY_OTG_CTRL_TESTM1 (1 << 16)
56#define TUSB_PHY_OTG_CTRL_TESTM0 (1 << 15)
57#define TUSB_PHY_OTG_CTRL_TX_DATA2 (1 << 14)
58#define TUSB_PHY_OTG_CTRL_TX_GZ2 (1 << 13)
59#define TUSB_PHY_OTG_CTRL_TX_ENABLE2 (1 << 12)
60#define TUSB_PHY_OTG_CTRL_DM_PULLDOWN (1 << 11)
61#define TUSB_PHY_OTG_CTRL_DP_PULLDOWN (1 << 10)
62#define TUSB_PHY_OTG_CTRL_OSC_EN (1 << 9)
63#define TUSB_PHY_OTG_CTRL_PHYREF_CLKSEL(v) (((v) & 3) << 7)
64#define TUSB_PHY_OTG_CTRL_PD (1 << 6)
65#define TUSB_PHY_OTG_CTRL_PLL_ON (1 << 5)
66#define TUSB_PHY_OTG_CTRL_EXT_RPU (1 << 4)
67#define TUSB_PHY_OTG_CTRL_PWR_GOOD (1 << 3)
68#define TUSB_PHY_OTG_CTRL_RESET (1 << 2)
69#define TUSB_PHY_OTG_CTRL_SUSPENDM (1 << 1)
70#define TUSB_PHY_OTG_CTRL_CLK_MODE (1 << 0)
71
72/*OTG status register */
73#define TUSB_DEV_OTG_STAT (TUSB_SYS_REG_BASE + 0x00c)
74#define TUSB_DEV_OTG_STAT_PWR_CLK_GOOD (1 << 8)
75#define TUSB_DEV_OTG_STAT_SESS_END (1 << 7)
76#define TUSB_DEV_OTG_STAT_SESS_VALID (1 << 6)
77#define TUSB_DEV_OTG_STAT_VBUS_VALID (1 << 5)
78#define TUSB_DEV_OTG_STAT_VBUS_SENSE (1 << 4)
79#define TUSB_DEV_OTG_STAT_ID_STATUS (1 << 3)
80#define TUSB_DEV_OTG_STAT_HOST_DISCON (1 << 2)
81#define TUSB_DEV_OTG_STAT_LINE_STATE (3 << 0)
82#define TUSB_DEV_OTG_STAT_DP_ENABLE (1 << 1)
83#define TUSB_DEV_OTG_STAT_DM_ENABLE (1 << 0)
84
85#define TUSB_DEV_OTG_TIMER (TUSB_SYS_REG_BASE + 0x010)
86# define TUSB_DEV_OTG_TIMER_ENABLE (1 << 31)
87# define TUSB_DEV_OTG_TIMER_VAL(v) ((v) & 0x07ffffff)
88#define TUSB_PRCM_REV (TUSB_SYS_REG_BASE + 0x014)
89
90/* PRCM configuration register */
91#define TUSB_PRCM_CONF (TUSB_SYS_REG_BASE + 0x018)
92#define TUSB_PRCM_CONF_SFW_CPEN (1 << 24)
93#define TUSB_PRCM_CONF_SYS_CLKSEL(v) (((v) & 3) << 16)
94
95/* PRCM management register */
96#define TUSB_PRCM_MNGMT (TUSB_SYS_REG_BASE + 0x01c)
97#define TUSB_PRCM_MNGMT_SRP_FIX_TIMER(v) (((v) & 0xf) << 25)
98#define TUSB_PRCM_MNGMT_SRP_FIX_EN (1 << 24)
99#define TUSB_PRCM_MNGMT_VBUS_VALID_TIMER(v) (((v) & 0xf) << 20)
100#define TUSB_PRCM_MNGMT_VBUS_VALID_FLT_EN (1 << 19)
101#define TUSB_PRCM_MNGMT_DFT_CLK_DIS (1 << 18)
102#define TUSB_PRCM_MNGMT_VLYNQ_CLK_DIS (1 << 17)
103#define TUSB_PRCM_MNGMT_OTG_SESS_END_EN (1 << 10)
104#define TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN (1 << 9)
105#define TUSB_PRCM_MNGMT_OTG_ID_PULLUP (1 << 8)
106#define TUSB_PRCM_MNGMT_15_SW_EN (1 << 4)
107#define TUSB_PRCM_MNGMT_33_SW_EN (1 << 3)
108#define TUSB_PRCM_MNGMT_5V_CPEN (1 << 2)
109#define TUSB_PRCM_MNGMT_PM_IDLE (1 << 1)
110#define TUSB_PRCM_MNGMT_DEV_IDLE (1 << 0)
111
112/* Wake-up source clear and mask registers */
113#define TUSB_PRCM_WAKEUP_SOURCE (TUSB_SYS_REG_BASE + 0x020)
114#define TUSB_PRCM_WAKEUP_CLEAR (TUSB_SYS_REG_BASE + 0x028)
115#define TUSB_PRCM_WAKEUP_MASK (TUSB_SYS_REG_BASE + 0x02c)
116#define TUSB_PRCM_WAKEUP_RESERVED_BITS (0xffffe << 13)
117#define TUSB_PRCM_WGPIO_7 (1 << 12)
118#define TUSB_PRCM_WGPIO_6 (1 << 11)
119#define TUSB_PRCM_WGPIO_5 (1 << 10)
120#define TUSB_PRCM_WGPIO_4 (1 << 9)
121#define TUSB_PRCM_WGPIO_3 (1 << 8)
122#define TUSB_PRCM_WGPIO_2 (1 << 7)
123#define TUSB_PRCM_WGPIO_1 (1 << 6)
124#define TUSB_PRCM_WGPIO_0 (1 << 5)
125#define TUSB_PRCM_WHOSTDISCON (1 << 4) /* Host disconnect */
126#define TUSB_PRCM_WBUS (1 << 3) /* USB bus resume */
127#define TUSB_PRCM_WNORCS (1 << 2) /* NOR chip select */
128#define TUSB_PRCM_WVBUS (1 << 1) /* OTG PHY VBUS */
129#define TUSB_PRCM_WID (1 << 0) /* OTG PHY ID detect */
130
131#define TUSB_PULLUP_1_CTRL (TUSB_SYS_REG_BASE + 0x030)
132#define TUSB_PULLUP_2_CTRL (TUSB_SYS_REG_BASE + 0x034)
133#define TUSB_INT_CTRL_REV (TUSB_SYS_REG_BASE + 0x038)
134#define TUSB_INT_CTRL_CONF (TUSB_SYS_REG_BASE + 0x03c)
135#define TUSB_USBIP_INT_SRC (TUSB_SYS_REG_BASE + 0x040)
136#define TUSB_USBIP_INT_SET (TUSB_SYS_REG_BASE + 0x044)
137#define TUSB_USBIP_INT_CLEAR (TUSB_SYS_REG_BASE + 0x048)
138#define TUSB_USBIP_INT_MASK (TUSB_SYS_REG_BASE + 0x04c)
139#define TUSB_DMA_INT_SRC (TUSB_SYS_REG_BASE + 0x050)
140#define TUSB_DMA_INT_SET (TUSB_SYS_REG_BASE + 0x054)
141#define TUSB_DMA_INT_CLEAR (TUSB_SYS_REG_BASE + 0x058)
142#define TUSB_DMA_INT_MASK (TUSB_SYS_REG_BASE + 0x05c)
143#define TUSB_GPIO_INT_SRC (TUSB_SYS_REG_BASE + 0x060)
144#define TUSB_GPIO_INT_SET (TUSB_SYS_REG_BASE + 0x064)
145#define TUSB_GPIO_INT_CLEAR (TUSB_SYS_REG_BASE + 0x068)
146#define TUSB_GPIO_INT_MASK (TUSB_SYS_REG_BASE + 0x06c)
147
148/* NOR flash interrupt source registers */
149#define TUSB_INT_SRC (TUSB_SYS_REG_BASE + 0x070)
150#define TUSB_INT_SRC_SET (TUSB_SYS_REG_BASE + 0x074)
151#define TUSB_INT_SRC_CLEAR (TUSB_SYS_REG_BASE + 0x078)
152#define TUSB_INT_MASK (TUSB_SYS_REG_BASE + 0x07c)
153#define TUSB_INT_SRC_TXRX_DMA_DONE (1 << 24)
154#define TUSB_INT_SRC_USB_IP_CORE (1 << 17)
155#define TUSB_INT_SRC_OTG_TIMEOUT (1 << 16)
156#define TUSB_INT_SRC_VBUS_SENSE_CHNG (1 << 15)
157#define TUSB_INT_SRC_ID_STATUS_CHNG (1 << 14)
158#define TUSB_INT_SRC_DEV_WAKEUP (1 << 13)
159#define TUSB_INT_SRC_DEV_READY (1 << 12)
160#define TUSB_INT_SRC_USB_IP_TX (1 << 9)
161#define TUSB_INT_SRC_USB_IP_RX (1 << 8)
162#define TUSB_INT_SRC_USB_IP_VBUS_ERR (1 << 7)
163#define TUSB_INT_SRC_USB_IP_VBUS_REQ (1 << 6)
164#define TUSB_INT_SRC_USB_IP_DISCON (1 << 5)
165#define TUSB_INT_SRC_USB_IP_CONN (1 << 4)
166#define TUSB_INT_SRC_USB_IP_SOF (1 << 3)
167#define TUSB_INT_SRC_USB_IP_RST_BABBLE (1 << 2)
168#define TUSB_INT_SRC_USB_IP_RESUME (1 << 1)
169#define TUSB_INT_SRC_USB_IP_SUSPEND (1 << 0)
170
171/* NOR flash interrupt registers reserved bits. Must be written as 0 */
172#define TUSB_INT_MASK_RESERVED_17 (0x3fff << 17)
173#define TUSB_INT_MASK_RESERVED_13 (1 << 13)
174#define TUSB_INT_MASK_RESERVED_8 (0xf << 8)
175#define TUSB_INT_SRC_RESERVED_26 (0x1f << 26)
176#define TUSB_INT_SRC_RESERVED_18 (0x3f << 18)
177#define TUSB_INT_SRC_RESERVED_10 (0x03 << 10)
178
179/* Reserved bits for NOR flash interrupt mask and clear register */
180#define TUSB_INT_MASK_RESERVED_BITS (TUSB_INT_MASK_RESERVED_17 | \
181 TUSB_INT_MASK_RESERVED_13 | \
182 TUSB_INT_MASK_RESERVED_8)
183
184/* Reserved bits for NOR flash interrupt status register */
185#define TUSB_INT_SRC_RESERVED_BITS (TUSB_INT_SRC_RESERVED_26 | \
186 TUSB_INT_SRC_RESERVED_18 | \
187 TUSB_INT_SRC_RESERVED_10)
188
189#define TUSB_GPIO_REV (TUSB_SYS_REG_BASE + 0x080)
190#define TUSB_GPIO_CONF (TUSB_SYS_REG_BASE + 0x084)
191#define TUSB_DMA_CTRL_REV (TUSB_SYS_REG_BASE + 0x100)
192#define TUSB_DMA_REQ_CONF (TUSB_SYS_REG_BASE + 0x104)
193#define TUSB_EP0_CONF (TUSB_SYS_REG_BASE + 0x108)
194#define TUSB_DMA_EP_MAP (TUSB_SYS_REG_BASE + 0x148)
195
196/* Offsets from each ep base register */
197#define TUSB_EP_TX_OFFSET 0x10c /* EP_IN in docs */
198#define TUSB_EP_RX_OFFSET 0x14c /* EP_OUT in docs */
199#define TUSB_EP_MAX_PACKET_SIZE_OFFSET 0x188
200
201#define TUSB_WAIT_COUNT (TUSB_SYS_REG_BASE + 0x1c8)
202#define TUSB_SCRATCH_PAD (TUSB_SYS_REG_BASE + 0x1c4)
203#define TUSB_PROD_TEST_RESET (TUSB_SYS_REG_BASE + 0x1d8)
204
205/* Device System & Control register bitfields */
206#define TUSB_INT_CTRL_CONF_INT_RELCYC(v) (((v) & 0x7) << 18)
207#define TUSB_INT_CTRL_CONF_INT_POLARITY (1 << 17)
208#define TUSB_INT_CTRL_CONF_INT_MODE (1 << 16)
209#define TUSB_GPIO_CONF_DMAREQ(v) (((v) & 0x3f) << 24)
210#define TUSB_DMA_REQ_CONF_BURST_SIZE(v) (((v) & 3) << 26)
211#define TUSB_DMA_REQ_CONF_DMA_REQ_EN(v) (((v) & 0x3f) << 20)
212#define TUSB_DMA_REQ_CONF_DMA_REQ_ASSER(v) (((v) & 0xf) << 16)
213#define TUSB_EP0_CONFIG_SW_EN (1 << 8)
214#define TUSB_EP0_CONFIG_DIR_TX (1 << 7)
215#define TUSB_EP0_CONFIG_XFR_SIZE(v) ((v) & 0x7f)
216#define TUSB_EP_CONFIG_SW_EN (1 << 31)
217#define TUSB_EP_CONFIG_XFR_SIZE(v) ((v) & 0x7fffffff)
218#define TUSB_PROD_TEST_RESET_VAL 0xa596
219#define TUSB_EP_FIFO(ep) (TUSB_FIFO_BASE + (ep) * 0x20)
220
221#define TUSB_DIDR1_LO (TUSB_SYS_REG_BASE + 0x1f8)
222#define TUSB_DIDR1_HI (TUSB_SYS_REG_BASE + 0x1fc)
223#define TUSB_DIDR1_HI_CHIP_REV(v) (((v) >> 17) & 0xf)
224#define TUSB_DIDR1_HI_REV_20 0
225#define TUSB_DIDR1_HI_REV_30 1
226#define TUSB_DIDR1_HI_REV_31 2
227
228#define TUSB_REV_10 0x10
229#define TUSB_REV_20 0x20
230#define TUSB_REV_30 0x30
231#define TUSB_REV_31 0x31
232
233#endif /* __TUSB6010_H__ */
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
new file mode 100644
index 000000000000..52f7f29cebda
--- /dev/null
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -0,0 +1,719 @@
1/*
2 * TUSB6010 USB 2.0 OTG Dual Role controller OMAP DMA interface
3 *
4 * Copyright (C) 2006 Nokia Corporation
5 * Tony Lindgren <tony@atomide.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/init.h>
15#include <linux/usb.h>
16#include <linux/platform_device.h>
17#include <linux/dma-mapping.h>
18#include <asm/arch/dma.h>
19#include <asm/arch/mux.h>
20
21#include "musb_core.h"
22
23#define to_chdat(c) ((struct tusb_omap_dma_ch *)(c)->private_data)
24
25#define MAX_DMAREQ 5 /* REVISIT: Really 6, but req5 not OK */
26
27struct tusb_omap_dma_ch {
28 struct musb *musb;
29 void __iomem *tbase;
30 unsigned long phys_offset;
31 int epnum;
32 u8 tx;
33 struct musb_hw_ep *hw_ep;
34
35 int ch;
36 s8 dmareq;
37 s8 sync_dev;
38
39 struct tusb_omap_dma *tusb_dma;
40
41 void __iomem *dma_addr;
42
43 u32 len;
44 u16 packet_sz;
45 u16 transfer_packet_sz;
46 u32 transfer_len;
47 u32 completed_len;
48};
49
50struct tusb_omap_dma {
51 struct dma_controller controller;
52 struct musb *musb;
53 void __iomem *tbase;
54
55 int ch;
56 s8 dmareq;
57 s8 sync_dev;
58 unsigned multichannel:1;
59};
60
61static int tusb_omap_dma_start(struct dma_controller *c)
62{
63 struct tusb_omap_dma *tusb_dma;
64
65 tusb_dma = container_of(c, struct tusb_omap_dma, controller);
66
67 /* DBG(3, "ep%i ch: %i\n", chdat->epnum, chdat->ch); */
68
69 return 0;
70}
71
72static int tusb_omap_dma_stop(struct dma_controller *c)
73{
74 struct tusb_omap_dma *tusb_dma;
75
76 tusb_dma = container_of(c, struct tusb_omap_dma, controller);
77
78 /* DBG(3, "ep%i ch: %i\n", chdat->epnum, chdat->ch); */
79
80 return 0;
81}
82
83/*
84 * Allocate dmareq0 to the current channel unless it's already taken
85 */
86static inline int tusb_omap_use_shared_dmareq(struct tusb_omap_dma_ch *chdat)
87{
88 u32 reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
89
90 if (reg != 0) {
91 DBG(3, "ep%i dmareq0 is busy for ep%i\n",
92 chdat->epnum, reg & 0xf);
93 return -EAGAIN;
94 }
95
96 if (chdat->tx)
97 reg = (1 << 4) | chdat->epnum;
98 else
99 reg = chdat->epnum;
100
101 musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
102
103 return 0;
104}
105
106static inline void tusb_omap_free_shared_dmareq(struct tusb_omap_dma_ch *chdat)
107{
108 u32 reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
109
110 if ((reg & 0xf) != chdat->epnum) {
111 printk(KERN_ERR "ep%i trying to release dmareq0 for ep%i\n",
112 chdat->epnum, reg & 0xf);
113 return;
114 }
115 musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, 0);
116}
117
118/*
119 * See also musb_dma_completion in plat_uds.c and musb_g_[tx|rx]() in
120 * musb_gadget.c.
121 */
122static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
123{
124 struct dma_channel *channel = (struct dma_channel *)data;
125 struct tusb_omap_dma_ch *chdat = to_chdat(channel);
126 struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
127 struct musb *musb = chdat->musb;
128 struct musb_hw_ep *hw_ep = chdat->hw_ep;
129 void __iomem *ep_conf = hw_ep->conf;
130 void __iomem *mbase = musb->mregs;
131 unsigned long remaining, flags, pio;
132 int ch;
133
134 spin_lock_irqsave(&musb->lock, flags);
135
136 if (tusb_dma->multichannel)
137 ch = chdat->ch;
138 else
139 ch = tusb_dma->ch;
140
141 if (ch_status != OMAP_DMA_BLOCK_IRQ)
142 printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
143
144 DBG(3, "ep%i %s dma callback ch: %i status: %x\n",
145 chdat->epnum, chdat->tx ? "tx" : "rx",
146 ch, ch_status);
147
148 if (chdat->tx)
149 remaining = musb_readl(ep_conf, TUSB_EP_TX_OFFSET);
150 else
151 remaining = musb_readl(ep_conf, TUSB_EP_RX_OFFSET);
152
153 remaining = TUSB_EP_CONFIG_XFR_SIZE(remaining);
154
155 /* HW issue #10: XFR_SIZE may get corrupt on DMA (both async & sync) */
156 if (unlikely(remaining > chdat->transfer_len)) {
157 DBG(2, "Corrupt %s dma ch%i XFR_SIZE: 0x%08lx\n",
158 chdat->tx ? "tx" : "rx", chdat->ch,
159 remaining);
160 remaining = 0;
161 }
162
163 channel->actual_len = chdat->transfer_len - remaining;
164 pio = chdat->len - channel->actual_len;
165
166 DBG(3, "DMA remaining %lu/%u\n", remaining, chdat->transfer_len);
167
168 /* Transfer remaining 1 - 31 bytes */
169 if (pio > 0 && pio < 32) {
170 u8 *buf;
171
172 DBG(3, "Using PIO for remaining %lu bytes\n", pio);
173 buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
174 if (chdat->tx) {
175 dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
176 chdat->transfer_len, DMA_TO_DEVICE);
177 musb_write_fifo(hw_ep, pio, buf);
178 } else {
179 musb_read_fifo(hw_ep, pio, buf);
180 dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
181 chdat->transfer_len, DMA_FROM_DEVICE);
182 }
183 channel->actual_len += pio;
184 }
185
186 if (!tusb_dma->multichannel)
187 tusb_omap_free_shared_dmareq(chdat);
188
189 channel->status = MUSB_DMA_STATUS_FREE;
190
191 /* Handle only RX callbacks here. TX callbacks must be handled based
192 * on the TUSB DMA status interrupt.
193 * REVISIT: Use both TUSB DMA status interrupt and OMAP DMA callback
194 * interrupt for RX and TX.
195 */
196 if (!chdat->tx)
197 musb_dma_completion(musb, chdat->epnum, chdat->tx);
198
199 /* We must terminate short tx transfers manually by setting TXPKTRDY.
200 * REVISIT: This same problem may occur with other MUSB dma as well.
201 * Easy to test with g_ether by pinging the MUSB board with ping -s54.
202 */
203 if ((chdat->transfer_len < chdat->packet_sz)
204 || (chdat->transfer_len % chdat->packet_sz != 0)) {
205 u16 csr;
206
207 if (chdat->tx) {
208 DBG(3, "terminating short tx packet\n");
209 musb_ep_select(mbase, chdat->epnum);
210 csr = musb_readw(hw_ep->regs, MUSB_TXCSR);
211 csr |= MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY
212 | MUSB_TXCSR_P_WZC_BITS;
213 musb_writew(hw_ep->regs, MUSB_TXCSR, csr);
214 }
215 }
216
217 spin_unlock_irqrestore(&musb->lock, flags);
218}
219
220static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
221 u8 rndis_mode, dma_addr_t dma_addr, u32 len)
222{
223 struct tusb_omap_dma_ch *chdat = to_chdat(channel);
224 struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
225 struct musb *musb = chdat->musb;
226 struct musb_hw_ep *hw_ep = chdat->hw_ep;
227 void __iomem *mbase = musb->mregs;
228 void __iomem *ep_conf = hw_ep->conf;
229 dma_addr_t fifo = hw_ep->fifo_sync;
230 struct omap_dma_channel_params dma_params;
231 u32 dma_remaining;
232 int src_burst, dst_burst;
233 u16 csr;
234 int ch;
235 s8 dmareq;
236 s8 sync_dev;
237
238 if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
239 return false;
240
241 /*
242 * HW issue #10: Async dma will eventually corrupt the XFR_SIZE
243 * register which will cause missed DMA interrupt. We could try to
244 * use a timer for the callback, but it is unsafe as the XFR_SIZE
245 * register is corrupt, and we won't know if the DMA worked.
246 */
247 if (dma_addr & 0x2)
248 return false;
249
250 /*
251 * Because of HW issue #10, it seems like mixing sync DMA and async
252 * PIO access can confuse the DMA. Make sure XFR_SIZE is reset before
253 * using the channel for DMA.
254 */
255 if (chdat->tx)
256 dma_remaining = musb_readl(ep_conf, TUSB_EP_TX_OFFSET);
257 else
258 dma_remaining = musb_readl(ep_conf, TUSB_EP_RX_OFFSET);
259
260 dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
261 if (dma_remaining) {
262 DBG(2, "Busy %s dma ch%i, not using: %08x\n",
263 chdat->tx ? "tx" : "rx", chdat->ch,
264 dma_remaining);
265 return false;
266 }
267
268 chdat->transfer_len = len & ~0x1f;
269
270 if (len < packet_sz)
271 chdat->transfer_packet_sz = chdat->transfer_len;
272 else
273 chdat->transfer_packet_sz = packet_sz;
274
275 if (tusb_dma->multichannel) {
276 ch = chdat->ch;
277 dmareq = chdat->dmareq;
278 sync_dev = chdat->sync_dev;
279 } else {
280 if (tusb_omap_use_shared_dmareq(chdat) != 0) {
281 DBG(3, "could not get dma for ep%i\n", chdat->epnum);
282 return false;
283 }
284 if (tusb_dma->ch < 0) {
285 /* REVISIT: This should get blocked earlier, happens
286 * with MSC ErrorRecoveryTest
287 */
288 WARN_ON(1);
289 return false;
290 }
291
292 ch = tusb_dma->ch;
293 dmareq = tusb_dma->dmareq;
294 sync_dev = tusb_dma->sync_dev;
295 omap_set_dma_callback(ch, tusb_omap_dma_cb, channel);
296 }
297
298 chdat->packet_sz = packet_sz;
299 chdat->len = len;
300 channel->actual_len = 0;
301 chdat->dma_addr = (void __iomem *)dma_addr;
302 channel->status = MUSB_DMA_STATUS_BUSY;
303
304 /* Since we're recycling dma areas, we need to clean or invalidate */
305 if (chdat->tx)
306 dma_cache_maint(phys_to_virt(dma_addr), len, DMA_TO_DEVICE);
307 else
308 dma_cache_maint(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE);
309
310 /* Use 16-bit transfer if dma_addr is not 32-bit aligned */
311 if ((dma_addr & 0x3) == 0) {
312 dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
313 dma_params.elem_count = 8; /* Elements in frame */
314 } else {
315 dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
316 dma_params.elem_count = 16; /* Elements in frame */
317 fifo = hw_ep->fifo_async;
318 }
319
320 dma_params.frame_count = chdat->transfer_len / 32; /* Burst sz frame */
321
322 DBG(3, "ep%i %s dma ch%i dma: %08x len: %u(%u) packet_sz: %i(%i)\n",
323 chdat->epnum, chdat->tx ? "tx" : "rx",
324 ch, dma_addr, chdat->transfer_len, len,
325 chdat->transfer_packet_sz, packet_sz);
326
327 /*
328 * Prepare omap DMA for transfer
329 */
330 if (chdat->tx) {
331 dma_params.src_amode = OMAP_DMA_AMODE_POST_INC;
332 dma_params.src_start = (unsigned long)dma_addr;
333 dma_params.src_ei = 0;
334 dma_params.src_fi = 0;
335
336 dma_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
337 dma_params.dst_start = (unsigned long)fifo;
338 dma_params.dst_ei = 1;
339 dma_params.dst_fi = -31; /* Loop 32 byte window */
340
341 dma_params.trigger = sync_dev;
342 dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
343 dma_params.src_or_dst_synch = 0; /* Dest sync */
344
345 src_burst = OMAP_DMA_DATA_BURST_16; /* 16x32 read */
346 dst_burst = OMAP_DMA_DATA_BURST_8; /* 8x32 write */
347 } else {
348 dma_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX;
349 dma_params.src_start = (unsigned long)fifo;
350 dma_params.src_ei = 1;
351 dma_params.src_fi = -31; /* Loop 32 byte window */
352
353 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
354 dma_params.dst_start = (unsigned long)dma_addr;
355 dma_params.dst_ei = 0;
356 dma_params.dst_fi = 0;
357
358 dma_params.trigger = sync_dev;
359 dma_params.sync_mode = OMAP_DMA_SYNC_FRAME;
360 dma_params.src_or_dst_synch = 1; /* Source sync */
361
362 src_burst = OMAP_DMA_DATA_BURST_8; /* 8x32 read */
363 dst_burst = OMAP_DMA_DATA_BURST_16; /* 16x32 write */
364 }
365
366 DBG(3, "ep%i %s using %i-bit %s dma from 0x%08lx to 0x%08lx\n",
367 chdat->epnum, chdat->tx ? "tx" : "rx",
368 (dma_params.data_type == OMAP_DMA_DATA_TYPE_S32) ? 32 : 16,
369 ((dma_addr & 0x3) == 0) ? "sync" : "async",
370 dma_params.src_start, dma_params.dst_start);
371
372 omap_set_dma_params(ch, &dma_params);
373 omap_set_dma_src_burst_mode(ch, src_burst);
374 omap_set_dma_dest_burst_mode(ch, dst_burst);
375 omap_set_dma_write_mode(ch, OMAP_DMA_WRITE_LAST_NON_POSTED);
376
377 /*
378 * Prepare MUSB for DMA transfer
379 */
380 if (chdat->tx) {
381 musb_ep_select(mbase, chdat->epnum);
382 csr = musb_readw(hw_ep->regs, MUSB_TXCSR);
383 csr |= (MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB
384 | MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
385 csr &= ~MUSB_TXCSR_P_UNDERRUN;
386 musb_writew(hw_ep->regs, MUSB_TXCSR, csr);
387 } else {
388 musb_ep_select(mbase, chdat->epnum);
389 csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
390 csr |= MUSB_RXCSR_DMAENAB;
391 csr &= ~(MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAMODE);
392 musb_writew(hw_ep->regs, MUSB_RXCSR,
393 csr | MUSB_RXCSR_P_WZC_BITS);
394 }
395
396 /*
397 * Start DMA transfer
398 */
399 omap_start_dma(ch);
400
401 if (chdat->tx) {
402 /* Send transfer_packet_sz packets at a time */
403 musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
404 chdat->transfer_packet_sz);
405
406 musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
407 TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
408 } else {
409 /* Receive transfer_packet_sz packets at a time */
410 musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
411 chdat->transfer_packet_sz << 16);
412
413 musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
414 TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
415 }
416
417 return true;
418}
419
420static int tusb_omap_dma_abort(struct dma_channel *channel)
421{
422 struct tusb_omap_dma_ch *chdat = to_chdat(channel);
423 struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
424
425 if (!tusb_dma->multichannel) {
426 if (tusb_dma->ch >= 0) {
427 omap_stop_dma(tusb_dma->ch);
428 omap_free_dma(tusb_dma->ch);
429 tusb_dma->ch = -1;
430 }
431
432 tusb_dma->dmareq = -1;
433 tusb_dma->sync_dev = -1;
434 }
435
436 channel->status = MUSB_DMA_STATUS_FREE;
437
438 return 0;
439}
440
441static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
442{
443 u32 reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
444 int i, dmareq_nr = -1;
445
446 const int sync_dev[6] = {
447 OMAP24XX_DMA_EXT_DMAREQ0,
448 OMAP24XX_DMA_EXT_DMAREQ1,
449 OMAP242X_DMA_EXT_DMAREQ2,
450 OMAP242X_DMA_EXT_DMAREQ3,
451 OMAP242X_DMA_EXT_DMAREQ4,
452 OMAP242X_DMA_EXT_DMAREQ5,
453 };
454
455 for (i = 0; i < MAX_DMAREQ; i++) {
456 int cur = (reg & (0xf << (i * 5))) >> (i * 5);
457 if (cur == 0) {
458 dmareq_nr = i;
459 break;
460 }
461 }
462
463 if (dmareq_nr == -1)
464 return -EAGAIN;
465
466 reg |= (chdat->epnum << (dmareq_nr * 5));
467 if (chdat->tx)
468 reg |= ((1 << 4) << (dmareq_nr * 5));
469 musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
470
471 chdat->dmareq = dmareq_nr;
472 chdat->sync_dev = sync_dev[chdat->dmareq];
473
474 return 0;
475}
476
477static inline void tusb_omap_dma_free_dmareq(struct tusb_omap_dma_ch *chdat)
478{
479 u32 reg;
480
481 if (!chdat || chdat->dmareq < 0)
482 return;
483
484 reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
485 reg &= ~(0x1f << (chdat->dmareq * 5));
486 musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
487
488 chdat->dmareq = -1;
489 chdat->sync_dev = -1;
490}
491
492static struct dma_channel *dma_channel_pool[MAX_DMAREQ];
493
494static struct dma_channel *
495tusb_omap_dma_allocate(struct dma_controller *c,
496 struct musb_hw_ep *hw_ep,
497 u8 tx)
498{
499 int ret, i;
500 const char *dev_name;
501 struct tusb_omap_dma *tusb_dma;
502 struct musb *musb;
503 void __iomem *tbase;
504 struct dma_channel *channel = NULL;
505 struct tusb_omap_dma_ch *chdat = NULL;
506 u32 reg;
507
508 tusb_dma = container_of(c, struct tusb_omap_dma, controller);
509 musb = tusb_dma->musb;
510 tbase = musb->ctrl_base;
511
512 reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
513 if (tx)
514 reg &= ~(1 << hw_ep->epnum);
515 else
516 reg &= ~(1 << (hw_ep->epnum + 15));
517 musb_writel(tbase, TUSB_DMA_INT_MASK, reg);
518
519 /* REVISIT: Why does dmareq5 not work? */
520 if (hw_ep->epnum == 0) {
521 DBG(3, "Not allowing DMA for ep0 %s\n", tx ? "tx" : "rx");
522 return NULL;
523 }
524
525 for (i = 0; i < MAX_DMAREQ; i++) {
526 struct dma_channel *ch = dma_channel_pool[i];
527 if (ch->status == MUSB_DMA_STATUS_UNKNOWN) {
528 ch->status = MUSB_DMA_STATUS_FREE;
529 channel = ch;
530 chdat = ch->private_data;
531 break;
532 }
533 }
534
535 if (!channel)
536 return NULL;
537
538 if (tx) {
539 chdat->tx = 1;
540 dev_name = "TUSB transmit";
541 } else {
542 chdat->tx = 0;
543 dev_name = "TUSB receive";
544 }
545
546 chdat->musb = tusb_dma->musb;
547 chdat->tbase = tusb_dma->tbase;
548 chdat->hw_ep = hw_ep;
549 chdat->epnum = hw_ep->epnum;
550 chdat->dmareq = -1;
551 chdat->completed_len = 0;
552 chdat->tusb_dma = tusb_dma;
553
554 channel->max_len = 0x7fffffff;
555 channel->desired_mode = 0;
556 channel->actual_len = 0;
557
558 if (tusb_dma->multichannel) {
559 ret = tusb_omap_dma_allocate_dmareq(chdat);
560 if (ret != 0)
561 goto free_dmareq;
562
563 ret = omap_request_dma(chdat->sync_dev, dev_name,
564 tusb_omap_dma_cb, channel, &chdat->ch);
565 if (ret != 0)
566 goto free_dmareq;
567 } else if (tusb_dma->ch == -1) {
568 tusb_dma->dmareq = 0;
569 tusb_dma->sync_dev = OMAP24XX_DMA_EXT_DMAREQ0;
570
571 /* Callback data gets set later in the shared dmareq case */
572 ret = omap_request_dma(tusb_dma->sync_dev, "TUSB shared",
573 tusb_omap_dma_cb, NULL, &tusb_dma->ch);
574 if (ret != 0)
575 goto free_dmareq;
576
577 chdat->dmareq = -1;
578 chdat->ch = -1;
579 }
580
581 DBG(3, "ep%i %s dma: %s dma%i dmareq%i sync%i\n",
582 chdat->epnum,
583 chdat->tx ? "tx" : "rx",
584 chdat->ch >= 0 ? "dedicated" : "shared",
585 chdat->ch >= 0 ? chdat->ch : tusb_dma->ch,
586 chdat->dmareq >= 0 ? chdat->dmareq : tusb_dma->dmareq,
587 chdat->sync_dev >= 0 ? chdat->sync_dev : tusb_dma->sync_dev);
588
589 return channel;
590
591free_dmareq:
592 tusb_omap_dma_free_dmareq(chdat);
593
594 DBG(3, "ep%i: Could not get a DMA channel\n", chdat->epnum);
595 channel->status = MUSB_DMA_STATUS_UNKNOWN;
596
597 return NULL;
598}
599
600static void tusb_omap_dma_release(struct dma_channel *channel)
601{
602 struct tusb_omap_dma_ch *chdat = to_chdat(channel);
603 struct musb *musb = chdat->musb;
604 void __iomem *tbase = musb->ctrl_base;
605 u32 reg;
606
607 DBG(3, "ep%i ch%i\n", chdat->epnum, chdat->ch);
608
609 reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
610 if (chdat->tx)
611 reg |= (1 << chdat->epnum);
612 else
613 reg |= (1 << (chdat->epnum + 15));
614 musb_writel(tbase, TUSB_DMA_INT_MASK, reg);
615
616 reg = musb_readl(tbase, TUSB_DMA_INT_CLEAR);
617 if (chdat->tx)
618 reg |= (1 << chdat->epnum);
619 else
620 reg |= (1 << (chdat->epnum + 15));
621 musb_writel(tbase, TUSB_DMA_INT_CLEAR, reg);
622
623 channel->status = MUSB_DMA_STATUS_UNKNOWN;
624
625 if (chdat->ch >= 0) {
626 omap_stop_dma(chdat->ch);
627 omap_free_dma(chdat->ch);
628 chdat->ch = -1;
629 }
630
631 if (chdat->dmareq >= 0)
632 tusb_omap_dma_free_dmareq(chdat);
633
634 channel = NULL;
635}
636
637void dma_controller_destroy(struct dma_controller *c)
638{
639 struct tusb_omap_dma *tusb_dma;
640 int i;
641
642 tusb_dma = container_of(c, struct tusb_omap_dma, controller);
643 for (i = 0; i < MAX_DMAREQ; i++) {
644 struct dma_channel *ch = dma_channel_pool[i];
645 if (ch) {
646 kfree(ch->private_data);
647 kfree(ch);
648 }
649 }
650
651 if (!tusb_dma->multichannel && tusb_dma && tusb_dma->ch >= 0)
652 omap_free_dma(tusb_dma->ch);
653
654 kfree(tusb_dma);
655}
656
657struct dma_controller *__init
658dma_controller_create(struct musb *musb, void __iomem *base)
659{
660 void __iomem *tbase = musb->ctrl_base;
661 struct tusb_omap_dma *tusb_dma;
662 int i;
663
664 /* REVISIT: Get dmareq lines used from board-*.c */
665
666 musb_writel(musb->ctrl_base, TUSB_DMA_INT_MASK, 0x7fffffff);
667 musb_writel(musb->ctrl_base, TUSB_DMA_EP_MAP, 0);
668
669 musb_writel(tbase, TUSB_DMA_REQ_CONF,
670 TUSB_DMA_REQ_CONF_BURST_SIZE(2)
671 | TUSB_DMA_REQ_CONF_DMA_REQ_EN(0x3f)
672 | TUSB_DMA_REQ_CONF_DMA_REQ_ASSER(2));
673
674 tusb_dma = kzalloc(sizeof(struct tusb_omap_dma), GFP_KERNEL);
675 if (!tusb_dma)
676 goto cleanup;
677
678 tusb_dma->musb = musb;
679 tusb_dma->tbase = musb->ctrl_base;
680
681 tusb_dma->ch = -1;
682 tusb_dma->dmareq = -1;
683 tusb_dma->sync_dev = -1;
684
685 tusb_dma->controller.start = tusb_omap_dma_start;
686 tusb_dma->controller.stop = tusb_omap_dma_stop;
687 tusb_dma->controller.channel_alloc = tusb_omap_dma_allocate;
688 tusb_dma->controller.channel_release = tusb_omap_dma_release;
689 tusb_dma->controller.channel_program = tusb_omap_dma_program;
690 tusb_dma->controller.channel_abort = tusb_omap_dma_abort;
691
692 if (tusb_get_revision(musb) >= TUSB_REV_30)
693 tusb_dma->multichannel = 1;
694
695 for (i = 0; i < MAX_DMAREQ; i++) {
696 struct dma_channel *ch;
697 struct tusb_omap_dma_ch *chdat;
698
699 ch = kzalloc(sizeof(struct dma_channel), GFP_KERNEL);
700 if (!ch)
701 goto cleanup;
702
703 dma_channel_pool[i] = ch;
704
705 chdat = kzalloc(sizeof(struct tusb_omap_dma_ch), GFP_KERNEL);
706 if (!chdat)
707 goto cleanup;
708
709 ch->status = MUSB_DMA_STATUS_UNKNOWN;
710 ch->private_data = chdat;
711 }
712
713 return &tusb_dma->controller;
714
715cleanup:
716 dma_controller_destroy(&tusb_dma->controller);
717
718 return NULL;
719}
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 8878c1767fc8..70338f4ec918 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -499,9 +499,10 @@ config USB_SERIAL_SAFE_PADDED
499config USB_SERIAL_SIERRAWIRELESS 499config USB_SERIAL_SIERRAWIRELESS
500 tristate "USB Sierra Wireless Driver" 500 tristate "USB Sierra Wireless Driver"
501 help 501 help
502 Say M here if you want to use a Sierra Wireless device (if 502 Say M here if you want to use Sierra Wireless devices.
503 using an PC 5220 or AC580 please use the Airprime driver 503
504 instead). 504 Many deviecs have a feature known as TRU-Install, for those devices
505 to work properly the USB Storage Sierra feature must be enabled.
505 506
506 To compile this driver as a module, choose M here: the 507 To compile this driver as a module, choose M here: the
507 module will be called sierra. 508 module will be called sierra.
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 838717250145..984f6eff4c47 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -563,6 +563,7 @@ static struct usb_device_id id_table_combined [] = {
563 { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, 563 { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
564 { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, 564 { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
565 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, 565 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
566 { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) },
566 { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, 567 { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
567 { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, 568 { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
568 { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, 569 { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
@@ -637,6 +638,7 @@ static struct usb_device_id id_table_combined [] = {
637 { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, 638 { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
638 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, 639 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
639 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, 640 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
641 { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
640 { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, 642 { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
641 { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, 643 { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
642 { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, 644 { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
@@ -646,6 +648,10 @@ static struct usb_device_id id_table_combined [] = {
646 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 648 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
647 { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID), 649 { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID),
648 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, 650 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
651 { USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID),
652 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
653 { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
654 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
649 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, 655 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
650 { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, 656 { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
651 { }, /* Optional parameter entry */ 657 { }, /* Optional parameter entry */
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index a577ea44dcf9..382265bba969 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -524,7 +524,9 @@
524#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ 524#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */
525#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ 525#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */
526#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ 526#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
527#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */
527#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ 528#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */
529#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */
528 530
529/* 531/*
530 * Definitions for ID TECH (www.idt-net.com) devices 532 * Definitions for ID TECH (www.idt-net.com) devices
@@ -815,6 +817,11 @@
815#define OLIMEX_VID 0x15BA 817#define OLIMEX_VID 0x15BA
816#define OLIMEX_ARM_USB_OCD_PID 0x0003 818#define OLIMEX_ARM_USB_OCD_PID 0x0003
817 819
820/* Luminary Micro Stellaris Boards, VID = FTDI_VID */
821/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */
822#define LMI_LM3S_DEVEL_BOARD_PID 0xbcd8
823#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9
824
818/* www.elsterelectricity.com Elster Unicom III Optical Probe */ 825/* www.elsterelectricity.com Elster Unicom III Optical Probe */
819#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */ 826#define FTDI_ELSTER_UNICOM_PID 0xE700 /* Product Id */
820 827
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e4eca95f2b0f..e143198aeb02 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -186,6 +186,23 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
186#define BANDRICH_VENDOR_ID 0x1A8D 186#define BANDRICH_VENDOR_ID 0x1A8D
187#define BANDRICH_PRODUCT_C100_1 0x1002 187#define BANDRICH_PRODUCT_C100_1 0x1002
188#define BANDRICH_PRODUCT_C100_2 0x1003 188#define BANDRICH_PRODUCT_C100_2 0x1003
189#define BANDRICH_PRODUCT_1004 0x1004
190#define BANDRICH_PRODUCT_1005 0x1005
191#define BANDRICH_PRODUCT_1006 0x1006
192#define BANDRICH_PRODUCT_1007 0x1007
193#define BANDRICH_PRODUCT_1008 0x1008
194#define BANDRICH_PRODUCT_1009 0x1009
195#define BANDRICH_PRODUCT_100A 0x100a
196
197#define BANDRICH_PRODUCT_100B 0x100b
198#define BANDRICH_PRODUCT_100C 0x100c
199#define BANDRICH_PRODUCT_100D 0x100d
200#define BANDRICH_PRODUCT_100E 0x100e
201
202#define BANDRICH_PRODUCT_100F 0x100f
203#define BANDRICH_PRODUCT_1010 0x1010
204#define BANDRICH_PRODUCT_1011 0x1011
205#define BANDRICH_PRODUCT_1012 0x1012
189 206
190#define AMOI_VENDOR_ID 0x1614 207#define AMOI_VENDOR_ID 0x1614
191#define AMOI_PRODUCT_9508 0x0800 208#define AMOI_PRODUCT_9508 0x0800
@@ -197,6 +214,10 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
197#define TELIT_VENDOR_ID 0x1bc7 214#define TELIT_VENDOR_ID 0x1bc7
198#define TELIT_PRODUCT_UC864E 0x1003 215#define TELIT_PRODUCT_UC864E 0x1003
199 216
217/* ZTE PRODUCTS */
218#define ZTE_VENDOR_ID 0x19d2
219#define ZTE_PRODUCT_MF628 0x0015
220
200static struct usb_device_id option_ids[] = { 221static struct usb_device_id option_ids[] = {
201 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, 222 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
202 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, 223 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -302,12 +323,28 @@ static struct usb_device_id option_ids[] = {
302 { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) }, 323 { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
303 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, 324 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
304 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, 325 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
326 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) },
327 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005) },
328 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006) },
329 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007) },
330 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008) },
331 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009) },
332 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A) },
333 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B) },
334 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C) },
335 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D) },
336 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E) },
337 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F) },
338 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010) },
339 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011) },
340 { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012) },
305 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, 341 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
306 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, 342 { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
307 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ 343 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
308 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ 344 { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
309 { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ 345 { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
310 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, 346 { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
347 { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
311 { } /* Terminating entry */ 348 { } /* Terminating entry */
312}; 349};
313MODULE_DEVICE_TABLE(usb, option_ids); 350MODULE_DEVICE_TABLE(usb, option_ids);
@@ -346,11 +383,7 @@ static struct usb_serial_driver option_1port_device = {
346 .read_int_callback = option_instat_callback, 383 .read_int_callback = option_instat_callback,
347}; 384};
348 385
349#ifdef CONFIG_USB_DEBUG
350static int debug; 386static int debug;
351#else
352#define debug 0
353#endif
354 387
355/* per port private data */ 388/* per port private data */
356 389
@@ -954,8 +987,5 @@ MODULE_DESCRIPTION(DRIVER_DESC);
954MODULE_VERSION(DRIVER_VERSION); 987MODULE_VERSION(DRIVER_VERSION);
955MODULE_LICENSE("GPL"); 988MODULE_LICENSE("GPL");
956 989
957#ifdef CONFIG_USB_DEBUG
958module_param(debug, bool, S_IRUGO | S_IWUSR); 990module_param(debug, bool, S_IRUGO | S_IWUSR);
959MODULE_PARM_DESC(debug, "Debug messages"); 991MODULE_PARM_DESC(debug, "Debug messages");
960#endif
961
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 2c9c446ad625..1ede1441cb1b 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -90,7 +90,6 @@ static struct usb_device_id id_table [] = {
90 { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, 90 { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
91 { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) }, 91 { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
92 { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) }, 92 { USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
93 { USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) },
94 { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, 93 { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
95 { } /* Terminating entry */ 94 { } /* Terminating entry */
96}; 95};
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 6ac3bbcf7a22..a3bd039c78e9 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -107,10 +107,6 @@
107#define COREGA_VENDOR_ID 0x07aa 107#define COREGA_VENDOR_ID 0x07aa
108#define COREGA_PRODUCT_ID 0x002a 108#define COREGA_PRODUCT_ID 0x002a
109 109
110/* HL HL-340 (ID: 4348:5523) */
111#define HL340_VENDOR_ID 0x4348
112#define HL340_PRODUCT_ID 0x5523
113
114/* Y.C. Cable U.S.A., Inc - USB to RS-232 */ 110/* Y.C. Cable U.S.A., Inc - USB to RS-232 */
115#define YCCABLE_VENDOR_ID 0x05ad 111#define YCCABLE_VENDOR_ID 0x05ad
116#define YCCABLE_PRODUCT_ID 0x0fba 112#define YCCABLE_PRODUCT_ID 0x0fba
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 2f6f1523ec56..706033753adb 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -14,7 +14,7 @@
14 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> 14 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
15*/ 15*/
16 16
17#define DRIVER_VERSION "v.1.2.9c" 17#define DRIVER_VERSION "v.1.2.13a"
18#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" 18#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
19#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" 19#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
20 20
@@ -31,6 +31,7 @@
31#define SWIMS_USB_REQUEST_SetPower 0x00 31#define SWIMS_USB_REQUEST_SetPower 0x00
32#define SWIMS_USB_REQUEST_SetNmea 0x07 32#define SWIMS_USB_REQUEST_SetNmea 0x07
33#define SWIMS_USB_REQUEST_SetMode 0x0B 33#define SWIMS_USB_REQUEST_SetMode 0x0B
34#define SWIMS_USB_REQUEST_GetSwocInfo 0x0A
34#define SWIMS_SET_MODE_Modem 0x0001 35#define SWIMS_SET_MODE_Modem 0x0001
35 36
36/* per port private data */ 37/* per port private data */
@@ -40,18 +41,11 @@
40 41
41static int debug; 42static int debug;
42static int nmea; 43static int nmea;
43static int truinstall = 1;
44
45enum devicetype {
46 DEVICE_3_PORT = 0,
47 DEVICE_1_PORT = 1,
48 DEVICE_INSTALLER = 2,
49};
50 44
51static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) 45static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
52{ 46{
53 int result; 47 int result;
54 dev_dbg(&udev->dev, "%s", "SET POWER STATE\n"); 48 dev_dbg(&udev->dev, "%s", __func__);
55 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 49 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
56 SWIMS_USB_REQUEST_SetPower, /* __u8 request */ 50 SWIMS_USB_REQUEST_SetPower, /* __u8 request */
57 USB_TYPE_VENDOR, /* __u8 request type */ 51 USB_TYPE_VENDOR, /* __u8 request type */
@@ -63,25 +57,10 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
63 return result; 57 return result;
64} 58}
65 59
66static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode)
67{
68 int result;
69 dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n");
70 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
71 SWIMS_USB_REQUEST_SetMode, /* __u8 request */
72 USB_TYPE_VENDOR, /* __u8 request type */
73 eSWocMode, /* __u16 value */
74 0x0000, /* __u16 index */
75 NULL, /* void *data */
76 0, /* __u16 size */
77 USB_CTRL_SET_TIMEOUT); /* int timeout */
78 return result;
79}
80
81static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) 60static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable)
82{ 61{
83 int result; 62 int result;
84 dev_dbg(&udev->dev, "%s", "NMEA Enable sent\n"); 63 dev_dbg(&udev->dev, "%s", __func__);
85 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 64 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
86 SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ 65 SWIMS_USB_REQUEST_SetNmea, /* __u8 request */
87 USB_TYPE_VENDOR, /* __u8 request type */ 66 USB_TYPE_VENDOR, /* __u8 request type */
@@ -97,6 +76,7 @@ static int sierra_calc_num_ports(struct usb_serial *serial)
97{ 76{
98 int result; 77 int result;
99 int *num_ports = usb_get_serial_data(serial); 78 int *num_ports = usb_get_serial_data(serial);
79 dev_dbg(&serial->dev->dev, "%s", __func__);
100 80
101 result = *num_ports; 81 result = *num_ports;
102 82
@@ -110,22 +90,23 @@ static int sierra_calc_num_ports(struct usb_serial *serial)
110 90
111static int sierra_calc_interface(struct usb_serial *serial) 91static int sierra_calc_interface(struct usb_serial *serial)
112{ 92{
113 int interface; 93 int interface;
114 struct usb_interface *p_interface; 94 struct usb_interface *p_interface;
115 struct usb_host_interface *p_host_interface; 95 struct usb_host_interface *p_host_interface;
96 dev_dbg(&serial->dev->dev, "%s", __func__);
116 97
117 /* Get the interface structure pointer from the serial struct */ 98 /* Get the interface structure pointer from the serial struct */
118 p_interface = serial->interface; 99 p_interface = serial->interface;
119 100
120 /* Get a pointer to the host interface structure */ 101 /* Get a pointer to the host interface structure */
121 p_host_interface = p_interface->cur_altsetting; 102 p_host_interface = p_interface->cur_altsetting;
122 103
123 /* read the interface descriptor for this active altsetting 104 /* read the interface descriptor for this active altsetting
124 * to find out the interface number we are on 105 * to find out the interface number we are on
125 */ 106 */
126 interface = p_host_interface->desc.bInterfaceNumber; 107 interface = p_host_interface->desc.bInterfaceNumber;
127 108
128 return interface; 109 return interface;
129} 110}
130 111
131static int sierra_probe(struct usb_serial *serial, 112static int sierra_probe(struct usb_serial *serial,
@@ -135,43 +116,40 @@ static int sierra_probe(struct usb_serial *serial,
135 struct usb_device *udev; 116 struct usb_device *udev;
136 int *num_ports; 117 int *num_ports;
137 u8 ifnum; 118 u8 ifnum;
119 u8 numendpoints;
120
121 dev_dbg(&serial->dev->dev, "%s", __func__);
138 122
139 num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); 123 num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL);
140 if (!num_ports) 124 if (!num_ports)
141 return -ENOMEM; 125 return -ENOMEM;
142 126
143 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; 127 ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber;
128 numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints;
144 udev = serial->dev; 129 udev = serial->dev;
145 130
146 /* Figure out the interface number from the serial structure */ 131 /* Figure out the interface number from the serial structure */
147 ifnum = sierra_calc_interface(serial); 132 ifnum = sierra_calc_interface(serial);
148
149 /*
150 * If this interface supports more than 1 alternate
151 * select the 2nd one
152 */
153 if (serial->interface->num_altsetting == 2) {
154 dev_dbg(&udev->dev,
155 "Selecting alt setting for interface %d\n",
156 ifnum);
157 133
158 /* We know the alternate setting is 1 for the MC8785 */ 134 /*
159 usb_set_interface(udev, ifnum, 1); 135 * If this interface supports more than 1 alternate
160 } 136 * select the 2nd one
137 */
138 if (serial->interface->num_altsetting == 2) {
139 dev_dbg(&udev->dev, "Selecting alt setting for interface %d\n",
140 ifnum);
141 /* We know the alternate setting is 1 for the MC8785 */
142 usb_set_interface(udev, ifnum, 1);
143 }
161 144
162 /* Check if in installer mode */ 145 /* Dummy interface present on some SKUs should be ignored */
163 if (truinstall && id->driver_info == DEVICE_INSTALLER) { 146 if (ifnum == 0x99)
164 dev_dbg(&udev->dev, "%s", "FOUND TRU-INSTALL DEVICE(SW)\n");
165 result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem);
166 /* Don't bind to the device when in installer mode */
167 kfree(num_ports);
168 return -EIO;
169 } else if (id->driver_info == DEVICE_1_PORT)
170 *num_ports = 1;
171 else if (ifnum == 0x99)
172 *num_ports = 0; 147 *num_ports = 0;
148 else if (numendpoints <= 3)
149 *num_ports = 1;
173 else 150 else
174 *num_ports = 3; 151 *num_ports = (numendpoints-1)/2;
152
175 /* 153 /*
176 * save off our num_ports info so that we can use it in the 154 * save off our num_ports info so that we can use it in the
177 * calc_num_ports callback 155 * calc_num_ports callback
@@ -187,40 +165,50 @@ static struct usb_device_id id_table [] = {
187 { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ 165 { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
188 { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ 166 { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
189 { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ 167 { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
168 { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
190 { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ 169 { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
191 { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ 170 { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
192 { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ 171 { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
193 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ 172 { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
194 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, /* Sierra Wireless C597 */ 173 /* Sierra Wireless C597 */
174 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
175 /* Sierra Wireless Device */
176 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
177 { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
195 178
196 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ 179 { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
197 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ 180 { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
198 { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ 181 { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
199 { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ 182 { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
200 { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Thinkpad internal) */ 183 { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */
201 { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ 184 { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
202 { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */ 185 { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */
203 { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ 186 { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
204 { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ 187 { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
205 { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ 188 { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
206 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ 189 { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
207 { USB_DEVICE(0x1199, 0x683B), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless MC8785 Composite*/ 190 { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
191 { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */
192 { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */
193 { USB_DEVICE(0x1199, 0x683E) }, /* Sierra Wireless MC8790 */
208 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ 194 { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */
209 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ 195 { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */
210 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ 196 { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */
211 { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ 197 { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */
212 { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */ 198 { USB_DEVICE(0x1199, 0x6855) }, /* Sierra Wireless AirCard 880 U */
213 { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ 199 { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */
214 { USB_DEVICE(0x1199, 0x6859), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ 200 { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */
215 { USB_DEVICE(0x1199, 0x685A), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 885 E */ 201 { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
216 202 /* Sierra Wireless C885 */
217 { USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */ 203 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
218 { USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */ 204 /* Sierra Wireless Device */
219 205 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
220 { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ 206 /* Sierra Wireless Device */
221 { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ 207 { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
208
209 { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
210 { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
222 211
223 { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},
224 { } 212 { }
225}; 213};
226MODULE_DEVICE_TABLE(usb, id_table); 214MODULE_DEVICE_TABLE(usb, id_table);
@@ -268,13 +256,19 @@ static int sierra_send_setup(struct tty_struct *tty,
268 if (portdata->rts_state) 256 if (portdata->rts_state)
269 val |= 0x02; 257 val |= 0x02;
270 258
271 /* Determine which port is targeted */ 259 /* If composite device then properly report interface */
272 if (port->bulk_out_endpointAddress == 2) 260 if (serial->num_ports == 1)
273 interface = 0; 261 interface = sierra_calc_interface(serial);
274 else if (port->bulk_out_endpointAddress == 4) 262
275 interface = 1; 263 /* Otherwise the need to do non-composite mapping */
276 else if (port->bulk_out_endpointAddress == 5) 264 else {
277 interface = 2; 265 if (port->bulk_out_endpointAddress == 2)
266 interface = 0;
267 else if (port->bulk_out_endpointAddress == 4)
268 interface = 1;
269 else if (port->bulk_out_endpointAddress == 5)
270 interface = 2;
271 }
278 272
279 return usb_control_msg(serial->dev, 273 return usb_control_msg(serial->dev,
280 usb_rcvctrlpipe(serial->dev, 0), 274 usb_rcvctrlpipe(serial->dev, 0),
@@ -713,7 +707,7 @@ static void sierra_shutdown(struct usb_serial *serial)
713static struct usb_serial_driver sierra_device = { 707static struct usb_serial_driver sierra_device = {
714 .driver = { 708 .driver = {
715 .owner = THIS_MODULE, 709 .owner = THIS_MODULE,
716 .name = "sierra1", 710 .name = "sierra",
717 }, 711 },
718 .description = "Sierra USB modem", 712 .description = "Sierra USB modem",
719 .id_table = id_table, 713 .id_table = id_table,
@@ -769,14 +763,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
769MODULE_VERSION(DRIVER_VERSION); 763MODULE_VERSION(DRIVER_VERSION);
770MODULE_LICENSE("GPL"); 764MODULE_LICENSE("GPL");
771 765
772module_param(truinstall, bool, 0); 766module_param(nmea, bool, S_IRUGO | S_IWUSR);
773MODULE_PARM_DESC(truinstall, "TRU-Install support");
774
775module_param(nmea, bool, 0);
776MODULE_PARM_DESC(nmea, "NMEA streaming"); 767MODULE_PARM_DESC(nmea, "NMEA streaming");
777 768
778#ifdef CONFIG_USB_DEBUG
779module_param(debug, bool, S_IRUGO | S_IWUSR); 769module_param(debug, bool, S_IRUGO | S_IWUSR);
780MODULE_PARM_DESC(debug, "Debug messages"); 770MODULE_PARM_DESC(debug, "Debug messages");
781#endif
782
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 8c2d531eedea..b157c48e8b78 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -122,9 +122,6 @@ static void return_serial(struct usb_serial *serial)
122 122
123 dbg("%s", __func__); 123 dbg("%s", __func__);
124 124
125 if (serial == NULL)
126 return;
127
128 for (i = 0; i < serial->num_ports; ++i) 125 for (i = 0; i < serial->num_ports; ++i)
129 serial_table[serial->minor + i] = NULL; 126 serial_table[serial->minor + i] = NULL;
130} 127}
@@ -142,7 +139,8 @@ static void destroy_serial(struct kref *kref)
142 serial->type->shutdown(serial); 139 serial->type->shutdown(serial);
143 140
144 /* return the minor range that this device had */ 141 /* return the minor range that this device had */
145 return_serial(serial); 142 if (serial->minor != SERIAL_TTY_NO_MINOR)
143 return_serial(serial);
146 144
147 for (i = 0; i < serial->num_ports; ++i) 145 for (i = 0; i < serial->num_ports; ++i)
148 serial->port[i]->port.count = 0; 146 serial->port[i]->port.count = 0;
@@ -575,6 +573,7 @@ static struct usb_serial *create_serial(struct usb_device *dev,
575 serial->interface = interface; 573 serial->interface = interface;
576 kref_init(&serial->kref); 574 kref_init(&serial->kref);
577 mutex_init(&serial->disc_mutex); 575 mutex_init(&serial->disc_mutex);
576 serial->minor = SERIAL_TTY_NO_MINOR;
578 577
579 return serial; 578 return serial;
580} 579}
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index 3d9249632ae1..c76034672c18 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -146,6 +146,18 @@ config USB_STORAGE_KARMA
146 on the resulting scsi device node returns the Karma to normal 146 on the resulting scsi device node returns the Karma to normal
147 operation. 147 operation.
148 148
149config USB_STORAGE_SIERRA
150 bool "Sierra Wireless TRU-Install Feature Support"
151 depends on USB_STORAGE
152 help
153 Say Y here to include additional code to support Sierra Wireless
154 products with the TRU-Install feature (e.g., AC597E, AC881U).
155
156 This code switches the Sierra Wireless device from being in
157 Mass Storage mode to Modem mode. It also has the ability to
158 support host software upgrades should full Linux support be added
159 to TRU-Install.
160
149config USB_STORAGE_CYPRESS_ATACB 161config USB_STORAGE_CYPRESS_ATACB
150 bool "SAT emulation on Cypress USB/ATA Bridge with ATACB" 162 bool "SAT emulation on Cypress USB/ATA Bridge with ATACB"
151 depends on USB_STORAGE 163 depends on USB_STORAGE
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 4c596c766c53..bc3415b475c9 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -21,6 +21,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
21usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o 21usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o
22usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o 22usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
23usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o 23usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o
24usb-storage-obj-$(CONFIG_USB_STORAGE_SIERRA) += sierra_ms.o
24usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o 25usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o
25 26
26usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ 27usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c
new file mode 100644
index 000000000000..4359a2cb42df
--- /dev/null
+++ b/drivers/usb/storage/sierra_ms.c
@@ -0,0 +1,207 @@
1#include <scsi/scsi.h>
2#include <scsi/scsi_host.h>
3#include <scsi/scsi_cmnd.h>
4#include <scsi/scsi_device.h>
5#include <linux/usb.h>
6
7#include "usb.h"
8#include "transport.h"
9#include "protocol.h"
10#include "scsiglue.h"
11#include "sierra_ms.h"
12#include "debug.h"
13
14#define SWIMS_USB_REQUEST_SetSwocMode 0x0B
15#define SWIMS_USB_REQUEST_GetSwocInfo 0x0A
16#define SWIMS_USB_INDEX_SetMode 0x0000
17#define SWIMS_SET_MODE_Modem 0x0001
18
19#define TRU_NORMAL 0x01
20#define TRU_FORCE_MS 0x02
21#define TRU_FORCE_MODEM 0x03
22
23static unsigned int swi_tru_install = 1;
24module_param(swi_tru_install, uint, S_IRUGO | S_IWUSR);
25MODULE_PARM_DESC(swi_tru_install, "TRU-Install mode (1=Full Logic (def),"
26 " 2=Force CD-Rom, 3=Force Modem)");
27
28struct swoc_info {
29 __u8 rev;
30 __u8 reserved[8];
31 __u16 LinuxSKU;
32 __u16 LinuxVer;
33 __u8 reserved2[47];
34} __attribute__((__packed__));
35
36static bool containsFullLinuxPackage(struct swoc_info *swocInfo)
37{
38 if ((swocInfo->LinuxSKU >= 0x2100 && swocInfo->LinuxSKU <= 0x2FFF) ||
39 (swocInfo->LinuxSKU >= 0x7100 && swocInfo->LinuxSKU <= 0x7FFF))
40 return true;
41 else
42 return false;
43}
44
45static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSWocMode)
46{
47 int result;
48 US_DEBUGP("SWIMS: %s", "DEVICE MODE SWITCH\n");
49 result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
50 SWIMS_USB_REQUEST_SetSwocMode, /* __u8 request */
51 USB_TYPE_VENDOR | USB_DIR_OUT, /* __u8 request type */
52 eSWocMode, /* __u16 value */
53 0x0000, /* __u16 index */
54 NULL, /* void *data */
55 0, /* __u16 size */
56 USB_CTRL_SET_TIMEOUT); /* int timeout */
57 return result;
58}
59
60
61static int sierra_get_swoc_info(struct usb_device *udev,
62 struct swoc_info *swocInfo)
63{
64 int result;
65
66 US_DEBUGP("SWIMS: Attempting to get TRU-Install info.\n");
67
68 result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
69 SWIMS_USB_REQUEST_GetSwocInfo, /* __u8 request */
70 USB_TYPE_VENDOR | USB_DIR_IN, /* __u8 request type */
71 0, /* __u16 value */
72 0, /* __u16 index */
73 (void *) swocInfo, /* void *data */
74 sizeof(struct swoc_info), /* __u16 size */
75 USB_CTRL_SET_TIMEOUT); /* int timeout */
76
77 swocInfo->LinuxSKU = le16_to_cpu(swocInfo->LinuxSKU);
78 swocInfo->LinuxVer = le16_to_cpu(swocInfo->LinuxVer);
79 return result;
80}
81
82static void debug_swoc(struct swoc_info *swocInfo)
83{
84 US_DEBUGP("SWIMS: SWoC Rev: %02d \n", swocInfo->rev);
85 US_DEBUGP("SWIMS: Linux SKU: %04X \n", swocInfo->LinuxSKU);
86 US_DEBUGP("SWIMS: Linux Version: %04X \n", swocInfo->LinuxVer);
87}
88
89
90static ssize_t show_truinst(struct device *dev, struct device_attribute *attr,
91 char *buf)
92{
93 struct swoc_info *swocInfo;
94 struct usb_interface *intf = to_usb_interface(dev);
95 struct usb_device *udev = interface_to_usbdev(intf);
96 int result;
97 if (swi_tru_install == TRU_FORCE_MS) {
98 result = snprintf(buf, PAGE_SIZE, "Forced Mass Storage\n");
99 } else {
100 swocInfo = kmalloc(sizeof(struct swoc_info), GFP_KERNEL);
101 if (!swocInfo) {
102 US_DEBUGP("SWIMS: Allocation failure\n");
103 snprintf(buf, PAGE_SIZE, "Error\n");
104 return -ENOMEM;
105 }
106 result = sierra_get_swoc_info(udev, swocInfo);
107 if (result < 0) {
108 US_DEBUGP("SWIMS: failed SWoC query\n");
109 kfree(swocInfo);
110 snprintf(buf, PAGE_SIZE, "Error\n");
111 return -EIO;
112 }
113 debug_swoc(swocInfo);
114 result = snprintf(buf, PAGE_SIZE,
115 "REV=%02d SKU=%04X VER=%04X\n",
116 swocInfo->rev,
117 swocInfo->LinuxSKU,
118 swocInfo->LinuxVer);
119 kfree(swocInfo);
120 }
121 return result;
122}
123static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL);
124
125int sierra_ms_init(struct us_data *us)
126{
127 int result, retries;
128 signed long delay_t;
129 struct swoc_info *swocInfo;
130 struct usb_device *udev;
131 struct Scsi_Host *sh;
132 struct scsi_device *sd;
133
134 delay_t = 2;
135 retries = 3;
136 result = 0;
137 udev = us->pusb_dev;
138
139 sh = us_to_host(us);
140 sd = scsi_get_host_dev(sh);
141
142 US_DEBUGP("SWIMS: sierra_ms_init called\n");
143
144 /* Force Modem mode */
145 if (swi_tru_install == TRU_FORCE_MODEM) {
146 US_DEBUGP("SWIMS: %s", "Forcing Modem Mode\n");
147 result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem);
148 if (result < 0)
149 US_DEBUGP("SWIMS: Failed to switch to modem mode.\n");
150 return -EIO;
151 }
152 /* Force Mass Storage mode (keep CD-Rom) */
153 else if (swi_tru_install == TRU_FORCE_MS) {
154 US_DEBUGP("SWIMS: %s", "Forcing Mass Storage Mode\n");
155 goto complete;
156 }
157 /* Normal TRU-Install Logic */
158 else {
159 US_DEBUGP("SWIMS: %s", "Normal SWoC Logic\n");
160
161 swocInfo = kmalloc(sizeof(struct swoc_info),
162 GFP_KERNEL);
163 if (!swocInfo) {
164 US_DEBUGP("SWIMS: %s", "Allocation failure\n");
165 return -ENOMEM;
166 }
167
168 retries = 3;
169 do {
170 retries--;
171 result = sierra_get_swoc_info(udev, swocInfo);
172 if (result < 0) {
173 US_DEBUGP("SWIMS: %s", "Failed SWoC query\n");
174 schedule_timeout_uninterruptible(2*HZ);
175 }
176 } while (retries && result < 0);
177
178 if (result < 0) {
179 US_DEBUGP("SWIMS: %s",
180 "Completely failed SWoC query\n");
181 kfree(swocInfo);
182 return -EIO;
183 }
184
185 debug_swoc(swocInfo);
186
187 /* If there is not Linux software on the TRU-Install device
188 * then switch to modem mode
189 */
190 if (!containsFullLinuxPackage(swocInfo)) {
191 US_DEBUGP("SWIMS: %s",
192 "Switching to Modem Mode\n");
193 result = sierra_set_ms_mode(udev,
194 SWIMS_SET_MODE_Modem);
195 if (result < 0)
196 US_DEBUGP("SWIMS: Failed to switch modem\n");
197 kfree(swocInfo);
198 return -EIO;
199 }
200 kfree(swocInfo);
201 }
202complete:
203 result = device_create_file(&us->pusb_intf->dev, &dev_attr_truinst);
204
205 return USB_STOR_TRANSPORT_GOOD;
206}
207
diff --git a/drivers/usb/storage/sierra_ms.h b/drivers/usb/storage/sierra_ms.h
new file mode 100644
index 000000000000..bb48634ac1fc
--- /dev/null
+++ b/drivers/usb/storage/sierra_ms.h
@@ -0,0 +1,4 @@
1#ifndef _SIERRA_MS_H_
2#define _SIERRA_MS_H_
3extern int sierra_ms_init(struct us_data *us);
4#endif
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index fcbbfdb7b2b0..3523a0bfa0ff 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -1032,8 +1032,21 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
1032 1032
1033 /* try to compute the actual residue, based on how much data 1033 /* try to compute the actual residue, based on how much data
1034 * was really transferred and what the device tells us */ 1034 * was really transferred and what the device tells us */
1035 if (residue) { 1035 if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
1036 if (!(us->fflags & US_FL_IGNORE_RESIDUE)) { 1036
1037 /* Heuristically detect devices that generate bogus residues
1038 * by seeing what happens with INQUIRY and READ CAPACITY
1039 * commands.
1040 */
1041 if (bcs->Status == US_BULK_STAT_OK &&
1042 scsi_get_resid(srb) == 0 &&
1043 ((srb->cmnd[0] == INQUIRY &&
1044 transfer_length == 36) ||
1045 (srb->cmnd[0] == READ_CAPACITY &&
1046 transfer_length == 8))) {
1047 us->fflags |= US_FL_IGNORE_RESIDUE;
1048
1049 } else {
1037 residue = min(residue, transfer_length); 1050 residue = min(residue, transfer_length);
1038 scsi_set_resid(srb, max(scsi_get_resid(srb), 1051 scsi_set_resid(srb, max(scsi_get_resid(srb),
1039 (int) residue)); 1052 (int) residue));
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 7ae69f55aa96..ba412e68d474 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -225,6 +225,13 @@ UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370,
225 US_SC_DEVICE, US_PR_DEVICE, NULL, 225 US_SC_DEVICE, US_PR_DEVICE, NULL,
226 US_FL_MAX_SECTORS_64 ), 226 US_FL_MAX_SECTORS_64 ),
227 227
228/* Reported by Cedric Godin <cedric@belbone.be> */
229UNUSUAL_DEV( 0x0421, 0x04b9, 0x0551, 0x0551,
230 "Nokia",
231 "5300",
232 US_SC_DEVICE, US_PR_DEVICE, NULL,
233 US_FL_FIX_CAPACITY ),
234
228/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ 235/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
229UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, 236UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
230 "SMSC", 237 "SMSC",
@@ -356,14 +363,14 @@ UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200,
356 US_FL_FIX_CAPACITY), 363 US_FL_FIX_CAPACITY),
357 364
358/* Reported by Emil Larsson <emil@swip.net> */ 365/* Reported by Emil Larsson <emil@swip.net> */
359UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0110, 366UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0111,
360 "NIKON", 367 "NIKON",
361 "NIKON DSC D80", 368 "NIKON DSC D80",
362 US_SC_DEVICE, US_PR_DEVICE, NULL, 369 US_SC_DEVICE, US_PR_DEVICE, NULL,
363 US_FL_FIX_CAPACITY), 370 US_FL_FIX_CAPACITY),
364 371
365/* Reported by Ortwin Glueck <odi@odi.ch> */ 372/* Reported by Ortwin Glueck <odi@odi.ch> */
366UNUSUAL_DEV( 0x04b0, 0x0413, 0x0110, 0x0110, 373UNUSUAL_DEV( 0x04b0, 0x0413, 0x0110, 0x0111,
367 "NIKON", 374 "NIKON",
368 "NIKON DSC D40", 375 "NIKON DSC D40",
369 US_SC_DEVICE, US_PR_DEVICE, NULL, 376 US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -1185,6 +1192,13 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff,
1185 US_SC_DEVICE, US_PR_DEVICE, NULL, 1192 US_SC_DEVICE, US_PR_DEVICE, NULL,
1186 US_FL_FIX_INQUIRY ), 1193 US_FL_FIX_INQUIRY ),
1187 1194
1195/* Reported by Rauch Wolke <rauchwolke@gmx.net> */
1196UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff,
1197 "Simple Tech/Datafab",
1198 "CF+SM Reader",
1199 US_SC_DEVICE, US_PR_DEVICE, NULL,
1200 US_FL_IGNORE_RESIDUE ),
1201
1188/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant 1202/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
1189 * to the USB storage specification in two ways: 1203 * to the USB storage specification in two ways:
1190 * - They tell us they are using transport protocol CBI. In reality they 1204 * - They tell us they are using transport protocol CBI. In reality they
@@ -1562,6 +1576,7 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100,
1562 US_SC_DEVICE, US_PR_DEVICE, NULL, 1576 US_SC_DEVICE, US_PR_DEVICE, NULL,
1563 0), 1577 0),
1564 1578
1579#ifdef CONFIG_USB_STORAGE_SIERRA
1565/* Reported by Kevin Lloyd <linux@sierrawireless.com> 1580/* Reported by Kevin Lloyd <linux@sierrawireless.com>
1566 * Entry is needed for the initializer function override, 1581 * Entry is needed for the initializer function override,
1567 * which instructs the device to load as a modem 1582 * which instructs the device to load as a modem
@@ -1570,8 +1585,9 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100,
1570UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, 1585UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999,
1571 "Sierra Wireless", 1586 "Sierra Wireless",
1572 "USB MMC Storage", 1587 "USB MMC Storage",
1573 US_SC_DEVICE, US_PR_DEVICE, NULL, 1588 US_SC_DEVICE, US_PR_DEVICE, sierra_ms_init,
1574 US_FL_IGNORE_DEVICE), 1589 0),
1590#endif
1575 1591
1576/* Reported by Jaco Kroon <jaco@kroon.co.za> 1592/* Reported by Jaco Kroon <jaco@kroon.co.za>
1577 * The usb-storage module found on the Digitech GNX4 (and supposedly other 1593 * The usb-storage module found on the Digitech GNX4 (and supposedly other
@@ -1743,6 +1759,15 @@ UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0002,
1743 US_FL_FIX_CAPACITY), 1759 US_FL_FIX_CAPACITY),
1744 1760
1745/* 1761/*
1762 * Patch by Jost Diederichs <jost@qdusa.com>
1763 */
1764UNUSUAL_DEV(0x22b8, 0x6410, 0x0001, 0x9999,
1765 "Motorola Inc.",
1766 "Motorola Phone (RAZRV3xx)",
1767 US_SC_DEVICE, US_PR_DEVICE, NULL,
1768 US_FL_FIX_CAPACITY),
1769
1770/*
1746 * Patch by Constantin Baranov <const@tltsu.ru> 1771 * Patch by Constantin Baranov <const@tltsu.ru>
1747 * Report by Andreas Koenecke. 1772 * Report by Andreas Koenecke.
1748 * Motorola ROKR Z6. 1773 * Motorola ROKR Z6.
@@ -1767,6 +1792,13 @@ UNUSUAL_DEV( 0x2770, 0x915d, 0x0010, 0x0010,
1767 US_SC_DEVICE, US_PR_DEVICE, NULL, 1792 US_SC_DEVICE, US_PR_DEVICE, NULL,
1768 US_FL_FIX_CAPACITY ), 1793 US_FL_FIX_CAPACITY ),
1769 1794
1795/* Reported by Andrey Rahmatullin <wrar@altlinux.org> */
1796UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100,
1797 "iRiver",
1798 "MP3 T10",
1799 US_SC_DEVICE, US_PR_DEVICE, NULL,
1800 US_FL_IGNORE_RESIDUE ),
1801
1770/* 1802/*
1771 * David Härdeman <david@2gen.com> 1803 * David Härdeman <david@2gen.com>
1772 * The key makes the SCSI stack print confusing (but harmless) messages 1804 * The key makes the SCSI stack print confusing (but harmless) messages
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index bfea851be985..73679aa506de 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -102,6 +102,9 @@
102#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB 102#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
103#include "cypress_atacb.h" 103#include "cypress_atacb.h"
104#endif 104#endif
105#ifdef CONFIG_USB_STORAGE_SIERRA
106#include "sierra_ms.h"
107#endif
105 108
106/* Some informational data */ 109/* Some informational data */
107MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); 110MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 017233d0c481..61c3d3f40fd1 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -29,7 +29,7 @@
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
31 31
32#include <asm/hardware.h> 32#include <mach/hardware.h>
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/mach-types.h> 35#include <asm/mach-types.h>
@@ -339,7 +339,7 @@ acornfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
339#endif 339#endif
340 340
341#ifdef HAS_VIDC20 341#ifdef HAS_VIDC20
342#include <asm/arch/acornfb.h> 342#include <mach/acornfb.h>
343 343
344#define MAX_SIZE 2*1024*1024 344#define MAX_SIZE 2*1024*1024
345 345
diff --git a/drivers/video/am200epd.c b/drivers/video/am200epd.c
index 32dd85126931..0c35b8b0160e 100644
--- a/drivers/video/am200epd.c
+++ b/drivers/video/am200epd.c
@@ -33,7 +33,7 @@
33 33
34#include <video/metronomefb.h> 34#include <video/metronomefb.h>
35 35
36#include <asm/arch/pxa-regs.h> 36#include <mach/pxa-regs.h>
37 37
38/* register offsets for gpio control */ 38/* register offsets for gpio control */
39#define LED_GPIO_PIN 51 39#define LED_GPIO_PIN 51
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 5b3a15dffb5f..9c5925927ece 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -18,9 +18,9 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/backlight.h> 19#include <linux/backlight.h>
20 20
21#include <asm/arch/board.h> 21#include <mach/board.h>
22#include <asm/arch/cpu.h> 22#include <mach/cpu.h>
23#include <asm/arch/gpio.h> 23#include <mach/gpio.h>
24 24
25#include <video/atmel_lcdc.h> 25#include <video/atmel_lcdc.h>
26 26
@@ -39,7 +39,9 @@
39#endif 39#endif
40 40
41#if defined(CONFIG_ARCH_AT91) 41#if defined(CONFIG_ARCH_AT91)
42#define ATMEL_LCDFB_FBINFO_DEFAULT FBINFO_DEFAULT 42#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \
43 | FBINFO_PARTIAL_PAN_OK \
44 | FBINFO_HWACCEL_YPAN)
43 45
44static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo, 46static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
45 struct fb_var_screeninfo *var) 47 struct fb_var_screeninfo *var)
@@ -177,7 +179,7 @@ static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
177 .type = FB_TYPE_PACKED_PIXELS, 179 .type = FB_TYPE_PACKED_PIXELS,
178 .visual = FB_VISUAL_TRUECOLOR, 180 .visual = FB_VISUAL_TRUECOLOR,
179 .xpanstep = 0, 181 .xpanstep = 0,
180 .ypanstep = 0, 182 .ypanstep = 1,
181 .ywrapstep = 0, 183 .ywrapstep = 0,
182 .accel = FB_ACCEL_NONE, 184 .accel = FB_ACCEL_NONE,
183}; 185};
@@ -240,9 +242,11 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo)
240{ 242{
241 struct fb_info *info = sinfo->info; 243 struct fb_info *info = sinfo->info;
242 struct fb_var_screeninfo *var = &info->var; 244 struct fb_var_screeninfo *var = &info->var;
245 unsigned int smem_len;
243 246
244 info->fix.smem_len = (var->xres_virtual * var->yres_virtual 247 smem_len = (var->xres_virtual * var->yres_virtual
245 * ((var->bits_per_pixel + 7) / 8)); 248 * ((var->bits_per_pixel + 7) / 8));
249 info->fix.smem_len = max(smem_len, sinfo->smem_len);
246 250
247 info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len, 251 info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len,
248 (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL); 252 (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL);
@@ -794,6 +798,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
794 sinfo->default_monspecs = pdata_sinfo->default_monspecs; 798 sinfo->default_monspecs = pdata_sinfo->default_monspecs;
795 sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control; 799 sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control;
796 sinfo->guard_time = pdata_sinfo->guard_time; 800 sinfo->guard_time = pdata_sinfo->guard_time;
801 sinfo->smem_len = pdata_sinfo->smem_len;
797 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; 802 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
798 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; 803 sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode;
799 } else { 804 } else {
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
index 4d13f68436e6..aa95f8350242 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/aty/radeon_accel.c
@@ -55,6 +55,10 @@ static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
55 OUTREG(DP_WRITE_MSK, 0xffffffff); 55 OUTREG(DP_WRITE_MSK, 0xffffffff);
56 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); 56 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
57 57
58 radeon_fifo_wait(2);
59 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
60 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
61
58 radeon_fifo_wait(2); 62 radeon_fifo_wait(2);
59 OUTREG(DST_Y_X, (region->dy << 16) | region->dx); 63 OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
60 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); 64 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
@@ -116,6 +120,10 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
116 OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) 120 OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
117 | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); 121 | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
118 122
123 radeon_fifo_wait(2);
124 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
125 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
126
119 radeon_fifo_wait(3); 127 radeon_fifo_wait(3);
120 OUTREG(SRC_Y_X, (sy << 16) | sx); 128 OUTREG(SRC_Y_X, (sy << 16) | sx);
121 OUTREG(DST_Y_X, (dy << 16) | dx); 129 OUTREG(DST_Y_X, (dy << 16) | dx);
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index 891875d53a49..cbad67e89826 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -25,9 +25,9 @@
25#include <linux/fb.h> 25#include <linux/fb.h>
26#include <linux/backlight.h> 26#include <linux/backlight.h>
27 27
28#include <asm/arch/hardware.h> 28#include <mach/hardware.h>
29#include <asm/arch/board.h> 29#include <mach/board.h>
30#include <asm/arch/mux.h> 30#include <mach/mux.h>
31 31
32#define OMAPBL_MAX_INTENSITY 0xff 32#define OMAPBL_MAX_INTENSITY 0xff
33 33
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index 9f8a389dc7ae..16f5db471ab5 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -27,12 +27,12 @@
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29 29
30#include <asm/hardware.h> 30#include <mach/hardware.h>
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33 33
34#include <asm/hardware/clps7111.h> 34#include <asm/hardware/clps7111.h>
35#include <asm/arch/syspld.h> 35#include <mach/syspld.h>
36 36
37struct fb_info *cfb; 37struct fb_info *cfb;
38 38
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 33859934a8e4..c6299e8a041d 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2518,7 +2518,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2518 c = vc->vc_video_erase_char; 2518 c = vc->vc_video_erase_char;
2519 vc->vc_video_erase_char = 2519 vc->vc_video_erase_char =
2520 ((c & 0xfe00) >> 1) | (c & 0xff); 2520 ((c & 0xfe00) >> 1) | (c & 0xff);
2521 c = vc->vc_def_color; 2521 c = vc->vc_scrl_erase_char;
2522 vc->vc_scrl_erase_char = 2522 vc->vc_scrl_erase_char =
2523 ((c & 0xFE00) >> 1) | (c & 0xFF); 2523 ((c & 0xFE00) >> 1) | (c & 0xFF);
2524 vc->vc_attr >>= 1; 2524 vc->vc_attr >>= 1;
@@ -2551,7 +2551,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2551 if (vc->vc_can_do_color) { 2551 if (vc->vc_can_do_color) {
2552 vc->vc_video_erase_char = 2552 vc->vc_video_erase_char =
2553 ((c & 0xff00) << 1) | (c & 0xff); 2553 ((c & 0xff00) << 1) | (c & 0xff);
2554 c = vc->vc_def_color; 2554 c = vc->vc_scrl_erase_char;
2555 vc->vc_scrl_erase_char = 2555 vc->vc_scrl_erase_char =
2556 ((c & 0xFF00) << 1) | (c & 0xFF); 2556 ((c & 0xFF00) << 1) | (c & 0xFF);
2557 vc->vc_attr <<= 1; 2557 vc->vc_attr <<= 1;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index de1b1365279b..a6e38e9ea73f 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -92,7 +92,7 @@ struct fbcon_ops {
92#define attr_fgcol(fgshift,s) \ 92#define attr_fgcol(fgshift,s) \
93 (((s) >> (fgshift)) & 0x0f) 93 (((s) >> (fgshift)) & 0x0f)
94#define attr_bgcol(bgshift,s) \ 94#define attr_bgcol(bgshift,s) \
95 (((s) >> (bgshift)) & 0x07) 95 (((s) >> (bgshift)) & 0x0f)
96 96
97/* Monochrome */ 97/* Monochrome */
98#define attr_bold(s) \ 98#define attr_bold(s) \
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index d0e4cb618269..41d62632dcdb 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1425,7 +1425,7 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
1425 1425
1426#ifdef CONFIG_ARCH_SHARK 1426#ifdef CONFIG_ARCH_SHARK
1427 1427
1428#include <asm/arch/hardware.h> 1428#include <mach/hardware.h>
1429 1429
1430static int __devinit cyberpro_vl_probe(void) 1430static int __devinit cyberpro_vl_probe(void)
1431{ 1431{
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index cc2810ef5de5..2735b79e52a1 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -71,7 +71,7 @@ struct epson1355_par {
71#if defined(CONFIG_ARM) 71#if defined(CONFIG_ARM)
72 72
73# ifdef CONFIG_ARCH_CEIVA 73# ifdef CONFIG_ARCH_CEIVA
74# include <asm/arch/hardware.h> 74# include <mach/hardware.h>
75# define EPSON1355FB_BASE_PHYS (CEIVA_PHYS_SED1355) 75# define EPSON1355FB_BASE_PHYS (CEIVA_PHYS_SED1355)
76# endif 76# endif
77 77
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index bd320a2bfb7c..fb51197d1c98 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -479,6 +479,10 @@ static void adjust_aoi_size_position(struct fb_var_screeninfo *var,
479 base_plane_width = machine_data->fsl_diu_info[0]->var.xres; 479 base_plane_width = machine_data->fsl_diu_info[0]->var.xres;
480 base_plane_height = machine_data->fsl_diu_info[0]->var.yres; 480 base_plane_height = machine_data->fsl_diu_info[0]->var.yres;
481 481
482 if (mfbi->x_aoi_d < 0)
483 mfbi->x_aoi_d = 0;
484 if (mfbi->y_aoi_d < 0)
485 mfbi->y_aoi_d = 0;
482 switch (index) { 486 switch (index) {
483 case 0: 487 case 0:
484 if (mfbi->x_aoi_d != 0) 488 if (mfbi->x_aoi_d != 0)
@@ -778,6 +782,22 @@ static void unmap_video_memory(struct fb_info *info)
778} 782}
779 783
780/* 784/*
785 * Using the fb_var_screeninfo in fb_info we set the aoi of this
786 * particular framebuffer. It is a light version of fsl_diu_set_par.
787 */
788static int fsl_diu_set_aoi(struct fb_info *info)
789{
790 struct fb_var_screeninfo *var = &info->var;
791 struct mfb_info *mfbi = info->par;
792 struct diu_ad *ad = mfbi->ad;
793
794 /* AOI should not be greater than display size */
795 ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset);
796 ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d);
797 return 0;
798}
799
800/*
781 * Using the fb_var_screeninfo in fb_info we set the resolution of this 801 * Using the fb_var_screeninfo in fb_info we set the resolution of this
782 * particular framebuffer. This function alters the fb_fix_screeninfo stored 802 * particular framebuffer. This function alters the fb_fix_screeninfo stored
783 * in fb_info. It does not alter var in fb_info since we are using that 803 * in fb_info. It does not alter var in fb_info since we are using that
@@ -817,11 +837,11 @@ static int fsl_diu_set_par(struct fb_info *info)
817 diu_ops.get_pixel_format(var->bits_per_pixel, 837 diu_ops.get_pixel_format(var->bits_per_pixel,
818 machine_data->monitor_port); 838 machine_data->monitor_port);
819 ad->addr = cpu_to_le32(info->fix.smem_start); 839 ad->addr = cpu_to_le32(info->fix.smem_start);
820 ad->src_size_g_alpha = cpu_to_le32((var->yres << 12) | 840 ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) |
821 var->xres) | mfbi->g_alpha; 841 var->xres_virtual) | mfbi->g_alpha;
822 /* fix me. AOI should not be greater than display size */ 842 /* AOI should not be greater than display size */
823 ad->aoi_size = cpu_to_le32((var->yres << 16) | var->xres); 843 ad->aoi_size = cpu_to_le32((var->yres << 16) | var->xres);
824 ad->offset_xyi = 0; 844 ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset);
825 ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); 845 ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d);
826 846
827 /* Disable chroma keying function */ 847 /* Disable chroma keying function */
@@ -921,6 +941,8 @@ static int fsl_diu_pan_display(struct fb_var_screeninfo *var,
921 else 941 else
922 info->var.vmode &= ~FB_VMODE_YWRAP; 942 info->var.vmode &= ~FB_VMODE_YWRAP;
923 943
944 fsl_diu_set_aoi(info);
945
924 return 0; 946 return 0;
925} 947}
926 948
@@ -989,7 +1011,7 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
989 pr_debug("set AOI display offset of index %d to (%d,%d)\n", 1011 pr_debug("set AOI display offset of index %d to (%d,%d)\n",
990 mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d); 1012 mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d);
991 fsl_diu_check_var(&info->var, info); 1013 fsl_diu_check_var(&info->var, info);
992 fsl_diu_set_par(info); 1014 fsl_diu_set_aoi(info);
993 break; 1015 break;
994 case MFB_GET_AOID: 1016 case MFB_GET_AOID:
995 aoi_d.x_aoi_d = mfbi->x_aoi_d; 1017 aoi_d.x_aoi_d = mfbi->x_aoi_d;
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 0c5a475c1cae..ccd986140c95 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -33,9 +33,9 @@
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
35 35
36#include <asm/hardware.h> 36#include <mach/hardware.h>
37#include <asm/io.h> 37#include <asm/io.h>
38#include <asm/arch/imxfb.h> 38#include <mach/imxfb.h>
39 39
40/* 40/*
41 * Complain if VAR is out of range. 41 * Complain if VAR is out of range.
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index 75ee5a12e549..c14e3e2212b3 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -87,13 +87,7 @@ static int matroxfb_gpio_getscl(void* data) {
87 return (matroxfb_read_gpio(b->minfo) & b->mask.clock) ? 1 : 0; 87 return (matroxfb_read_gpio(b->minfo) & b->mask.clock) ? 1 : 0;
88} 88}
89 89
90static struct i2c_adapter matrox_i2c_adapter_template = 90static const struct i2c_algo_bit_data matrox_i2c_algo_template =
91{
92 .owner = THIS_MODULE,
93 .id = I2C_HW_B_G400,
94};
95
96static struct i2c_algo_bit_data matrox_i2c_algo_template =
97{ 91{
98 .setsda = matroxfb_gpio_setsda, 92 .setsda = matroxfb_gpio_setsda,
99 .setscl = matroxfb_gpio_setscl, 93 .setscl = matroxfb_gpio_setscl,
@@ -112,7 +106,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
112 b->minfo = minfo; 106 b->minfo = minfo;
113 b->mask.data = data; 107 b->mask.data = data;
114 b->mask.clock = clock; 108 b->mask.clock = clock;
115 b->adapter = matrox_i2c_adapter_template; 109 b->adapter.owner = THIS_MODULE;
116 snprintf(b->adapter.name, sizeof(b->adapter.name), name, 110 snprintf(b->adapter.name, sizeof(b->adapter.name), name,
117 minfo->fbcon.node); 111 minfo->fbcon.node);
118 i2c_set_adapdata(&b->adapter, b); 112 i2c_set_adapdata(&b->adapter, b);
@@ -187,6 +181,17 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
187 MAT_DATA, MAT_CLK, "MAVEN:fb%u", 0); 181 MAT_DATA, MAT_CLK, "MAVEN:fb%u", 0);
188 if (err) 182 if (err)
189 printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n"); 183 printk(KERN_INFO "i2c-matroxfb: Could not register Maven i2c bus. Continuing anyway.\n");
184 else {
185 struct i2c_board_info maven_info = {
186 I2C_BOARD_INFO("maven", 0x1b),
187 };
188 unsigned short const addr_list[2] = {
189 0x1b, I2C_CLIENT_END
190 };
191
192 i2c_new_probed_device(&m2info->maven.adapter,
193 &maven_info, addr_list);
194 }
190 } 195 }
191 return m2info; 196 return m2info;
192fail_ddc1:; 197fail_ddc1:;
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index 89da27bd5c49..042408a8c631 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -19,8 +19,6 @@
19#include <linux/matroxfb.h> 19#include <linux/matroxfb.h>
20#include <asm/div64.h> 20#include <asm/div64.h>
21 21
22#define MAVEN_I2CID (0x1B)
23
24#define MGATVO_B 1 22#define MGATVO_B 1
25#define MGATVO_C 2 23#define MGATVO_C 2
26 24
@@ -128,7 +126,7 @@ static int get_ctrl_id(__u32 v4l2_id) {
128 126
129struct maven_data { 127struct maven_data {
130 struct matrox_fb_info* primary_head; 128 struct matrox_fb_info* primary_head;
131 struct i2c_client client; 129 struct i2c_client *client;
132 int version; 130 int version;
133}; 131};
134 132
@@ -974,7 +972,7 @@ static inline int maven_compute_timming(struct maven_data* md,
974 972
975static int maven_program_timming(struct maven_data* md, 973static int maven_program_timming(struct maven_data* md,
976 const struct mavenregs* m) { 974 const struct mavenregs* m) {
977 struct i2c_client* c = &md->client; 975 struct i2c_client *c = md->client;
978 976
979 if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) { 977 if (m->mode == MATROXFB_OUTPUT_MODE_MONITOR) {
980 LR(0x80); 978 LR(0x80);
@@ -1011,7 +1009,7 @@ static int maven_program_timming(struct maven_data* md,
1011} 1009}
1012 1010
1013static inline int maven_resync(struct maven_data* md) { 1011static inline int maven_resync(struct maven_data* md) {
1014 struct i2c_client* c = &md->client; 1012 struct i2c_client *c = md->client;
1015 maven_set_reg(c, 0x95, 0x20); /* start whole thing */ 1013 maven_set_reg(c, 0x95, 0x20); /* start whole thing */
1016 return 0; 1014 return 0;
1017} 1015}
@@ -1069,48 +1067,48 @@ static int maven_set_control (struct maven_data* md,
1069 maven_compute_bwlevel(md, &blacklevel, &whitelevel); 1067 maven_compute_bwlevel(md, &blacklevel, &whitelevel);
1070 blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8); 1068 blacklevel = (blacklevel >> 2) | ((blacklevel & 3) << 8);
1071 whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8); 1069 whitelevel = (whitelevel >> 2) | ((whitelevel & 3) << 8);
1072 maven_set_reg_pair(&md->client, 0x0e, blacklevel); 1070 maven_set_reg_pair(md->client, 0x0e, blacklevel);
1073 maven_set_reg_pair(&md->client, 0x1e, whitelevel); 1071 maven_set_reg_pair(md->client, 0x1e, whitelevel);
1074 } 1072 }
1075 break; 1073 break;
1076 case V4L2_CID_SATURATION: 1074 case V4L2_CID_SATURATION:
1077 { 1075 {
1078 maven_set_reg(&md->client, 0x20, p->value); 1076 maven_set_reg(md->client, 0x20, p->value);
1079 maven_set_reg(&md->client, 0x22, p->value); 1077 maven_set_reg(md->client, 0x22, p->value);
1080 } 1078 }
1081 break; 1079 break;
1082 case V4L2_CID_HUE: 1080 case V4L2_CID_HUE:
1083 { 1081 {
1084 maven_set_reg(&md->client, 0x25, p->value); 1082 maven_set_reg(md->client, 0x25, p->value);
1085 } 1083 }
1086 break; 1084 break;
1087 case V4L2_CID_GAMMA: 1085 case V4L2_CID_GAMMA:
1088 { 1086 {
1089 const struct maven_gamma* g; 1087 const struct maven_gamma* g;
1090 g = maven_compute_gamma(md); 1088 g = maven_compute_gamma(md);
1091 maven_set_reg(&md->client, 0x83, g->reg83); 1089 maven_set_reg(md->client, 0x83, g->reg83);
1092 maven_set_reg(&md->client, 0x84, g->reg84); 1090 maven_set_reg(md->client, 0x84, g->reg84);
1093 maven_set_reg(&md->client, 0x85, g->reg85); 1091 maven_set_reg(md->client, 0x85, g->reg85);
1094 maven_set_reg(&md->client, 0x86, g->reg86); 1092 maven_set_reg(md->client, 0x86, g->reg86);
1095 maven_set_reg(&md->client, 0x87, g->reg87); 1093 maven_set_reg(md->client, 0x87, g->reg87);
1096 maven_set_reg(&md->client, 0x88, g->reg88); 1094 maven_set_reg(md->client, 0x88, g->reg88);
1097 maven_set_reg(&md->client, 0x89, g->reg89); 1095 maven_set_reg(md->client, 0x89, g->reg89);
1098 maven_set_reg(&md->client, 0x8a, g->reg8a); 1096 maven_set_reg(md->client, 0x8a, g->reg8a);
1099 maven_set_reg(&md->client, 0x8b, g->reg8b); 1097 maven_set_reg(md->client, 0x8b, g->reg8b);
1100 } 1098 }
1101 break; 1099 break;
1102 case MATROXFB_CID_TESTOUT: 1100 case MATROXFB_CID_TESTOUT:
1103 { 1101 {
1104 unsigned char val 1102 unsigned char val
1105 = maven_get_reg(&md->client,0x8d); 1103 = maven_get_reg(md->client, 0x8d);
1106 if (p->value) val |= 0x10; 1104 if (p->value) val |= 0x10;
1107 else val &= ~0x10; 1105 else val &= ~0x10;
1108 maven_set_reg(&md->client, 0x8d, val); 1106 maven_set_reg(md->client, 0x8d, val);
1109 } 1107 }
1110 break; 1108 break;
1111 case MATROXFB_CID_DEFLICKER: 1109 case MATROXFB_CID_DEFLICKER:
1112 { 1110 {
1113 maven_set_reg(&md->client, 0x93, maven_compute_deflicker(md)); 1111 maven_set_reg(md->client, 0x93, maven_compute_deflicker(md));
1114 } 1112 }
1115 break; 1113 break;
1116 } 1114 }
@@ -1189,6 +1187,7 @@ static int maven_init_client(struct i2c_client* clnt) {
1189 MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo); 1187 MINFO_FROM(container_of(clnt->adapter, struct i2c_bit_adapter, adapter)->minfo);
1190 1188
1191 md->primary_head = MINFO; 1189 md->primary_head = MINFO;
1190 md->client = clnt;
1192 down_write(&ACCESS_FBINFO(altout.lock)); 1191 down_write(&ACCESS_FBINFO(altout.lock));
1193 ACCESS_FBINFO(outputs[1]).output = &maven_altout; 1192 ACCESS_FBINFO(outputs[1]).output = &maven_altout;
1194 ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src; 1193 ACCESS_FBINFO(outputs[1]).src = ACCESS_FBINFO(outputs[1]).default_src;
@@ -1232,14 +1231,11 @@ static int maven_shutdown_client(struct i2c_client* clnt) {
1232 return 0; 1231 return 0;
1233} 1232}
1234 1233
1235static const unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END }; 1234static int maven_probe(struct i2c_client *client,
1236I2C_CLIENT_INSMOD; 1235 const struct i2c_device_id *id)
1237 1236{
1238static struct i2c_driver maven_driver; 1237 struct i2c_adapter *adapter = client->adapter;
1239 1238 int err = -ENODEV;
1240static int maven_detect_client(struct i2c_adapter* adapter, int address, int kind) {
1241 int err = 0;
1242 struct i2c_client* new_client;
1243 struct maven_data* data; 1239 struct maven_data* data;
1244 1240
1245 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA | 1241 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_WORD_DATA |
@@ -1250,50 +1246,37 @@ static int maven_detect_client(struct i2c_adapter* adapter, int address, int kin
1250 err = -ENOMEM; 1246 err = -ENOMEM;
1251 goto ERROR0; 1247 goto ERROR0;
1252 } 1248 }
1253 new_client = &data->client; 1249 i2c_set_clientdata(client, data);
1254 i2c_set_clientdata(new_client, data); 1250 err = maven_init_client(client);
1255 new_client->addr = address;
1256 new_client->adapter = adapter;
1257 new_client->driver = &maven_driver;
1258 new_client->flags = 0;
1259 strlcpy(new_client->name, "maven", I2C_NAME_SIZE);
1260 if ((err = i2c_attach_client(new_client)))
1261 goto ERROR3;
1262 err = maven_init_client(new_client);
1263 if (err) 1251 if (err)
1264 goto ERROR4; 1252 goto ERROR4;
1265 return 0; 1253 return 0;
1266ERROR4:; 1254ERROR4:;
1267 i2c_detach_client(new_client); 1255 kfree(data);
1268ERROR3:;
1269 kfree(new_client);
1270ERROR0:; 1256ERROR0:;
1271 return err; 1257 return err;
1272} 1258}
1273 1259
1274static int maven_attach_adapter(struct i2c_adapter* adapter) { 1260static int maven_remove(struct i2c_client *client)
1275 if (adapter->id == I2C_HW_B_G400) 1261{
1276 return i2c_probe(adapter, &addr_data, &maven_detect_client);
1277 return 0;
1278}
1279
1280static int maven_detach_client(struct i2c_client* client) {
1281 int err;
1282
1283 if ((err = i2c_detach_client(client)))
1284 return err;
1285 maven_shutdown_client(client); 1262 maven_shutdown_client(client);
1286 kfree(i2c_get_clientdata(client)); 1263 kfree(i2c_get_clientdata(client));
1287 return 0; 1264 return 0;
1288} 1265}
1289 1266
1267static const struct i2c_device_id maven_id[] = {
1268 { "maven", 0 },
1269 { }
1270};
1271MODULE_DEVICE_TABLE(i2c, maven_id);
1272
1290static struct i2c_driver maven_driver={ 1273static struct i2c_driver maven_driver={
1291 .driver = { 1274 .driver = {
1292 .name = "maven", 1275 .name = "maven",
1293 }, 1276 },
1294 .id = I2C_DRIVERID_MGATVO, 1277 .probe = maven_probe,
1295 .attach_adapter = maven_attach_adapter, 1278 .remove = maven_remove,
1296 .detach_client = maven_detach_client, 1279 .id_table = maven_id,
1297}; 1280};
1298 1281
1299static int __init matroxfb_maven_init(void) 1282static int __init matroxfb_maven_init(void)
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index 4d8ad9cd0e19..9dfcf39d3367 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -26,9 +26,9 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/clk.h> 27#include <linux/clk.h>
28 28
29#include <asm/arch/dma.h> 29#include <mach/dma.h>
30#include <asm/arch/omapfb.h> 30#include <mach/omapfb.h>
31#include <asm/arch/blizzard.h> 31#include <mach/blizzard.h>
32 32
33#include "dispc.h" 33#include "dispc.h"
34 34
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index ab77c51fe9d6..6efcf89e7fbe 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -25,9 +25,9 @@
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/io.h> 26#include <linux/io.h>
27 27
28#include <asm/arch/sram.h> 28#include <mach/sram.h>
29#include <asm/arch/omapfb.h> 29#include <mach/omapfb.h>
30#include <asm/arch/board.h> 30#include <mach/board.h>
31 31
32#include "dispc.h" 32#include "dispc.h"
33 33
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 1e642b7a20fe..f24df0b54e1c 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -26,9 +26,9 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/clk.h> 27#include <linux/clk.h>
28 28
29#include <asm/arch/dma.h> 29#include <mach/dma.h>
30#include <asm/arch/omapfb.h> 30#include <mach/omapfb.h>
31#include <asm/arch/hwa742.h> 31#include <mach/hwa742.h>
32 32
33#define HWA742_REV_CODE_REG 0x0 33#define HWA742_REV_CODE_REG 0x0
34#define HWA742_CONFIG_REG 0x2 34#define HWA742_CONFIG_REG 0x2
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c
index 31e978349a80..2486237ebba5 100644
--- a/drivers/video/omap/lcd_h3.c
+++ b/drivers/video/omap/lcd_h3.c
@@ -23,8 +23,8 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/i2c/tps65010.h> 24#include <linux/i2c/tps65010.h>
25 25
26#include <asm/arch/gpio.h> 26#include <mach/gpio.h>
27#include <asm/arch/omapfb.h> 27#include <mach/omapfb.h>
28 28
29#define MODULE_NAME "omapfb-lcd_h3" 29#define MODULE_NAME "omapfb-lcd_h3"
30 30
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
index fd6f0eb16de1..88c19d424ef7 100644
--- a/drivers/video/omap/lcd_h4.c
+++ b/drivers/video/omap/lcd_h4.c
@@ -22,7 +22,7 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24 24
25#include <asm/arch/omapfb.h> 25#include <mach/omapfb.h>
26 26
27static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) 27static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
28{ 28{
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c
index 551f385861d1..6953ed4b5820 100644
--- a/drivers/video/omap/lcd_inn1510.c
+++ b/drivers/video/omap/lcd_inn1510.c
@@ -23,8 +23,8 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/io.h> 24#include <linux/io.h>
25 25
26#include <asm/arch/fpga.h> 26#include <mach/fpga.h>
27#include <asm/arch/omapfb.h> 27#include <mach/omapfb.h>
28 28
29static int innovator1510_panel_init(struct lcd_panel *panel, 29static int innovator1510_panel_init(struct lcd_panel *panel,
30 struct omapfb_device *fbdev) 30 struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 5ef119c813e0..6a42c6a0cd99 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -22,8 +22,8 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24 24
25#include <asm/arch/gpio.h> 25#include <mach/gpio.h>
26#include <asm/arch/omapfb.h> 26#include <mach/omapfb.h>
27 27
28#define MODULE_NAME "omapfb-lcd_h3" 28#define MODULE_NAME "omapfb-lcd_h3"
29 29
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index a38038840fd6..a4a725f427a4 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -23,9 +23,9 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25 25
26#include <asm/arch/gpio.h> 26#include <mach/gpio.h>
27#include <asm/arch/mux.h> 27#include <mach/mux.h>
28#include <asm/arch/omapfb.h> 28#include <mach/omapfb.h>
29 29
30static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) 30static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
31{ 31{
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index 52bdfdac42c9..218317366e6e 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -23,8 +23,8 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/io.h> 24#include <linux/io.h>
25 25
26#include <asm/arch/fpga.h> 26#include <mach/fpga.h>
27#include <asm/arch/omapfb.h> 27#include <mach/omapfb.h>
28 28
29static int palmte_panel_init(struct lcd_panel *panel, 29static int palmte_panel_init(struct lcd_panel *panel,
30 struct omapfb_device *fbdev) 30 struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c
index 4bb349f54356..57b0f6cf6a5a 100644
--- a/drivers/video/omap/lcd_palmtt.c
+++ b/drivers/video/omap/lcd_palmtt.c
@@ -29,8 +29,8 @@ GPIO13 - screen blanking
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/io.h> 30#include <linux/io.h>
31 31
32#include <asm/arch/gpio.h> 32#include <mach/gpio.h>
33#include <asm/arch/omapfb.h> 33#include <mach/omapfb.h>
34 34
35static int palmtt_panel_init(struct lcd_panel *panel, 35static int palmtt_panel_init(struct lcd_panel *panel,
36 struct omapfb_device *fbdev) 36 struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c
index ea6170ddff35..d33d78b11723 100644
--- a/drivers/video/omap/lcd_palmz71.c
+++ b/drivers/video/omap/lcd_palmz71.c
@@ -24,7 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/io.h> 25#include <linux/io.h>
26 26
27#include <asm/arch/omapfb.h> 27#include <mach/omapfb.h>
28 28
29static int palmz71_panel_init(struct lcd_panel *panel, 29static int palmz71_panel_init(struct lcd_panel *panel,
30 struct omapfb_device *fbdev) 30 struct omapfb_device *fbdev)
diff --git a/drivers/video/omap/lcd_sx1.c b/drivers/video/omap/lcd_sx1.c
index c4f306a4e5c9..caa6a896cb8b 100644
--- a/drivers/video/omap/lcd_sx1.c
+++ b/drivers/video/omap/lcd_sx1.c
@@ -23,10 +23,10 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/io.h> 24#include <linux/io.h>
25 25
26#include <asm/arch/gpio.h> 26#include <mach/gpio.h>
27#include <asm/arch/omapfb.h> 27#include <mach/omapfb.h>
28#include <asm/arch/mcbsp.h> 28#include <mach/mcbsp.h>
29#include <asm/arch/mux.h> 29#include <mach/mux.h>
30 30
31/* 31/*
32 * OMAP310 GPIO registers 32 * OMAP310 GPIO registers
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index fb19ed4992db..83514f066712 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -29,8 +29,8 @@
29#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
30#include <linux/clk.h> 30#include <linux/clk.h>
31 31
32#include <asm/arch/dma.h> 32#include <mach/dma.h>
33#include <asm/arch/omapfb.h> 33#include <mach/omapfb.h>
34 34
35#include <asm/mach-types.h> 35#include <asm/mach-types.h>
36 36
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index f85af5c4fa68..51a138bd113c 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -28,9 +28,8 @@
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/uaccess.h> 29#include <linux/uaccess.h>
30 30
31#include <asm/mach-types.h> 31#include <mach/dma.h>
32#include <asm/arch/dma.h> 32#include <mach/omapfb.h>
33#include <asm/arch/omapfb.h>
34 33
35#define MODULE_NAME "omapfb" 34#define MODULE_NAME "omapfb"
36 35
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index 789cfd23c36b..4a6f13d3facf 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -27,7 +27,7 @@
27#include <linux/clk.h> 27#include <linux/clk.h>
28#include <linux/io.h> 28#include <linux/io.h>
29 29
30#include <asm/arch/omapfb.h> 30#include <mach/omapfb.h>
31 31
32#include "dispc.h" 32#include "dispc.h"
33 33
diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c
index fafd0f26b90f..6359353c2c67 100644
--- a/drivers/video/omap/sossi.c
+++ b/drivers/video/omap/sossi.c
@@ -24,8 +24,8 @@
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/io.h> 25#include <linux/io.h>
26 26
27#include <asm/arch/dma.h> 27#include <mach/dma.h>
28#include <asm/arch/omapfb.h> 28#include <mach/omapfb.h>
29 29
30#include "lcdc.h" 30#include "lcdc.h"
31 31
diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h
index d80a614d89ed..1234d4375d92 100644
--- a/drivers/video/pnx4008/dum.h
+++ b/drivers/video/pnx4008/dum.h
@@ -12,7 +12,7 @@
12#ifndef __PNX008_DUM_H__ 12#ifndef __PNX008_DUM_H__
13#define __PNX008_DUM_H__ 13#define __PNX008_DUM_H__
14 14
15#include <asm/arch/platform.h> 15#include <mach/platform.h>
16 16
17#define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE) 17#define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE)
18#define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE) 18#define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE)
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
index d23bf0d659b6..2aa09bce3944 100644
--- a/drivers/video/pnx4008/sdum.c
+++ b/drivers/video/pnx4008/sdum.c
@@ -30,7 +30,7 @@
30#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33#include <asm/arch/gpio.h> 33#include <mach/gpio.h>
34 34
35#include "sdum.h" 35#include "sdum.h"
36#include "fbcommon.h" 36#include "fbcommon.h"
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 69de2fed6c58..97204497d9f7 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -45,14 +45,14 @@
45#include <linux/kthread.h> 45#include <linux/kthread.h>
46#include <linux/freezer.h> 46#include <linux/freezer.h>
47 47
48#include <asm/hardware.h> 48#include <mach/hardware.h>
49#include <asm/io.h> 49#include <asm/io.h>
50#include <asm/irq.h> 50#include <asm/irq.h>
51#include <asm/div64.h> 51#include <asm/div64.h>
52#include <asm/arch/pxa-regs.h> 52#include <mach/pxa-regs.h>
53#include <asm/arch/pxa2xx-gpio.h> 53#include <mach/pxa2xx-gpio.h>
54#include <asm/arch/bitfield.h> 54#include <mach/bitfield.h>
55#include <asm/arch/pxafb.h> 55#include <mach/pxafb.h>
56 56
57/* 57/*
58 * Complain if VAR is out of range. 58 * Complain if VAR is out of range.
@@ -1031,7 +1031,9 @@ static void pxafb_setup_gpio(struct pxafb_info *fbi)
1031 pxa_gpio_mode(GPIO74_LCD_FCLK_MD); 1031 pxa_gpio_mode(GPIO74_LCD_FCLK_MD);
1032 pxa_gpio_mode(GPIO75_LCD_LCLK_MD); 1032 pxa_gpio_mode(GPIO75_LCD_LCLK_MD);
1033 pxa_gpio_mode(GPIO76_LCD_PCLK_MD); 1033 pxa_gpio_mode(GPIO76_LCD_PCLK_MD);
1034 pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD); 1034
1035 if ((lccr0 & LCCR0_PAS) == 0)
1036 pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD);
1035} 1037}
1036 1038
1037static void pxafb_enable_controller(struct pxafb_info *fbi) 1039static void pxafb_enable_controller(struct pxafb_info *fbi)
@@ -1400,6 +1402,8 @@ static void pxafb_decode_mach_info(struct pxafb_info *fbi,
1400 if (lcd_conn == LCD_MONO_STN_8BPP) 1402 if (lcd_conn == LCD_MONO_STN_8BPP)
1401 fbi->lccr0 |= LCCR0_DPD; 1403 fbi->lccr0 |= LCCR0_DPD;
1402 1404
1405 fbi->lccr0 |= (lcd_conn & LCD_ALTERNATE_MAPPING) ? LCCR0_LDDALT : 0;
1406
1403 fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff); 1407 fbi->lccr3 = LCCR3_Acb((inf->lcd_conn >> 10) & 0xff);
1404 fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0; 1408 fbi->lccr3 |= (lcd_conn & LCD_BIAS_ACTIVE_LOW) ? LCCR3_OEP : 0;
1405 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0; 1409 fbi->lccr3 |= (lcd_conn & LCD_PCLK_EDGE_FALL) ? LCCR3_PCP : 0;
@@ -1673,53 +1677,63 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)");
1673#define pxafb_setup_options() (0) 1677#define pxafb_setup_options() (0)
1674#endif 1678#endif
1675 1679
1676static int __devinit pxafb_probe(struct platform_device *dev)
1677{
1678 struct pxafb_info *fbi;
1679 struct pxafb_mach_info *inf;
1680 struct resource *r;
1681 int irq, ret;
1682
1683 dev_dbg(&dev->dev, "pxafb_probe\n");
1684
1685 inf = dev->dev.platform_data;
1686 ret = -ENOMEM;
1687 fbi = NULL;
1688 if (!inf)
1689 goto failed;
1690
1691 ret = pxafb_parse_options(&dev->dev, g_options);
1692 if (ret < 0)
1693 goto failed;
1694
1695#ifdef DEBUG_VAR 1680#ifdef DEBUG_VAR
1696 /* Check for various illegal bit-combinations. Currently only 1681/* Check for various illegal bit-combinations. Currently only
1697 * a warning is given. */ 1682 * a warning is given. */
1683static void __devinit pxafb_check_options(struct device *dev,
1684 struct pxafb_mach_info *inf)
1685{
1686 if (inf->lcd_conn)
1687 return;
1698 1688
1699 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK) 1689 if (inf->lccr0 & LCCR0_INVALID_CONFIG_MASK)
1700 dev_warn(&dev->dev, "machine LCCR0 setting contains " 1690 dev_warn(dev, "machine LCCR0 setting contains "
1701 "illegal bits: %08x\n", 1691 "illegal bits: %08x\n",
1702 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK); 1692 inf->lccr0 & LCCR0_INVALID_CONFIG_MASK);
1703 if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK) 1693 if (inf->lccr3 & LCCR3_INVALID_CONFIG_MASK)
1704 dev_warn(&dev->dev, "machine LCCR3 setting contains " 1694 dev_warn(dev, "machine LCCR3 setting contains "
1705 "illegal bits: %08x\n", 1695 "illegal bits: %08x\n",
1706 inf->lccr3 & LCCR3_INVALID_CONFIG_MASK); 1696 inf->lccr3 & LCCR3_INVALID_CONFIG_MASK);
1707 if (inf->lccr0 & LCCR0_DPD && 1697 if (inf->lccr0 & LCCR0_DPD &&
1708 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas || 1698 ((inf->lccr0 & LCCR0_PAS) != LCCR0_Pas ||
1709 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl || 1699 (inf->lccr0 & LCCR0_SDS) != LCCR0_Sngl ||
1710 (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono)) 1700 (inf->lccr0 & LCCR0_CMS) != LCCR0_Mono))
1711 dev_warn(&dev->dev, "Double Pixel Data (DPD) mode is " 1701 dev_warn(dev, "Double Pixel Data (DPD) mode is "
1712 "only valid in passive mono" 1702 "only valid in passive mono"
1713 " single panel mode\n"); 1703 " single panel mode\n");
1714 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act && 1704 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Act &&
1715 (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual) 1705 (inf->lccr0 & LCCR0_SDS) == LCCR0_Dual)
1716 dev_warn(&dev->dev, "Dual panel only valid in passive mode\n"); 1706 dev_warn(dev, "Dual panel only valid in passive mode\n");
1717 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas && 1707 if ((inf->lccr0 & LCCR0_PAS) == LCCR0_Pas &&
1718 (inf->modes->upper_margin || inf->modes->lower_margin)) 1708 (inf->modes->upper_margin || inf->modes->lower_margin))
1719 dev_warn(&dev->dev, "Upper and lower margins must be 0 in " 1709 dev_warn(dev, "Upper and lower margins must be 0 in "
1720 "passive mode\n"); 1710 "passive mode\n");
1711}
1712#else
1713#define pxafb_check_options(...) do {} while (0)
1721#endif 1714#endif
1722 1715
1716static int __devinit pxafb_probe(struct platform_device *dev)
1717{
1718 struct pxafb_info *fbi;
1719 struct pxafb_mach_info *inf;
1720 struct resource *r;
1721 int irq, ret;
1722
1723 dev_dbg(&dev->dev, "pxafb_probe\n");
1724
1725 inf = dev->dev.platform_data;
1726 ret = -ENOMEM;
1727 fbi = NULL;
1728 if (!inf)
1729 goto failed;
1730
1731 ret = pxafb_parse_options(&dev->dev, g_options);
1732 if (ret < 0)
1733 goto failed;
1734
1735 pxafb_check_options(&dev->dev, inf);
1736
1723 dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n", 1737 dev_dbg(&dev->dev, "got a %dx%dx%d LCD\n",
1724 inf->modes->xres, 1738 inf->modes->xres,
1725 inf->modes->yres, 1739 inf->modes->yres,
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index f0598961c6b0..79cf0b1976aa 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -29,9 +29,9 @@
29#include <asm/div64.h> 29#include <asm/div64.h>
30 30
31#include <asm/mach/map.h> 31#include <asm/mach/map.h>
32#include <asm/arch/regs-lcd.h> 32#include <mach/regs-lcd.h>
33#include <asm/arch/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <asm/arch/fb.h> 34#include <mach/fb.h>
35 35
36#ifdef CONFIG_PM 36#ifdef CONFIG_PM
37#include <linux/pm.h> 37#include <linux/pm.h>
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 78bcdbc3f484..c052bd4c0b06 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -177,11 +177,11 @@
177#include <linux/dma-mapping.h> 177#include <linux/dma-mapping.h>
178#include <linux/mutex.h> 178#include <linux/mutex.h>
179 179
180#include <asm/hardware.h> 180#include <mach/hardware.h>
181#include <asm/io.h> 181#include <asm/io.h>
182#include <asm/mach-types.h> 182#include <asm/mach-types.h>
183#include <asm/arch/assabet.h> 183#include <mach/assabet.h>
184#include <asm/arch/shannon.h> 184#include <mach/shannon.h>
185 185
186/* 186/*
187 * debugging? 187 * debugging?
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 48399e134c0d..db20542796bf 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -285,10 +285,11 @@ config ALIM1535_WDT
285 285
286config ALIM7101_WDT 286config ALIM7101_WDT
287 tristate "ALi M7101 PMU Computer Watchdog" 287 tristate "ALi M7101 PMU Computer Watchdog"
288 depends on X86 && PCI 288 depends on PCI
289 help 289 help
290 This is the driver for the hardware watchdog on the ALi M7101 PMU 290 This is the driver for the hardware watchdog on the ALi M7101 PMU
291 as used in the x86 Cobalt servers. 291 as used in the x86 Cobalt servers and also found in some
292 SPARC Netra servers too.
292 293
293 To compile this driver as a module, choose M here: the 294 To compile this driver as a module, choose M here: the
294 module will be called alim7101_wdt. 295 module will be called alim7101_wdt.
@@ -463,7 +464,7 @@ config PC87413_WDT
463 module will be called pc87413_wdt. 464 module will be called pc87413_wdt.
464 465
465 Most people will say N. 466 Most people will say N.
466 467
467config 60XX_WDT 468config 60XX_WDT
468 tristate "SBC-60XX Watchdog Timer" 469 tristate "SBC-60XX Watchdog Timer"
469 depends on X86 470 depends on X86
@@ -695,9 +696,17 @@ config 8xx_WDT
695 tristate "MPC8xx Watchdog Timer" 696 tristate "MPC8xx Watchdog Timer"
696 depends on 8xx 697 depends on 8xx
697 698
698config 83xx_WDT 699config 8xxx_WDT
699 tristate "MPC83xx Watchdog Timer" 700 tristate "MPC8xxx Platform Watchdog Timer"
700 depends on PPC_83xx 701 depends on PPC_8xx || PPC_83xx || PPC_86xx
702 help
703 This driver is for a SoC level watchdog that exists on some
704 Freescale PowerPC processors. So far this driver supports:
705 - MPC8xx watchdogs
706 - MPC83xx watchdogs
707 - MPC86xx watchdogs
708
709 For BookE processors (MPC85xx) use the BOOKE_WDT driver instead.
701 710
702config MV64X60_WDT 711config MV64X60_WDT
703 tristate "MV64X60 (Marvell Discovery) Watchdog Timer" 712 tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index edd305a64e63..ca3dc043d786 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -66,7 +66,10 @@ obj-$(CONFIG_IB700_WDT) += ib700wdt.o
66obj-$(CONFIG_IBMASR) += ibmasr.o 66obj-$(CONFIG_IBMASR) += ibmasr.o
67obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o 67obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
68obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o 68obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
69obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o 69obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
70ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y)
71obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
72endif
70obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o 73obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
71obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o 74obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
72obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o 75obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
@@ -92,7 +95,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
92 95
93# MIPS Architecture 96# MIPS Architecture
94obj-$(CONFIG_INDYDOG) += indydog.o 97obj-$(CONFIG_INDYDOG) += indydog.o
95obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o 98obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
96obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o 99obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
97obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o 100obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
98obj-$(CONFIG_AR7_WDT) += ar7_wdt.o 101obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
@@ -103,7 +106,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
103# POWERPC Architecture 106# POWERPC Architecture
104obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 107obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
105obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o 108obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o
106obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o 109obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o
107obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o 110obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
108obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o 111obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
109 112
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 85269c365a10..6e46a551395c 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -58,39 +58,45 @@
58#include <linux/types.h> /* For standard types (like size_t) */ 58#include <linux/types.h> /* For standard types (like size_t) */
59#include <linux/errno.h> /* For the -ENODEV/... values */ 59#include <linux/errno.h> /* For the -ENODEV/... values */
60#include <linux/kernel.h> /* For printk/panic/... */ 60#include <linux/kernel.h> /* For printk/panic/... */
61#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ 61#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV
62 (WATCHDOG_MINOR) */
62#include <linux/watchdog.h> /* For the watchdog specific items */ 63#include <linux/watchdog.h> /* For the watchdog specific items */
63#include <linux/fs.h> /* For file operations */ 64#include <linux/fs.h> /* For file operations */
64#include <linux/ioport.h> /* For io-port access */ 65#include <linux/ioport.h> /* For io-port access */
65#include <linux/platform_device.h> /* For platform_driver framework */ 66#include <linux/platform_device.h> /* For platform_driver framework */
66#include <linux/init.h> /* For __init/__exit/... */ 67#include <linux/init.h> /* For __init/__exit/... */
67 68#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
68#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 69#include <linux/io.h> /* For inb/outb/... */
69#include <asm/io.h> /* For inb/outb/... */
70 70
71/* Module information */ 71/* Module information */
72#define DRV_NAME "acquirewdt" 72#define DRV_NAME "acquirewdt"
73#define PFX DRV_NAME ": " 73#define PFX DRV_NAME ": "
74#define WATCHDOG_NAME "Acquire WDT" 74#define WATCHDOG_NAME "Acquire WDT"
75#define WATCHDOG_HEARTBEAT 0 /* There is no way to see what the correct time-out period is */ 75/* There is no way to see what the correct time-out period is */
76#define WATCHDOG_HEARTBEAT 0
76 77
77/* internal variables */ 78/* internal variables */
78static struct platform_device *acq_platform_device; /* the watchdog platform device */ 79/* the watchdog platform device */
80static struct platform_device *acq_platform_device;
79static unsigned long acq_is_open; 81static unsigned long acq_is_open;
80static char expect_close; 82static char expect_close;
81 83
82/* module parameters */ 84/* module parameters */
83static int wdt_stop = 0x43; /* You must set this - there is no sane way to probe for this board. */ 85/* You must set this - there is no sane way to probe for this board. */
86static int wdt_stop = 0x43;
84module_param(wdt_stop, int, 0); 87module_param(wdt_stop, int, 0);
85MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)"); 88MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)");
86 89
87static int wdt_start = 0x443; /* You must set this - there is no sane way to probe for this board. */ 90/* You must set this - there is no sane way to probe for this board. */
91static int wdt_start = 0x443;
88module_param(wdt_start, int, 0); 92module_param(wdt_start, int, 0);
89MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)"); 93MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)");
90 94
91static int nowayout = WATCHDOG_NOWAYOUT; 95static int nowayout = WATCHDOG_NOWAYOUT;
92module_param(nowayout, int, 0); 96module_param(nowayout, int, 0);
93MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 97MODULE_PARM_DESC(nowayout,
98 "Watchdog cannot be stopped once started (default="
99 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
94 100
95/* 101/*
96 * Watchdog Operations 102 * Watchdog Operations
@@ -112,18 +118,18 @@ static void acq_stop(void)
112 * /dev/watchdog handling 118 * /dev/watchdog handling
113 */ 119 */
114 120
115static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 121static ssize_t acq_write(struct file *file, const char __user *buf,
122 size_t count, loff_t *ppos)
116{ 123{
117 /* See if we got the magic character 'V' and reload the timer */ 124 /* See if we got the magic character 'V' and reload the timer */
118 if(count) { 125 if (count) {
119 if (!nowayout) { 126 if (!nowayout) {
120 size_t i; 127 size_t i;
121
122 /* note: just in case someone wrote the magic character 128 /* note: just in case someone wrote the magic character
123 * five months ago... */ 129 five months ago... */
124 expect_close = 0; 130 expect_close = 0;
125 131 /* scan to see whether or not we got the
126 /* scan to see whether or not we got the magic character */ 132 magic character */
127 for (i = 0; i != count; i++) { 133 for (i = 0; i != count; i++) {
128 char c; 134 char c;
129 if (get_user(c, buf + i)) 135 if (get_user(c, buf + i))
@@ -132,64 +138,55 @@ static ssize_t acq_write(struct file *file, const char __user *buf, size_t count
132 expect_close = 42; 138 expect_close = 42;
133 } 139 }
134 } 140 }
135 141 /* Well, anyhow someone wrote to us, we should
136 /* Well, anyhow someone wrote to us, we should return that favour */ 142 return that favour */
137 acq_keepalive(); 143 acq_keepalive();
138 } 144 }
139 return count; 145 return count;
140} 146}
141 147
142static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 148static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
143 unsigned long arg)
144{ 149{
145 int options, retval = -EINVAL; 150 int options, retval = -EINVAL;
146 void __user *argp = (void __user *)arg; 151 void __user *argp = (void __user *)arg;
147 int __user *p = argp; 152 int __user *p = argp;
148 static struct watchdog_info ident = 153 static struct watchdog_info ident = {
149 {
150 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 154 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
151 .firmware_version = 1, 155 .firmware_version = 1,
152 .identity = WATCHDOG_NAME, 156 .identity = WATCHDOG_NAME,
153 }; 157 };
154 158
155 switch(cmd) 159 switch (cmd) {
156 {
157 case WDIOC_GETSUPPORT: 160 case WDIOC_GETSUPPORT:
158 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 161 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
159 162
160 case WDIOC_GETSTATUS: 163 case WDIOC_GETSTATUS:
161 case WDIOC_GETBOOTSTATUS: 164 case WDIOC_GETBOOTSTATUS:
162 return put_user(0, p); 165 return put_user(0, p);
163
164 case WDIOC_KEEPALIVE:
165 acq_keepalive();
166 return 0;
167
168 case WDIOC_GETTIMEOUT:
169 return put_user(WATCHDOG_HEARTBEAT, p);
170 166
171 case WDIOC_SETOPTIONS: 167 case WDIOC_SETOPTIONS:
172 { 168 {
173 if (get_user(options, p)) 169 if (get_user(options, p))
174 return -EFAULT; 170 return -EFAULT;
175 171 if (options & WDIOS_DISABLECARD) {
176 if (options & WDIOS_DISABLECARD) 172 acq_stop();
177 { 173 retval = 0;
178 acq_stop(); 174 }
179 retval = 0; 175 if (options & WDIOS_ENABLECARD) {
180 } 176 acq_keepalive();
181 177 retval = 0;
182 if (options & WDIOS_ENABLECARD) 178 }
183 { 179 return retval;
184 acq_keepalive();
185 retval = 0;
186 }
187
188 return retval;
189 } 180 }
181 case WDIOC_KEEPALIVE:
182 acq_keepalive();
183 return 0;
184
185 case WDIOC_GETTIMEOUT:
186 return put_user(WATCHDOG_HEARTBEAT, p);
190 187
191 default: 188 default:
192 return -ENOTTY; 189 return -ENOTTY;
193 } 190 }
194} 191}
195 192
@@ -211,7 +208,8 @@ static int acq_close(struct inode *inode, struct file *file)
211 if (expect_close == 42) { 208 if (expect_close == 42) {
212 acq_stop(); 209 acq_stop();
213 } else { 210 } else {
214 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 211 printk(KERN_CRIT PFX
212 "Unexpected close, not stopping watchdog!\n");
215 acq_keepalive(); 213 acq_keepalive();
216 } 214 }
217 clear_bit(0, &acq_is_open); 215 clear_bit(0, &acq_is_open);
@@ -227,7 +225,7 @@ static const struct file_operations acq_fops = {
227 .owner = THIS_MODULE, 225 .owner = THIS_MODULE,
228 .llseek = no_llseek, 226 .llseek = no_llseek,
229 .write = acq_write, 227 .write = acq_write,
230 .ioctl = acq_ioctl, 228 .unlocked_ioctl = acq_ioctl,
231 .open = acq_open, 229 .open = acq_open,
232 .release = acq_close, 230 .release = acq_close,
233}; 231};
@@ -248,32 +246,29 @@ static int __devinit acq_probe(struct platform_device *dev)
248 246
249 if (wdt_stop != wdt_start) { 247 if (wdt_stop != wdt_start) {
250 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 248 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
251 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 249 printk(KERN_ERR PFX
252 wdt_stop); 250 "I/O address 0x%04x already in use\n", wdt_stop);
253 ret = -EIO; 251 ret = -EIO;
254 goto out; 252 goto out;
255 } 253 }
256 } 254 }
257 255
258 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { 256 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) {
259 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 257 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
260 wdt_start); 258 wdt_start);
261 ret = -EIO; 259 ret = -EIO;
262 goto unreg_stop; 260 goto unreg_stop;
263 } 261 }
264
265 ret = misc_register(&acq_miscdev); 262 ret = misc_register(&acq_miscdev);
266 if (ret != 0) { 263 if (ret != 0) {
267 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 264 printk(KERN_ERR PFX
268 WATCHDOG_MINOR, ret); 265 "cannot register miscdev on minor=%d (err=%d)\n",
266 WATCHDOG_MINOR, ret);
269 goto unreg_regions; 267 goto unreg_regions;
270 } 268 }
271 269 printk(KERN_INFO PFX "initialized. (nowayout=%d)\n", nowayout);
272 printk (KERN_INFO PFX "initialized. (nowayout=%d)\n",
273 nowayout);
274 270
275 return 0; 271 return 0;
276
277unreg_regions: 272unreg_regions:
278 release_region(wdt_start, 1); 273 release_region(wdt_start, 1);
279unreg_stop: 274unreg_stop:
@@ -286,9 +281,9 @@ out:
286static int __devexit acq_remove(struct platform_device *dev) 281static int __devexit acq_remove(struct platform_device *dev)
287{ 282{
288 misc_deregister(&acq_miscdev); 283 misc_deregister(&acq_miscdev);
289 release_region(wdt_start,1); 284 release_region(wdt_start, 1);
290 if(wdt_stop != wdt_start) 285 if (wdt_stop != wdt_start)
291 release_region(wdt_stop,1); 286 release_region(wdt_stop, 1);
292 287
293 return 0; 288 return 0;
294} 289}
@@ -313,18 +308,19 @@ static int __init acq_init(void)
313{ 308{
314 int err; 309 int err;
315 310
316 printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n"); 311 printk(KERN_INFO
312 "WDT driver for Acquire single board computer initialising.\n");
317 313
318 err = platform_driver_register(&acquirewdt_driver); 314 err = platform_driver_register(&acquirewdt_driver);
319 if (err) 315 if (err)
320 return err; 316 return err;
321 317
322 acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 318 acq_platform_device = platform_device_register_simple(DRV_NAME,
319 -1, NULL, 0);
323 if (IS_ERR(acq_platform_device)) { 320 if (IS_ERR(acq_platform_device)) {
324 err = PTR_ERR(acq_platform_device); 321 err = PTR_ERR(acq_platform_device);
325 goto unreg_platform_driver; 322 goto unreg_platform_driver;
326 } 323 }
327
328 return 0; 324 return 0;
329 325
330unreg_platform_driver: 326unreg_platform_driver:
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 8121cc247343..a5110f93a755 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -37,9 +37,9 @@
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/io.h>
41#include <linux/uaccess.h>
40 42
41#include <asm/io.h>
42#include <asm/uaccess.h>
43#include <asm/system.h> 43#include <asm/system.h>
44 44
45#define DRV_NAME "advantechwdt" 45#define DRV_NAME "advantechwdt"
@@ -47,7 +47,8 @@
47#define WATCHDOG_NAME "Advantech WDT" 47#define WATCHDOG_NAME "Advantech WDT"
48#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ 48#define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */
49 49
50static struct platform_device *advwdt_platform_device; /* the watchdog platform device */ 50/* the watchdog platform device */
51static struct platform_device *advwdt_platform_device;
51static unsigned long advwdt_is_open; 52static unsigned long advwdt_is_open;
52static char adv_expect_close; 53static char adv_expect_close;
53 54
@@ -72,35 +73,35 @@ MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)");
72 73
73static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 74static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
74module_param(timeout, int, 0); 75module_param(timeout, int, 0);
75MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 76MODULE_PARM_DESC(timeout,
77 "Watchdog timeout in seconds. 1<= timeout <=63, default="
78 __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
76 79
77static int nowayout = WATCHDOG_NOWAYOUT; 80static int nowayout = WATCHDOG_NOWAYOUT;
78module_param(nowayout, int, 0); 81module_param(nowayout, int, 0);
79MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 82MODULE_PARM_DESC(nowayout,
83 "Watchdog cannot be stopped once started (default="
84 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
80 85
81/* 86/*
82 * Watchdog Operations 87 * Watchdog Operations
83 */ 88 */
84 89
85static void 90static void advwdt_ping(void)
86advwdt_ping(void)
87{ 91{
88 /* Write a watchdog value */ 92 /* Write a watchdog value */
89 outb_p(timeout, wdt_start); 93 outb_p(timeout, wdt_start);
90} 94}
91 95
92static void 96static void advwdt_disable(void)
93advwdt_disable(void)
94{ 97{
95 inb_p(wdt_stop); 98 inb_p(wdt_stop);
96} 99}
97 100
98static int 101static int advwdt_set_heartbeat(int t)
99advwdt_set_heartbeat(int t)
100{ 102{
101 if ((t < 1) || (t > 63)) 103 if (t < 1 || t > 63)
102 return -EINVAL; 104 return -EINVAL;
103
104 timeout = t; 105 timeout = t;
105 return 0; 106 return 0;
106} 107}
@@ -109,8 +110,8 @@ advwdt_set_heartbeat(int t)
109 * /dev/watchdog handling 110 * /dev/watchdog handling
110 */ 111 */
111 112
112static ssize_t 113static ssize_t advwdt_write(struct file *file, const char __user *buf,
113advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 114 size_t count, loff_t *ppos)
114{ 115{
115 if (count) { 116 if (count) {
116 if (!nowayout) { 117 if (!nowayout) {
@@ -120,7 +121,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp
120 121
121 for (i = 0; i != count; i++) { 122 for (i = 0; i != count; i++) {
122 char c; 123 char c;
123 if (get_user(c, buf+i)) 124 if (get_user(c, buf + i))
124 return -EFAULT; 125 return -EFAULT;
125 if (c == 'V') 126 if (c == 'V')
126 adv_expect_close = 42; 127 adv_expect_close = 42;
@@ -131,9 +132,7 @@ advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *pp
131 return count; 132 return count;
132} 133}
133 134
134static int 135static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
135advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
136 unsigned long arg)
137{ 136{
138 int new_timeout; 137 int new_timeout;
139 void __user *argp = (void __user *)arg; 138 void __user *argp = (void __user *)arg;
@@ -146,57 +145,50 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
146 145
147 switch (cmd) { 146 switch (cmd) {
148 case WDIOC_GETSUPPORT: 147 case WDIOC_GETSUPPORT:
149 if (copy_to_user(argp, &ident, sizeof(ident))) 148 if (copy_to_user(argp, &ident, sizeof(ident)))
150 return -EFAULT; 149 return -EFAULT;
151 break; 150 break;
152 151
153 case WDIOC_GETSTATUS: 152 case WDIOC_GETSTATUS:
154 case WDIOC_GETBOOTSTATUS: 153 case WDIOC_GETBOOTSTATUS:
155 return put_user(0, p); 154 return put_user(0, p);
156
157 case WDIOC_KEEPALIVE:
158 advwdt_ping();
159 break;
160
161 case WDIOC_SETTIMEOUT:
162 if (get_user(new_timeout, p))
163 return -EFAULT;
164 if (advwdt_set_heartbeat(new_timeout))
165 return -EINVAL;
166 advwdt_ping();
167 /* Fall */
168
169 case WDIOC_GETTIMEOUT:
170 return put_user(timeout, p);
171 155
172 case WDIOC_SETOPTIONS: 156 case WDIOC_SETOPTIONS:
173 { 157 {
174 int options, retval = -EINVAL; 158 int options, retval = -EINVAL;
175
176 if (get_user(options, p))
177 return -EFAULT;
178
179 if (options & WDIOS_DISABLECARD) {
180 advwdt_disable();
181 retval = 0;
182 }
183 159
184 if (options & WDIOS_ENABLECARD) { 160 if (get_user(options, p))
185 advwdt_ping(); 161 return -EFAULT;
186 retval = 0; 162 if (options & WDIOS_DISABLECARD) {
187 } 163 advwdt_disable();
188 164 retval = 0;
189 return retval; 165 }
166 if (options & WDIOS_ENABLECARD) {
167 advwdt_ping();
168 retval = 0;
169 }
170 return retval;
190 } 171 }
172 case WDIOC_KEEPALIVE:
173 advwdt_ping();
174 break;
191 175
176 case WDIOC_SETTIMEOUT:
177 if (get_user(new_timeout, p))
178 return -EFAULT;
179 if (advwdt_set_heartbeat(new_timeout))
180 return -EINVAL;
181 advwdt_ping();
182 /* Fall */
183 case WDIOC_GETTIMEOUT:
184 return put_user(timeout, p);
192 default: 185 default:
193 return -ENOTTY; 186 return -ENOTTY;
194 } 187 }
195 return 0; 188 return 0;
196} 189}
197 190
198static int 191static int advwdt_open(struct inode *inode, struct file *file)
199advwdt_open(struct inode *inode, struct file *file)
200{ 192{
201 if (test_and_set_bit(0, &advwdt_is_open)) 193 if (test_and_set_bit(0, &advwdt_is_open))
202 return -EBUSY; 194 return -EBUSY;
@@ -208,13 +200,13 @@ advwdt_open(struct inode *inode, struct file *file)
208 return nonseekable_open(inode, file); 200 return nonseekable_open(inode, file);
209} 201}
210 202
211static int 203static int advwdt_close(struct inode *inode, struct file *file)
212advwdt_close(struct inode *inode, struct file *file)
213{ 204{
214 if (adv_expect_close == 42) { 205 if (adv_expect_close == 42) {
215 advwdt_disable(); 206 advwdt_disable();
216 } else { 207 } else {
217 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 208 printk(KERN_CRIT PFX
209 "Unexpected close, not stopping watchdog!\n");
218 advwdt_ping(); 210 advwdt_ping();
219 } 211 }
220 clear_bit(0, &advwdt_is_open); 212 clear_bit(0, &advwdt_is_open);
@@ -230,7 +222,7 @@ static const struct file_operations advwdt_fops = {
230 .owner = THIS_MODULE, 222 .owner = THIS_MODULE,
231 .llseek = no_llseek, 223 .llseek = no_llseek,
232 .write = advwdt_write, 224 .write = advwdt_write,
233 .ioctl = advwdt_ioctl, 225 .unlocked_ioctl = advwdt_ioctl,
234 .open = advwdt_open, 226 .open = advwdt_open,
235 .release = advwdt_close, 227 .release = advwdt_close,
236}; 228};
@@ -245,23 +237,24 @@ static struct miscdevice advwdt_miscdev = {
245 * Init & exit routines 237 * Init & exit routines
246 */ 238 */
247 239
248static int __devinit 240static int __devinit advwdt_probe(struct platform_device *dev)
249advwdt_probe(struct platform_device *dev)
250{ 241{
251 int ret; 242 int ret;
252 243
253 if (wdt_stop != wdt_start) { 244 if (wdt_stop != wdt_start) {
254 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) { 245 if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
255 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 246 printk(KERN_ERR PFX
256 wdt_stop); 247 "I/O address 0x%04x already in use\n",
248 wdt_stop);
257 ret = -EIO; 249 ret = -EIO;
258 goto out; 250 goto out;
259 } 251 }
260 } 252 }
261 253
262 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) { 254 if (!request_region(wdt_start, 1, WATCHDOG_NAME)) {
263 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 255 printk(KERN_ERR PFX
264 wdt_start); 256 "I/O address 0x%04x already in use\n",
257 wdt_start);
265 ret = -EIO; 258 ret = -EIO;
266 goto unreg_stop; 259 goto unreg_stop;
267 } 260 }
@@ -269,20 +262,19 @@ advwdt_probe(struct platform_device *dev)
269 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 262 /* Check that the heartbeat value is within it's range ; if not reset to the default */
270 if (advwdt_set_heartbeat(timeout)) { 263 if (advwdt_set_heartbeat(timeout)) {
271 advwdt_set_heartbeat(WATCHDOG_TIMEOUT); 264 advwdt_set_heartbeat(WATCHDOG_TIMEOUT);
272 printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", 265 printk(KERN_INFO PFX
273 timeout); 266 "timeout value must be 1<=x<=63, using %d\n", timeout);
274 } 267 }
275 268
276 ret = misc_register(&advwdt_miscdev); 269 ret = misc_register(&advwdt_miscdev);
277 if (ret != 0) { 270 if (ret != 0) {
278 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 271 printk(KERN_ERR PFX
279 WATCHDOG_MINOR, ret); 272 "cannot register miscdev on minor=%d (err=%d)\n",
273 WATCHDOG_MINOR, ret);
280 goto unreg_regions; 274 goto unreg_regions;
281 } 275 }
282 276 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
283 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
284 timeout, nowayout); 277 timeout, nowayout);
285
286out: 278out:
287 return ret; 279 return ret;
288unreg_regions: 280unreg_regions:
@@ -293,19 +285,17 @@ unreg_stop:
293 goto out; 285 goto out;
294} 286}
295 287
296static int __devexit 288static int __devexit advwdt_remove(struct platform_device *dev)
297advwdt_remove(struct platform_device *dev)
298{ 289{
299 misc_deregister(&advwdt_miscdev); 290 misc_deregister(&advwdt_miscdev);
300 release_region(wdt_start,1); 291 release_region(wdt_start, 1);
301 if(wdt_stop != wdt_start) 292 if (wdt_stop != wdt_start)
302 release_region(wdt_stop,1); 293 release_region(wdt_stop, 1);
303 294
304 return 0; 295 return 0;
305} 296}
306 297
307static void 298static void advwdt_shutdown(struct platform_device *dev)
308advwdt_shutdown(struct platform_device *dev)
309{ 299{
310 /* Turn the WDT off if we have a soft shutdown */ 300 /* Turn the WDT off if we have a soft shutdown */
311 advwdt_disable(); 301 advwdt_disable();
@@ -321,18 +311,19 @@ static struct platform_driver advwdt_driver = {
321 }, 311 },
322}; 312};
323 313
324static int __init 314static int __init advwdt_init(void)
325advwdt_init(void)
326{ 315{
327 int err; 316 int err;
328 317
329 printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n"); 318 printk(KERN_INFO
319 "WDT driver for Advantech single board computer initialising.\n");
330 320
331 err = platform_driver_register(&advwdt_driver); 321 err = platform_driver_register(&advwdt_driver);
332 if (err) 322 if (err)
333 return err; 323 return err;
334 324
335 advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 325 advwdt_platform_device = platform_device_register_simple(DRV_NAME,
326 -1, NULL, 0);
336 if (IS_ERR(advwdt_platform_device)) { 327 if (IS_ERR(advwdt_platform_device)) {
337 err = PTR_ERR(advwdt_platform_device); 328 err = PTR_ERR(advwdt_platform_device);
338 goto unreg_platform_driver; 329 goto unreg_platform_driver;
@@ -345,8 +336,7 @@ unreg_platform_driver:
345 return err; 336 return err;
346} 337}
347 338
348static void __exit 339static void __exit advwdt_exit(void)
349advwdt_exit(void)
350{ 340{
351 platform_device_unregister(advwdt_platform_device); 341 platform_device_unregister(advwdt_platform_device);
352 platform_driver_unregister(&advwdt_driver); 342 platform_driver_unregister(&advwdt_driver);
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 2b1fbdb2fcf7..2a7690ecf97d 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -18,9 +18,8 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/pci.h> 20#include <linux/pci.h>
21 21#include <linux/uaccess.h>
22#include <asm/uaccess.h> 22#include <linux/io.h>
23#include <asm/io.h>
24 23
25#define WATCHDOG_NAME "ALi_M1535" 24#define WATCHDOG_NAME "ALi_M1535"
26#define PFX WATCHDOG_NAME ": " 25#define PFX WATCHDOG_NAME ": "
@@ -30,17 +29,21 @@
30static unsigned long ali_is_open; 29static unsigned long ali_is_open;
31static char ali_expect_release; 30static char ali_expect_release;
32static struct pci_dev *ali_pci; 31static struct pci_dev *ali_pci;
33static u32 ali_timeout_bits; /* stores the computed timeout */ 32static u32 ali_timeout_bits; /* stores the computed timeout */
34static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */ 33static DEFINE_SPINLOCK(ali_lock); /* Guards the hardware */
35 34
36/* module parameters */ 35/* module parameters */
37static int timeout = WATCHDOG_TIMEOUT; 36static int timeout = WATCHDOG_TIMEOUT;
38module_param(timeout, int, 0); 37module_param(timeout, int, 0);
39MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 38MODULE_PARM_DESC(timeout,
39 "Watchdog timeout in seconds. (0 < timeout < 18000, default="
40 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
40 41
41static int nowayout = WATCHDOG_NOWAYOUT; 42static int nowayout = WATCHDOG_NOWAYOUT;
42module_param(nowayout, int, 0); 43module_param(nowayout, int, 0);
43MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 44MODULE_PARM_DESC(nowayout,
45 "Watchdog cannot be stopped once started (default="
46 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
44 47
45/* 48/*
46 * ali_start - start watchdog countdown 49 * ali_start - start watchdog countdown
@@ -103,15 +106,16 @@ static void ali_keepalive(void)
103 106
104static int ali_settimer(int t) 107static int ali_settimer(int t)
105{ 108{
106 if(t < 0) 109 if (t < 0)
107 return -EINVAL; 110 return -EINVAL;
108 else if(t < 60) 111 else if (t < 60)
109 ali_timeout_bits = t|(1<<6); 112 ali_timeout_bits = t|(1<<6);
110 else if(t < 3600) 113 else if (t < 3600)
111 ali_timeout_bits = (t/60)|(1<<7); 114 ali_timeout_bits = (t/60)|(1<<7);
112 else if(t < 18000) 115 else if (t < 18000)
113 ali_timeout_bits = (t/300)|(1<<6)|(1<<7); 116 ali_timeout_bits = (t/300)|(1<<6)|(1<<7);
114 else return -EINVAL; 117 else
118 return -EINVAL;
115 119
116 timeout = t; 120 timeout = t;
117 return 0; 121 return 0;
@@ -134,21 +138,22 @@ static int ali_settimer(int t)
134 */ 138 */
135 139
136static ssize_t ali_write(struct file *file, const char __user *data, 140static ssize_t ali_write(struct file *file, const char __user *data,
137 size_t len, loff_t * ppos) 141 size_t len, loff_t *ppos)
138{ 142{
139 /* See if we got the magic character 'V' and reload the timer */ 143 /* See if we got the magic character 'V' and reload the timer */
140 if (len) { 144 if (len) {
141 if (!nowayout) { 145 if (!nowayout) {
142 size_t i; 146 size_t i;
143 147
144 /* note: just in case someone wrote the magic character 148 /* note: just in case someone wrote the
145 * five months ago... */ 149 magic character five months ago... */
146 ali_expect_release = 0; 150 ali_expect_release = 0;
147 151
148 /* scan to see whether or not we got the magic character */ 152 /* scan to see whether or not we got
153 the magic character */
149 for (i = 0; i != len; i++) { 154 for (i = 0; i != len; i++) {
150 char c; 155 char c;
151 if(get_user(c, data+i)) 156 if (get_user(c, data + i))
152 return -EFAULT; 157 return -EFAULT;
153 if (c == 'V') 158 if (c == 'V')
154 ali_expect_release = 42; 159 ali_expect_release = 42;
@@ -163,7 +168,6 @@ static ssize_t ali_write(struct file *file, const char __user *data,
163 168
164/* 169/*
165 * ali_ioctl - handle watchdog ioctls 170 * ali_ioctl - handle watchdog ioctls
166 * @inode: VFS inode
167 * @file: VFS file pointer 171 * @file: VFS file pointer
168 * @cmd: ioctl number 172 * @cmd: ioctl number
169 * @arg: arguments to the ioctl 173 * @arg: arguments to the ioctl
@@ -172,8 +176,7 @@ static ssize_t ali_write(struct file *file, const char __user *data,
172 * we want an extension to enable irq ack monitoring and the like 176 * we want an extension to enable irq ack monitoring and the like
173 */ 177 */
174 178
175static int ali_ioctl(struct inode *inode, struct file *file, 179static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
176 unsigned int cmd, unsigned long arg)
177{ 180{
178 void __user *argp = (void __user *)arg; 181 void __user *argp = (void __user *)arg;
179 int __user *p = argp; 182 int __user *p = argp;
@@ -186,57 +189,45 @@ static int ali_ioctl(struct inode *inode, struct file *file,
186 }; 189 };
187 190
188 switch (cmd) { 191 switch (cmd) {
189 case WDIOC_GETSUPPORT: 192 case WDIOC_GETSUPPORT:
190 return copy_to_user(argp, &ident, 193 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
191 sizeof (ident)) ? -EFAULT : 0; 194
192 195 case WDIOC_GETSTATUS:
193 case WDIOC_GETSTATUS: 196 case WDIOC_GETBOOTSTATUS:
194 case WDIOC_GETBOOTSTATUS: 197 return put_user(0, p);
195 return put_user(0, p); 198 case WDIOC_SETOPTIONS:
196 199 {
197 case WDIOC_KEEPALIVE: 200 int new_options, retval = -EINVAL;
198 ali_keepalive(); 201
199 return 0; 202 if (get_user(new_options, p))
200 203 return -EFAULT;
201 case WDIOC_SETOPTIONS: 204 if (new_options & WDIOS_DISABLECARD) {
202 { 205 ali_stop();
203 int new_options, retval = -EINVAL; 206 retval = 0;
204
205 if (get_user (new_options, p))
206 return -EFAULT;
207
208 if (new_options & WDIOS_DISABLECARD) {
209 ali_stop();
210 retval = 0;
211 }
212
213 if (new_options & WDIOS_ENABLECARD) {
214 ali_start();
215 retval = 0;
216 }
217
218 return retval;
219 } 207 }
220 208 if (new_options & WDIOS_ENABLECARD) {
221 case WDIOC_SETTIMEOUT: 209 ali_start();
222 { 210 retval = 0;
223 int new_timeout;
224
225 if (get_user(new_timeout, p))
226 return -EFAULT;
227
228 if (ali_settimer(new_timeout))
229 return -EINVAL;
230
231 ali_keepalive();
232 /* Fall */
233 } 211 }
234 212 return retval;
235 case WDIOC_GETTIMEOUT: 213 }
236 return put_user(timeout, p); 214 case WDIOC_KEEPALIVE:
237 215 ali_keepalive();
238 default: 216 return 0;
239 return -ENOTTY; 217 case WDIOC_SETTIMEOUT:
218 {
219 int new_timeout;
220 if (get_user(new_timeout, p))
221 return -EFAULT;
222 if (ali_settimer(new_timeout))
223 return -EINVAL;
224 ali_keepalive();
225 /* Fall */
226 }
227 case WDIOC_GETTIMEOUT:
228 return put_user(timeout, p);
229 default:
230 return -ENOTTY;
240 } 231 }
241} 232}
242 233
@@ -274,10 +265,11 @@ static int ali_release(struct inode *inode, struct file *file)
274 /* 265 /*
275 * Shut off the timer. 266 * Shut off the timer.
276 */ 267 */
277 if (ali_expect_release == 42) { 268 if (ali_expect_release == 42)
278 ali_stop(); 269 ali_stop();
279 } else { 270 else {
280 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 271 printk(KERN_CRIT PFX
272 "Unexpected close, not stopping watchdog!\n");
281 ali_keepalive(); 273 ali_keepalive();
282 } 274 }
283 clear_bit(0, &ali_is_open); 275 clear_bit(0, &ali_is_open);
@@ -292,13 +284,11 @@ static int ali_release(struct inode *inode, struct file *file)
292 */ 284 */
293 285
294 286
295static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 287static int ali_notify_sys(struct notifier_block *this,
288 unsigned long code, void *unused)
296{ 289{
297 if (code==SYS_DOWN || code==SYS_HALT) { 290 if (code == SYS_DOWN || code == SYS_HALT)
298 /* Turn the WDT off */ 291 ali_stop(); /* Turn the WDT off */
299 ali_stop();
300 }
301
302 return NOTIFY_DONE; 292 return NOTIFY_DONE;
303} 293}
304 294
@@ -340,10 +330,10 @@ static int __init ali_find_watchdog(void)
340 330
341 /* Check for the a 7101 PMU */ 331 /* Check for the a 7101 PMU */
342 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); 332 pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL);
343 if(pdev == NULL) 333 if (pdev == NULL)
344 return -ENODEV; 334 return -ENODEV;
345 335
346 if(pci_enable_device(pdev)) { 336 if (pci_enable_device(pdev)) {
347 pci_dev_put(pdev); 337 pci_dev_put(pdev);
348 return -EIO; 338 return -EIO;
349 } 339 }
@@ -355,9 +345,12 @@ static int __init ali_find_watchdog(void)
355 */ 345 */
356 pci_read_config_dword(pdev, 0xCC, &wdog); 346 pci_read_config_dword(pdev, 0xCC, &wdog);
357 347
358 wdog &= ~0x3F; /* Timer bits */ 348 /* Timer bits */
359 wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24)); /* Issued events */ 349 wdog &= ~0x3F;
360 wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)); /* No monitor bits */ 350 /* Issued events */
351 wdog &= ~((1<<27)|(1<<26)|(1<<25)|(1<<24));
352 /* No monitor bits */
353 wdog &= ~((1<<16)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9));
361 354
362 pci_write_config_dword(pdev, 0xCC, wdog); 355 pci_write_config_dword(pdev, 0xCC, wdog);
363 356
@@ -369,12 +362,12 @@ static int __init ali_find_watchdog(void)
369 */ 362 */
370 363
371static const struct file_operations ali_fops = { 364static const struct file_operations ali_fops = {
372 .owner = THIS_MODULE, 365 .owner = THIS_MODULE,
373 .llseek = no_llseek, 366 .llseek = no_llseek,
374 .write = ali_write, 367 .write = ali_write,
375 .ioctl = ali_ioctl, 368 .unlocked_ioctl = ali_ioctl,
376 .open = ali_open, 369 .open = ali_open,
377 .release = ali_release, 370 .release = ali_release,
378}; 371};
379 372
380static struct miscdevice ali_miscdev = { 373static struct miscdevice ali_miscdev = {
@@ -399,15 +392,16 @@ static int __init watchdog_init(void)
399 int ret; 392 int ret;
400 393
401 /* Check whether or not the hardware watchdog is there */ 394 /* Check whether or not the hardware watchdog is there */
402 if (ali_find_watchdog() != 0) { 395 if (ali_find_watchdog() != 0)
403 return -ENODEV; 396 return -ENODEV;
404 }
405 397
406 /* Check that the timeout value is within it's range ; if not reset to the default */ 398 /* Check that the timeout value is within it's range;
399 if not reset to the default */
407 if (timeout < 1 || timeout >= 18000) { 400 if (timeout < 1 || timeout >= 18000) {
408 timeout = WATCHDOG_TIMEOUT; 401 timeout = WATCHDOG_TIMEOUT;
409 printk(KERN_INFO PFX "timeout value must be 0<timeout<18000, using %d\n", 402 printk(KERN_INFO PFX
410 timeout); 403 "timeout value must be 0 < timeout < 18000, using %d\n",
404 timeout);
411 } 405 }
412 406
413 /* Calculate the watchdog's timeout */ 407 /* Calculate the watchdog's timeout */
@@ -415,15 +409,16 @@ static int __init watchdog_init(void)
415 409
416 ret = register_reboot_notifier(&ali_notifier); 410 ret = register_reboot_notifier(&ali_notifier);
417 if (ret != 0) { 411 if (ret != 0) {
418 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 412 printk(KERN_ERR PFX
419 ret); 413 "cannot register reboot notifier (err=%d)\n", ret);
420 goto out; 414 goto out;
421 } 415 }
422 416
423 ret = misc_register(&ali_miscdev); 417 ret = misc_register(&ali_miscdev);
424 if (ret != 0) { 418 if (ret != 0) {
425 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 419 printk(KERN_ERR PFX
426 WATCHDOG_MINOR, ret); 420 "cannot register miscdev on minor=%d (err=%d)\n",
421 WATCHDOG_MINOR, ret);
427 goto unreg_reboot; 422 goto unreg_reboot;
428 } 423 }
429 424
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 238273c98656..a045ef869439 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -31,9 +31,9 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/fs.h> 32#include <linux/fs.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/io.h>
35#include <linux/uaccess.h>
34 36
35#include <asm/io.h>
36#include <asm/uaccess.h>
37#include <asm/system.h> 37#include <asm/system.h>
38 38
39#define OUR_NAME "alim7101_wdt" 39#define OUR_NAME "alim7101_wdt"
@@ -60,13 +60,17 @@
60 */ 60 */
61 61
62#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 62#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
63static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 63/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
64static int timeout = WATCHDOG_TIMEOUT;
64module_param(timeout, int, 0); 65module_param(timeout, int, 0);
65MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 66MODULE_PARM_DESC(timeout,
67 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
68 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
66 69
67static int use_gpio = 0; /* Use the pic (for a1d revision alim7101) */ 70static int use_gpio; /* Use the pic (for a1d revision alim7101) */
68module_param(use_gpio, int, 0); 71module_param(use_gpio, int, 0);
69MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog. (required by old cobalt boards)"); 72MODULE_PARM_DESC(use_gpio,
73 "Use the gpio watchdog (required by old cobalt boards).");
70 74
71static void wdt_timer_ping(unsigned long); 75static void wdt_timer_ping(unsigned long);
72static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1); 76static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1);
@@ -77,8 +81,9 @@ static struct pci_dev *alim7101_pmu;
77 81
78static int nowayout = WATCHDOG_NOWAYOUT; 82static int nowayout = WATCHDOG_NOWAYOUT;
79module_param(nowayout, int, 0); 83module_param(nowayout, int, 0);
80MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 84MODULE_PARM_DESC(nowayout,
81 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 85 "Watchdog cannot be stopped once started (default="
86 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 87
83/* 88/*
84 * Whack the dog 89 * Whack the dog
@@ -89,23 +94,26 @@ static void wdt_timer_ping(unsigned long data)
89 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 94 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
90 * we agree to ping the WDT 95 * we agree to ping the WDT
91 */ 96 */
92 char tmp; 97 char tmp;
93 98
94 if(time_before(jiffies, next_heartbeat)) 99 if (time_before(jiffies, next_heartbeat)) {
95 {
96 /* Ping the WDT (this is actually a disarm/arm sequence) */ 100 /* Ping the WDT (this is actually a disarm/arm sequence) */
97 pci_read_config_byte(alim7101_pmu, 0x92, &tmp); 101 pci_read_config_byte(alim7101_pmu, 0x92, &tmp);
98 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); 102 pci_write_config_byte(alim7101_pmu,
99 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); 103 ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
104 pci_write_config_byte(alim7101_pmu,
105 ALI_7101_WDT, (tmp | ALI_WDT_ARM));
100 if (use_gpio) { 106 if (use_gpio) {
101 pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); 107 pci_read_config_byte(alim7101_pmu,
102 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp 108 ALI_7101_GPIO_O, &tmp);
103 | 0x20); 109 pci_write_config_byte(alim7101_pmu,
104 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp 110 ALI_7101_GPIO_O, tmp | 0x20);
105 & ~0x20); 111 pci_write_config_byte(alim7101_pmu,
112 ALI_7101_GPIO_O, tmp & ~0x20);
106 } 113 }
107 } else { 114 } else {
108 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 115 printk(KERN_WARNING PFX
116 "Heartbeat lost! Will not ping the watchdog\n");
109 } 117 }
110 /* Re-set the timer interval */ 118 /* Re-set the timer interval */
111 mod_timer(&timer, jiffies + WDT_INTERVAL); 119 mod_timer(&timer, jiffies + WDT_INTERVAL);
@@ -117,21 +125,27 @@ static void wdt_timer_ping(unsigned long data)
117 125
118static void wdt_change(int writeval) 126static void wdt_change(int writeval)
119{ 127{
120 char tmp; 128 char tmp;
121 129
122 pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp); 130 pci_read_config_byte(alim7101_pmu, ALI_7101_WDT, &tmp);
123 if (writeval == WDT_ENABLE) { 131 if (writeval == WDT_ENABLE) {
124 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM)); 132 pci_write_config_byte(alim7101_pmu,
133 ALI_7101_WDT, (tmp | ALI_WDT_ARM));
125 if (use_gpio) { 134 if (use_gpio) {
126 pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); 135 pci_read_config_byte(alim7101_pmu,
127 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp & ~0x20); 136 ALI_7101_GPIO_O, &tmp);
137 pci_write_config_byte(alim7101_pmu,
138 ALI_7101_GPIO_O, tmp & ~0x20);
128 } 139 }
129 140
130 } else { 141 } else {
131 pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM)); 142 pci_write_config_byte(alim7101_pmu,
143 ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
132 if (use_gpio) { 144 if (use_gpio) {
133 pci_read_config_byte(alim7101_pmu, ALI_7101_GPIO_O, &tmp); 145 pci_read_config_byte(alim7101_pmu,
134 pci_write_config_byte(alim7101_pmu, ALI_7101_GPIO_O, tmp | 0x20); 146 ALI_7101_GPIO_O, &tmp);
147 pci_write_config_byte(alim7101_pmu,
148 ALI_7101_GPIO_O, tmp | 0x20);
135 } 149 }
136 } 150 }
137} 151}
@@ -169,10 +183,11 @@ static void wdt_keepalive(void)
169 * /dev/watchdog handling 183 * /dev/watchdog handling
170 */ 184 */
171 185
172static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 186static ssize_t fop_write(struct file *file, const char __user *buf,
187 size_t count, loff_t *ppos)
173{ 188{
174 /* See if we got the magic character 'V' and reload the timer */ 189 /* See if we got the magic character 'V' and reload the timer */
175 if(count) { 190 if (count) {
176 if (!nowayout) { 191 if (!nowayout) {
177 size_t ofs; 192 size_t ofs;
178 193
@@ -183,7 +198,7 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
183 /* now scan */ 198 /* now scan */
184 for (ofs = 0; ofs != count; ofs++) { 199 for (ofs = 0; ofs != count; ofs++) {
185 char c; 200 char c;
186 if (get_user(c, buf+ofs)) 201 if (get_user(c, buf + ofs))
187 return -EFAULT; 202 return -EFAULT;
188 if (c == 'V') 203 if (c == 'V')
189 wdt_expect_close = 42; 204 wdt_expect_close = 42;
@@ -195,119 +210,116 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
195 return count; 210 return count;
196} 211}
197 212
198static int fop_open(struct inode * inode, struct file * file) 213static int fop_open(struct inode *inode, struct file *file)
199{ 214{
200 /* Just in case we're already talking to someone... */ 215 /* Just in case we're already talking to someone... */
201 if(test_and_set_bit(0, &wdt_is_open)) 216 if (test_and_set_bit(0, &wdt_is_open))
202 return -EBUSY; 217 return -EBUSY;
203 /* Good, fire up the show */ 218 /* Good, fire up the show */
204 wdt_startup(); 219 wdt_startup();
205 return nonseekable_open(inode, file); 220 return nonseekable_open(inode, file);
206} 221}
207 222
208static int fop_close(struct inode * inode, struct file * file) 223static int fop_close(struct inode *inode, struct file *file)
209{ 224{
210 if(wdt_expect_close == 42) 225 if (wdt_expect_close == 42)
211 wdt_turnoff(); 226 wdt_turnoff();
212 else { 227 else {
213 /* wim: shouldn't there be a: del_timer(&timer); */ 228 /* wim: shouldn't there be a: del_timer(&timer); */
214 printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); 229 printk(KERN_CRIT PFX
230 "device file closed unexpectedly. Will not stop the WDT!\n");
215 } 231 }
216 clear_bit(0, &wdt_is_open); 232 clear_bit(0, &wdt_is_open);
217 wdt_expect_close = 0; 233 wdt_expect_close = 0;
218 return 0; 234 return 0;
219} 235}
220 236
221static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 237static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
222{ 238{
223 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
224 int __user *p = argp; 240 int __user *p = argp;
225 static struct watchdog_info ident = 241 static struct watchdog_info ident = {
226 { 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
227 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 243 | WDIOF_MAGICCLOSE,
228 .firmware_version = 1, 244 .firmware_version = 1,
229 .identity = "ALiM7101", 245 .identity = "ALiM7101",
230 }; 246 };
231 247
232 switch(cmd) 248 switch (cmd) {
249 case WDIOC_GETSUPPORT:
250 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
251 case WDIOC_GETSTATUS:
252 case WDIOC_GETBOOTSTATUS:
253 return put_user(0, p);
254 case WDIOC_SETOPTIONS:
233 { 255 {
234 case WDIOC_GETSUPPORT: 256 int new_options, retval = -EINVAL;
235 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
236 case WDIOC_GETSTATUS:
237 case WDIOC_GETBOOTSTATUS:
238 return put_user(0, p);
239 case WDIOC_KEEPALIVE:
240 wdt_keepalive();
241 return 0;
242 case WDIOC_SETOPTIONS:
243 {
244 int new_options, retval = -EINVAL;
245
246 if(get_user(new_options, p))
247 return -EFAULT;
248
249 if(new_options & WDIOS_DISABLECARD) {
250 wdt_turnoff();
251 retval = 0;
252 }
253 257
254 if(new_options & WDIOS_ENABLECARD) { 258 if (get_user(new_options, p))
255 wdt_startup(); 259 return -EFAULT;
256 retval = 0; 260 if (new_options & WDIOS_DISABLECARD) {
257 } 261 wdt_turnoff();
258 262 retval = 0;
259 return retval;
260 } 263 }
261 case WDIOC_SETTIMEOUT: 264 if (new_options & WDIOS_ENABLECARD) {
262 { 265 wdt_startup();
263 int new_timeout; 266 retval = 0;
264
265 if(get_user(new_timeout, p))
266 return -EFAULT;
267
268 if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
269 return -EINVAL;
270
271 timeout = new_timeout;
272 wdt_keepalive();
273 /* Fall through */
274 } 267 }
275 case WDIOC_GETTIMEOUT: 268 return retval;
276 return put_user(timeout, p); 269 }
277 default: 270 case WDIOC_KEEPALIVE:
278 return -ENOTTY; 271 wdt_keepalive();
272 return 0;
273 case WDIOC_SETTIMEOUT:
274 {
275 int new_timeout;
276
277 if (get_user(new_timeout, p))
278 return -EFAULT;
279 /* arbitrary upper limit */
280 if (new_timeout < 1 || new_timeout > 3600)
281 return -EINVAL;
282 timeout = new_timeout;
283 wdt_keepalive();
284 /* Fall through */
285 }
286 case WDIOC_GETTIMEOUT:
287 return put_user(timeout, p);
288 default:
289 return -ENOTTY;
279 } 290 }
280} 291}
281 292
282static const struct file_operations wdt_fops = { 293static const struct file_operations wdt_fops = {
283 .owner= THIS_MODULE, 294 .owner = THIS_MODULE,
284 .llseek= no_llseek, 295 .llseek = no_llseek,
285 .write= fop_write, 296 .write = fop_write,
286 .open= fop_open, 297 .open = fop_open,
287 .release= fop_close, 298 .release = fop_close,
288 .ioctl= fop_ioctl, 299 .unlocked_ioctl = fop_ioctl,
289}; 300};
290 301
291static struct miscdevice wdt_miscdev = { 302static struct miscdevice wdt_miscdev = {
292 .minor=WATCHDOG_MINOR, 303 .minor = WATCHDOG_MINOR,
293 .name="watchdog", 304 .name = "watchdog",
294 .fops=&wdt_fops, 305 .fops = &wdt_fops,
295}; 306};
296 307
297/* 308/*
298 * Notifier for system down 309 * Notifier for system down
299 */ 310 */
300 311
301static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 312static int wdt_notify_sys(struct notifier_block *this,
313 unsigned long code, void *unused)
302{ 314{
303 if (code==SYS_DOWN || code==SYS_HALT) 315 if (code == SYS_DOWN || code == SYS_HALT)
304 wdt_turnoff(); 316 wdt_turnoff();
305 317
306 if (code==SYS_RESTART) { 318 if (code == SYS_RESTART) {
307 /* 319 /*
308 * Cobalt devices have no way of rebooting themselves other than 320 * Cobalt devices have no way of rebooting themselves other
309 * getting the watchdog to pull reset, so we restart the watchdog on 321 * than getting the watchdog to pull reset, so we restart the
310 * reboot with no heartbeat 322 * watchdog on reboot with no heartbeat
311 */ 323 */
312 wdt_change(WDT_ENABLE); 324 wdt_change(WDT_ENABLE);
313 printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n"); 325 printk(KERN_INFO PFX "Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
@@ -320,8 +332,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void
320 * turn the timebomb registers off. 332 * turn the timebomb registers off.
321 */ 333 */
322 334
323static struct notifier_block wdt_notifier= 335static struct notifier_block wdt_notifier = {
324{
325 .notifier_call = wdt_notify_sys, 336 .notifier_call = wdt_notify_sys,
326}; 337};
327 338
@@ -354,7 +365,8 @@ static int __init alim7101_wdt_init(void)
354 ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, 365 ali1543_south = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
355 NULL); 366 NULL);
356 if (!ali1543_south) { 367 if (!ali1543_south) {
357 printk(KERN_INFO PFX "ALi 1543 South-Bridge not present - WDT not set\n"); 368 printk(KERN_INFO PFX
369 "ALi 1543 South-Bridge not present - WDT not set\n");
358 goto err_out; 370 goto err_out;
359 } 371 }
360 pci_read_config_byte(ali1543_south, 0x5e, &tmp); 372 pci_read_config_byte(ali1543_south, 0x5e, &tmp);
@@ -363,24 +375,25 @@ static int __init alim7101_wdt_init(void)
363 if (!use_gpio) { 375 if (!use_gpio) {
364 printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n"); 376 printk(KERN_INFO PFX "Detected old alim7101 revision 'a1d'. If this is a cobalt board, set the 'use_gpio' module parameter.\n");
365 goto err_out; 377 goto err_out;
366 } 378 }
367 nowayout = 1; 379 nowayout = 1;
368 } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) { 380 } else if ((tmp & 0x1e) != 0x12 && (tmp & 0x1e) != 0x00) {
369 printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n"); 381 printk(KERN_INFO PFX "ALi 1543 South-Bridge does not have the correct revision number (???1001?) - WDT not set\n");
370 goto err_out; 382 goto err_out;
371 } 383 }
372 384
373 if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ 385 if (timeout < 1 || timeout > 3600) {
374 { 386 /* arbitrary upper limit */
375 timeout = WATCHDOG_TIMEOUT; 387 timeout = WATCHDOG_TIMEOUT;
376 printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", 388 printk(KERN_INFO PFX
377 timeout); 389 "timeout value must be 1 <= x <= 3600, using %d\n",
390 timeout);
378 } 391 }
379 392
380 rc = register_reboot_notifier(&wdt_notifier); 393 rc = register_reboot_notifier(&wdt_notifier);
381 if (rc) { 394 if (rc) {
382 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 395 printk(KERN_ERR PFX
383 rc); 396 "cannot register reboot notifier (err=%d)\n", rc);
384 goto err_out; 397 goto err_out;
385 } 398 }
386 399
@@ -391,9 +404,8 @@ static int __init alim7101_wdt_init(void)
391 goto err_out_reboot; 404 goto err_out_reboot;
392 } 405 }
393 406
394 if (nowayout) { 407 if (nowayout)
395 __module_get(THIS_MODULE); 408 __module_get(THIS_MODULE);
396 }
397 409
398 printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n", 410 printk(KERN_INFO PFX "WDT driver for ALi M7101 initialised. timeout=%d sec (nowayout=%d)\n",
399 timeout, nowayout); 411 timeout, nowayout);
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index ef7b0d67095e..55dcbfe2bb72 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -213,7 +213,7 @@ static int ar7_wdt_notify_sys(struct notifier_block *this,
213} 213}
214 214
215static struct notifier_block ar7_wdt_notifier = { 215static struct notifier_block ar7_wdt_notifier = {
216 .notifier_call = ar7_wdt_notify_sys 216 .notifier_call = ar7_wdt_notify_sys,
217}; 217};
218 218
219static ssize_t ar7_wdt_write(struct file *file, const char *data, 219static ssize_t ar7_wdt_write(struct file *file, const char *data,
@@ -230,7 +230,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
230 expect_close = 0; 230 expect_close = 0;
231 for (i = 0; i < len; ++i) { 231 for (i = 0; i < len; ++i) {
232 char c; 232 char c;
233 if (get_user(c, data+i)) 233 if (get_user(c, data + i))
234 return -EFAULT; 234 return -EFAULT;
235 if (c == 'V') 235 if (c == 'V')
236 expect_close = 1; 236 expect_close = 1;
@@ -251,8 +251,6 @@ static long ar7_wdt_ioctl(struct file *file,
251 int new_margin; 251 int new_margin;
252 252
253 switch (cmd) { 253 switch (cmd) {
254 default:
255 return -ENOTTY;
256 case WDIOC_GETSUPPORT: 254 case WDIOC_GETSUPPORT:
257 if (copy_to_user((struct watchdog_info *)arg, &ident, 255 if (copy_to_user((struct watchdog_info *)arg, &ident,
258 sizeof(ident))) 256 sizeof(ident)))
@@ -281,6 +279,8 @@ static long ar7_wdt_ioctl(struct file *file,
281 if (put_user(margin, (int *)arg)) 279 if (put_user(margin, (int *)arg))
282 return -EFAULT; 280 return -EFAULT;
283 return 0; 281 return 0;
282 default:
283 return -ENOTTY;
284 } 284 }
285} 285}
286 286
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index ae0fca5e8749..e8ae638e5804 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -212,8 +212,8 @@ static struct watchdog_info at32_wdt_info = {
212/* 212/*
213 * Handle commands from user-space. 213 * Handle commands from user-space.
214 */ 214 */
215static int at32_wdt_ioctl(struct inode *inode, struct file *file, 215static long at32_wdt_ioctl(struct file *file,
216 unsigned int cmd, unsigned long arg) 216 unsigned int cmd, unsigned long arg)
217{ 217{
218 int ret = -ENOTTY; 218 int ret = -ENOTTY;
219 int time; 219 int time;
@@ -221,27 +221,10 @@ static int at32_wdt_ioctl(struct inode *inode, struct file *file,
221 int __user *p = argp; 221 int __user *p = argp;
222 222
223 switch (cmd) { 223 switch (cmd) {
224 case WDIOC_KEEPALIVE:
225 at32_wdt_pat();
226 ret = 0;
227 break;
228 case WDIOC_GETSUPPORT: 224 case WDIOC_GETSUPPORT:
229 ret = copy_to_user(argp, &at32_wdt_info, 225 ret = copy_to_user(argp, &at32_wdt_info,
230 sizeof(at32_wdt_info)) ? -EFAULT : 0; 226 sizeof(at32_wdt_info)) ? -EFAULT : 0;
231 break; 227 break;
232 case WDIOC_SETTIMEOUT:
233 ret = get_user(time, p);
234 if (ret)
235 break;
236 ret = at32_wdt_settimeout(time);
237 if (ret)
238 break;
239 /* Enable new time value */
240 at32_wdt_start();
241 /* fall through */
242 case WDIOC_GETTIMEOUT:
243 ret = put_user(wdt->timeout, p);
244 break;
245 case WDIOC_GETSTATUS: 228 case WDIOC_GETSTATUS:
246 ret = put_user(0, p); 229 ret = put_user(0, p);
247 break; 230 break;
@@ -258,6 +241,23 @@ static int at32_wdt_ioctl(struct inode *inode, struct file *file,
258 at32_wdt_start(); 241 at32_wdt_start();
259 ret = 0; 242 ret = 0;
260 break; 243 break;
244 case WDIOC_KEEPALIVE:
245 at32_wdt_pat();
246 ret = 0;
247 break;
248 case WDIOC_SETTIMEOUT:
249 ret = get_user(time, p);
250 if (ret)
251 break;
252 ret = at32_wdt_settimeout(time);
253 if (ret)
254 break;
255 /* Enable new time value */
256 at32_wdt_start();
257 /* fall through */
258 case WDIOC_GETTIMEOUT:
259 ret = put_user(wdt->timeout, p);
260 break;
261 } 261 }
262 262
263 return ret; 263 return ret;
@@ -283,7 +283,7 @@ static ssize_t at32_wdt_write(struct file *file, const char __user *data,
283 */ 283 */
284 for (i = 0; i != len; i++) { 284 for (i = 0; i != len; i++) {
285 char c; 285 char c;
286 if (get_user(c, data+i)) 286 if (get_user(c, data + i))
287 return -EFAULT; 287 return -EFAULT;
288 if (c == 'V') 288 if (c == 'V')
289 expect_release = 42; 289 expect_release = 42;
@@ -298,7 +298,7 @@ static ssize_t at32_wdt_write(struct file *file, const char __user *data,
298static const struct file_operations at32_wdt_fops = { 298static const struct file_operations at32_wdt_fops = {
299 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
300 .llseek = no_llseek, 300 .llseek = no_llseek,
301 .ioctl = at32_wdt_ioctl, 301 .unlocked_ioctl = at32_wdt_ioctl,
302 .open = at32_wdt_open, 302 .open = at32_wdt_open,
303 .release = at32_wdt_close, 303 .release = at32_wdt_close,
304 .write = at32_wdt_write, 304 .write = at32_wdt_write,
@@ -391,7 +391,6 @@ static int __exit at32_wdt_remove(struct platform_device *pdev)
391 wdt = NULL; 391 wdt = NULL;
392 platform_set_drvdata(pdev, NULL); 392 platform_set_drvdata(pdev, NULL);
393 } 393 }
394
395 return 0; 394 return 0;
396} 395}
397 396
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 9ff9a9565320..d061f0ad2d20 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -20,9 +20,8 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/watchdog.h> 22#include <linux/watchdog.h>
23#include <asm/uaccess.h> 23#include <linux/uaccess.h>
24#include <asm/arch/at91_st.h> 24#include <mach/at91_st.h>
25
26 25
27#define WDT_DEFAULT_TIME 5 /* seconds */ 26#define WDT_DEFAULT_TIME 5 /* seconds */
28#define WDT_MAX_TIME 256 /* seconds */ 27#define WDT_MAX_TIME 256 /* seconds */
@@ -31,11 +30,14 @@ static int wdt_time = WDT_DEFAULT_TIME;
31static int nowayout = WATCHDOG_NOWAYOUT; 30static int nowayout = WATCHDOG_NOWAYOUT;
32 31
33module_param(wdt_time, int, 0); 32module_param(wdt_time, int, 0);
34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); 33MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
34 __MODULE_STRING(WDT_DEFAULT_TIME) ")");
35 35
36#ifdef CONFIG_WATCHDOG_NOWAYOUT 36#ifdef CONFIG_WATCHDOG_NOWAYOUT
37module_param(nowayout, int, 0); 37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 38MODULE_PARM_DESC(nowayout,
39 "Watchdog cannot be stopped once started (default="
40 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39#endif 41#endif
40 42
41 43
@@ -46,7 +48,7 @@ static unsigned long at91wdt_busy;
46/* 48/*
47 * Disable the watchdog. 49 * Disable the watchdog.
48 */ 50 */
49static void inline at91_wdt_stop(void) 51static inline void at91_wdt_stop(void)
50{ 52{
51 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); 53 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN);
52} 54}
@@ -54,16 +56,17 @@ static void inline at91_wdt_stop(void)
54/* 56/*
55 * Enable and reset the watchdog. 57 * Enable and reset the watchdog.
56 */ 58 */
57static void inline at91_wdt_start(void) 59static inline void at91_wdt_start(void)
58{ 60{
59 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); 61 at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
62 (((65536 * wdt_time) >> 8) & AT91_ST_WDV));
60 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 63 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
61} 64}
62 65
63/* 66/*
64 * Reload the watchdog timer. (ie, pat the watchdog) 67 * Reload the watchdog timer. (ie, pat the watchdog)
65 */ 68 */
66static void inline at91_wdt_reload(void) 69static inline void at91_wdt_reload(void)
67{ 70{
68 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); 71 at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
69} 72}
@@ -89,8 +92,9 @@ static int at91_wdt_open(struct inode *inode, struct file *file)
89 */ 92 */
90static int at91_wdt_close(struct inode *inode, struct file *file) 93static int at91_wdt_close(struct inode *inode, struct file *file)
91{ 94{
95 /* Disable the watchdog when file is closed */
92 if (!nowayout) 96 if (!nowayout)
93 at91_wdt_stop(); /* Disable the watchdog when file is closed */ 97 at91_wdt_stop();
94 98
95 clear_bit(0, &at91wdt_busy); 99 clear_bit(0, &at91wdt_busy);
96 return 0; 100 return 0;
@@ -110,7 +114,8 @@ static int at91_wdt_settimeout(int new_time)
110 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 114 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
111 return -EINVAL; 115 return -EINVAL;
112 116
113 /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ 117 /* Set new watchdog time. It will be used when
118 at91_wdt_start() is called. */
114 wdt_time = new_time; 119 wdt_time = new_time;
115 return 0; 120 return 0;
116} 121}
@@ -123,60 +128,52 @@ static struct watchdog_info at91_wdt_info = {
123/* 128/*
124 * Handle commands from user-space. 129 * Handle commands from user-space.
125 */ 130 */
126static int at91_wdt_ioctl(struct inode *inode, struct file *file, 131static long at91_wdt_ioctl(struct file *file,
127 unsigned int cmd, unsigned long arg) 132 unsigned int cmd, unsigned long arg)
128{ 133{
129 void __user *argp = (void __user *)arg; 134 void __user *argp = (void __user *)arg;
130 int __user *p = argp; 135 int __user *p = argp;
131 int new_value; 136 int new_value;
132 137
133 switch(cmd) { 138 switch (cmd) {
134 case WDIOC_KEEPALIVE: 139 case WDIOC_GETSUPPORT:
135 at91_wdt_reload(); /* pat the watchdog */ 140 return copy_to_user(argp, &at91_wdt_info,
136 return 0; 141 sizeof(at91_wdt_info)) ? -EFAULT : 0;
137 142 case WDIOC_GETSTATUS:
138 case WDIOC_GETSUPPORT: 143 case WDIOC_GETBOOTSTATUS:
139 return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; 144 return put_user(0, p);
140 145 case WDIOC_SETOPTIONS:
141 case WDIOC_SETTIMEOUT: 146 if (get_user(new_value, p))
142 if (get_user(new_value, p)) 147 return -EFAULT;
143 return -EFAULT; 148 if (new_value & WDIOS_DISABLECARD)
144 149 at91_wdt_stop();
145 if (at91_wdt_settimeout(new_value)) 150 if (new_value & WDIOS_ENABLECARD)
146 return -EINVAL;
147
148 /* Enable new time value */
149 at91_wdt_start(); 151 at91_wdt_start();
150 152 return 0;
151 /* Return current value */ 153 case WDIOC_KEEPALIVE:
152 return put_user(wdt_time, p); 154 at91_wdt_reload(); /* pat the watchdog */
153 155 return 0;
154 case WDIOC_GETTIMEOUT: 156 case WDIOC_SETTIMEOUT:
155 return put_user(wdt_time, p); 157 if (get_user(new_value, p))
156 158 return -EFAULT;
157 case WDIOC_GETSTATUS: 159 if (at91_wdt_settimeout(new_value))
158 case WDIOC_GETBOOTSTATUS: 160 return -EINVAL;
159 return put_user(0, p); 161 /* Enable new time value */
160 162 at91_wdt_start();
161 case WDIOC_SETOPTIONS: 163 /* Return current value */
162 if (get_user(new_value, p)) 164 return put_user(wdt_time, p);
163 return -EFAULT; 165 case WDIOC_GETTIMEOUT:
164 166 return put_user(wdt_time, p);
165 if (new_value & WDIOS_DISABLECARD) 167 default:
166 at91_wdt_stop(); 168 return -ENOTTY;
167 if (new_value & WDIOS_ENABLECARD)
168 at91_wdt_start();
169 return 0;
170
171 default:
172 return -ENOTTY;
173 } 169 }
174} 170}
175 171
176/* 172/*
177 * Pat the watchdog whenever device is written to. 173 * Pat the watchdog whenever device is written to.
178 */ 174 */
179static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 175static ssize_t at91_wdt_write(struct file *file, const char *data,
176 size_t len, loff_t *ppos)
180{ 177{
181 at91_wdt_reload(); /* pat the watchdog */ 178 at91_wdt_reload(); /* pat the watchdog */
182 return len; 179 return len;
@@ -187,7 +184,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l
187static const struct file_operations at91wdt_fops = { 184static const struct file_operations at91wdt_fops = {
188 .owner = THIS_MODULE, 185 .owner = THIS_MODULE,
189 .llseek = no_llseek, 186 .llseek = no_llseek,
190 .ioctl = at91_wdt_ioctl, 187 .unlocked_ioctl = at91_wdt_ioctl,
191 .open = at91_wdt_open, 188 .open = at91_wdt_open,
192 .release = at91_wdt_close, 189 .release = at91_wdt_close,
193 .write = at91_wdt_write, 190 .write = at91_wdt_write,
@@ -211,7 +208,8 @@ static int __init at91wdt_probe(struct platform_device *pdev)
211 if (res) 208 if (res)
212 return res; 209 return res;
213 210
214 printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); 211 printk(KERN_INFO "AT91 Watchdog Timer enabled (%d seconds%s)\n",
212 wdt_time, nowayout ? ", nowayout" : "");
215 return 0; 213 return 0;
216} 214}
217 215
@@ -265,7 +263,8 @@ static struct platform_driver at91wdt_driver = {
265 263
266static int __init at91_wdt_init(void) 264static int __init at91_wdt_init(void)
267{ 265{
268 /* Check that the heartbeat value is within range; if not reset to the default */ 266 /* Check that the heartbeat value is within range;
267 if not reset to the default */
269 if (at91_wdt_settimeout(wdt_time)) { 268 if (at91_wdt_settimeout(wdt_time)) {
270 at91_wdt_settimeout(WDT_DEFAULT_TIME); 269 at91_wdt_settimeout(WDT_DEFAULT_TIME);
271 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); 270 pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time);
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 03b3e3d91e7c..31b42253054e 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -24,8 +24,8 @@
24#include <linux/reboot.h> 24#include <linux/reboot.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/uaccess.h>
27#include <asm/blackfin.h> 28#include <asm/blackfin.h>
28#include <asm/uaccess.h>
29 29
30#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) 30#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
31#define stampit() stamp("here i am") 31#define stampit() stamp("here i am")
@@ -148,7 +148,8 @@ static int bfin_wdt_set_timeout(unsigned long t)
148 int run = bfin_wdt_running(); 148 int run = bfin_wdt_running();
149 bfin_wdt_stop(); 149 bfin_wdt_stop();
150 bfin_write_WDOG_CNT(cnt); 150 bfin_write_WDOG_CNT(cnt);
151 if (run) bfin_wdt_start(); 151 if (run)
152 bfin_wdt_start();
152 } 153 }
153 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags); 154 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
154 155
@@ -191,16 +192,15 @@ static int bfin_wdt_release(struct inode *inode, struct file *file)
191{ 192{
192 stampit(); 193 stampit();
193 194
194 if (expect_close == 42) { 195 if (expect_close == 42)
195 bfin_wdt_stop(); 196 bfin_wdt_stop();
196 } else { 197 else {
197 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 198 printk(KERN_CRIT PFX
199 "Unexpected close, not stopping watchdog!\n");
198 bfin_wdt_keepalive(); 200 bfin_wdt_keepalive();
199 } 201 }
200
201 expect_close = 0; 202 expect_close = 0;
202 clear_bit(0, &open_check); 203 clear_bit(0, &open_check);
203
204 return 0; 204 return 0;
205} 205}
206 206
@@ -214,7 +214,7 @@ static int bfin_wdt_release(struct inode *inode, struct file *file)
214 * Pings the watchdog on write. 214 * Pings the watchdog on write.
215 */ 215 */
216static ssize_t bfin_wdt_write(struct file *file, const char __user *data, 216static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
217 size_t len, loff_t *ppos) 217 size_t len, loff_t *ppos)
218{ 218{
219 stampit(); 219 stampit();
220 220
@@ -241,7 +241,6 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
241 241
242/** 242/**
243 * bfin_wdt_ioctl - Query Device 243 * bfin_wdt_ioctl - Query Device
244 * @inode: inode of device
245 * @file: file handle of device 244 * @file: file handle of device
246 * @cmd: watchdog command 245 * @cmd: watchdog command
247 * @arg: argument 246 * @arg: argument
@@ -249,8 +248,8 @@ static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
249 * Query basic information from the device or ping it, as outlined by the 248 * Query basic information from the device or ping it, as outlined by the
250 * watchdog API. 249 * watchdog API.
251 */ 250 */
252static int bfin_wdt_ioctl(struct inode *inode, struct file *file, 251static long bfin_wdt_ioctl(struct file *file,
253 unsigned int cmd, unsigned long arg) 252 unsigned int cmd, unsigned long arg)
254{ 253{
255 void __user *argp = (void __user *)arg; 254 void __user *argp = (void __user *)arg;
256 int __user *p = argp; 255 int __user *p = argp;
@@ -258,59 +257,49 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file,
258 stampit(); 257 stampit();
259 258
260 switch (cmd) { 259 switch (cmd) {
261 default: 260 case WDIOC_GETSUPPORT:
262 return -ENOTTY; 261 if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info)))
263 262 return -EFAULT;
264 case WDIOC_GETSUPPORT: 263 else
265 if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info)))
266 return -EFAULT;
267 else
268 return 0;
269
270 case WDIOC_GETSTATUS:
271 case WDIOC_GETBOOTSTATUS:
272 return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p);
273
274 case WDIOC_KEEPALIVE:
275 bfin_wdt_keepalive();
276 return 0; 264 return 0;
277 265 case WDIOC_GETSTATUS:
278 case WDIOC_SETTIMEOUT: { 266 case WDIOC_GETBOOTSTATUS:
279 int new_timeout; 267 return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p);
280 268 case WDIOC_SETOPTIONS: {
281 if (get_user(new_timeout, p)) 269 unsigned long flags;
282 return -EFAULT; 270 int options, ret = -EINVAL;
283 271
284 if (bfin_wdt_set_timeout(new_timeout)) 272 if (get_user(options, p))
285 return -EINVAL; 273 return -EFAULT;
274
275 spin_lock_irqsave(&bfin_wdt_spinlock, flags);
276 if (options & WDIOS_DISABLECARD) {
277 bfin_wdt_stop();
278 ret = 0;
286 } 279 }
287 /* Fall */ 280 if (options & WDIOS_ENABLECARD) {
288 case WDIOC_GETTIMEOUT: 281 bfin_wdt_start();
289 return put_user(timeout, p); 282 ret = 0;
290
291 case WDIOC_SETOPTIONS: {
292 unsigned long flags;
293 int options, ret = -EINVAL;
294
295 if (get_user(options, p))
296 return -EFAULT;
297
298 spin_lock_irqsave(&bfin_wdt_spinlock, flags);
299
300 if (options & WDIOS_DISABLECARD) {
301 bfin_wdt_stop();
302 ret = 0;
303 }
304
305 if (options & WDIOS_ENABLECARD) {
306 bfin_wdt_start();
307 ret = 0;
308 }
309
310 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
311
312 return ret;
313 } 283 }
284 spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
285 return ret;
286 }
287 case WDIOC_KEEPALIVE:
288 bfin_wdt_keepalive();
289 return 0;
290 case WDIOC_SETTIMEOUT: {
291 int new_timeout;
292
293 if (get_user(new_timeout, p))
294 return -EFAULT;
295 if (bfin_wdt_set_timeout(new_timeout))
296 return -EINVAL;
297 }
298 /* Fall */
299 case WDIOC_GETTIMEOUT:
300 return put_user(timeout, p);
301 default:
302 return -ENOTTY;
314 } 303 }
315} 304}
316 305
@@ -323,8 +312,8 @@ static int bfin_wdt_ioctl(struct inode *inode, struct file *file,
323 * Handles specific events, such as turning off the watchdog during a 312 * Handles specific events, such as turning off the watchdog during a
324 * shutdown event. 313 * shutdown event.
325 */ 314 */
326static int bfin_wdt_notify_sys(struct notifier_block *this, unsigned long code, 315static int bfin_wdt_notify_sys(struct notifier_block *this,
327 void *unused) 316 unsigned long code, void *unused)
328{ 317{
329 stampit(); 318 stampit();
330 319
@@ -379,12 +368,12 @@ static int bfin_wdt_resume(struct platform_device *pdev)
379#endif 368#endif
380 369
381static const struct file_operations bfin_wdt_fops = { 370static const struct file_operations bfin_wdt_fops = {
382 .owner = THIS_MODULE, 371 .owner = THIS_MODULE,
383 .llseek = no_llseek, 372 .llseek = no_llseek,
384 .write = bfin_wdt_write, 373 .write = bfin_wdt_write,
385 .ioctl = bfin_wdt_ioctl, 374 .unlocked_ioctl = bfin_wdt_ioctl,
386 .open = bfin_wdt_open, 375 .open = bfin_wdt_open,
387 .release = bfin_wdt_release, 376 .release = bfin_wdt_release,
388}; 377};
389 378
390static struct miscdevice bfin_wdt_miscdev = { 379static struct miscdevice bfin_wdt_miscdev = {
@@ -396,8 +385,8 @@ static struct miscdevice bfin_wdt_miscdev = {
396static struct watchdog_info bfin_wdt_info = { 385static struct watchdog_info bfin_wdt_info = {
397 .identity = "Blackfin Watchdog", 386 .identity = "Blackfin Watchdog",
398 .options = WDIOF_SETTIMEOUT | 387 .options = WDIOF_SETTIMEOUT |
399 WDIOF_KEEPALIVEPING | 388 WDIOF_KEEPALIVEPING |
400 WDIOF_MAGICCLOSE, 389 WDIOF_MAGICCLOSE,
401}; 390};
402 391
403static struct notifier_block bfin_wdt_notifier = { 392static struct notifier_block bfin_wdt_notifier = {
@@ -416,14 +405,16 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev)
416 405
417 ret = register_reboot_notifier(&bfin_wdt_notifier); 406 ret = register_reboot_notifier(&bfin_wdt_notifier);
418 if (ret) { 407 if (ret) {
419 pr_devinit(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); 408 pr_devinit(KERN_ERR PFX
409 "cannot register reboot notifier (err=%d)\n", ret);
420 return ret; 410 return ret;
421 } 411 }
422 412
423 ret = misc_register(&bfin_wdt_miscdev); 413 ret = misc_register(&bfin_wdt_miscdev);
424 if (ret) { 414 if (ret) {
425 pr_devinit(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 415 pr_devinit(KERN_ERR PFX
426 WATCHDOG_MINOR, ret); 416 "cannot register miscdev on minor=%d (err=%d)\n",
417 WATCHDOG_MINOR, ret);
427 unregister_reboot_notifier(&bfin_wdt_notifier); 418 unregister_reboot_notifier(&bfin_wdt_notifier);
428 return ret; 419 return ret;
429 } 420 }
@@ -516,7 +507,11 @@ MODULE_LICENSE("GPL");
516MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 507MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
517 508
518module_param(timeout, uint, 0); 509module_param(timeout, uint, 0);
519MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 510MODULE_PARM_DESC(timeout,
511 "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default="
512 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
520 513
521module_param(nowayout, int, 0); 514module_param(nowayout, int, 0);
522MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 515MODULE_PARM_DESC(nowayout,
516 "Watchdog cannot be stopped once started (default="
517 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index 770824458d45..c3b78a76f173 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -18,9 +18,9 @@
18#include <linux/miscdevice.h> 18#include <linux/miscdevice.h>
19#include <linux/notifier.h> 19#include <linux/notifier.h>
20#include <linux/watchdog.h> 20#include <linux/watchdog.h>
21#include <linux/uaccess.h>
21 22
22#include <asm/reg_booke.h> 23#include <asm/reg_booke.h>
23#include <asm/uaccess.h>
24#include <asm/system.h> 24#include <asm/system.h>
25 25
26/* If the kernel parameter wdt=1, the watchdog will be enabled at boot. 26/* If the kernel parameter wdt=1, the watchdog will be enabled at boot.
@@ -32,7 +32,7 @@
32 */ 32 */
33 33
34#ifdef CONFIG_FSL_BOOKE 34#ifdef CONFIG_FSL_BOOKE
35#define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */ 35#define WDT_PERIOD_DEFAULT 63 /* Ex. wdt_period=28 bus=333Mhz,reset=~40sec */
36#else 36#else
37#define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */ 37#define WDT_PERIOD_DEFAULT 3 /* Refer to the PPC40x and PPC4xx manuals */
38#endif /* for timing information */ 38#endif /* for timing information */
@@ -82,16 +82,15 @@ static struct watchdog_info ident = {
82 .identity = "PowerPC Book-E Watchdog", 82 .identity = "PowerPC Book-E Watchdog",
83}; 83};
84 84
85static int booke_wdt_ioctl(struct inode *inode, struct file *file, 85static long booke_wdt_ioctl(struct file *file,
86 unsigned int cmd, unsigned long arg) 86 unsigned int cmd, unsigned long arg)
87{ 87{
88 u32 tmp = 0; 88 u32 tmp = 0;
89 u32 __user *p = (u32 __user *)arg; 89 u32 __user *p = (u32 __user *)arg;
90 90
91 switch (cmd) { 91 switch (cmd) {
92 case WDIOC_GETSUPPORT: 92 case WDIOC_GETSUPPORT:
93 if (copy_to_user((struct watchdog_info __user *)arg, &ident, 93 if (copy_to_user(arg, &ident, sizeof(struct watchdog_info)))
94 sizeof(struct watchdog_info)))
95 return -EFAULT; 94 return -EFAULT;
96 case WDIOC_GETSTATUS: 95 case WDIOC_GETSTATUS:
97 return put_user(ident.options, p); 96 return put_user(ident.options, p);
@@ -100,16 +99,6 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file,
100 tmp = mfspr(SPRN_TSR) & TSR_WRS(3); 99 tmp = mfspr(SPRN_TSR) & TSR_WRS(3);
101 /* returns 1 if last reset was caused by the WDT */ 100 /* returns 1 if last reset was caused by the WDT */
102 return (tmp ? 1 : 0); 101 return (tmp ? 1 : 0);
103 case WDIOC_KEEPALIVE:
104 booke_wdt_ping();
105 return 0;
106 case WDIOC_SETTIMEOUT:
107 if (get_user(booke_wdt_period, p))
108 return -EFAULT;
109 mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period));
110 return 0;
111 case WDIOC_GETTIMEOUT:
112 return put_user(booke_wdt_period, p);
113 case WDIOC_SETOPTIONS: 102 case WDIOC_SETOPTIONS:
114 if (get_user(tmp, p)) 103 if (get_user(tmp, p))
115 return -EINVAL; 104 return -EINVAL;
@@ -119,6 +108,17 @@ static int booke_wdt_ioctl(struct inode *inode, struct file *file,
119 } else 108 } else
120 return -EINVAL; 109 return -EINVAL;
121 return 0; 110 return 0;
111 case WDIOC_KEEPALIVE:
112 booke_wdt_ping();
113 return 0;
114 case WDIOC_SETTIMEOUT:
115 if (get_user(booke_wdt_period, p))
116 return -EFAULT;
117 mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP(0)) |
118 WDTP(booke_wdt_period));
119 return 0;
120 case WDIOC_GETTIMEOUT:
121 return put_user(booke_wdt_period, p);
122 default: 122 default:
123 return -ENOTTY; 123 return -ENOTTY;
124 } 124 }
@@ -132,8 +132,9 @@ static int booke_wdt_open(struct inode *inode, struct file *file)
132 if (booke_wdt_enabled == 0) { 132 if (booke_wdt_enabled == 0) {
133 booke_wdt_enabled = 1; 133 booke_wdt_enabled = 1;
134 on_each_cpu(__booke_wdt_enable, NULL, 0); 134 on_each_cpu(__booke_wdt_enable, NULL, 0);
135 printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " 135 printk(KERN_INFO
136 "(wdt_period=%d)\n", booke_wdt_period); 136 "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
137 booke_wdt_period);
137 } 138 }
138 spin_unlock(&booke_wdt_lock); 139 spin_unlock(&booke_wdt_lock);
139 140
@@ -144,7 +145,7 @@ static const struct file_operations booke_wdt_fops = {
144 .owner = THIS_MODULE, 145 .owner = THIS_MODULE,
145 .llseek = no_llseek, 146 .llseek = no_llseek,
146 .write = booke_wdt_write, 147 .write = booke_wdt_write,
147 .ioctl = booke_wdt_ioctl, 148 .unlocked_ioctl = booke_wdt_ioctl,
148 .open = booke_wdt_open, 149 .open = booke_wdt_open,
149}; 150};
150 151
@@ -175,8 +176,9 @@ static int __init booke_wdt_init(void)
175 176
176 spin_lock(&booke_wdt_lock); 177 spin_lock(&booke_wdt_lock);
177 if (booke_wdt_enabled == 1) { 178 if (booke_wdt_enabled == 1) {
178 printk(KERN_INFO "PowerPC Book-E Watchdog Timer Enabled " 179 printk(KERN_INFO
179 "(wdt_period=%d)\n", booke_wdt_period); 180 "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
181 booke_wdt_period);
180 on_each_cpu(__booke_wdt_enable, NULL, 0); 182 on_each_cpu(__booke_wdt_enable, NULL, 0);
181 } 183 }
182 spin_unlock(&booke_wdt_lock); 184 spin_unlock(&booke_wdt_lock);
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index df72f90123df..71f6d7eec9a8 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -30,16 +30,16 @@
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/completion.h> 31#include <linux/completion.h>
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <asm/io.h> 33#include <linux/io.h>
34#include <asm/uaccess.h> 34#include <linux/uaccess.h>
35
36#include <linux/watchdog.h> 35#include <linux/watchdog.h>
37 36
38/* adjustable parameters */ 37/* adjustable parameters */
39 38
40static int verbose = 0; 39static int verbose;
41static int port = 0x91; 40static int port = 0x91;
42static int ticks = 10000; 41static int ticks = 10000;
42static spinlock_t cpu5wdt_lock;
43 43
44#define PFX "cpu5wdt: " 44#define PFX "cpu5wdt: "
45 45
@@ -70,12 +70,13 @@ static struct {
70 70
71static void cpu5wdt_trigger(unsigned long unused) 71static void cpu5wdt_trigger(unsigned long unused)
72{ 72{
73 if ( verbose > 2 ) 73 if (verbose > 2)
74 printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks); 74 printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks);
75 75
76 if( cpu5wdt_device.running ) 76 if (cpu5wdt_device.running)
77 ticks--; 77 ticks--;
78 78
79 spin_lock(&cpu5wdt_lock);
79 /* keep watchdog alive */ 80 /* keep watchdog alive */
80 outb(1, port + CPU5WDT_TRIGGER_REG); 81 outb(1, port + CPU5WDT_TRIGGER_REG);
81 82
@@ -86,6 +87,7 @@ static void cpu5wdt_trigger(unsigned long unused)
86 /* ticks doesn't matter anyway */ 87 /* ticks doesn't matter anyway */
87 complete(&cpu5wdt_device.stop); 88 complete(&cpu5wdt_device.stop);
88 } 89 }
90 spin_unlock(&cpu5wdt_lock);
89 91
90} 92}
91 93
@@ -93,14 +95,17 @@ static void cpu5wdt_reset(void)
93{ 95{
94 ticks = cpu5wdt_device.default_ticks; 96 ticks = cpu5wdt_device.default_ticks;
95 97
96 if ( verbose ) 98 if (verbose)
97 printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks); 99 printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks);
98 100
99} 101}
100 102
101static void cpu5wdt_start(void) 103static void cpu5wdt_start(void)
102{ 104{
103 if ( !cpu5wdt_device.queue ) { 105 unsigned long flags;
106
107 spin_lock_irqsave(&cpu5wdt_lock, flags);
108 if (!cpu5wdt_device.queue) {
104 cpu5wdt_device.queue = 1; 109 cpu5wdt_device.queue = 1;
105 outb(0, port + CPU5WDT_TIME_A_REG); 110 outb(0, port + CPU5WDT_TIME_A_REG);
106 outb(0, port + CPU5WDT_TIME_B_REG); 111 outb(0, port + CPU5WDT_TIME_B_REG);
@@ -111,18 +116,20 @@ static void cpu5wdt_start(void)
111 } 116 }
112 /* if process dies, counter is not decremented */ 117 /* if process dies, counter is not decremented */
113 cpu5wdt_device.running++; 118 cpu5wdt_device.running++;
119 spin_unlock_irqrestore(&cpu5wdt_lock, flags);
114} 120}
115 121
116static int cpu5wdt_stop(void) 122static int cpu5wdt_stop(void)
117{ 123{
118 if ( cpu5wdt_device.running ) 124 unsigned long flags;
119 cpu5wdt_device.running = 0;
120 125
126 spin_lock_irqsave(&cpu5wdt_lock, flags);
127 if (cpu5wdt_device.running)
128 cpu5wdt_device.running = 0;
121 ticks = cpu5wdt_device.default_ticks; 129 ticks = cpu5wdt_device.default_ticks;
122 130 spin_unlock_irqrestore(&cpu5wdt_lock, flags);
123 if ( verbose ) 131 if (verbose)
124 printk(KERN_CRIT PFX "stop not possible\n"); 132 printk(KERN_CRIT PFX "stop not possible\n");
125
126 return -EIO; 133 return -EIO;
127} 134}
128 135
@@ -130,9 +137,8 @@ static int cpu5wdt_stop(void)
130 137
131static int cpu5wdt_open(struct inode *inode, struct file *file) 138static int cpu5wdt_open(struct inode *inode, struct file *file)
132{ 139{
133 if ( test_and_set_bit(0, &cpu5wdt_device.inuse) ) 140 if (test_and_set_bit(0, &cpu5wdt_device.inuse))
134 return -EBUSY; 141 return -EBUSY;
135
136 return nonseekable_open(inode, file); 142 return nonseekable_open(inode, file);
137} 143}
138 144
@@ -142,67 +148,58 @@ static int cpu5wdt_release(struct inode *inode, struct file *file)
142 return 0; 148 return 0;
143} 149}
144 150
145static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 151static long cpu5wdt_ioctl(struct file *file, unsigned int cmd,
152 unsigned long arg)
146{ 153{
147 void __user *argp = (void __user *)arg; 154 void __user *argp = (void __user *)arg;
155 int __user *p = argp;
148 unsigned int value; 156 unsigned int value;
149 static struct watchdog_info ident = 157 static struct watchdog_info ident = {
150 {
151 .options = WDIOF_CARDRESET, 158 .options = WDIOF_CARDRESET,
152 .identity = "CPU5 WDT", 159 .identity = "CPU5 WDT",
153 }; 160 };
154 161
155 switch(cmd) { 162 switch (cmd) {
156 case WDIOC_KEEPALIVE: 163 case WDIOC_GETSUPPORT:
157 cpu5wdt_reset(); 164 if (copy_to_user(argp, &ident, sizeof(ident)))
158 break; 165 return -EFAULT;
159 case WDIOC_GETSTATUS: 166 break;
160 value = inb(port + CPU5WDT_STATUS_REG); 167 case WDIOC_GETSTATUS:
161 value = (value >> 2) & 1; 168 value = inb(port + CPU5WDT_STATUS_REG);
162 if ( copy_to_user(argp, &value, sizeof(int)) ) 169 value = (value >> 2) & 1;
163 return -EFAULT; 170 return put_user(value, p);
164 break; 171 case WDIOC_GETBOOTSTATUS:
165 case WDIOC_GETBOOTSTATUS: 172 return put_user(0, p);
166 if ( copy_to_user(argp, &value, sizeof(int)) ) 173 case WDIOC_SETOPTIONS:
167 return -EFAULT; 174 if (get_user(value, p))
168 break; 175 return -EFAULT;
169 case WDIOC_GETSUPPORT: 176 if (value & WDIOS_ENABLECARD)
170 if ( copy_to_user(argp, &ident, sizeof(ident)) ) 177 cpu5wdt_start();
171 return -EFAULT; 178 if (value & WDIOS_DISABLECARD)
172 break; 179 cpu5wdt_stop();
173 case WDIOC_SETOPTIONS: 180 break;
174 if ( copy_from_user(&value, argp, sizeof(int)) ) 181 case WDIOC_KEEPALIVE:
175 return -EFAULT; 182 cpu5wdt_reset();
176 switch(value) { 183 break;
177 case WDIOS_ENABLECARD: 184 default:
178 cpu5wdt_start(); 185 return -ENOTTY;
179 break;
180 case WDIOS_DISABLECARD:
181 return cpu5wdt_stop();
182 default:
183 return -EINVAL;
184 }
185 break;
186 default:
187 return -ENOTTY;
188 } 186 }
189 return 0; 187 return 0;
190} 188}
191 189
192static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 190static ssize_t cpu5wdt_write(struct file *file, const char __user *buf,
191 size_t count, loff_t *ppos)
193{ 192{
194 if ( !count ) 193 if (!count)
195 return -EIO; 194 return -EIO;
196
197 cpu5wdt_reset(); 195 cpu5wdt_reset();
198
199 return count; 196 return count;
200} 197}
201 198
202static const struct file_operations cpu5wdt_fops = { 199static const struct file_operations cpu5wdt_fops = {
203 .owner = THIS_MODULE, 200 .owner = THIS_MODULE,
204 .llseek = no_llseek, 201 .llseek = no_llseek,
205 .ioctl = cpu5wdt_ioctl, 202 .unlocked_ioctl = cpu5wdt_ioctl,
206 .open = cpu5wdt_open, 203 .open = cpu5wdt_open,
207 .write = cpu5wdt_write, 204 .write = cpu5wdt_write,
208 .release = cpu5wdt_release, 205 .release = cpu5wdt_release,
@@ -221,37 +218,36 @@ static int __devinit cpu5wdt_init(void)
221 unsigned int val; 218 unsigned int val;
222 int err; 219 int err;
223 220
224 if ( verbose ) 221 if (verbose)
225 printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose); 222 printk(KERN_DEBUG PFX
223 "port=0x%x, verbose=%i\n", port, verbose);
226 224
227 if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) { 225 init_completion(&cpu5wdt_device.stop);
226 spin_lock_init(&cpu5wdt_lock);
227 cpu5wdt_device.queue = 0;
228 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
229 cpu5wdt_device.default_ticks = ticks;
230
231 if (!request_region(port, CPU5WDT_EXTENT, PFX)) {
228 printk(KERN_ERR PFX "request_region failed\n"); 232 printk(KERN_ERR PFX "request_region failed\n");
229 err = -EBUSY; 233 err = -EBUSY;
230 goto no_port; 234 goto no_port;
231 } 235 }
232 236
233 if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) {
234 printk(KERN_ERR PFX "misc_register failed\n");
235 goto no_misc;
236 }
237
238 /* watchdog reboot? */ 237 /* watchdog reboot? */
239 val = inb(port + CPU5WDT_STATUS_REG); 238 val = inb(port + CPU5WDT_STATUS_REG);
240 val = (val >> 2) & 1; 239 val = (val >> 2) & 1;
241 if ( !val ) 240 if (!val)
242 printk(KERN_INFO PFX "sorry, was my fault\n"); 241 printk(KERN_INFO PFX "sorry, was my fault\n");
243 242
244 init_completion(&cpu5wdt_device.stop); 243 err = misc_register(&cpu5wdt_misc);
245 cpu5wdt_device.queue = 0; 244 if (err < 0) {
246 245 printk(KERN_ERR PFX "misc_register failed\n");
247 clear_bit(0, &cpu5wdt_device.inuse); 246 goto no_misc;
248 247 }
249 setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
250 248
251 cpu5wdt_device.default_ticks = ticks;
252 249
253 printk(KERN_INFO PFX "init success\n"); 250 printk(KERN_INFO PFX "init success\n");
254
255 return 0; 251 return 0;
256 252
257no_misc: 253no_misc:
@@ -267,7 +263,7 @@ static int __devinit cpu5wdt_init_module(void)
267 263
268static void __devexit cpu5wdt_exit(void) 264static void __devexit cpu5wdt_exit(void)
269{ 265{
270 if ( cpu5wdt_device.queue ) { 266 if (cpu5wdt_device.queue) {
271 cpu5wdt_device.queue = 0; 267 cpu5wdt_device.queue = 0;
272 wait_for_completion(&cpu5wdt_device.stop); 268 wait_for_completion(&cpu5wdt_device.stop);
273 } 269 }
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 1782c79eff06..2e1360286732 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -22,10 +22,9 @@
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25 25#include <linux/uaccess.h>
26#include <asm/hardware.h> 26#include <linux/io.h>
27#include <asm/uaccess.h> 27#include <mach/hardware.h>
28#include <asm/io.h>
29 28
30#define MODULE_NAME "DAVINCI-WDT: " 29#define MODULE_NAME "DAVINCI-WDT: "
31 30
@@ -143,9 +142,8 @@ static struct watchdog_info ident = {
143 .identity = "DaVinci Watchdog", 142 .identity = "DaVinci Watchdog",
144}; 143};
145 144
146static int 145static long davinci_wdt_ioctl(struct file *file,
147davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 146 unsigned int cmd, unsigned long arg)
148 unsigned long arg)
149{ 147{
150 int ret = -ENOTTY; 148 int ret = -ENOTTY;
151 149
@@ -160,14 +158,14 @@ davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
160 ret = put_user(0, (int *)arg); 158 ret = put_user(0, (int *)arg);
161 break; 159 break;
162 160
163 case WDIOC_GETTIMEOUT:
164 ret = put_user(heartbeat, (int *)arg);
165 break;
166
167 case WDIOC_KEEPALIVE: 161 case WDIOC_KEEPALIVE:
168 wdt_service(); 162 wdt_service();
169 ret = 0; 163 ret = 0;
170 break; 164 break;
165
166 case WDIOC_GETTIMEOUT:
167 ret = put_user(heartbeat, (int *)arg);
168 break;
171 } 169 }
172 return ret; 170 return ret;
173} 171}
@@ -184,7 +182,7 @@ static const struct file_operations davinci_wdt_fops = {
184 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
185 .llseek = no_llseek, 183 .llseek = no_llseek,
186 .write = davinci_wdt_write, 184 .write = davinci_wdt_write,
187 .ioctl = davinci_wdt_ioctl, 185 .unlocked_ioctl = davinci_wdt_ioctl,
188 .open = davinci_wdt_open, 186 .open = davinci_wdt_open,
189 .release = davinci_wdt_release, 187 .release = davinci_wdt_release,
190}; 188};
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 0e4787a0bb87..e9f950ff86ea 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -28,9 +28,8 @@
28#include <linux/miscdevice.h> 28#include <linux/miscdevice.h>
29#include <linux/watchdog.h> 29#include <linux/watchdog.h>
30#include <linux/timer.h> 30#include <linux/timer.h>
31 31#include <linux/uaccess.h>
32#include <asm/hardware.h> 32#include <mach/hardware.h>
33#include <asm/uaccess.h>
34 33
35#define WDT_VERSION "0.3" 34#define WDT_VERSION "0.3"
36#define PFX "ep93xx_wdt: " 35#define PFX "ep93xx_wdt: "
@@ -136,9 +135,8 @@ static struct watchdog_info ident = {
136 .identity = "EP93xx Watchdog", 135 .identity = "EP93xx Watchdog",
137}; 136};
138 137
139static int 138static long ep93xx_wdt_ioctl(struct file *file,
140ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 139 unsigned int cmd, unsigned long arg)
141 unsigned long arg)
142{ 140{
143 int ret = -ENOTTY; 141 int ret = -ENOTTY;
144 142
@@ -156,15 +154,15 @@ ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
156 ret = put_user(boot_status, (int __user *)arg); 154 ret = put_user(boot_status, (int __user *)arg);
157 break; 155 break;
158 156
159 case WDIOC_GETTIMEOUT:
160 /* actually, it is 0.250 seconds.... */
161 ret = put_user(1, (int __user *)arg);
162 break;
163
164 case WDIOC_KEEPALIVE: 157 case WDIOC_KEEPALIVE:
165 wdt_keepalive(); 158 wdt_keepalive();
166 ret = 0; 159 ret = 0;
167 break; 160 break;
161
162 case WDIOC_GETTIMEOUT:
163 /* actually, it is 0.250 seconds.... */
164 ret = put_user(1, (int __user *)arg);
165 break;
168 } 166 }
169 return ret; 167 return ret;
170} 168}
@@ -174,8 +172,8 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
174 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) 172 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
175 wdt_shutdown(); 173 wdt_shutdown();
176 else 174 else
177 printk(KERN_CRIT PFX "Device closed unexpectedly - " 175 printk(KERN_CRIT PFX
178 "timer will not stop\n"); 176 "Device closed unexpectedly - timer will not stop\n");
179 177
180 clear_bit(WDT_IN_USE, &wdt_status); 178 clear_bit(WDT_IN_USE, &wdt_status);
181 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 179 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
@@ -186,7 +184,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
186static const struct file_operations ep93xx_wdt_fops = { 184static const struct file_operations ep93xx_wdt_fops = {
187 .owner = THIS_MODULE, 185 .owner = THIS_MODULE,
188 .write = ep93xx_wdt_write, 186 .write = ep93xx_wdt_write,
189 .ioctl = ep93xx_wdt_ioctl, 187 .unlocked_ioctl = ep93xx_wdt_ioctl,
190 .open = ep93xx_wdt_open, 188 .open = ep93xx_wdt_open,
191 .release = ep93xx_wdt_release, 189 .release = ep93xx_wdt_release,
192}; 190};
@@ -243,7 +241,9 @@ module_param(nowayout, int, 0);
243MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); 241MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
244 242
245module_param(timeout, int, 0); 243module_param(timeout, int, 0);
246MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 244MODULE_PARM_DESC(timeout,
245 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
246 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
247 247
248MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>," 248MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
249 "Alessandro Zummo <a.zummo@towertech.it>"); 249 "Alessandro Zummo <a.zummo@towertech.it>");
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index b14e9d1f164d..bbd14e34319f 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -56,14 +56,15 @@
56#include <linux/notifier.h> 56#include <linux/notifier.h>
57#include <linux/reboot.h> 57#include <linux/reboot.h>
58#include <linux/init.h> 58#include <linux/init.h>
59#include <linux/io.h>
60#include <linux/uaccess.h>
59 61
60#include <asm/io.h>
61#include <asm/uaccess.h>
62#include <asm/system.h> 62#include <asm/system.h>
63 63
64static unsigned long eurwdt_is_open; 64static unsigned long eurwdt_is_open;
65static int eurwdt_timeout; 65static int eurwdt_timeout;
66static char eur_expect_close; 66static char eur_expect_close;
67static spinlock_t eurwdt_lock;
67 68
68/* 69/*
69 * You must set these - there is no sane way to probe for this board. 70 * You must set these - there is no sane way to probe for this board.
@@ -78,7 +79,9 @@ static char *ev = "int";
78 79
79static int nowayout = WATCHDOG_NOWAYOUT; 80static int nowayout = WATCHDOG_NOWAYOUT;
80module_param(nowayout, int, 0); 81module_param(nowayout, int, 0);
81MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 82MODULE_PARM_DESC(nowayout,
83 "Watchdog cannot be stopped once started (default="
84 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
82 85
83/* 86/*
84 * Some symbolic names 87 * Some symbolic names
@@ -137,7 +140,8 @@ static void eurwdt_activate_timer(void)
137{ 140{
138 eurwdt_disable_timer(); 141 eurwdt_disable_timer();
139 eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */ 142 eurwdt_write_reg(WDT_CTRL_REG, 0x01); /* activate the WDT */
140 eurwdt_write_reg(WDT_OUTPIN_CFG, !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT); 143 eurwdt_write_reg(WDT_OUTPIN_CFG,
144 !strcmp("int", ev) ? WDT_EVENT_INT : WDT_EVENT_REBOOT);
141 145
142 /* Setting interrupt line */ 146 /* Setting interrupt line */
143 if (irq == 2 || irq > 15 || irq < 0) { 147 if (irq == 2 || irq > 15 || irq < 0) {
@@ -206,21 +210,21 @@ size_t count, loff_t *ppos)
206 210
207 for (i = 0; i != count; i++) { 211 for (i = 0; i != count; i++) {
208 char c; 212 char c;
209 if(get_user(c, buf+i)) 213 if (get_user(c, buf + i))
210 return -EFAULT; 214 return -EFAULT;
211 if (c == 'V') 215 if (c == 'V')
212 eur_expect_close = 42; 216 eur_expect_close = 42;
213 } 217 }
214 } 218 }
219 spin_lock(&eurwdt_lock);
215 eurwdt_ping(); /* the default timeout */ 220 eurwdt_ping(); /* the default timeout */
221 spin_unlock(&eurwdt_lock);
216 } 222 }
217
218 return count; 223 return count;
219} 224}
220 225
221/** 226/**
222 * eurwdt_ioctl: 227 * eurwdt_ioctl:
223 * @inode: inode of the device
224 * @file: file handle to the device 228 * @file: file handle to the device
225 * @cmd: watchdog command 229 * @cmd: watchdog command
226 * @arg: argument pointer 230 * @arg: argument pointer
@@ -229,13 +233,14 @@ size_t count, loff_t *ppos)
229 * according to their available features. 233 * according to their available features.
230 */ 234 */
231 235
232static int eurwdt_ioctl(struct inode *inode, struct file *file, 236static long eurwdt_ioctl(struct file *file,
233 unsigned int cmd, unsigned long arg) 237 unsigned int cmd, unsigned long arg)
234{ 238{
235 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
236 int __user *p = argp; 240 int __user *p = argp;
237 static struct watchdog_info ident = { 241 static struct watchdog_info ident = {
238 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
243 | WDIOF_MAGICCLOSE,
239 .firmware_version = 1, 244 .firmware_version = 1,
240 .identity = "WDT Eurotech CPU-1220/1410", 245 .identity = "WDT Eurotech CPU-1220/1410",
241 }; 246 };
@@ -243,10 +248,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
243 int time; 248 int time;
244 int options, retval = -EINVAL; 249 int options, retval = -EINVAL;
245 250
246 switch(cmd) { 251 switch (cmd) {
247 default:
248 return -ENOTTY;
249
250 case WDIOC_GETSUPPORT: 252 case WDIOC_GETSUPPORT:
251 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 253 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
252 254
@@ -254,8 +256,26 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
254 case WDIOC_GETBOOTSTATUS: 256 case WDIOC_GETBOOTSTATUS:
255 return put_user(0, p); 257 return put_user(0, p);
256 258
259 case WDIOC_SETOPTIONS:
260 if (get_user(options, p))
261 return -EFAULT;
262 spin_lock(&eurwdt_lock);
263 if (options & WDIOS_DISABLECARD) {
264 eurwdt_disable_timer();
265 retval = 0;
266 }
267 if (options & WDIOS_ENABLECARD) {
268 eurwdt_activate_timer();
269 eurwdt_ping();
270 retval = 0;
271 }
272 spin_unlock(&eurwdt_lock);
273 return retval;
274
257 case WDIOC_KEEPALIVE: 275 case WDIOC_KEEPALIVE:
276 spin_lock(&eurwdt_lock);
258 eurwdt_ping(); 277 eurwdt_ping();
278 spin_unlock(&eurwdt_lock);
259 return 0; 279 return 0;
260 280
261 case WDIOC_SETTIMEOUT: 281 case WDIOC_SETTIMEOUT:
@@ -266,26 +286,17 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
266 if (time < 0 || time > 255) 286 if (time < 0 || time > 255)
267 return -EINVAL; 287 return -EINVAL;
268 288
289 spin_lock(&eurwdt_lock);
269 eurwdt_timeout = time; 290 eurwdt_timeout = time;
270 eurwdt_set_timeout(time); 291 eurwdt_set_timeout(time);
292 spin_unlock(&eurwdt_lock);
271 /* Fall */ 293 /* Fall */
272 294
273 case WDIOC_GETTIMEOUT: 295 case WDIOC_GETTIMEOUT:
274 return put_user(eurwdt_timeout, p); 296 return put_user(eurwdt_timeout, p);
275 297
276 case WDIOC_SETOPTIONS: 298 default:
277 if (get_user(options, p)) 299 return -ENOTTY;
278 return -EFAULT;
279 if (options & WDIOS_DISABLECARD) {
280 eurwdt_disable_timer();
281 retval = 0;
282 }
283 if (options & WDIOS_ENABLECARD) {
284 eurwdt_activate_timer();
285 eurwdt_ping();
286 retval = 0;
287 }
288 return retval;
289 } 300 }
290} 301}
291 302
@@ -322,10 +333,11 @@ static int eurwdt_open(struct inode *inode, struct file *file)
322 333
323static int eurwdt_release(struct inode *inode, struct file *file) 334static int eurwdt_release(struct inode *inode, struct file *file)
324{ 335{
325 if (eur_expect_close == 42) { 336 if (eur_expect_close == 42)
326 eurwdt_disable_timer(); 337 eurwdt_disable_timer();
327 } else { 338 else {
328 printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n"); 339 printk(KERN_CRIT
340 "eurwdt: Unexpected close, not stopping watchdog!\n");
329 eurwdt_ping(); 341 eurwdt_ping();
330 } 342 }
331 clear_bit(0, &eurwdt_is_open); 343 clear_bit(0, &eurwdt_is_open);
@@ -348,10 +360,8 @@ static int eurwdt_release(struct inode *inode, struct file *file)
348static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, 360static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
349 void *unused) 361 void *unused)
350{ 362{
351 if (code == SYS_DOWN || code == SYS_HALT) { 363 if (code == SYS_DOWN || code == SYS_HALT)
352 /* Turn the card off */ 364 eurwdt_disable_timer(); /* Turn the card off */
353 eurwdt_disable_timer();
354 }
355 365
356 return NOTIFY_DONE; 366 return NOTIFY_DONE;
357} 367}
@@ -362,11 +372,11 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
362 372
363 373
364static const struct file_operations eurwdt_fops = { 374static const struct file_operations eurwdt_fops = {
365 .owner = THIS_MODULE, 375 .owner = THIS_MODULE,
366 .llseek = no_llseek, 376 .llseek = no_llseek,
367 .write = eurwdt_write, 377 .write = eurwdt_write,
368 .ioctl = eurwdt_ioctl, 378 .unlocked_ioctl = eurwdt_ioctl,
369 .open = eurwdt_open, 379 .open = eurwdt_open,
370 .release = eurwdt_release, 380 .release = eurwdt_release,
371}; 381};
372 382
@@ -419,7 +429,7 @@ static int __init eurwdt_init(void)
419 int ret; 429 int ret;
420 430
421 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL); 431 ret = request_irq(irq, eurwdt_interrupt, IRQF_DISABLED, "eurwdt", NULL);
422 if(ret) { 432 if (ret) {
423 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq); 433 printk(KERN_ERR "eurwdt: IRQ %d is not free.\n", irq);
424 goto out; 434 goto out;
425 } 435 }
@@ -432,10 +442,13 @@ static int __init eurwdt_init(void)
432 442
433 ret = register_reboot_notifier(&eurwdt_notifier); 443 ret = register_reboot_notifier(&eurwdt_notifier);
434 if (ret) { 444 if (ret) {
435 printk(KERN_ERR "eurwdt: can't register reboot notifier (err=%d)\n", ret); 445 printk(KERN_ERR
446 "eurwdt: can't register reboot notifier (err=%d)\n", ret);
436 goto outreg; 447 goto outreg;
437 } 448 }
438 449
450 spin_lock_init(&eurwdt_lock);
451
439 ret = misc_register(&eurwdt_miscdev); 452 ret = misc_register(&eurwdt_miscdev);
440 if (ret) { 453 if (ret) {
441 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n", 454 printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index 30d09cbbad94..614a5c7017b6 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -17,8 +17,8 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/uaccess.h>
20 21
21#include <asm/uaccess.h>
22#include <asm/geode.h> 22#include <asm/geode.h>
23 23
24#define GEODEWDT_HZ 500 24#define GEODEWDT_HZ 500
@@ -77,27 +77,24 @@ static int geodewdt_set_heartbeat(int val)
77 return 0; 77 return 0;
78} 78}
79 79
80static int 80static int geodewdt_open(struct inode *inode, struct file *file)
81geodewdt_open(struct inode *inode, struct file *file)
82{ 81{
83 if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags)) 82 if (test_and_set_bit(WDT_FLAGS_OPEN, &wdt_flags))
84 return -EBUSY; 83 return -EBUSY;
85 84
86 if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags)) 85 if (!test_and_clear_bit(WDT_FLAGS_ORPHAN, &wdt_flags))
87 __module_get(THIS_MODULE); 86 __module_get(THIS_MODULE);
88 87
89 geodewdt_ping(); 88 geodewdt_ping();
90 return nonseekable_open(inode, file); 89 return nonseekable_open(inode, file);
91} 90}
92 91
93static int 92static int geodewdt_release(struct inode *inode, struct file *file)
94geodewdt_release(struct inode *inode, struct file *file)
95{ 93{
96 if (safe_close) { 94 if (safe_close) {
97 geodewdt_disable(); 95 geodewdt_disable();
98 module_put(THIS_MODULE); 96 module_put(THIS_MODULE);
99 } 97 } else {
100 else {
101 printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n"); 98 printk(KERN_CRIT "Unexpected close - watchdog is not stopping.\n");
102 geodewdt_ping(); 99 geodewdt_ping();
103 100
@@ -109,11 +106,10 @@ geodewdt_release(struct inode *inode, struct file *file)
109 return 0; 106 return 0;
110} 107}
111 108
112static ssize_t 109static ssize_t geodewdt_write(struct file *file, const char __user *data,
113geodewdt_write(struct file *file, const char __user *data, size_t len, 110 size_t len, loff_t *ppos)
114 loff_t *ppos)
115{ 111{
116 if(len) { 112 if (len) {
117 if (!nowayout) { 113 if (!nowayout) {
118 size_t i; 114 size_t i;
119 safe_close = 0; 115 safe_close = 0;
@@ -134,9 +130,8 @@ geodewdt_write(struct file *file, const char __user *data, size_t len,
134 return len; 130 return len;
135} 131}
136 132
137static int 133static int geodewdt_ioctl(struct inode *inode, struct file *file,
138geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 134 unsigned int cmd, unsigned long arg)
139 unsigned long arg)
140{ 135{
141 void __user *argp = (void __user *)arg; 136 void __user *argp = (void __user *)arg;
142 int __user *p = argp; 137 int __user *p = argp;
@@ -147,9 +142,9 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
147 | WDIOF_MAGICCLOSE, 142 | WDIOF_MAGICCLOSE,
148 .firmware_version = 1, 143 .firmware_version = 1,
149 .identity = WATCHDOG_NAME, 144 .identity = WATCHDOG_NAME,
150 }; 145 };
151 146
152 switch(cmd) { 147 switch (cmd) {
153 case WDIOC_GETSUPPORT: 148 case WDIOC_GETSUPPORT:
154 return copy_to_user(argp, &ident, 149 return copy_to_user(argp, &ident,
155 sizeof(ident)) ? -EFAULT : 0; 150 sizeof(ident)) ? -EFAULT : 0;
@@ -159,22 +154,6 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
159 case WDIOC_GETBOOTSTATUS: 154 case WDIOC_GETBOOTSTATUS:
160 return put_user(0, p); 155 return put_user(0, p);
161 156
162 case WDIOC_KEEPALIVE:
163 geodewdt_ping();
164 return 0;
165
166 case WDIOC_SETTIMEOUT:
167 if (get_user(interval, p))
168 return -EFAULT;
169
170 if (geodewdt_set_heartbeat(interval))
171 return -EINVAL;
172
173/* Fall through */
174
175 case WDIOC_GETTIMEOUT:
176 return put_user(timeout, p);
177
178 case WDIOC_SETOPTIONS: 157 case WDIOC_SETOPTIONS:
179 { 158 {
180 int options, ret = -EINVAL; 159 int options, ret = -EINVAL;
@@ -194,6 +173,20 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
194 173
195 return ret; 174 return ret;
196 } 175 }
176 case WDIOC_KEEPALIVE:
177 geodewdt_ping();
178 return 0;
179
180 case WDIOC_SETTIMEOUT:
181 if (get_user(interval, p))
182 return -EFAULT;
183
184 if (geodewdt_set_heartbeat(interval))
185 return -EINVAL;
186 /* Fall through */
187 case WDIOC_GETTIMEOUT:
188 return put_user(timeout, p);
189
197 default: 190 default:
198 return -ENOTTY; 191 return -ENOTTY;
199 } 192 }
@@ -202,22 +195,21 @@ geodewdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
202} 195}
203 196
204static const struct file_operations geodewdt_fops = { 197static const struct file_operations geodewdt_fops = {
205 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
206 .llseek = no_llseek, 199 .llseek = no_llseek,
207 .write = geodewdt_write, 200 .write = geodewdt_write,
208 .ioctl = geodewdt_ioctl, 201 .ioctl = geodewdt_ioctl,
209 .open = geodewdt_open, 202 .open = geodewdt_open,
210 .release = geodewdt_release, 203 .release = geodewdt_release,
211}; 204};
212 205
213static struct miscdevice geodewdt_miscdev = { 206static struct miscdevice geodewdt_miscdev = {
214 .minor = WATCHDOG_MINOR, 207 .minor = WATCHDOG_MINOR,
215 .name = "watchdog", 208 .name = "watchdog",
216 .fops = &geodewdt_fops 209 .fops = &geodewdt_fops,
217}; 210};
218 211
219static int __devinit 212static int __devinit geodewdt_probe(struct platform_device *dev)
220geodewdt_probe(struct platform_device *dev)
221{ 213{
222 int ret, timer; 214 int ret, timer;
223 215
@@ -248,15 +240,13 @@ geodewdt_probe(struct platform_device *dev)
248 return ret; 240 return ret;
249} 241}
250 242
251static int __devexit 243static int __devexit geodewdt_remove(struct platform_device *dev)
252geodewdt_remove(struct platform_device *dev)
253{ 244{
254 misc_deregister(&geodewdt_miscdev); 245 misc_deregister(&geodewdt_miscdev);
255 return 0; 246 return 0;
256} 247}
257 248
258static void 249static void geodewdt_shutdown(struct platform_device *dev)
259geodewdt_shutdown(struct platform_device *dev)
260{ 250{
261 geodewdt_disable(); 251 geodewdt_disable();
262} 252}
@@ -271,8 +261,7 @@ static struct platform_driver geodewdt_driver = {
271 }, 261 },
272}; 262};
273 263
274static int __init 264static int __init geodewdt_init(void)
275geodewdt_init(void)
276{ 265{
277 int ret; 266 int ret;
278 267
@@ -292,8 +281,7 @@ err:
292 return ret; 281 return ret;
293} 282}
294 283
295static void __exit 284static void __exit geodewdt_exit(void)
296geodewdt_exit(void)
297{ 285{
298 platform_device_unregister(geodewdt_platform_device); 286 platform_device_unregister(geodewdt_platform_device);
299 platform_driver_unregister(&geodewdt_driver); 287 platform_driver_unregister(&geodewdt_driver);
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index ccd6c530782d..d039d5f2fd1c 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -39,9 +39,7 @@
39#include <linux/string.h> 39#include <linux/string.h>
40#include <linux/bootmem.h> 40#include <linux/bootmem.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <asm/dmi.h>
43#include <asm/desc.h> 42#include <asm/desc.h>
44#include <asm/kdebug.h>
45 43
46#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */ 44#define PCI_BIOS32_SD_VALUE 0x5F32335F /* "_32_" */
47#define CRU_BIOS_SIGNATURE_VALUE 0x55524324 45#define CRU_BIOS_SIGNATURE_VALUE 0x55524324
@@ -407,7 +405,7 @@ static int __devinit detect_cru_service(void)
407 dmi_walk(dmi_find_cru); 405 dmi_walk(dmi_find_cru);
408 406
409 /* if cru_rom_addr has been set then we found a CRU service */ 407 /* if cru_rom_addr has been set then we found a CRU service */
410 return ((cru_rom_addr != NULL)? 0: -ENODEV); 408 return ((cru_rom_addr != NULL) ? 0: -ENODEV);
411} 409}
412 410
413/* ------------------------------------------------------------------------- */ 411/* ------------------------------------------------------------------------- */
@@ -535,7 +533,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data,
535 /* scan to see whether or not we got the magic char. */ 533 /* scan to see whether or not we got the magic char. */
536 for (i = 0; i != len; i++) { 534 for (i = 0; i != len; i++) {
537 char c; 535 char c;
538 if (get_user(c, data+i)) 536 if (get_user(c, data + i))
539 return -EFAULT; 537 return -EFAULT;
540 if (c == 'V') 538 if (c == 'V')
541 expect_release = 42; 539 expect_release = 42;
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index ca44fd9b19bb..c13383f7fcb9 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -9,18 +9,18 @@
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 * 11 *
12 * based on i810-tco.c which is in turn based on softdog.c 12 * based on i810-tco.c which is in turn based on softdog.c
13 * 13 *
14 * The timer is implemented in the following I/O controller hubs: 14 * The timer is implemented in the following I/O controller hubs:
15 * (See the intel documentation on http://developer.intel.com.) 15 * (See the intel documentation on http://developer.intel.com.)
16 * 6300ESB chip : document number 300641-003 16 * 6300ESB chip : document number 300641-003
17 * 17 *
18 * 2004YYZZ Ross Biro 18 * 2004YYZZ Ross Biro
19 * Initial version 0.01 19 * Initial version 0.01
20 * 2004YYZZ Ross Biro 20 * 2004YYZZ Ross Biro
21 * Version 0.02 21 * Version 0.02
22 * 20050210 David Härdeman <david@2gen.com> 22 * 20050210 David Härdeman <david@2gen.com>
23 * Ported driver to kernel 2.6 23 * Ported driver to kernel 2.6
24 */ 24 */
25 25
26/* 26/*
@@ -38,9 +38,8 @@
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/ioport.h> 40#include <linux/ioport.h>
41 41#include <linux/uaccess.h>
42#include <asm/uaccess.h> 42#include <linux/io.h>
43#include <asm/io.h>
44 43
45/* Module and version information */ 44/* Module and version information */
46#define ESB_VERSION "0.03" 45#define ESB_VERSION "0.03"
@@ -59,17 +58,17 @@
59#define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */ 58#define ESB_RELOAD_REG BASEADDR + 0x0c /* Reload register */
60 59
61/* Lock register bits */ 60/* Lock register bits */
62#define ESB_WDT_FUNC ( 0x01 << 2 ) /* Watchdog functionality */ 61#define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */
63#define ESB_WDT_ENABLE ( 0x01 << 1 ) /* Enable WDT */ 62#define ESB_WDT_ENABLE (0x01 << 1) /* Enable WDT */
64#define ESB_WDT_LOCK ( 0x01 << 0 ) /* Lock (nowayout) */ 63#define ESB_WDT_LOCK (0x01 << 0) /* Lock (nowayout) */
65 64
66/* Config register bits */ 65/* Config register bits */
67#define ESB_WDT_REBOOT ( 0x01 << 5 ) /* Enable reboot on timeout */ 66#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
68#define ESB_WDT_FREQ ( 0x01 << 2 ) /* Decrement frequency */ 67#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */
69#define ESB_WDT_INTTYPE ( 0x11 << 0 ) /* Interrupt type on timer1 timeout */ 68#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */
70 69
71/* Reload register bits */ 70/* Reload register bits */
72#define ESB_WDT_RELOAD ( 0x01 << 8 ) /* prevent timeout */ 71#define ESB_WDT_RELOAD (0x01 << 8) /* prevent timeout */
73 72
74/* Magic constants */ 73/* Magic constants */
75#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */ 74#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */
@@ -84,14 +83,20 @@ static unsigned short triggered; /* The status of the watchdog upon boot */
84static char esb_expect_close; 83static char esb_expect_close;
85 84
86/* module parameters */ 85/* module parameters */
87#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (1<heartbeat<2*1023) */ 86/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
87#define WATCHDOG_HEARTBEAT 30
88static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 88static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
89
89module_param(heartbeat, int, 0); 90module_param(heartbeat, int, 0);
90MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 91MODULE_PARM_DESC(heartbeat,
92 "Watchdog heartbeat in seconds. (1<heartbeat<2046, default="
93 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
91 94
92static int nowayout = WATCHDOG_NOWAYOUT; 95static int nowayout = WATCHDOG_NOWAYOUT;
93module_param(nowayout, int, 0); 96module_param(nowayout, int, 0);
94MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 97MODULE_PARM_DESC(nowayout,
98 "Watchdog cannot be stopped once started (default="
99 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
95 100
96/* 101/*
97 * Some i6300ESB specific functions 102 * Some i6300ESB specific functions
@@ -103,9 +108,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _
103 * reload register. After this the appropriate registers can be written 108 * reload register. After this the appropriate registers can be written
104 * to once before they need to be unlocked again. 109 * to once before they need to be unlocked again.
105 */ 110 */
106static inline void esb_unlock_registers(void) { 111static inline void esb_unlock_registers(void)
107 writeb(ESB_UNLOCK1, ESB_RELOAD_REG); 112{
108 writeb(ESB_UNLOCK2, ESB_RELOAD_REG); 113 writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
114 writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
109} 115}
110 116
111static void esb_timer_start(void) 117static void esb_timer_start(void)
@@ -114,8 +120,7 @@ static void esb_timer_start(void)
114 120
115 /* Enable or Enable + Lock? */ 121 /* Enable or Enable + Lock? */
116 val = 0x02 | (nowayout ? 0x01 : 0x00); 122 val = 0x02 | (nowayout ? 0x01 : 0x00);
117 123 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
118 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
119} 124}
120 125
121static int esb_timer_stop(void) 126static int esb_timer_stop(void)
@@ -140,7 +145,7 @@ static void esb_timer_keepalive(void)
140 spin_lock(&esb_lock); 145 spin_lock(&esb_lock);
141 esb_unlock_registers(); 146 esb_unlock_registers();
142 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 147 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
143 /* FIXME: Do we need to flush anything here? */ 148 /* FIXME: Do we need to flush anything here? */
144 spin_unlock(&esb_lock); 149 spin_unlock(&esb_lock);
145} 150}
146 151
@@ -165,9 +170,9 @@ static int esb_timer_set_heartbeat(int time)
165 170
166 /* Write timer 2 */ 171 /* Write timer 2 */
167 esb_unlock_registers(); 172 esb_unlock_registers();
168 writel(val, ESB_TIMER2_REG); 173 writel(val, ESB_TIMER2_REG);
169 174
170 /* Reload */ 175 /* Reload */
171 esb_unlock_registers(); 176 esb_unlock_registers();
172 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG); 177 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
173 178
@@ -179,54 +184,55 @@ static int esb_timer_set_heartbeat(int time)
179 return 0; 184 return 0;
180} 185}
181 186
182static int esb_timer_read (void) 187static int esb_timer_read(void)
183{ 188{
184 u32 count; 189 u32 count;
185 190
186 /* This isn't documented, and doesn't take into 191 /* This isn't documented, and doesn't take into
187 * acount which stage is running, but it looks 192 * acount which stage is running, but it looks
188 * like a 20 bit count down, so we might as well report it. 193 * like a 20 bit count down, so we might as well report it.
189 */ 194 */
190 pci_read_config_dword(esb_pci, 0x64, &count); 195 pci_read_config_dword(esb_pci, 0x64, &count);
191 return (int)count; 196 return (int)count;
192} 197}
193 198
194/* 199/*
195 * /dev/watchdog handling 200 * /dev/watchdog handling
196 */ 201 */
197 202
198static int esb_open (struct inode *inode, struct file *file) 203static int esb_open(struct inode *inode, struct file *file)
199{ 204{
200 /* /dev/watchdog can only be opened once */ 205 /* /dev/watchdog can only be opened once */
201 if (test_and_set_bit(0, &timer_alive)) 206 if (test_and_set_bit(0, &timer_alive))
202 return -EBUSY; 207 return -EBUSY;
203 208
204 /* Reload and activate timer */ 209 /* Reload and activate timer */
205 esb_timer_keepalive (); 210 esb_timer_keepalive();
206 esb_timer_start (); 211 esb_timer_start();
207 212
208 return nonseekable_open(inode, file); 213 return nonseekable_open(inode, file);
209} 214}
210 215
211static int esb_release (struct inode *inode, struct file *file) 216static int esb_release(struct inode *inode, struct file *file)
212{ 217{
213 /* Shut off the timer. */ 218 /* Shut off the timer. */
214 if (esb_expect_close == 42) { 219 if (esb_expect_close == 42)
215 esb_timer_stop (); 220 esb_timer_stop();
216 } else { 221 else {
217 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 222 printk(KERN_CRIT PFX
218 esb_timer_keepalive (); 223 "Unexpected close, not stopping watchdog!\n");
219 } 224 esb_timer_keepalive();
220 clear_bit(0, &timer_alive); 225 }
221 esb_expect_close = 0; 226 clear_bit(0, &timer_alive);
222 return 0; 227 esb_expect_close = 0;
228 return 0;
223} 229}
224 230
225static ssize_t esb_write (struct file *file, const char __user *data, 231static ssize_t esb_write(struct file *file, const char __user *data,
226 size_t len, loff_t * ppos) 232 size_t len, loff_t *ppos)
227{ 233{
228 /* See if we got the magic character 'V' and reload the timer */ 234 /* See if we got the magic character 'V' and reload the timer */
229 if (len) { 235 if (len) {
230 if (!nowayout) { 236 if (!nowayout) {
231 size_t i; 237 size_t i;
232 238
@@ -237,7 +243,7 @@ static ssize_t esb_write (struct file *file, const char __user *data,
237 /* scan to see whether or not we got the magic character */ 243 /* scan to see whether or not we got the magic character */
238 for (i = 0; i != len; i++) { 244 for (i = 0; i != len; i++) {
239 char c; 245 char c;
240 if(get_user(c, data+i)) 246 if (get_user(c, data + i))
241 return -EFAULT; 247 return -EFAULT;
242 if (c == 'V') 248 if (c == 'V')
243 esb_expect_close = 42; 249 esb_expect_close = 42;
@@ -245,92 +251,84 @@ static ssize_t esb_write (struct file *file, const char __user *data,
245 } 251 }
246 252
247 /* someone wrote to us, we should reload the timer */ 253 /* someone wrote to us, we should reload the timer */
248 esb_timer_keepalive (); 254 esb_timer_keepalive();
249 } 255 }
250 return len; 256 return len;
251} 257}
252 258
253static int esb_ioctl (struct inode *inode, struct file *file, 259static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
254 unsigned int cmd, unsigned long arg)
255{ 260{
256 int new_options, retval = -EINVAL; 261 int new_options, retval = -EINVAL;
257 int new_heartbeat; 262 int new_heartbeat;
258 void __user *argp = (void __user *)arg; 263 void __user *argp = (void __user *)arg;
259 int __user *p = argp; 264 int __user *p = argp;
260 static struct watchdog_info ident = { 265 static struct watchdog_info ident = {
261 .options = WDIOF_SETTIMEOUT | 266 .options = WDIOF_SETTIMEOUT |
262 WDIOF_KEEPALIVEPING | 267 WDIOF_KEEPALIVEPING |
263 WDIOF_MAGICCLOSE, 268 WDIOF_MAGICCLOSE,
264 .firmware_version = 0, 269 .firmware_version = 0,
265 .identity = ESB_MODULE_NAME, 270 .identity = ESB_MODULE_NAME,
266 }; 271 };
267 272
268 switch (cmd) { 273 switch (cmd) {
269 case WDIOC_GETSUPPORT: 274 case WDIOC_GETSUPPORT:
270 return copy_to_user(argp, &ident, 275 return copy_to_user(argp, &ident,
271 sizeof (ident)) ? -EFAULT : 0; 276 sizeof(ident)) ? -EFAULT : 0;
272
273 case WDIOC_GETSTATUS:
274 return put_user (esb_timer_read(), p);
275
276 case WDIOC_GETBOOTSTATUS:
277 return put_user (triggered, p);
278 277
279 case WDIOC_KEEPALIVE: 278 case WDIOC_GETSTATUS:
280 esb_timer_keepalive (); 279 return put_user(esb_timer_read(), p);
281 return 0;
282 280
283 case WDIOC_SETOPTIONS: 281 case WDIOC_GETBOOTSTATUS:
284 { 282 return put_user(triggered, p);
285 if (get_user (new_options, p))
286 return -EFAULT;
287 283
288 if (new_options & WDIOS_DISABLECARD) { 284 case WDIOC_SETOPTIONS:
289 esb_timer_stop (); 285 {
290 retval = 0; 286 if (get_user(new_options, p))
291 } 287 return -EFAULT;
292 288
293 if (new_options & WDIOS_ENABLECARD) { 289 if (new_options & WDIOS_DISABLECARD) {
294 esb_timer_keepalive (); 290 esb_timer_stop();
295 esb_timer_start (); 291 retval = 0;
296 retval = 0; 292 }
297 }
298
299 return retval;
300 }
301
302 case WDIOC_SETTIMEOUT:
303 {
304 if (get_user(new_heartbeat, p))
305 return -EFAULT;
306
307 if (esb_timer_set_heartbeat(new_heartbeat))
308 return -EINVAL;
309
310 esb_timer_keepalive ();
311 /* Fall */
312 }
313
314 case WDIOC_GETTIMEOUT:
315 return put_user(heartbeat, p);
316 293
317 default: 294 if (new_options & WDIOS_ENABLECARD) {
318 return -ENOTTY; 295 esb_timer_keepalive();
319 } 296 esb_timer_start();
297 retval = 0;
298 }
299 return retval;
300 }
301 case WDIOC_KEEPALIVE:
302 esb_timer_keepalive();
303 return 0;
304
305 case WDIOC_SETTIMEOUT:
306 {
307 if (get_user(new_heartbeat, p))
308 return -EFAULT;
309 if (esb_timer_set_heartbeat(new_heartbeat))
310 return -EINVAL;
311 esb_timer_keepalive();
312 /* Fall */
313 }
314 case WDIOC_GETTIMEOUT:
315 return put_user(heartbeat, p);
316 default:
317 return -ENOTTY;
318 }
320} 319}
321 320
322/* 321/*
323 * Notify system 322 * Notify system
324 */ 323 */
325 324
326static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused) 325static int esb_notify_sys(struct notifier_block *this,
326 unsigned long code, void *unused)
327{ 327{
328 if (code==SYS_DOWN || code==SYS_HALT) { 328 if (code == SYS_DOWN || code == SYS_HALT)
329 /* Turn the WDT off */ 329 esb_timer_stop(); /* Turn the WDT off */
330 esb_timer_stop ();
331 }
332 330
333 return NOTIFY_DONE; 331 return NOTIFY_DONE;
334} 332}
335 333
336/* 334/*
@@ -338,22 +336,22 @@ static int esb_notify_sys (struct notifier_block *this, unsigned long code, void
338 */ 336 */
339 337
340static const struct file_operations esb_fops = { 338static const struct file_operations esb_fops = {
341 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
342 .llseek = no_llseek, 340 .llseek = no_llseek,
343 .write = esb_write, 341 .write = esb_write,
344 .ioctl = esb_ioctl, 342 .unlocked_ioctl = esb_ioctl,
345 .open = esb_open, 343 .open = esb_open,
346 .release = esb_release, 344 .release = esb_release,
347}; 345};
348 346
349static struct miscdevice esb_miscdev = { 347static struct miscdevice esb_miscdev = {
350 .minor = WATCHDOG_MINOR, 348 .minor = WATCHDOG_MINOR,
351 .name = "watchdog", 349 .name = "watchdog",
352 .fops = &esb_fops, 350 .fops = &esb_fops,
353}; 351};
354 352
355static struct notifier_block esb_notifier = { 353static struct notifier_block esb_notifier = {
356 .notifier_call = esb_notify_sys, 354 .notifier_call = esb_notify_sys,
357}; 355};
358 356
359/* 357/*
@@ -365,50 +363,44 @@ static struct notifier_block esb_notifier = {
365 * want to register another driver on the same PCI id. 363 * want to register another driver on the same PCI id.
366 */ 364 */
367static struct pci_device_id esb_pci_tbl[] = { 365static struct pci_device_id esb_pci_tbl[] = {
368 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, 366 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
369 { 0, }, /* End of list */ 367 { 0, }, /* End of list */
370}; 368};
371MODULE_DEVICE_TABLE (pci, esb_pci_tbl); 369MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
372 370
373/* 371/*
374 * Init & exit routines 372 * Init & exit routines
375 */ 373 */
376 374
377static unsigned char __init esb_getdevice (void) 375static unsigned char __init esb_getdevice(void)
378{ 376{
379 u8 val1; 377 u8 val1;
380 unsigned short val2; 378 unsigned short val2;
379 /*
380 * Find the PCI device
381 */
381 382
382 struct pci_dev *dev = NULL; 383 esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
383 /* 384 PCI_DEVICE_ID_INTEL_ESB_9, NULL);
384 * Find the PCI device
385 */
386
387 for_each_pci_dev(dev) {
388 if (pci_match_id(esb_pci_tbl, dev)) {
389 esb_pci = dev;
390 break;
391 }
392 }
393 385
394 if (esb_pci) { 386 if (esb_pci) {
395 if (pci_enable_device(esb_pci)) { 387 if (pci_enable_device(esb_pci)) {
396 printk (KERN_ERR PFX "failed to enable device\n"); 388 printk(KERN_ERR PFX "failed to enable device\n");
397 goto err_devput; 389 goto err_devput;
398 } 390 }
399 391
400 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { 392 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
401 printk (KERN_ERR PFX "failed to request region\n"); 393 printk(KERN_ERR PFX "failed to request region\n");
402 goto err_disable; 394 goto err_disable;
403 } 395 }
404 396
405 BASEADDR = ioremap(pci_resource_start(esb_pci, 0), 397 BASEADDR = ioremap(pci_resource_start(esb_pci, 0),
406 pci_resource_len(esb_pci, 0)); 398 pci_resource_len(esb_pci, 0));
407 if (BASEADDR == NULL) { 399 if (BASEADDR == NULL) {
408 /* Something's wrong here, BASEADDR has to be set */ 400 /* Something's wrong here, BASEADDR has to be set */
409 printk (KERN_ERR PFX "failed to get BASEADDR\n"); 401 printk(KERN_ERR PFX "failed to get BASEADDR\n");
410 goto err_release; 402 goto err_release;
411 } 403 }
412 404
413 /* 405 /*
414 * The watchdog has two timers, it can be setup so that the 406 * The watchdog has two timers, it can be setup so that the
@@ -425,7 +417,7 @@ static unsigned char __init esb_getdevice (void)
425 /* Check that the WDT isn't already locked */ 417 /* Check that the WDT isn't already locked */
426 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); 418 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
427 if (val1 & ESB_WDT_LOCK) 419 if (val1 & ESB_WDT_LOCK)
428 printk (KERN_WARNING PFX "nowayout already set\n"); 420 printk(KERN_WARNING PFX "nowayout already set\n");
429 421
430 /* Set the timer to watchdog mode and disable it for now */ 422 /* Set the timer to watchdog mode and disable it for now */
431 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); 423 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
@@ -452,44 +444,44 @@ err_devput:
452 return 0; 444 return 0;
453} 445}
454 446
455static int __init watchdog_init (void) 447static int __init watchdog_init(void)
456{ 448{
457 int ret; 449 int ret;
458 450
459 /* Check whether or not the hardware watchdog is there */ 451 /* Check whether or not the hardware watchdog is there */
460 if (!esb_getdevice () || esb_pci == NULL) 452 if (!esb_getdevice() || esb_pci == NULL)
461 return -ENODEV; 453 return -ENODEV;
462 454
463 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 455 /* Check that the heartbeat value is within it's range;
464 if (esb_timer_set_heartbeat (heartbeat)) { 456 if not reset to the default */
465 esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT); 457 if (esb_timer_set_heartbeat(heartbeat)) {
466 printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n", 458 esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT);
467 heartbeat); 459 printk(KERN_INFO PFX
468 } 460 "heartbeat value must be 1<heartbeat<2046, using %d\n",
469 461 heartbeat);
470 ret = register_reboot_notifier(&esb_notifier); 462 }
471 if (ret != 0) { 463 ret = register_reboot_notifier(&esb_notifier);
472 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 464 if (ret != 0) {
473 ret); 465 printk(KERN_ERR PFX
474 goto err_unmap; 466 "cannot register reboot notifier (err=%d)\n", ret);
475 } 467 goto err_unmap;
476 468 }
477 ret = misc_register(&esb_miscdev);
478 if (ret != 0) {
479 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
480 WATCHDOG_MINOR, ret);
481 goto err_notifier;
482 }
483
484 esb_timer_stop ();
485
486 printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
487 BASEADDR, heartbeat, nowayout);
488 469
489 return 0; 470 ret = misc_register(&esb_miscdev);
471 if (ret != 0) {
472 printk(KERN_ERR PFX
473 "cannot register miscdev on minor=%d (err=%d)\n",
474 WATCHDOG_MINOR, ret);
475 goto err_notifier;
476 }
477 esb_timer_stop();
478 printk(KERN_INFO PFX
479 "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
480 BASEADDR, heartbeat, nowayout);
481 return 0;
490 482
491err_notifier: 483err_notifier:
492 unregister_reboot_notifier(&esb_notifier); 484 unregister_reboot_notifier(&esb_notifier);
493err_unmap: 485err_unmap:
494 iounmap(BASEADDR); 486 iounmap(BASEADDR);
495/* err_release: */ 487/* err_release: */
@@ -498,18 +490,18 @@ err_unmap:
498 pci_disable_device(esb_pci); 490 pci_disable_device(esb_pci);
499/* err_devput: */ 491/* err_devput: */
500 pci_dev_put(esb_pci); 492 pci_dev_put(esb_pci);
501 return ret; 493 return ret;
502} 494}
503 495
504static void __exit watchdog_cleanup (void) 496static void __exit watchdog_cleanup(void)
505{ 497{
506 /* Stop the timer before we leave */ 498 /* Stop the timer before we leave */
507 if (!nowayout) 499 if (!nowayout)
508 esb_timer_stop (); 500 esb_timer_stop();
509 501
510 /* Deregister */ 502 /* Deregister */
511 misc_deregister(&esb_miscdev); 503 misc_deregister(&esb_miscdev);
512 unregister_reboot_notifier(&esb_notifier); 504 unregister_reboot_notifier(&esb_notifier);
513 iounmap(BASEADDR); 505 iounmap(BASEADDR);
514 pci_release_region(esb_pci, 0); 506 pci_release_region(esb_pci, 0);
515 pci_disable_device(esb_pci); 507 pci_disable_device(esb_pci);
diff --git a/drivers/watchdog/iTCO_vendor.h b/drivers/watchdog/iTCO_vendor.h
new file mode 100644
index 000000000000..9e27e6422f66
--- /dev/null
+++ b/drivers/watchdog/iTCO_vendor.h
@@ -0,0 +1,15 @@
1/* iTCO Vendor Specific Support hooks */
2#ifdef CONFIG_ITCO_VENDOR_SUPPORT
3extern void iTCO_vendor_pre_start(unsigned long, unsigned int);
4extern void iTCO_vendor_pre_stop(unsigned long);
5extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int);
6extern void iTCO_vendor_pre_set_heartbeat(unsigned int);
7extern int iTCO_vendor_check_noreboot_on(void);
8#else
9#define iTCO_vendor_pre_start(acpibase, heartbeat) {}
10#define iTCO_vendor_pre_stop(acpibase) {}
11#define iTCO_vendor_pre_keepalive(acpibase, heartbeat) {}
12#define iTCO_vendor_pre_set_heartbeat(heartbeat) {}
13#define iTCO_vendor_check_noreboot_on() 1
14 /* 1=check noreboot; 0=don't check */
15#endif
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index cafc465f2ae3..ca344a85eb95 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -18,9 +18,9 @@
18 */ 18 */
19 19
20/* Module and version information */ 20/* Module and version information */
21#define DRV_NAME "iTCO_vendor_support" 21#define DRV_NAME "iTCO_vendor_support"
22#define DRV_VERSION "1.01" 22#define DRV_VERSION "1.01"
23#define DRV_RELDATE "11-Nov-2006" 23#define DRV_RELDATE "11-Nov-2006"
24#define PFX DRV_NAME ": " 24#define PFX DRV_NAME ": "
25 25
26/* Includes */ 26/* Includes */
@@ -31,19 +31,22 @@
31#include <linux/kernel.h> /* For printk/panic/... */ 31#include <linux/kernel.h> /* For printk/panic/... */
32#include <linux/init.h> /* For __init/__exit/... */ 32#include <linux/init.h> /* For __init/__exit/... */
33#include <linux/ioport.h> /* For io-port access */ 33#include <linux/ioport.h> /* For io-port access */
34#include <linux/io.h> /* For inb/outb/... */
34 35
35#include <asm/io.h> /* For inb/outb/... */ 36#include "iTCO_vendor.h"
36 37
37/* iTCO defines */ 38/* iTCO defines */
38#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */ 39#define SMI_EN acpibase + 0x30 /* SMI Control and Enable Register */
39#define TCOBASE acpibase + 0x60 /* TCO base address */ 40#define TCOBASE acpibase + 0x60 /* TCO base address */
40#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ 41#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */
41 42
42/* List of vendor support modes */ 43/* List of vendor support modes */
43#define SUPERMICRO_OLD_BOARD 1 /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ 44/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */
44#define SUPERMICRO_NEW_BOARD 2 /* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */ 45#define SUPERMICRO_OLD_BOARD 1
46/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems */
47#define SUPERMICRO_NEW_BOARD 2
45 48
46static int vendorsupport = 0; 49static int vendorsupport;
47module_param(vendorsupport, int, 0); 50module_param(vendorsupport, int, 0);
48MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+"); 51MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (none), 1=SuperMicro Pent3, 2=SuperMicro Pent4+");
49 52
@@ -143,34 +146,35 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase)
143 */ 146 */
144 147
145/* I/O Port's */ 148/* I/O Port's */
146#define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */ 149#define SM_REGINDEX 0x2e /* SuperMicro ICH4+ Register Index */
147#define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */ 150#define SM_DATAIO 0x2f /* SuperMicro ICH4+ Register Data I/O */
148 151
149/* Control Register's */ 152/* Control Register's */
150#define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */ 153#define SM_CTLPAGESW 0x07 /* SuperMicro ICH4+ Control Page Switch */
151#define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */ 154#define SM_CTLPAGE 0x08 /* SuperMicro ICH4+ Control Page Num */
152 155
153#define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */ 156#define SM_WATCHENABLE 0x30 /* Watchdog enable: Bit 0: 0=off, 1=on */
154 157
155#define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */ 158#define SM_WATCHPAGE 0x87 /* Watchdog unlock control page */
156 159
157#define SM_ENDWATCH 0xAA /* Watchdog lock control page */ 160#define SM_ENDWATCH 0xAA /* Watchdog lock control page */
158 161
159#define SM_COUNTMODE 0xf5 /* Watchdog count mode select */ 162#define SM_COUNTMODE 0xf5 /* Watchdog count mode select */
160 /* (Bit 3: 0 = seconds, 1 = minutes */ 163 /* (Bit 3: 0 = seconds, 1 = minutes */
161 164
162#define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */ 165#define SM_WATCHTIMER 0xf6 /* 8-bits, Watchdog timer counter (RW) */
163 166
164#define SM_RESETCONTROL 0xf7 /* Watchdog reset control */ 167#define SM_RESETCONTROL 0xf7 /* Watchdog reset control */
165 /* Bit 6: timer is reset by kbd interrupt */ 168 /* Bit 6: timer is reset by kbd interrupt */
166 /* Bit 7: timer is reset by mouse interrupt */ 169 /* Bit 7: timer is reset by mouse interrupt */
167 170
168static void supermicro_new_unlock_watchdog(void) 171static void supermicro_new_unlock_watchdog(void)
169{ 172{
170 outb(SM_WATCHPAGE, SM_REGINDEX); /* Write 0x87 to port 0x2e twice */ 173 /* Write 0x87 to port 0x2e twice */
171 outb(SM_WATCHPAGE, SM_REGINDEX); 174 outb(SM_WATCHPAGE, SM_REGINDEX);
172 175 outb(SM_WATCHPAGE, SM_REGINDEX);
173 outb(SM_CTLPAGESW, SM_REGINDEX); /* Switch to watchdog control page */ 176 /* Switch to watchdog control page */
177 outb(SM_CTLPAGESW, SM_REGINDEX);
174 outb(SM_CTLPAGE, SM_DATAIO); 178 outb(SM_CTLPAGE, SM_DATAIO);
175} 179}
176 180
@@ -192,7 +196,7 @@ static void supermicro_new_pre_start(unsigned int heartbeat)
192 outb(val, SM_DATAIO); 196 outb(val, SM_DATAIO);
193 197
194 /* Write heartbeat interval to WDOG */ 198 /* Write heartbeat interval to WDOG */
195 outb (SM_WATCHTIMER, SM_REGINDEX); 199 outb(SM_WATCHTIMER, SM_REGINDEX);
196 outb((heartbeat & 255), SM_DATAIO); 200 outb((heartbeat & 255), SM_DATAIO);
197 201
198 /* Make sure keyboard/mouse interrupts don't interfere */ 202 /* Make sure keyboard/mouse interrupts don't interfere */
@@ -277,7 +281,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_set_heartbeat);
277 281
278int iTCO_vendor_check_noreboot_on(void) 282int iTCO_vendor_check_noreboot_on(void)
279{ 283{
280 switch(vendorsupport) { 284 switch (vendorsupport) {
281 case SUPERMICRO_OLD_BOARD: 285 case SUPERMICRO_OLD_BOARD:
282 return 0; 286 return 0;
283 default: 287 default:
@@ -288,13 +292,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on);
288 292
289static int __init iTCO_vendor_init_module(void) 293static int __init iTCO_vendor_init_module(void)
290{ 294{
291 printk (KERN_INFO PFX "vendor-support=%d\n", vendorsupport); 295 printk(KERN_INFO PFX "vendor-support=%d\n", vendorsupport);
292 return 0; 296 return 0;
293} 297}
294 298
295static void __exit iTCO_vendor_exit_module(void) 299static void __exit iTCO_vendor_exit_module(void)
296{ 300{
297 printk (KERN_INFO PFX "Module Unloaded\n"); 301 printk(KERN_INFO PFX "Module Unloaded\n");
298} 302}
299 303
300module_init(iTCO_vendor_init_module); 304module_init(iTCO_vendor_init_module);
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 95ba985bd341..bfb93bc2ca9f 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -55,9 +55,9 @@
55 */ 55 */
56 56
57/* Module and version information */ 57/* Module and version information */
58#define DRV_NAME "iTCO_wdt" 58#define DRV_NAME "iTCO_wdt"
59#define DRV_VERSION "1.03" 59#define DRV_VERSION "1.03"
60#define DRV_RELDATE "30-Apr-2008" 60#define DRV_RELDATE "30-Apr-2008"
61#define PFX DRV_NAME ": " 61#define PFX DRV_NAME ": "
62 62
63/* Includes */ 63/* Includes */
@@ -66,7 +66,8 @@
66#include <linux/types.h> /* For standard types (like size_t) */ 66#include <linux/types.h> /* For standard types (like size_t) */
67#include <linux/errno.h> /* For the -ENODEV/... values */ 67#include <linux/errno.h> /* For the -ENODEV/... values */
68#include <linux/kernel.h> /* For printk/panic/... */ 68#include <linux/kernel.h> /* For printk/panic/... */
69#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ 69#include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV
70 (WATCHDOG_MINOR) */
70#include <linux/watchdog.h> /* For the watchdog specific items */ 71#include <linux/watchdog.h> /* For the watchdog specific items */
71#include <linux/init.h> /* For __init/__exit/... */ 72#include <linux/init.h> /* For __init/__exit/... */
72#include <linux/fs.h> /* For file operations */ 73#include <linux/fs.h> /* For file operations */
@@ -74,9 +75,10 @@
74#include <linux/pci.h> /* For pci functions */ 75#include <linux/pci.h> /* For pci functions */
75#include <linux/ioport.h> /* For io-port access */ 76#include <linux/ioport.h> /* For io-port access */
76#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 77#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
78#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
79#include <linux/io.h> /* For inb/outb/... */
77 80
78#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 81#include "iTCO_vendor.h"
79#include <asm/io.h> /* For inb/outb/... */
80 82
81/* TCO related info */ 83/* TCO related info */
82enum iTCO_chipsets { 84enum iTCO_chipsets {
@@ -105,7 +107,7 @@ enum iTCO_chipsets {
105 TCO_ICH9, /* ICH9 */ 107 TCO_ICH9, /* ICH9 */
106 TCO_ICH9R, /* ICH9R */ 108 TCO_ICH9R, /* ICH9R */
107 TCO_ICH9DH, /* ICH9DH */ 109 TCO_ICH9DH, /* ICH9DH */
108 TCO_ICH9DO, /* ICH9DO */ 110 TCO_ICH9DO, /* ICH9DO */
109 TCO_631XESB, /* 631xESB/632xESB */ 111 TCO_631XESB, /* 631xESB/632xESB */
110}; 112};
111 113
@@ -140,7 +142,7 @@ static struct {
140 {"ICH9DH", 2}, 142 {"ICH9DH", 2},
141 {"ICH9DO", 2}, 143 {"ICH9DO", 2},
142 {"631xESB/632xESB", 2}, 144 {"631xESB/632xESB", 2},
143 {NULL,0} 145 {NULL, 0}
144}; 146};
145 147
146#define ITCO_PCI_DEVICE(dev, data) \ 148#define ITCO_PCI_DEVICE(dev, data) \
@@ -159,32 +161,32 @@ static struct {
159 * functions that probably will be registered by other drivers. 161 * functions that probably will be registered by other drivers.
160 */ 162 */
161static struct pci_device_id iTCO_wdt_pci_tbl[] = { 163static struct pci_device_id iTCO_wdt_pci_tbl[] = {
162 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH )}, 164 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AA_0, TCO_ICH)},
163 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0 )}, 165 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801AB_0, TCO_ICH0)},
164 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2 )}, 166 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_0, TCO_ICH2)},
165 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M )}, 167 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801BA_10, TCO_ICH2M)},
166 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3 )}, 168 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_0, TCO_ICH3)},
167 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M )}, 169 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801CA_12, TCO_ICH3M)},
168 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4 )}, 170 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_0, TCO_ICH4)},
169 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M )}, 171 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801DB_12, TCO_ICH4M)},
170 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH )}, 172 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801E_0, TCO_CICH)},
171 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5 )}, 173 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_82801EB_0, TCO_ICH5)},
172 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)}, 174 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB_1, TCO_6300ESB)},
173 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6 )}, 175 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_0, TCO_ICH6)},
174 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M )}, 176 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_1, TCO_ICH6M)},
175 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W )}, 177 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH6_2, TCO_ICH6W)},
176 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7 )}, 178 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_0, TCO_ICH7)},
177 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M )}, 179 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_1, TCO_ICH7M)},
178 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)}, 180 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH7_31, TCO_ICH7MDH)},
179 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8 )}, 181 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_0, TCO_ICH8)},
180 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME )}, 182 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_1, TCO_ICH8ME)},
181 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH )}, 183 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_2, TCO_ICH8DH)},
182 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO )}, 184 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_3, TCO_ICH8DO)},
183 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M )}, 185 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH8_4, TCO_ICH8M)},
184 { ITCO_PCI_DEVICE(0x2918, TCO_ICH9 )}, 186 { ITCO_PCI_DEVICE(0x2918, TCO_ICH9)},
185 { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R )}, 187 { ITCO_PCI_DEVICE(0x2916, TCO_ICH9R)},
186 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH )}, 188 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_2, TCO_ICH9DH)},
187 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO )}, 189 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ICH9_4, TCO_ICH9DO)},
188 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)}, 190 { ITCO_PCI_DEVICE(PCI_DEVICE_ID_INTEL_ESB2_0, TCO_631XESB)},
189 { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)}, 191 { ITCO_PCI_DEVICE(0x2671, TCO_631XESB)},
190 { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)}, 192 { ITCO_PCI_DEVICE(0x2672, TCO_631XESB)},
@@ -203,13 +205,15 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
203 { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)}, 205 { ITCO_PCI_DEVICE(0x267f, TCO_631XESB)},
204 { 0, }, /* End of list */ 206 { 0, }, /* End of list */
205}; 207};
206MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl); 208MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl);
207 209
208/* Address definitions for the TCO */ 210/* Address definitions for the TCO */
209#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* TCO base address */ 211/* TCO base address */
210#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 /* SMI Control and Enable Register */ 212#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60
213/* SMI Control and Enable Register */
214#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30
211 215
212#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Current Value */ 216#define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */
213#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ 217#define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */
214#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ 218#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */
215#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ 219#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */
@@ -222,15 +226,21 @@ MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);
222/* internal variables */ 226/* internal variables */
223static unsigned long is_active; 227static unsigned long is_active;
224static char expect_release; 228static char expect_release;
225static struct { /* this is private data for the iTCO_wdt device */ 229static struct { /* this is private data for the iTCO_wdt device */
226 unsigned int iTCO_version; /* TCO version/generation */ 230 /* TCO version/generation */
227 unsigned long ACPIBASE; /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ 231 unsigned int iTCO_version;
228 unsigned long __iomem *gcs; /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2) */ 232 /* The cards ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
229 spinlock_t io_lock; /* the lock for io operations */ 233 unsigned long ACPIBASE;
230 struct pci_dev *pdev; /* the PCI-device */ 234 /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
235 unsigned long __iomem *gcs;
236 /* the lock for io operations */
237 spinlock_t io_lock;
238 /* the PCI-device */
239 struct pci_dev *pdev;
231} iTCO_wdt_private; 240} iTCO_wdt_private;
232 241
233static struct platform_device *iTCO_wdt_platform_device; /* the watchdog platform device */ 242/* the watchdog platform device */
243static struct platform_device *iTCO_wdt_platform_device;
234 244
235/* module parameters */ 245/* module parameters */
236#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 246#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
@@ -240,22 +250,9 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO
240 250
241static int nowayout = WATCHDOG_NOWAYOUT; 251static int nowayout = WATCHDOG_NOWAYOUT;
242module_param(nowayout, int, 0); 252module_param(nowayout, int, 0);
243MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 253MODULE_PARM_DESC(nowayout,
244 254 "Watchdog cannot be stopped once started (default="
245/* iTCO Vendor Specific Support hooks */ 255 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
246#ifdef CONFIG_ITCO_VENDOR_SUPPORT
247extern void iTCO_vendor_pre_start(unsigned long, unsigned int);
248extern void iTCO_vendor_pre_stop(unsigned long);
249extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int);
250extern void iTCO_vendor_pre_set_heartbeat(unsigned int);
251extern int iTCO_vendor_check_noreboot_on(void);
252#else
253#define iTCO_vendor_pre_start(acpibase, heartbeat) {}
254#define iTCO_vendor_pre_stop(acpibase) {}
255#define iTCO_vendor_pre_keepalive(acpibase,heartbeat) {}
256#define iTCO_vendor_pre_set_heartbeat(heartbeat) {}
257#define iTCO_vendor_check_noreboot_on() 1 /* 1=check noreboot; 0=don't check */
258#endif
259 256
260/* 257/*
261 * Some TCO specific functions 258 * Some TCO specific functions
@@ -369,11 +366,10 @@ static int iTCO_wdt_keepalive(void)
369 iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); 366 iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat);
370 367
371 /* Reload the timer by writing to the TCO Timer Counter register */ 368 /* Reload the timer by writing to the TCO Timer Counter register */
372 if (iTCO_wdt_private.iTCO_version == 2) { 369 if (iTCO_wdt_private.iTCO_version == 2)
373 outw(0x01, TCO_RLD); 370 outw(0x01, TCO_RLD);
374 } else if (iTCO_wdt_private.iTCO_version == 1) { 371 else if (iTCO_wdt_private.iTCO_version == 1)
375 outb(0x01, TCO_RLD); 372 outb(0x01, TCO_RLD);
376 }
377 373
378 spin_unlock(&iTCO_wdt_private.io_lock); 374 spin_unlock(&iTCO_wdt_private.io_lock);
379 return 0; 375 return 0;
@@ -425,7 +421,7 @@ static int iTCO_wdt_set_heartbeat(int t)
425 return 0; 421 return 0;
426} 422}
427 423
428static int iTCO_wdt_get_timeleft (int *time_left) 424static int iTCO_wdt_get_timeleft(int *time_left)
429{ 425{
430 unsigned int val16; 426 unsigned int val16;
431 unsigned char val8; 427 unsigned char val8;
@@ -454,7 +450,7 @@ static int iTCO_wdt_get_timeleft (int *time_left)
454 * /dev/watchdog handling 450 * /dev/watchdog handling
455 */ 451 */
456 452
457static int iTCO_wdt_open (struct inode *inode, struct file *file) 453static int iTCO_wdt_open(struct inode *inode, struct file *file)
458{ 454{
459 /* /dev/watchdog can only be opened once */ 455 /* /dev/watchdog can only be opened once */
460 if (test_and_set_bit(0, &is_active)) 456 if (test_and_set_bit(0, &is_active))
@@ -468,7 +464,7 @@ static int iTCO_wdt_open (struct inode *inode, struct file *file)
468 return nonseekable_open(inode, file); 464 return nonseekable_open(inode, file);
469} 465}
470 466
471static int iTCO_wdt_release (struct inode *inode, struct file *file) 467static int iTCO_wdt_release(struct inode *inode, struct file *file)
472{ 468{
473 /* 469 /*
474 * Shut off the timer. 470 * Shut off the timer.
@@ -476,7 +472,8 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file)
476 if (expect_release == 42) { 472 if (expect_release == 42) {
477 iTCO_wdt_stop(); 473 iTCO_wdt_stop();
478 } else { 474 } else {
479 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 475 printk(KERN_CRIT PFX
476 "Unexpected close, not stopping watchdog!\n");
480 iTCO_wdt_keepalive(); 477 iTCO_wdt_keepalive();
481 } 478 }
482 clear_bit(0, &is_active); 479 clear_bit(0, &is_active);
@@ -484,22 +481,23 @@ static int iTCO_wdt_release (struct inode *inode, struct file *file)
484 return 0; 481 return 0;
485} 482}
486 483
487static ssize_t iTCO_wdt_write (struct file *file, const char __user *data, 484static ssize_t iTCO_wdt_write(struct file *file, const char __user *data,
488 size_t len, loff_t * ppos) 485 size_t len, loff_t *ppos)
489{ 486{
490 /* See if we got the magic character 'V' and reload the timer */ 487 /* See if we got the magic character 'V' and reload the timer */
491 if (len) { 488 if (len) {
492 if (!nowayout) { 489 if (!nowayout) {
493 size_t i; 490 size_t i;
494 491
495 /* note: just in case someone wrote the magic character 492 /* note: just in case someone wrote the magic
496 * five months ago... */ 493 character five months ago... */
497 expect_release = 0; 494 expect_release = 0;
498 495
499 /* scan to see whether or not we got the magic character */ 496 /* scan to see whether or not we got the
497 magic character */
500 for (i = 0; i != len; i++) { 498 for (i = 0; i != len; i++) {
501 char c; 499 char c;
502 if (get_user(c, data+i)) 500 if (get_user(c, data + i))
503 return -EFAULT; 501 return -EFAULT;
504 if (c == 'V') 502 if (c == 'V')
505 expect_release = 42; 503 expect_release = 42;
@@ -512,8 +510,8 @@ static ssize_t iTCO_wdt_write (struct file *file, const char __user *data,
512 return len; 510 return len;
513} 511}
514 512
515static int iTCO_wdt_ioctl (struct inode *inode, struct file *file, 513static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
516 unsigned int cmd, unsigned long arg) 514 unsigned long arg)
517{ 515{
518 int new_options, retval = -EINVAL; 516 int new_options, retval = -EINVAL;
519 int new_heartbeat; 517 int new_heartbeat;
@@ -528,64 +526,52 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
528 }; 526 };
529 527
530 switch (cmd) { 528 switch (cmd) {
531 case WDIOC_GETSUPPORT: 529 case WDIOC_GETSUPPORT:
532 return copy_to_user(argp, &ident, 530 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
533 sizeof (ident)) ? -EFAULT : 0; 531 case WDIOC_GETSTATUS:
534 532 case WDIOC_GETBOOTSTATUS:
535 case WDIOC_GETSTATUS: 533 return put_user(0, p);
536 case WDIOC_GETBOOTSTATUS: 534
537 return put_user(0, p); 535 case WDIOC_SETOPTIONS:
538 536 {
539 case WDIOC_KEEPALIVE: 537 if (get_user(new_options, p))
540 iTCO_wdt_keepalive(); 538 return -EFAULT;
541 return 0; 539
542 540 if (new_options & WDIOS_DISABLECARD) {
543 case WDIOC_SETOPTIONS: 541 iTCO_wdt_stop();
544 { 542 retval = 0;
545 if (get_user(new_options, p))
546 return -EFAULT;
547
548 if (new_options & WDIOS_DISABLECARD) {
549 iTCO_wdt_stop();
550 retval = 0;
551 }
552
553 if (new_options & WDIOS_ENABLECARD) {
554 iTCO_wdt_keepalive();
555 iTCO_wdt_start();
556 retval = 0;
557 }
558
559 return retval;
560 } 543 }
561 544 if (new_options & WDIOS_ENABLECARD) {
562 case WDIOC_SETTIMEOUT:
563 {
564 if (get_user(new_heartbeat, p))
565 return -EFAULT;
566
567 if (iTCO_wdt_set_heartbeat(new_heartbeat))
568 return -EINVAL;
569
570 iTCO_wdt_keepalive(); 545 iTCO_wdt_keepalive();
571 /* Fall */ 546 iTCO_wdt_start();
572 } 547 retval = 0;
573
574 case WDIOC_GETTIMEOUT:
575 return put_user(heartbeat, p);
576
577 case WDIOC_GETTIMELEFT:
578 {
579 int time_left;
580
581 if (iTCO_wdt_get_timeleft(&time_left))
582 return -EINVAL;
583
584 return put_user(time_left, p);
585 } 548 }
549 return retval;
550 }
551 case WDIOC_KEEPALIVE:
552 iTCO_wdt_keepalive();
553 return 0;
586 554
587 default: 555 case WDIOC_SETTIMEOUT:
588 return -ENOTTY; 556 {
557 if (get_user(new_heartbeat, p))
558 return -EFAULT;
559 if (iTCO_wdt_set_heartbeat(new_heartbeat))
560 return -EINVAL;
561 iTCO_wdt_keepalive();
562 /* Fall */
563 }
564 case WDIOC_GETTIMEOUT:
565 return put_user(heartbeat, p);
566 case WDIOC_GETTIMELEFT:
567 {
568 int time_left;
569 if (iTCO_wdt_get_timeleft(&time_left))
570 return -EINVAL;
571 return put_user(time_left, p);
572 }
573 default:
574 return -ENOTTY;
589 } 575 }
590} 576}
591 577
@@ -594,12 +580,12 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
594 */ 580 */
595 581
596static const struct file_operations iTCO_wdt_fops = { 582static const struct file_operations iTCO_wdt_fops = {
597 .owner = THIS_MODULE, 583 .owner = THIS_MODULE,
598 .llseek = no_llseek, 584 .llseek = no_llseek,
599 .write = iTCO_wdt_write, 585 .write = iTCO_wdt_write,
600 .ioctl = iTCO_wdt_ioctl, 586 .unlocked_ioctl = iTCO_wdt_ioctl,
601 .open = iTCO_wdt_open, 587 .open = iTCO_wdt_open,
602 .release = iTCO_wdt_release, 588 .release = iTCO_wdt_release,
603}; 589};
604 590
605static struct miscdevice iTCO_wdt_miscdev = { 591static struct miscdevice iTCO_wdt_miscdev = {
@@ -612,7 +598,8 @@ static struct miscdevice iTCO_wdt_miscdev = {
612 * Init & exit routines 598 * Init & exit routines
613 */ 599 */
614 600
615static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent, struct platform_device *dev) 601static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
602 const struct pci_device_id *ent, struct platform_device *dev)
616{ 603{
617 int ret; 604 int ret;
618 u32 base_address; 605 u32 base_address;
@@ -632,17 +619,19 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
632 pci_dev_put(pdev); 619 pci_dev_put(pdev);
633 return -ENODEV; 620 return -ENODEV;
634 } 621 }
635 iTCO_wdt_private.iTCO_version = iTCO_chipset_info[ent->driver_data].iTCO_version; 622 iTCO_wdt_private.iTCO_version =
623 iTCO_chipset_info[ent->driver_data].iTCO_version;
636 iTCO_wdt_private.ACPIBASE = base_address; 624 iTCO_wdt_private.ACPIBASE = base_address;
637 iTCO_wdt_private.pdev = pdev; 625 iTCO_wdt_private.pdev = pdev;
638 626
639 /* Get the Memory-Mapped GCS register, we need it for the NO_REBOOT flag (TCO v2) */ 627 /* Get the Memory-Mapped GCS register, we need it for the
640 /* To get access to it you have to read RCBA from PCI Config space 0xf0 628 NO_REBOOT flag (TCO v2). To get access to it you have to
641 and use it as base. GCS = RCBA + ICH6_GCS(0x3410). */ 629 read RCBA from PCI Config space 0xf0 and use it as base.
630 GCS = RCBA + ICH6_GCS(0x3410). */
642 if (iTCO_wdt_private.iTCO_version == 2) { 631 if (iTCO_wdt_private.iTCO_version == 2) {
643 pci_read_config_dword(pdev, 0xf0, &base_address); 632 pci_read_config_dword(pdev, 0xf0, &base_address);
644 RCBA = base_address & 0xffffc000; 633 RCBA = base_address & 0xffffc000;
645 iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410),4); 634 iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4);
646 } 635 }
647 636
648 /* Check chipset's NO_REBOOT bit */ 637 /* Check chipset's NO_REBOOT bit */
@@ -657,8 +646,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
657 646
658 /* Set the TCO_EN bit in SMI_EN register */ 647 /* Set the TCO_EN bit in SMI_EN register */
659 if (!request_region(SMI_EN, 4, "iTCO_wdt")) { 648 if (!request_region(SMI_EN, 4, "iTCO_wdt")) {
660 printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", 649 printk(KERN_ERR PFX
661 SMI_EN ); 650 "I/O address 0x%04lx already in use\n", SMI_EN);
662 ret = -EIO; 651 ret = -EIO;
663 goto out; 652 goto out;
664 } 653 }
@@ -667,18 +656,20 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
667 outl(val32, SMI_EN); 656 outl(val32, SMI_EN);
668 release_region(SMI_EN, 4); 657 release_region(SMI_EN, 4);
669 658
670 /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ 659 /* The TCO I/O registers reside in a 32-byte range pointed to
671 if (!request_region (TCOBASE, 0x20, "iTCO_wdt")) { 660 by the TCOBASE value */
672 printk (KERN_ERR PFX "I/O address 0x%04lx already in use\n", 661 if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) {
662 printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n",
673 TCOBASE); 663 TCOBASE);
674 ret = -EIO; 664 ret = -EIO;
675 goto out; 665 goto out;
676 } 666 }
677 667
678 printk(KERN_INFO PFX "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", 668 printk(KERN_INFO PFX
679 iTCO_chipset_info[ent->driver_data].name, 669 "Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n",
680 iTCO_chipset_info[ent->driver_data].iTCO_version, 670 iTCO_chipset_info[ent->driver_data].name,
681 TCOBASE); 671 iTCO_chipset_info[ent->driver_data].iTCO_version,
672 TCOBASE);
682 673
683 /* Clear out the (probably old) status */ 674 /* Clear out the (probably old) status */
684 outb(0, TCO1_STS); 675 outb(0, TCO1_STS);
@@ -687,27 +678,29 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device
687 /* Make sure the watchdog is not running */ 678 /* Make sure the watchdog is not running */
688 iTCO_wdt_stop(); 679 iTCO_wdt_stop();
689 680
690 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 681 /* Check that the heartbeat value is within it's range;
682 if not reset to the default */
691 if (iTCO_wdt_set_heartbeat(heartbeat)) { 683 if (iTCO_wdt_set_heartbeat(heartbeat)) {
692 iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT); 684 iTCO_wdt_set_heartbeat(WATCHDOG_HEARTBEAT);
693 printk(KERN_INFO PFX "heartbeat value must be 2<heartbeat<39 (TCO v1) or 613 (TCO v2), using %d\n", 685 printk(KERN_INFO PFX "heartbeat value must be 2 < heartbeat < 39 (TCO v1) or 613 (TCO v2), using %d\n",
694 heartbeat); 686 heartbeat);
695 } 687 }
696 688
697 ret = misc_register(&iTCO_wdt_miscdev); 689 ret = misc_register(&iTCO_wdt_miscdev);
698 if (ret != 0) { 690 if (ret != 0) {
699 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 691 printk(KERN_ERR PFX
700 WATCHDOG_MINOR, ret); 692 "cannot register miscdev on minor=%d (err=%d)\n",
693 WATCHDOG_MINOR, ret);
701 goto unreg_region; 694 goto unreg_region;
702 } 695 }
703 696
704 printk (KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 697 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
705 heartbeat, nowayout); 698 heartbeat, nowayout);
706 699
707 return 0; 700 return 0;
708 701
709unreg_region: 702unreg_region:
710 release_region (TCOBASE, 0x20); 703 release_region(TCOBASE, 0x20);
711out: 704out:
712 if (iTCO_wdt_private.iTCO_version == 2) 705 if (iTCO_wdt_private.iTCO_version == 2)
713 iounmap(iTCO_wdt_private.gcs); 706 iounmap(iTCO_wdt_private.gcs);
@@ -796,7 +789,8 @@ static int __init iTCO_wdt_init_module(void)
796 if (err) 789 if (err)
797 return err; 790 return err;
798 791
799 iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 792 iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME,
793 -1, NULL, 0);
800 if (IS_ERR(iTCO_wdt_platform_device)) { 794 if (IS_ERR(iTCO_wdt_platform_device)) {
801 err = PTR_ERR(iTCO_wdt_platform_device); 795 err = PTR_ERR(iTCO_wdt_platform_device);
802 goto unreg_platform_driver; 796 goto unreg_platform_driver;
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index 4b89f401691a..05a28106e8eb 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -41,9 +41,9 @@
41#include <linux/spinlock.h> 41#include <linux/spinlock.h>
42#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/platform_device.h> 43#include <linux/platform_device.h>
44#include <linux/io.h>
45#include <linux/uaccess.h>
44 46
45#include <asm/io.h>
46#include <asm/uaccess.h>
47#include <asm/system.h> 47#include <asm/system.h>
48 48
49static struct platform_device *ibwdt_platform_device; 49static struct platform_device *ibwdt_platform_device;
@@ -120,15 +120,16 @@ static int wd_margin = WD_TIMO;
120 120
121static int nowayout = WATCHDOG_NOWAYOUT; 121static int nowayout = WATCHDOG_NOWAYOUT;
122module_param(nowayout, int, 0); 122module_param(nowayout, int, 0);
123MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 123MODULE_PARM_DESC(nowayout,
124 "Watchdog cannot be stopped once started (default="
125 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
124 126
125 127
126/* 128/*
127 * Watchdog Operations 129 * Watchdog Operations
128 */ 130 */
129 131
130static void 132static void ibwdt_ping(void)
131ibwdt_ping(void)
132{ 133{
133 spin_lock(&ibwdt_lock); 134 spin_lock(&ibwdt_lock);
134 135
@@ -138,16 +139,14 @@ ibwdt_ping(void)
138 spin_unlock(&ibwdt_lock); 139 spin_unlock(&ibwdt_lock);
139} 140}
140 141
141static void 142static void ibwdt_disable(void)
142ibwdt_disable(void)
143{ 143{
144 spin_lock(&ibwdt_lock); 144 spin_lock(&ibwdt_lock);
145 outb_p(0, WDT_STOP); 145 outb_p(0, WDT_STOP);
146 spin_unlock(&ibwdt_lock); 146 spin_unlock(&ibwdt_lock);
147} 147}
148 148
149static int 149static int ibwdt_set_heartbeat(int t)
150ibwdt_set_heartbeat(int t)
151{ 150{
152 int i; 151 int i;
153 152
@@ -165,8 +164,8 @@ ibwdt_set_heartbeat(int t)
165 * /dev/watchdog handling 164 * /dev/watchdog handling
166 */ 165 */
167 166
168static ssize_t 167static ssize_t ibwdt_write(struct file *file, const char __user *buf,
169ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 168 size_t count, loff_t *ppos)
170{ 169{
171 if (count) { 170 if (count) {
172 if (!nowayout) { 171 if (!nowayout) {
@@ -188,77 +187,71 @@ ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppo
188 return count; 187 return count;
189} 188}
190 189
191static int 190static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
192ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
193 unsigned long arg)
194{ 191{
195 int new_margin; 192 int new_margin;
196 void __user *argp = (void __user *)arg; 193 void __user *argp = (void __user *)arg;
197 int __user *p = argp; 194 int __user *p = argp;
198 195
199 static struct watchdog_info ident = { 196 static struct watchdog_info ident = {
200 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 197 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
198 | WDIOF_MAGICCLOSE,
201 .firmware_version = 1, 199 .firmware_version = 1,
202 .identity = "IB700 WDT", 200 .identity = "IB700 WDT",
203 }; 201 };
204 202
205 switch (cmd) { 203 switch (cmd) {
206 case WDIOC_GETSUPPORT: 204 case WDIOC_GETSUPPORT:
207 if (copy_to_user(argp, &ident, sizeof(ident))) 205 if (copy_to_user(argp, &ident, sizeof(ident)))
208 return -EFAULT; 206 return -EFAULT;
209 break; 207 break;
210 208
211 case WDIOC_GETSTATUS: 209 case WDIOC_GETSTATUS:
212 case WDIOC_GETBOOTSTATUS: 210 case WDIOC_GETBOOTSTATUS:
213 return put_user(0, p); 211 return put_user(0, p);
214
215 case WDIOC_KEEPALIVE:
216 ibwdt_ping();
217 break;
218
219 case WDIOC_SETTIMEOUT:
220 if (get_user(new_margin, p))
221 return -EFAULT;
222 if (ibwdt_set_heartbeat(new_margin))
223 return -EINVAL;
224 ibwdt_ping();
225 /* Fall */
226
227 case WDIOC_GETTIMEOUT:
228 return put_user(wd_times[wd_margin], p);
229 212
230 case WDIOC_SETOPTIONS: 213 case WDIOC_SETOPTIONS:
231 { 214 {
232 int options, retval = -EINVAL; 215 int options, retval = -EINVAL;
233 216
234 if (get_user(options, p)) 217 if (get_user(options, p))
235 return -EFAULT; 218 return -EFAULT;
236 219
237 if (options & WDIOS_DISABLECARD) { 220 if (options & WDIOS_DISABLECARD) {
238 ibwdt_disable(); 221 ibwdt_disable();
239 retval = 0; 222 retval = 0;
240 } 223 }
224 if (options & WDIOS_ENABLECARD) {
225 ibwdt_ping();
226 retval = 0;
227 }
228 return retval;
229 }
230 case WDIOC_KEEPALIVE:
231 ibwdt_ping();
232 break;
241 233
242 if (options & WDIOS_ENABLECARD) { 234 case WDIOC_SETTIMEOUT:
243 ibwdt_ping(); 235 if (get_user(new_margin, p))
244 retval = 0; 236 return -EFAULT;
245 } 237 if (ibwdt_set_heartbeat(new_margin))
238 return -EINVAL;
239 ibwdt_ping();
240 /* Fall */
246 241
247 return retval; 242 case WDIOC_GETTIMEOUT:
248 } 243 return put_user(wd_times[wd_margin], p);
249 244
250 default: 245 default:
251 return -ENOTTY; 246 return -ENOTTY;
252 } 247 }
253 return 0; 248 return 0;
254} 249}
255 250
256static int 251static int ibwdt_open(struct inode *inode, struct file *file)
257ibwdt_open(struct inode *inode, struct file *file)
258{ 252{
259 if (test_and_set_bit(0, &ibwdt_is_open)) { 253 if (test_and_set_bit(0, &ibwdt_is_open))
260 return -EBUSY; 254 return -EBUSY;
261 }
262 if (nowayout) 255 if (nowayout)
263 __module_get(THIS_MODULE); 256 __module_get(THIS_MODULE);
264 257
@@ -267,13 +260,13 @@ ibwdt_open(struct inode *inode, struct file *file)
267 return nonseekable_open(inode, file); 260 return nonseekable_open(inode, file);
268} 261}
269 262
270static int 263static int ibwdt_close(struct inode *inode, struct file *file)
271ibwdt_close(struct inode *inode, struct file *file)
272{ 264{
273 if (expect_close == 42) { 265 if (expect_close == 42) {
274 ibwdt_disable(); 266 ibwdt_disable();
275 } else { 267 } else {
276 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 268 printk(KERN_CRIT PFX
269 "WDT device closed unexpectedly. WDT will not stop!\n");
277 ibwdt_ping(); 270 ibwdt_ping();
278 } 271 }
279 clear_bit(0, &ibwdt_is_open); 272 clear_bit(0, &ibwdt_is_open);
@@ -289,7 +282,7 @@ static const struct file_operations ibwdt_fops = {
289 .owner = THIS_MODULE, 282 .owner = THIS_MODULE,
290 .llseek = no_llseek, 283 .llseek = no_llseek,
291 .write = ibwdt_write, 284 .write = ibwdt_write,
292 .ioctl = ibwdt_ioctl, 285 .unlocked_ioctl = ibwdt_ioctl,
293 .open = ibwdt_open, 286 .open = ibwdt_open,
294 .release = ibwdt_close, 287 .release = ibwdt_close,
295}; 288};
@@ -310,21 +303,23 @@ static int __devinit ibwdt_probe(struct platform_device *dev)
310 303
311#if WDT_START != WDT_STOP 304#if WDT_START != WDT_STOP
312 if (!request_region(WDT_STOP, 1, "IB700 WDT")) { 305 if (!request_region(WDT_STOP, 1, "IB700 WDT")) {
313 printk (KERN_ERR PFX "STOP method I/O %X is not available.\n", WDT_STOP); 306 printk(KERN_ERR PFX "STOP method I/O %X is not available.\n",
307 WDT_STOP);
314 res = -EIO; 308 res = -EIO;
315 goto out_nostopreg; 309 goto out_nostopreg;
316 } 310 }
317#endif 311#endif
318 312
319 if (!request_region(WDT_START, 1, "IB700 WDT")) { 313 if (!request_region(WDT_START, 1, "IB700 WDT")) {
320 printk (KERN_ERR PFX "START method I/O %X is not available.\n", WDT_START); 314 printk(KERN_ERR PFX "START method I/O %X is not available.\n",
315 WDT_START);
321 res = -EIO; 316 res = -EIO;
322 goto out_nostartreg; 317 goto out_nostartreg;
323 } 318 }
324 319
325 res = misc_register(&ibwdt_miscdev); 320 res = misc_register(&ibwdt_miscdev);
326 if (res) { 321 if (res) {
327 printk (KERN_ERR PFX "failed to register misc device\n"); 322 printk(KERN_ERR PFX "failed to register misc device\n");
328 goto out_nomisc; 323 goto out_nomisc;
329 } 324 }
330 return 0; 325 return 0;
@@ -342,9 +337,9 @@ out_nostopreg:
342static int __devexit ibwdt_remove(struct platform_device *dev) 337static int __devexit ibwdt_remove(struct platform_device *dev)
343{ 338{
344 misc_deregister(&ibwdt_miscdev); 339 misc_deregister(&ibwdt_miscdev);
345 release_region(WDT_START,1); 340 release_region(WDT_START, 1);
346#if WDT_START != WDT_STOP 341#if WDT_START != WDT_STOP
347 release_region(WDT_STOP,1); 342 release_region(WDT_STOP, 1);
348#endif 343#endif
349 return 0; 344 return 0;
350} 345}
@@ -369,13 +364,15 @@ static int __init ibwdt_init(void)
369{ 364{
370 int err; 365 int err;
371 366
372 printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n"); 367 printk(KERN_INFO PFX
368 "WDT driver for IB700 single board computer initialising.\n");
373 369
374 err = platform_driver_register(&ibwdt_driver); 370 err = platform_driver_register(&ibwdt_driver);
375 if (err) 371 if (err)
376 return err; 372 return err;
377 373
378 ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0); 374 ibwdt_platform_device = platform_device_register_simple(DRV_NAME,
375 -1, NULL, 0);
379 if (IS_ERR(ibwdt_platform_device)) { 376 if (IS_ERR(ibwdt_platform_device)) {
380 err = PTR_ERR(ibwdt_platform_device); 377 err = PTR_ERR(ibwdt_platform_device);
381 goto unreg_platform_driver; 378 goto unreg_platform_driver;
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c
index 94155f6136c2..b82405cfb4cd 100644
--- a/drivers/watchdog/ibmasr.c
+++ b/drivers/watchdog/ibmasr.c
@@ -19,9 +19,8 @@
19#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
20#include <linux/watchdog.h> 20#include <linux/watchdog.h>
21#include <linux/dmi.h> 21#include <linux/dmi.h>
22 22#include <linux/io.h>
23#include <asm/io.h> 23#include <linux/uaccess.h>
24#include <asm/uaccess.h>
25 24
26 25
27enum { 26enum {
@@ -70,10 +69,13 @@ static char asr_expect_close;
70static unsigned int asr_type, asr_base, asr_length; 69static unsigned int asr_type, asr_base, asr_length;
71static unsigned int asr_read_addr, asr_write_addr; 70static unsigned int asr_read_addr, asr_write_addr;
72static unsigned char asr_toggle_mask, asr_disable_mask; 71static unsigned char asr_toggle_mask, asr_disable_mask;
72static spinlock_t asr_lock;
73 73
74static void asr_toggle(void) 74static void __asr_toggle(void)
75{ 75{
76 unsigned char reg = inb(asr_read_addr); 76 unsigned char reg;
77
78 reg = inb(asr_read_addr);
77 79
78 outb(reg & ~asr_toggle_mask, asr_write_addr); 80 outb(reg & ~asr_toggle_mask, asr_write_addr);
79 reg = inb(asr_read_addr); 81 reg = inb(asr_read_addr);
@@ -83,12 +85,21 @@ static void asr_toggle(void)
83 85
84 outb(reg & ~asr_toggle_mask, asr_write_addr); 86 outb(reg & ~asr_toggle_mask, asr_write_addr);
85 reg = inb(asr_read_addr); 87 reg = inb(asr_read_addr);
88 spin_unlock(&asr_lock);
89}
90
91static void asr_toggle(void)
92{
93 spin_lock(&asr_lock);
94 __asr_toggle();
95 spin_unlock(&asr_lock);
86} 96}
87 97
88static void asr_enable(void) 98static void asr_enable(void)
89{ 99{
90 unsigned char reg; 100 unsigned char reg;
91 101
102 spin_lock(&asr_lock);
92 if (asr_type == ASMTYPE_TOPAZ) { 103 if (asr_type == ASMTYPE_TOPAZ) {
93 /* asr_write_addr == asr_read_addr */ 104 /* asr_write_addr == asr_read_addr */
94 reg = inb(asr_read_addr); 105 reg = inb(asr_read_addr);
@@ -99,17 +110,21 @@ static void asr_enable(void)
99 * First make sure the hardware timer is reset by toggling 110 * First make sure the hardware timer is reset by toggling
100 * ASR hardware timer line. 111 * ASR hardware timer line.
101 */ 112 */
102 asr_toggle(); 113 __asr_toggle();
103 114
104 reg = inb(asr_read_addr); 115 reg = inb(asr_read_addr);
105 outb(reg & ~asr_disable_mask, asr_write_addr); 116 outb(reg & ~asr_disable_mask, asr_write_addr);
106 } 117 }
107 reg = inb(asr_read_addr); 118 reg = inb(asr_read_addr);
119 spin_unlock(&asr_lock);
108} 120}
109 121
110static void asr_disable(void) 122static void asr_disable(void)
111{ 123{
112 unsigned char reg = inb(asr_read_addr); 124 unsigned char reg;
125
126 spin_lock(&asr_lock);
127 reg = inb(asr_read_addr);
113 128
114 if (asr_type == ASMTYPE_TOPAZ) 129 if (asr_type == ASMTYPE_TOPAZ)
115 /* asr_write_addr == asr_read_addr */ 130 /* asr_write_addr == asr_read_addr */
@@ -122,6 +137,7 @@ static void asr_disable(void)
122 outb(reg | asr_disable_mask, asr_write_addr); 137 outb(reg | asr_disable_mask, asr_write_addr);
123 } 138 }
124 reg = inb(asr_read_addr); 139 reg = inb(asr_read_addr);
140 spin_unlock(&asr_lock);
125} 141}
126 142
127static int __init asr_get_base_address(void) 143static int __init asr_get_base_address(void)
@@ -133,7 +149,8 @@ static int __init asr_get_base_address(void)
133 149
134 switch (asr_type) { 150 switch (asr_type) {
135 case ASMTYPE_TOPAZ: 151 case ASMTYPE_TOPAZ:
136 /* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */ 152 /* SELECT SuperIO CHIP FOR QUERYING
153 (WRITE 0x07 TO BOTH 0x2E and 0x2F) */
137 outb(0x07, 0x2e); 154 outb(0x07, 0x2e);
138 outb(0x07, 0x2f); 155 outb(0x07, 0x2f);
139 156
@@ -154,14 +171,26 @@ static int __init asr_get_base_address(void)
154 171
155 case ASMTYPE_JASPER: 172 case ASMTYPE_JASPER:
156 type = "Jaspers "; 173 type = "Jaspers ";
157 174#if 0
158 /* FIXME: need to use pci_config_lock here, but it's not exported */ 175 u32 r;
176 /* Suggested fix */
177 pdev = pci_get_bus_and_slot(0, DEVFN(0x1f, 0));
178 if (pdev == NULL)
179 return -ENODEV;
180 pci_read_config_dword(pdev, 0x58, &r);
181 asr_base = r & 0xFFFE;
182 pci_dev_put(pdev);
183#else
184 /* FIXME: need to use pci_config_lock here,
185 but it's not exported */
159 186
160/* spin_lock_irqsave(&pci_config_lock, flags);*/ 187/* spin_lock_irqsave(&pci_config_lock, flags);*/
161 188
162 /* Select the SuperIO chip in the PCI I/O port register */ 189 /* Select the SuperIO chip in the PCI I/O port register */
163 outl(0x8000f858, 0xcf8); 190 outl(0x8000f858, 0xcf8);
164 191
192 /* BUS 0, Slot 1F, fnc 0, offset 58 */
193
165 /* 194 /*
166 * Read the base address for the SuperIO chip. 195 * Read the base address for the SuperIO chip.
167 * Only the lower 16 bits are valid, but the address is word 196 * Only the lower 16 bits are valid, but the address is word
@@ -170,7 +199,7 @@ static int __init asr_get_base_address(void)
170 asr_base = inl(0xcfc) & 0xfffe; 199 asr_base = inl(0xcfc) & 0xfffe;
171 200
172/* spin_unlock_irqrestore(&pci_config_lock, flags);*/ 201/* spin_unlock_irqrestore(&pci_config_lock, flags);*/
173 202#endif
174 asr_read_addr = asr_write_addr = 203 asr_read_addr = asr_write_addr =
175 asr_base + JASPER_ASR_REG_OFFSET; 204 asr_base + JASPER_ASR_REG_OFFSET;
176 asr_toggle_mask = JASPER_ASR_TOGGLE_MASK; 205 asr_toggle_mask = JASPER_ASR_TOGGLE_MASK;
@@ -241,66 +270,57 @@ static ssize_t asr_write(struct file *file, const char __user *buf,
241 return count; 270 return count;
242} 271}
243 272
244static int asr_ioctl(struct inode *inode, struct file *file, 273static long asr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
245 unsigned int cmd, unsigned long arg)
246{ 274{
247 static const struct watchdog_info ident = { 275 static const struct watchdog_info ident = {
248 .options = WDIOF_KEEPALIVEPING | 276 .options = WDIOF_KEEPALIVEPING |
249 WDIOF_MAGICCLOSE, 277 WDIOF_MAGICCLOSE,
250 .identity = "IBM ASR" 278 .identity = "IBM ASR",
251 }; 279 };
252 void __user *argp = (void __user *)arg; 280 void __user *argp = (void __user *)arg;
253 int __user *p = argp; 281 int __user *p = argp;
254 int heartbeat; 282 int heartbeat;
255 283
256 switch (cmd) { 284 switch (cmd) {
257 case WDIOC_GETSUPPORT: 285 case WDIOC_GETSUPPORT:
258 return copy_to_user(argp, &ident, sizeof(ident)) ? 286 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
259 -EFAULT : 0; 287 case WDIOC_GETSTATUS:
260 288 case WDIOC_GETBOOTSTATUS:
261 case WDIOC_GETSTATUS: 289 return put_user(0, p);
262 case WDIOC_GETBOOTSTATUS: 290 case WDIOC_SETOPTIONS:
263 return put_user(0, p); 291 {
264 292 int new_options, retval = -EINVAL;
265 case WDIOC_KEEPALIVE: 293 if (get_user(new_options, p))
294 return -EFAULT;
295 if (new_options & WDIOS_DISABLECARD) {
296 asr_disable();
297 retval = 0;
298 }
299 if (new_options & WDIOS_ENABLECARD) {
300 asr_enable();
266 asr_toggle(); 301 asr_toggle();
267 return 0; 302 retval = 0;
268
269 /*
270 * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
271 * and WDIOC_GETTIMEOUT always returns 256.
272 */
273 case WDIOC_GETTIMEOUT:
274 heartbeat = 256;
275 return put_user(heartbeat, p);
276
277 case WDIOC_SETOPTIONS: {
278 int new_options, retval = -EINVAL;
279
280 if (get_user(new_options, p))
281 return -EFAULT;
282
283 if (new_options & WDIOS_DISABLECARD) {
284 asr_disable();
285 retval = 0;
286 }
287
288 if (new_options & WDIOS_ENABLECARD) {
289 asr_enable();
290 asr_toggle();
291 retval = 0;
292 }
293
294 return retval;
295 } 303 }
304 return retval;
305 }
306 case WDIOC_KEEPALIVE:
307 asr_toggle();
308 return 0;
309 /*
310 * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
311 * and WDIOC_GETTIMEOUT always returns 256.
312 */
313 case WDIOC_GETTIMEOUT:
314 heartbeat = 256;
315 return put_user(heartbeat, p);
316 default:
317 return -ENOTTY;
296 } 318 }
297
298 return -ENOTTY;
299} 319}
300 320
301static int asr_open(struct inode *inode, struct file *file) 321static int asr_open(struct inode *inode, struct file *file)
302{ 322{
303 if(test_and_set_bit(0, &asr_is_open)) 323 if (test_and_set_bit(0, &asr_is_open))
304 return -EBUSY; 324 return -EBUSY;
305 325
306 asr_toggle(); 326 asr_toggle();
@@ -314,7 +334,8 @@ static int asr_release(struct inode *inode, struct file *file)
314 if (asr_expect_close == 42) 334 if (asr_expect_close == 42)
315 asr_disable(); 335 asr_disable();
316 else { 336 else {
317 printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); 337 printk(KERN_CRIT PFX
338 "unexpected close, not stopping watchdog!\n");
318 asr_toggle(); 339 asr_toggle();
319 } 340 }
320 clear_bit(0, &asr_is_open); 341 clear_bit(0, &asr_is_open);
@@ -323,12 +344,12 @@ static int asr_release(struct inode *inode, struct file *file)
323} 344}
324 345
325static const struct file_operations asr_fops = { 346static const struct file_operations asr_fops = {
326 .owner = THIS_MODULE, 347 .owner = THIS_MODULE,
327 .llseek = no_llseek, 348 .llseek = no_llseek,
328 .write = asr_write, 349 .write = asr_write,
329 .ioctl = asr_ioctl, 350 .unlocked_ioctl = asr_ioctl,
330 .open = asr_open, 351 .open = asr_open,
331 .release = asr_release, 352 .release = asr_release,
332}; 353};
333 354
334static struct miscdevice asr_miscdev = { 355static struct miscdevice asr_miscdev = {
@@ -367,6 +388,8 @@ static int __init ibmasr_init(void)
367 if (!asr_type) 388 if (!asr_type)
368 return -ENODEV; 389 return -ENODEV;
369 390
391 spin_lock_init(&asr_lock);
392
370 rc = asr_get_base_address(); 393 rc = asr_get_base_address();
371 if (rc) 394 if (rc)
372 return rc; 395 return rc;
@@ -395,7 +418,9 @@ module_init(ibmasr_init);
395module_exit(ibmasr_exit); 418module_exit(ibmasr_exit);
396 419
397module_param(nowayout, int, 0); 420module_param(nowayout, int, 0);
398MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 421MODULE_PARM_DESC(nowayout,
422 "Watchdog cannot be stopped once started (default="
423 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
399 424
400MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); 425MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
401MODULE_AUTHOR("Andrey Panin"); 426MODULE_AUTHOR("Andrey Panin");
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index 788245bdaa7f..73c9e7992feb 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22 2 * IndyDog 0.3 A Hardware Watchdog Device for SGI IP22
3 * 3 *
4 * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>, All Rights Reserved. 4 * (c) Copyright 2002 Guido Guenther <agx@sigxcpu.org>,
5 * All Rights Reserved.
5 * 6 *
6 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -22,32 +23,42 @@
22#include <linux/notifier.h> 23#include <linux/notifier.h>
23#include <linux/reboot.h> 24#include <linux/reboot.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <asm/uaccess.h> 26#include <linux/uaccess.h>
26#include <asm/sgi/mc.h> 27#include <asm/sgi/mc.h>
27 28
28#define PFX "indydog: " 29#define PFX "indydog: "
29static int indydog_alive; 30static unsigned long indydog_alive;
31static spinlock_t indydog_lock;
30 32
31#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 33#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
32 34
33static int nowayout = WATCHDOG_NOWAYOUT; 35static int nowayout = WATCHDOG_NOWAYOUT;
34module_param(nowayout, int, 0); 36module_param(nowayout, int, 0);
35MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 37MODULE_PARM_DESC(nowayout,
38 "Watchdog cannot be stopped once started (default="
39 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
36 40
37static void indydog_start(void) 41static void indydog_start(void)
38{ 42{
39 u32 mc_ctrl0 = sgimc->cpuctrl0; 43 u32 mc_ctrl0;
40 44
45 spin_lock(&indydog_lock);
46 mc_ctrl0 = sgimc->cpuctrl0;
41 mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG; 47 mc_ctrl0 = sgimc->cpuctrl0 | SGIMC_CCTRL0_WDOG;
42 sgimc->cpuctrl0 = mc_ctrl0; 48 sgimc->cpuctrl0 = mc_ctrl0;
49 spin_unlock(&indydog_lock);
43} 50}
44 51
45static void indydog_stop(void) 52static void indydog_stop(void)
46{ 53{
47 u32 mc_ctrl0 = sgimc->cpuctrl0; 54 u32 mc_ctrl0;
48 55
56 spin_lock(&indydog_lock);
57
58 mc_ctrl0 = sgimc->cpuctrl0;
49 mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; 59 mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG;
50 sgimc->cpuctrl0 = mc_ctrl0; 60 sgimc->cpuctrl0 = mc_ctrl0;
61 spin_unlock(&indydog_lock);
51 62
52 printk(KERN_INFO PFX "Stopped watchdog timer.\n"); 63 printk(KERN_INFO PFX "Stopped watchdog timer.\n");
53} 64}
@@ -62,7 +73,7 @@ static void indydog_ping(void)
62 */ 73 */
63static int indydog_open(struct inode *inode, struct file *file) 74static int indydog_open(struct inode *inode, struct file *file)
64{ 75{
65 if (indydog_alive) 76 if (test_and_set_bit(0, &indydog_alive))
66 return -EBUSY; 77 return -EBUSY;
67 78
68 if (nowayout) 79 if (nowayout)
@@ -84,23 +95,21 @@ static int indydog_release(struct inode *inode, struct file *file)
84 * Lock it in if it's a module and we defined ...NOWAYOUT */ 95 * Lock it in if it's a module and we defined ...NOWAYOUT */
85 if (!nowayout) 96 if (!nowayout)
86 indydog_stop(); /* Turn the WDT off */ 97 indydog_stop(); /* Turn the WDT off */
87 98 clear_bit(0, &indydog_alive);
88 indydog_alive = 0;
89
90 return 0; 99 return 0;
91} 100}
92 101
93static ssize_t indydog_write(struct file *file, const char *data, size_t len, loff_t *ppos) 102static ssize_t indydog_write(struct file *file, const char *data,
103 size_t len, loff_t *ppos)
94{ 104{
95 /* Refresh the timer. */ 105 /* Refresh the timer. */
96 if (len) { 106 if (len)
97 indydog_ping(); 107 indydog_ping();
98 }
99 return len; 108 return len;
100} 109}
101 110
102static int indydog_ioctl(struct inode *inode, struct file *file, 111static long indydog_ioctl(struct file *file, unsigned int cmd,
103 unsigned int cmd, unsigned long arg) 112 unsigned long arg)
104{ 113{
105 int options, retval = -EINVAL; 114 int options, retval = -EINVAL;
106 static struct watchdog_info ident = { 115 static struct watchdog_info ident = {
@@ -111,42 +120,40 @@ static int indydog_ioctl(struct inode *inode, struct file *file,
111 }; 120 };
112 121
113 switch (cmd) { 122 switch (cmd) {
114 default: 123 case WDIOC_GETSUPPORT:
115 return -ENOTTY; 124 if (copy_to_user((struct watchdog_info *)arg,
116 case WDIOC_GETSUPPORT: 125 &ident, sizeof(ident)))
117 if (copy_to_user((struct watchdog_info *)arg, 126 return -EFAULT;
118 &ident, sizeof(ident))) 127 return 0;
119 return -EFAULT; 128 case WDIOC_GETSTATUS:
120 return 0; 129 case WDIOC_GETBOOTSTATUS:
121 case WDIOC_GETSTATUS: 130 return put_user(0, (int *)arg);
122 case WDIOC_GETBOOTSTATUS: 131 case WDIOC_SETOPTIONS:
123 return put_user(0,(int *)arg); 132 {
124 case WDIOC_KEEPALIVE: 133 if (get_user(options, (int *)arg))
125 indydog_ping(); 134 return -EFAULT;
126 return 0; 135 if (options & WDIOS_DISABLECARD) {
127 case WDIOC_GETTIMEOUT: 136 indydog_stop();
128 return put_user(WATCHDOG_TIMEOUT,(int *)arg); 137 retval = 0;
129 case WDIOC_SETOPTIONS:
130 {
131 if (get_user(options, (int *)arg))
132 return -EFAULT;
133
134 if (options & WDIOS_DISABLECARD) {
135 indydog_stop();
136 retval = 0;
137 }
138
139 if (options & WDIOS_ENABLECARD) {
140 indydog_start();
141 retval = 0;
142 }
143
144 return retval;
145 } 138 }
139 if (options & WDIOS_ENABLECARD) {
140 indydog_start();
141 retval = 0;
142 }
143 return retval;
144 }
145 case WDIOC_KEEPALIVE:
146 indydog_ping();
147 return 0;
148 case WDIOC_GETTIMEOUT:
149 return put_user(WATCHDOG_TIMEOUT, (int *)arg);
150 default:
151 return -ENOTTY;
146 } 152 }
147} 153}
148 154
149static int indydog_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 155static int indydog_notify_sys(struct notifier_block *this,
156 unsigned long code, void *unused)
150{ 157{
151 if (code == SYS_DOWN || code == SYS_HALT) 158 if (code == SYS_DOWN || code == SYS_HALT)
152 indydog_stop(); /* Turn the WDT off */ 159 indydog_stop(); /* Turn the WDT off */
@@ -158,7 +165,7 @@ static const struct file_operations indydog_fops = {
158 .owner = THIS_MODULE, 165 .owner = THIS_MODULE,
159 .llseek = no_llseek, 166 .llseek = no_llseek,
160 .write = indydog_write, 167 .write = indydog_write,
161 .ioctl = indydog_ioctl, 168 .unlocked_ioctl = indydog_ioctl,
162 .open = indydog_open, 169 .open = indydog_open,
163 .release = indydog_release, 170 .release = indydog_release,
164}; 171};
@@ -180,17 +187,20 @@ static int __init watchdog_init(void)
180{ 187{
181 int ret; 188 int ret;
182 189
190 spin_lock_init(&indydog_lock);
191
183 ret = register_reboot_notifier(&indydog_notifier); 192 ret = register_reboot_notifier(&indydog_notifier);
184 if (ret) { 193 if (ret) {
185 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 194 printk(KERN_ERR PFX
186 ret); 195 "cannot register reboot notifier (err=%d)\n", ret);
187 return ret; 196 return ret;
188 } 197 }
189 198
190 ret = misc_register(&indydog_miscdev); 199 ret = misc_register(&indydog_miscdev);
191 if (ret) { 200 if (ret) {
192 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 201 printk(KERN_ERR PFX
193 WATCHDOG_MINOR, ret); 202 "cannot register miscdev on minor=%d (err=%d)\n",
203 WATCHDOG_MINOR, ret);
194 unregister_reboot_notifier(&indydog_notifier); 204 unregister_reboot_notifier(&indydog_notifier);
195 return ret; 205 return ret;
196 } 206 }
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c
index bbbd91af754d..96eb2cbe5874 100644
--- a/drivers/watchdog/iop_wdt.c
+++ b/drivers/watchdog/iop_wdt.c
@@ -32,11 +32,12 @@
32#include <linux/miscdevice.h> 32#include <linux/miscdevice.h>
33#include <linux/watchdog.h> 33#include <linux/watchdog.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <asm/hardware.h> 35#include <mach/hardware.h>
36 36
37static int nowayout = WATCHDOG_NOWAYOUT; 37static int nowayout = WATCHDOG_NOWAYOUT;
38static unsigned long wdt_status; 38static unsigned long wdt_status;
39static unsigned long boot_status; 39static unsigned long boot_status;
40static spinlock_t wdt_lock;
40 41
41#define WDT_IN_USE 0 42#define WDT_IN_USE 0
42#define WDT_OK_TO_CLOSE 1 43#define WDT_OK_TO_CLOSE 1
@@ -68,8 +69,10 @@ static void wdt_enable(void)
68 /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF 69 /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
69 * Takes approx. 10.7s to timeout 70 * Takes approx. 10.7s to timeout
70 */ 71 */
72 spin_lock(&wdt_lock);
71 write_wdtcr(IOP_WDTCR_EN_ARM); 73 write_wdtcr(IOP_WDTCR_EN_ARM);
72 write_wdtcr(IOP_WDTCR_EN); 74 write_wdtcr(IOP_WDTCR_EN);
75 spin_unlock(&wdt_lock);
73} 76}
74 77
75/* returns 0 if the timer was successfully disabled */ 78/* returns 0 if the timer was successfully disabled */
@@ -77,9 +80,11 @@ static int wdt_disable(void)
77{ 80{
78 /* Stop Counting */ 81 /* Stop Counting */
79 if (wdt_supports_disable()) { 82 if (wdt_supports_disable()) {
83 spin_lock(&wdt_lock);
80 write_wdtcr(IOP_WDTCR_DIS_ARM); 84 write_wdtcr(IOP_WDTCR_DIS_ARM);
81 write_wdtcr(IOP_WDTCR_DIS); 85 write_wdtcr(IOP_WDTCR_DIS);
82 clear_bit(WDT_ENABLED, &wdt_status); 86 clear_bit(WDT_ENABLED, &wdt_status);
87 spin_unlock(&wdt_lock);
83 printk(KERN_INFO "WATCHDOG: Disabled\n"); 88 printk(KERN_INFO "WATCHDOG: Disabled\n");
84 return 0; 89 return 0;
85 } else 90 } else
@@ -92,16 +97,12 @@ static int iop_wdt_open(struct inode *inode, struct file *file)
92 return -EBUSY; 97 return -EBUSY;
93 98
94 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 99 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
95
96 wdt_enable(); 100 wdt_enable();
97
98 set_bit(WDT_ENABLED, &wdt_status); 101 set_bit(WDT_ENABLED, &wdt_status);
99
100 return nonseekable_open(inode, file); 102 return nonseekable_open(inode, file);
101} 103}
102 104
103static ssize_t 105static ssize_t iop_wdt_write(struct file *file, const char *data, size_t len,
104iop_wdt_write(struct file *file, const char *data, size_t len,
105 loff_t *ppos) 106 loff_t *ppos)
106{ 107{
107 if (len) { 108 if (len) {
@@ -121,46 +122,35 @@ iop_wdt_write(struct file *file, const char *data, size_t len,
121 } 122 }
122 wdt_enable(); 123 wdt_enable();
123 } 124 }
124
125 return len; 125 return len;
126} 126}
127 127
128static struct watchdog_info ident = { 128static const struct watchdog_info ident = {
129 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 129 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
130 .identity = "iop watchdog", 130 .identity = "iop watchdog",
131}; 131};
132 132
133static int 133static long iop_wdt_ioctl(struct file *file,
134iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 134 unsigned int cmd, unsigned long arg)
135 unsigned long arg)
136{ 135{
137 int options; 136 int options;
138 int ret = -ENOTTY; 137 int ret = -ENOTTY;
138 int __user *argp = (int __user *)arg;
139 139
140 switch (cmd) { 140 switch (cmd) {
141 case WDIOC_GETSUPPORT: 141 case WDIOC_GETSUPPORT:
142 if (copy_to_user 142 if (copy_to_user(argp, &ident, sizeof ident))
143 ((struct watchdog_info *)arg, &ident, sizeof ident))
144 ret = -EFAULT; 143 ret = -EFAULT;
145 else 144 else
146 ret = 0; 145 ret = 0;
147 break; 146 break;
148 147
149 case WDIOC_GETSTATUS: 148 case WDIOC_GETSTATUS:
150 ret = put_user(0, (int *)arg); 149 ret = put_user(0, argp);
151 break; 150 break;
152 151
153 case WDIOC_GETBOOTSTATUS: 152 case WDIOC_GETBOOTSTATUS:
154 ret = put_user(boot_status, (int *)arg); 153 ret = put_user(boot_status, argp);
155 break;
156
157 case WDIOC_GETTIMEOUT:
158 ret = put_user(iop_watchdog_timeout(), (int *)arg);
159 break;
160
161 case WDIOC_KEEPALIVE:
162 wdt_enable();
163 ret = 0;
164 break; 154 break;
165 155
166 case WDIOC_SETOPTIONS: 156 case WDIOC_SETOPTIONS:
@@ -177,14 +167,21 @@ iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
177 } else 167 } else
178 ret = 0; 168 ret = 0;
179 } 169 }
180
181 if (options & WDIOS_ENABLECARD) { 170 if (options & WDIOS_ENABLECARD) {
182 wdt_enable(); 171 wdt_enable();
183 ret = 0; 172 ret = 0;
184 } 173 }
185 break; 174 break;
186 }
187 175
176 case WDIOC_KEEPALIVE:
177 wdt_enable();
178 ret = 0;
179 break;
180
181 case WDIOC_GETTIMEOUT:
182 ret = put_user(iop_watchdog_timeout(), argp);
183 break;
184 }
188 return ret; 185 return ret;
189} 186}
190 187
@@ -214,7 +211,7 @@ static const struct file_operations iop_wdt_fops = {
214 .owner = THIS_MODULE, 211 .owner = THIS_MODULE,
215 .llseek = no_llseek, 212 .llseek = no_llseek,
216 .write = iop_wdt_write, 213 .write = iop_wdt_write,
217 .ioctl = iop_wdt_ioctl, 214 .unlocked_ioctl = iop_wdt_ioctl,
218 .open = iop_wdt_open, 215 .open = iop_wdt_open,
219 .release = iop_wdt_release, 216 .release = iop_wdt_release,
220}; 217};
@@ -229,10 +226,8 @@ static int __init iop_wdt_init(void)
229{ 226{
230 int ret; 227 int ret;
231 228
232 ret = misc_register(&iop_wdt_miscdev); 229 spin_lock_init(&wdt_lock);
233 if (ret == 0) 230
234 printk("iop watchdog timer: timeout %lu sec\n",
235 iop_watchdog_timeout());
236 231
237 /* check if the reset was caused by the watchdog timer */ 232 /* check if the reset was caused by the watchdog timer */
238 boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0; 233 boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
@@ -242,6 +237,13 @@ static int __init iop_wdt_init(void)
242 */ 237 */
243 write_wdtsr(IOP13XX_WDTCR_IB_RESET); 238 write_wdtsr(IOP13XX_WDTCR_IB_RESET);
244 239
240 /* Register after we have the device set up so we cannot race
241 with an open */
242 ret = misc_register(&iop_wdt_miscdev);
243 if (ret == 0)
244 printk(KERN_INFO "iop watchdog timer: timeout %lu sec\n",
245 iop_watchdog_timeout());
246
245 return ret; 247 return ret;
246} 248}
247 249
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index 51bfd5721833..2270ee07c01b 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -221,7 +221,7 @@ static ssize_t it8712f_wdt_write(struct file *file, const char __user *data,
221 expect_close = 0; 221 expect_close = 0;
222 for (i = 0; i < len; ++i) { 222 for (i = 0; i < len; ++i) {
223 char c; 223 char c;
224 if (get_user(c, data+i)) 224 if (get_user(c, data + i))
225 return -EFAULT; 225 return -EFAULT;
226 if (c == 'V') 226 if (c == 'V')
227 expect_close = 42; 227 expect_close = 42;
@@ -244,8 +244,6 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
244 int value; 244 int value;
245 245
246 switch (cmd) { 246 switch (cmd) {
247 default:
248 return -ENOTTY;
249 case WDIOC_GETSUPPORT: 247 case WDIOC_GETSUPPORT:
250 if (copy_to_user(argp, &ident, sizeof(ident))) 248 if (copy_to_user(argp, &ident, sizeof(ident)))
251 return -EFAULT; 249 return -EFAULT;
@@ -284,6 +282,8 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
284 if (put_user(margin, p)) 282 if (put_user(margin, p))
285 return -EFAULT; 283 return -EFAULT;
286 return 0; 284 return 0;
285 default:
286 return -ENOTTY;
287 } 287 }
288} 288}
289 289
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index dc7548dcaf35..4f4b35a20d84 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -25,42 +25,44 @@
25#include <linux/watchdog.h> 25#include <linux/watchdog.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/bitops.h> 27#include <linux/bitops.h>
28 28#include <linux/uaccess.h>
29#include <asm/hardware.h> 29#include <mach/hardware.h>
30#include <asm/uaccess.h>
31 30
32static int nowayout = WATCHDOG_NOWAYOUT; 31static int nowayout = WATCHDOG_NOWAYOUT;
33static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */ 32static unsigned int heartbeat = 60; /* (secs) Default is 1 minute */
34static unsigned long wdt_status; 33static unsigned long wdt_status;
34static spinlock_t wdt_lock;
35 35
36#define WDT_IN_USE 0 36#define WDT_IN_USE 0
37#define WDT_OK_TO_CLOSE 1 37#define WDT_OK_TO_CLOSE 1
38 38
39static unsigned long wdt_tick_rate; 39static unsigned long wdt_tick_rate;
40 40
41static void 41static void wdt_enable(void)
42wdt_enable(void)
43{ 42{
43 spin_lock(&wdt_lock);
44 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE); 44 ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE);
45 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE); 45 ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE);
46 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 46 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
47 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE); 47 ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE);
48 spin_unlock(&wdt_lock);
48} 49}
49 50
50static void 51static void wdt_disable(void)
51wdt_disable(void)
52{ 52{
53 spin_lock(&wdt_lock);
53 ixp2000_reg_write(IXP2000_T4_CTL, 0); 54 ixp2000_reg_write(IXP2000_T4_CTL, 0);
55 spin_unlock(&wdt_lock);
54} 56}
55 57
56static void 58static void wdt_keepalive(void)
57wdt_keepalive(void)
58{ 59{
60 spin_lock(&wdt_lock);
59 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate); 61 ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
62 spin_unlock(&wdt_lock);
60} 63}
61 64
62static int 65static int ixp2000_wdt_open(struct inode *inode, struct file *file)
63ixp2000_wdt_open(struct inode *inode, struct file *file)
64{ 66{
65 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 67 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
66 return -EBUSY; 68 return -EBUSY;
@@ -72,8 +74,8 @@ ixp2000_wdt_open(struct inode *inode, struct file *file)
72 return nonseekable_open(inode, file); 74 return nonseekable_open(inode, file);
73} 75}
74 76
75static ssize_t 77static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
76ixp2000_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 78 size_t len, loff_t *ppos)
77{ 79{
78 if (len) { 80 if (len) {
79 if (!nowayout) { 81 if (!nowayout) {
@@ -103,9 +105,8 @@ static struct watchdog_info ident = {
103 .identity = "IXP2000 Watchdog", 105 .identity = "IXP2000 Watchdog",
104}; 106};
105 107
106static int 108static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd,
107ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 109 unsigned long arg)
108 unsigned long arg)
109{ 110{
110 int ret = -ENOTTY; 111 int ret = -ENOTTY;
111 int time; 112 int time;
@@ -124,6 +125,11 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
124 ret = put_user(0, (int *)arg); 125 ret = put_user(0, (int *)arg);
125 break; 126 break;
126 127
128 case WDIOC_KEEPALIVE:
129 wdt_enable();
130 ret = 0;
131 break;
132
127 case WDIOC_SETTIMEOUT: 133 case WDIOC_SETTIMEOUT:
128 ret = get_user(time, (int *)arg); 134 ret = get_user(time, (int *)arg);
129 if (ret) 135 if (ret)
@@ -141,26 +147,18 @@ ixp2000_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
141 case WDIOC_GETTIMEOUT: 147 case WDIOC_GETTIMEOUT:
142 ret = put_user(heartbeat, (int *)arg); 148 ret = put_user(heartbeat, (int *)arg);
143 break; 149 break;
144
145 case WDIOC_KEEPALIVE:
146 wdt_enable();
147 ret = 0;
148 break;
149 } 150 }
150 151
151 return ret; 152 return ret;
152} 153}
153 154
154static int 155static int ixp2000_wdt_release(struct inode *inode, struct file *file)
155ixp2000_wdt_release(struct inode *inode, struct file *file)
156{ 156{
157 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { 157 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
158 wdt_disable(); 158 wdt_disable();
159 } else { 159 else
160 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " 160 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
161 "timer will not stop\n"); 161 "timer will not stop\n");
162 }
163
164 clear_bit(WDT_IN_USE, &wdt_status); 162 clear_bit(WDT_IN_USE, &wdt_status);
165 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 163 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
166 164
@@ -168,18 +166,16 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
168} 166}
169 167
170 168
171static const struct file_operations ixp2000_wdt_fops = 169static const struct file_operations ixp2000_wdt_fops = {
172{
173 .owner = THIS_MODULE, 170 .owner = THIS_MODULE,
174 .llseek = no_llseek, 171 .llseek = no_llseek,
175 .write = ixp2000_wdt_write, 172 .write = ixp2000_wdt_write,
176 .ioctl = ixp2000_wdt_ioctl, 173 .unlocked_ioctl = ixp2000_wdt_ioctl,
177 .open = ixp2000_wdt_open, 174 .open = ixp2000_wdt_open,
178 .release = ixp2000_wdt_release, 175 .release = ixp2000_wdt_release,
179}; 176};
180 177
181static struct miscdevice ixp2000_wdt_miscdev = 178static struct miscdevice ixp2000_wdt_miscdev = {
182{
183 .minor = WATCHDOG_MINOR, 179 .minor = WATCHDOG_MINOR,
184 .name = "watchdog", 180 .name = "watchdog",
185 .fops = &ixp2000_wdt_fops, 181 .fops = &ixp2000_wdt_fops,
@@ -191,9 +187,8 @@ static int __init ixp2000_wdt_init(void)
191 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); 187 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n");
192 return -EIO; 188 return -EIO;
193 } 189 }
194
195 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; 190 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
196 191 spin_lock_init(&wdt_lock);
197 return misc_register(&ixp2000_wdt_miscdev); 192 return misc_register(&ixp2000_wdt_miscdev);
198} 193}
199 194
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 5864bb865cfe..8302ef005be7 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -22,48 +22,47 @@
22#include <linux/watchdog.h> 22#include <linux/watchdog.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25 25#include <linux/uaccess.h>
26#include <asm/hardware.h> 26#include <mach/hardware.h>
27#include <asm/uaccess.h>
28 27
29static int nowayout = WATCHDOG_NOWAYOUT; 28static int nowayout = WATCHDOG_NOWAYOUT;
30static int heartbeat = 60; /* (secs) Default is 1 minute */ 29static int heartbeat = 60; /* (secs) Default is 1 minute */
31static unsigned long wdt_status; 30static unsigned long wdt_status;
32static unsigned long boot_status; 31static unsigned long boot_status;
32static DEFINE_SPINLOCK(wdt_lock);
33 33
34#define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL) 34#define WDT_TICK_RATE (IXP4XX_PERIPHERAL_BUS_CLOCK * 1000000UL)
35 35
36#define WDT_IN_USE 0 36#define WDT_IN_USE 0
37#define WDT_OK_TO_CLOSE 1 37#define WDT_OK_TO_CLOSE 1
38 38
39static void 39static void wdt_enable(void)
40wdt_enable(void)
41{ 40{
41 spin_lock(&wdt_lock);
42 *IXP4XX_OSWK = IXP4XX_WDT_KEY; 42 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
43 *IXP4XX_OSWE = 0; 43 *IXP4XX_OSWE = 0;
44 *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat; 44 *IXP4XX_OSWT = WDT_TICK_RATE * heartbeat;
45 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE; 45 *IXP4XX_OSWE = IXP4XX_WDT_COUNT_ENABLE | IXP4XX_WDT_RESET_ENABLE;
46 *IXP4XX_OSWK = 0; 46 *IXP4XX_OSWK = 0;
47 spin_unlock(&wdt_lock);
47} 48}
48 49
49static void 50static void wdt_disable(void)
50wdt_disable(void)
51{ 51{
52 spin_lock(&wdt_lock);
52 *IXP4XX_OSWK = IXP4XX_WDT_KEY; 53 *IXP4XX_OSWK = IXP4XX_WDT_KEY;
53 *IXP4XX_OSWE = 0; 54 *IXP4XX_OSWE = 0;
54 *IXP4XX_OSWK = 0; 55 *IXP4XX_OSWK = 0;
56 spin_unlock(&wdt_lock);
55} 57}
56 58
57static int 59static int ixp4xx_wdt_open(struct inode *inode, struct file *file)
58ixp4xx_wdt_open(struct inode *inode, struct file *file)
59{ 60{
60 if (test_and_set_bit(WDT_IN_USE, &wdt_status)) 61 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
61 return -EBUSY; 62 return -EBUSY;
62 63
63 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 64 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
64
65 wdt_enable(); 65 wdt_enable();
66
67 return nonseekable_open(inode, file); 66 return nonseekable_open(inode, file);
68} 67}
69 68
@@ -87,7 +86,6 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
87 } 86 }
88 wdt_enable(); 87 wdt_enable();
89 } 88 }
90
91 return len; 89 return len;
92} 90}
93 91
@@ -98,9 +96,8 @@ static struct watchdog_info ident = {
98}; 96};
99 97
100 98
101static int 99static long ixp4xx_wdt_ioctl(struct file *file, unsigned int cmd,
102ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 100 unsigned long arg)
103 unsigned long arg)
104{ 101{
105 int ret = -ENOTTY; 102 int ret = -ENOTTY;
106 int time; 103 int time;
@@ -119,6 +116,11 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
119 ret = put_user(boot_status, (int *)arg); 116 ret = put_user(boot_status, (int *)arg);
120 break; 117 break;
121 118
119 case WDIOC_KEEPALIVE:
120 wdt_enable();
121 ret = 0;
122 break;
123
122 case WDIOC_SETTIMEOUT: 124 case WDIOC_SETTIMEOUT:
123 ret = get_user(time, (int *)arg); 125 ret = get_user(time, (int *)arg);
124 if (ret) 126 if (ret)
@@ -136,25 +138,17 @@ ixp4xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
136 case WDIOC_GETTIMEOUT: 138 case WDIOC_GETTIMEOUT:
137 ret = put_user(heartbeat, (int *)arg); 139 ret = put_user(heartbeat, (int *)arg);
138 break; 140 break;
139
140 case WDIOC_KEEPALIVE:
141 wdt_enable();
142 ret = 0;
143 break;
144 } 141 }
145 return ret; 142 return ret;
146} 143}
147 144
148static int 145static int ixp4xx_wdt_release(struct inode *inode, struct file *file)
149ixp4xx_wdt_release(struct inode *inode, struct file *file)
150{ 146{
151 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { 147 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
152 wdt_disable(); 148 wdt_disable();
153 } else { 149 else
154 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " 150 printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
155 "timer will not stop\n"); 151 "timer will not stop\n");
156 }
157
158 clear_bit(WDT_IN_USE, &wdt_status); 152 clear_bit(WDT_IN_USE, &wdt_status);
159 clear_bit(WDT_OK_TO_CLOSE, &wdt_status); 153 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
160 154
@@ -162,18 +156,16 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file)
162} 156}
163 157
164 158
165static const struct file_operations ixp4xx_wdt_fops = 159static const struct file_operations ixp4xx_wdt_fops = {
166{
167 .owner = THIS_MODULE, 160 .owner = THIS_MODULE,
168 .llseek = no_llseek, 161 .llseek = no_llseek,
169 .write = ixp4xx_wdt_write, 162 .write = ixp4xx_wdt_write,
170 .ioctl = ixp4xx_wdt_ioctl, 163 .unlocked_ioctl = ixp4xx_wdt_ioctl,
171 .open = ixp4xx_wdt_open, 164 .open = ixp4xx_wdt_open,
172 .release = ixp4xx_wdt_release, 165 .release = ixp4xx_wdt_release,
173}; 166};
174 167
175static struct miscdevice ixp4xx_wdt_miscdev = 168static struct miscdevice ixp4xx_wdt_miscdev = {
176{
177 .minor = WATCHDOG_MINOR, 169 .minor = WATCHDOG_MINOR,
178 .name = "watchdog", 170 .name = "watchdog",
179 .fops = &ixp4xx_wdt_fops, 171 .fops = &ixp4xx_wdt_fops,
@@ -186,19 +178,18 @@ static int __init ixp4xx_wdt_init(void)
186 178
187 asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :); 179 asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
188 if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { 180 if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
189 printk("IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected - " 181 printk(KERN_ERR "IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected"
190 "watchdog disabled\n"); 182 " - watchdog disabled\n");
191 183
192 return -ENODEV; 184 return -ENODEV;
193 } 185 }
194 186 spin_lock_init(&wdt_lock);
195 ret = misc_register(&ixp4xx_wdt_miscdev);
196 if (ret == 0)
197 printk("IXP4xx Watchdog Timer: heartbeat %d sec\n", heartbeat);
198
199 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ? 187 boot_status = (*IXP4XX_OSST & IXP4XX_OSST_TIMER_WARM_RESET) ?
200 WDIOF_CARDRESET : 0; 188 WDIOF_CARDRESET : 0;
201 189 ret = misc_register(&ixp4xx_wdt_miscdev);
190 if (ret == 0)
191 printk(KERN_INFO "IXP4xx Watchdog Timer: heartbeat %d sec\n",
192 heartbeat);
202 return ret; 193 return ret;
203} 194}
204 195
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index df5a6b811ccd..0b798fdaa378 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -19,10 +19,9 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/watchdog.h> 21#include <linux/watchdog.h>
22#include <asm/io.h> 22#include <linux/io.h>
23#include <asm/uaccess.h> 23#include <linux/uaccess.h>
24#include <asm/arch/regs-timer.h> 24#include <mach/regs-timer.h>
25
26 25
27#define WDT_DEFAULT_TIME 5 /* seconds */ 26#define WDT_DEFAULT_TIME 5 /* seconds */
28#define WDT_MAX_TIME 171 /* seconds */ 27#define WDT_MAX_TIME 171 /* seconds */
@@ -31,38 +30,44 @@ static int wdt_time = WDT_DEFAULT_TIME;
31static int nowayout = WATCHDOG_NOWAYOUT; 30static int nowayout = WATCHDOG_NOWAYOUT;
32 31
33module_param(wdt_time, int, 0); 32module_param(wdt_time, int, 0);
34MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); 33MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
34 __MODULE_STRING(WDT_DEFAULT_TIME) ")");
35 35
36#ifdef CONFIG_WATCHDOG_NOWAYOUT 36#ifdef CONFIG_WATCHDOG_NOWAYOUT
37module_param(nowayout, int, 0); 37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 38MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
39 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
39#endif 40#endif
40 41
41 42
42static unsigned long ks8695wdt_busy; 43static unsigned long ks8695wdt_busy;
44static spinlock_t ks8695_lock;
43 45
44/* ......................................................................... */ 46/* ......................................................................... */
45 47
46/* 48/*
47 * Disable the watchdog. 49 * Disable the watchdog.
48 */ 50 */
49static void inline ks8695_wdt_stop(void) 51static inline void ks8695_wdt_stop(void)
50{ 52{
51 unsigned long tmcon; 53 unsigned long tmcon;
52 54
55 spin_lock(&ks8695_lock);
53 /* disable timer0 */ 56 /* disable timer0 */
54 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 57 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
55 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 58 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
59 spin_unlock(&ks8695_lock);
56} 60}
57 61
58/* 62/*
59 * Enable and reset the watchdog. 63 * Enable and reset the watchdog.
60 */ 64 */
61static void inline ks8695_wdt_start(void) 65static inline void ks8695_wdt_start(void)
62{ 66{
63 unsigned long tmcon; 67 unsigned long tmcon;
64 unsigned long tval = wdt_time * CLOCK_TICK_RATE; 68 unsigned long tval = wdt_time * CLOCK_TICK_RATE;
65 69
70 spin_lock(&ks8695_lock);
66 /* disable timer0 */ 71 /* disable timer0 */
67 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 72 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
68 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 73 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
@@ -73,19 +78,22 @@ static void inline ks8695_wdt_start(void)
73 /* re-enable timer0 */ 78 /* re-enable timer0 */
74 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 79 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
75 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 80 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
81 spin_unlock(&ks8695_lock);
76} 82}
77 83
78/* 84/*
79 * Reload the watchdog timer. (ie, pat the watchdog) 85 * Reload the watchdog timer. (ie, pat the watchdog)
80 */ 86 */
81static void inline ks8695_wdt_reload(void) 87static inline void ks8695_wdt_reload(void)
82{ 88{
83 unsigned long tmcon; 89 unsigned long tmcon;
84 90
91 spin_lock(&ks8695_lock);
85 /* disable, then re-enable timer0 */ 92 /* disable, then re-enable timer0 */
86 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON); 93 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
87 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 94 __raw_writel(tmcon & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
88 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON); 95 __raw_writel(tmcon | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
96 spin_unlock(&ks8695_lock);
89} 97}
90 98
91/* 99/*
@@ -102,7 +110,8 @@ static int ks8695_wdt_settimeout(int new_time)
102 if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) 110 if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
103 return -EINVAL; 111 return -EINVAL;
104 112
105 /* Set new watchdog time. It will be used when ks8695_wdt_start() is called. */ 113 /* Set new watchdog time. It will be used when
114 ks8695_wdt_start() is called. */
106 wdt_time = new_time; 115 wdt_time = new_time;
107 return 0; 116 return 0;
108} 117}
@@ -128,9 +137,9 @@ static int ks8695_wdt_open(struct inode *inode, struct file *file)
128 */ 137 */
129static int ks8695_wdt_close(struct inode *inode, struct file *file) 138static int ks8695_wdt_close(struct inode *inode, struct file *file)
130{ 139{
140 /* Disable the watchdog when file is closed */
131 if (!nowayout) 141 if (!nowayout)
132 ks8695_wdt_stop(); /* Disable the watchdog when file is closed */ 142 ks8695_wdt_stop();
133
134 clear_bit(0, &ks8695wdt_busy); 143 clear_bit(0, &ks8695wdt_busy);
135 return 0; 144 return 0;
136} 145}
@@ -143,60 +152,52 @@ static struct watchdog_info ks8695_wdt_info = {
143/* 152/*
144 * Handle commands from user-space. 153 * Handle commands from user-space.
145 */ 154 */
146static int ks8695_wdt_ioctl(struct inode *inode, struct file *file, 155static long ks8695_wdt_ioctl(struct file *file, unsigned int cmd,
147 unsigned int cmd, unsigned long arg) 156 unsigned long arg)
148{ 157{
149 void __user *argp = (void __user *)arg; 158 void __user *argp = (void __user *)arg;
150 int __user *p = argp; 159 int __user *p = argp;
151 int new_value; 160 int new_value;
152 161
153 switch(cmd) { 162 switch (cmd) {
154 case WDIOC_KEEPALIVE: 163 case WDIOC_GETSUPPORT:
155 ks8695_wdt_reload(); /* pat the watchdog */ 164 return copy_to_user(argp, &ks8695_wdt_info,
156 return 0; 165 sizeof(ks8695_wdt_info)) ? -EFAULT : 0;
157 166 case WDIOC_GETSTATUS:
158 case WDIOC_GETSUPPORT: 167 case WDIOC_GETBOOTSTATUS:
159 return copy_to_user(argp, &ks8695_wdt_info, sizeof(ks8695_wdt_info)) ? -EFAULT : 0; 168 return put_user(0, p);
160 169 case WDIOC_SETOPTIONS:
161 case WDIOC_SETTIMEOUT: 170 if (get_user(new_value, p))
162 if (get_user(new_value, p)) 171 return -EFAULT;
163 return -EFAULT; 172 if (new_value & WDIOS_DISABLECARD)
164 173 ks8695_wdt_stop();
165 if (ks8695_wdt_settimeout(new_value)) 174 if (new_value & WDIOS_ENABLECARD)
166 return -EINVAL;
167
168 /* Enable new time value */
169 ks8695_wdt_start(); 175 ks8695_wdt_start();
170 176 return 0;
171 /* Return current value */ 177 case WDIOC_KEEPALIVE:
172 return put_user(wdt_time, p); 178 ks8695_wdt_reload(); /* pat the watchdog */
173 179 return 0;
174 case WDIOC_GETTIMEOUT: 180 case WDIOC_SETTIMEOUT:
175 return put_user(wdt_time, p); 181 if (get_user(new_value, p))
176 182 return -EFAULT;
177 case WDIOC_GETSTATUS: 183 if (ks8695_wdt_settimeout(new_value))
178 case WDIOC_GETBOOTSTATUS: 184 return -EINVAL;
179 return put_user(0, p); 185 /* Enable new time value */
180 186 ks8695_wdt_start();
181 case WDIOC_SETOPTIONS: 187 /* Return current value */
182 if (get_user(new_value, p)) 188 return put_user(wdt_time, p);
183 return -EFAULT; 189 case WDIOC_GETTIMEOUT:
184 190 return put_user(wdt_time, p);
185 if (new_value & WDIOS_DISABLECARD) 191 default:
186 ks8695_wdt_stop(); 192 return -ENOTTY;
187 if (new_value & WDIOS_ENABLECARD)
188 ks8695_wdt_start();
189 return 0;
190
191 default:
192 return -ENOTTY;
193 } 193 }
194} 194}
195 195
196/* 196/*
197 * Pat the watchdog whenever device is written to. 197 * Pat the watchdog whenever device is written to.
198 */ 198 */
199static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 199static ssize_t ks8695_wdt_write(struct file *file, const char *data,
200 size_t len, loff_t *ppos)
200{ 201{
201 ks8695_wdt_reload(); /* pat the watchdog */ 202 ks8695_wdt_reload(); /* pat the watchdog */
202 return len; 203 return len;
@@ -207,7 +208,7 @@ static ssize_t ks8695_wdt_write(struct file *file, const char *data, size_t len,
207static const struct file_operations ks8695wdt_fops = { 208static const struct file_operations ks8695wdt_fops = {
208 .owner = THIS_MODULE, 209 .owner = THIS_MODULE,
209 .llseek = no_llseek, 210 .llseek = no_llseek,
210 .ioctl = ks8695_wdt_ioctl, 211 .unlocked_ioctl = ks8695_wdt_ioctl,
211 .open = ks8695_wdt_open, 212 .open = ks8695_wdt_open,
212 .release = ks8695_wdt_close, 213 .release = ks8695_wdt_close,
213 .write = ks8695_wdt_write, 214 .write = ks8695_wdt_write,
@@ -231,7 +232,8 @@ static int __init ks8695wdt_probe(struct platform_device *pdev)
231 if (res) 232 if (res)
232 return res; 233 return res;
233 234
234 printk("KS8695 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); 235 printk(KERN_INFO "KS8695 Watchdog Timer enabled (%d seconds%s)\n",
236 wdt_time, nowayout ? ", nowayout" : "");
235 return 0; 237 return 0;
236} 238}
237 239
@@ -285,12 +287,14 @@ static struct platform_driver ks8695wdt_driver = {
285 287
286static int __init ks8695_wdt_init(void) 288static int __init ks8695_wdt_init(void)
287{ 289{
288 /* Check that the heartbeat value is within range; if not reset to the default */ 290 spin_lock_init(&ks8695_lock);
291 /* Check that the heartbeat value is within range;
292 if not reset to the default */
289 if (ks8695_wdt_settimeout(wdt_time)) { 293 if (ks8695_wdt_settimeout(wdt_time)) {
290 ks8695_wdt_settimeout(WDT_DEFAULT_TIME); 294 ks8695_wdt_settimeout(WDT_DEFAULT_TIME);
291 pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n", wdt_time, WDT_MAX_TIME); 295 pr_info("ks8695_wdt: wdt_time value must be 1 <= wdt_time <= %i, using %d\n",
296 wdt_time, WDT_MAX_TIME);
292 } 297 }
293
294 return platform_driver_register(&ks8695wdt_driver); 298 return platform_driver_register(&ks8695wdt_driver);
295} 299}
296 300
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 6905135a776c..2dfc27559bf7 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -40,9 +40,9 @@
40#include <linux/notifier.h> 40#include <linux/notifier.h>
41#include <linux/reboot.h> 41#include <linux/reboot.h>
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/io.h>
44#include <linux/uaccess.h>
43 45
44#include <asm/io.h>
45#include <asm/uaccess.h>
46#include <asm/system.h> 46#include <asm/system.h>
47 47
48/* ports */ 48/* ports */
@@ -95,7 +95,9 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
95 95
96static int nowayout = WATCHDOG_NOWAYOUT; 96static int nowayout = WATCHDOG_NOWAYOUT;
97module_param(nowayout, int, 0); 97module_param(nowayout, int, 0);
98MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 98MODULE_PARM_DESC(nowayout,
99 "Watchdog cannot be stopped once started (default="
100 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
99 101
100#define PFX "machzwd" 102#define PFX "machzwd"
101 103
@@ -114,7 +116,7 @@ static struct watchdog_info zf_info = {
114 * 3 = GEN_SCI 116 * 3 = GEN_SCI
115 * defaults to GEN_RESET (0) 117 * defaults to GEN_RESET (0)
116 */ 118 */
117static int action = 0; 119static int action;
118module_param(action, int, 0); 120module_param(action, int, 0);
119MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); 121MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
120 122
@@ -123,10 +125,9 @@ static void zf_ping(unsigned long data);
123static int zf_action = GEN_RESET; 125static int zf_action = GEN_RESET;
124static unsigned long zf_is_open; 126static unsigned long zf_is_open;
125static char zf_expect_close; 127static char zf_expect_close;
126static DEFINE_SPINLOCK(zf_lock);
127static DEFINE_SPINLOCK(zf_port_lock); 128static DEFINE_SPINLOCK(zf_port_lock);
128static DEFINE_TIMER(zf_timer, zf_ping, 0, 0); 129static DEFINE_TIMER(zf_timer, zf_ping, 0, 0);
129static unsigned long next_heartbeat = 0; 130static unsigned long next_heartbeat;
130 131
131 132
132/* timeout for user land heart beat (10 seconds) */ 133/* timeout for user land heart beat (10 seconds) */
@@ -171,13 +172,13 @@ static inline void zf_set_control(unsigned short new)
171 172
172static inline void zf_set_timer(unsigned short new, unsigned char n) 173static inline void zf_set_timer(unsigned short new, unsigned char n)
173{ 174{
174 switch(n){ 175 switch (n) {
175 case WD1: 176 case WD1:
176 zf_writew(COUNTER_1, new); 177 zf_writew(COUNTER_1, new);
177 case WD2: 178 case WD2:
178 zf_writeb(COUNTER_2, new > 0xff ? 0xff : new); 179 zf_writeb(COUNTER_2, new > 0xff ? 0xff : new);
179 default: 180 default:
180 return; 181 return;
181 } 182 }
182} 183}
183 184
@@ -241,10 +242,8 @@ static void zf_ping(unsigned long data)
241 242
242 zf_writeb(COUNTER_2, 0xff); 243 zf_writeb(COUNTER_2, 0xff);
243 244
244 if(time_before(jiffies, next_heartbeat)){ 245 if (time_before(jiffies, next_heartbeat)) {
245
246 dprintk("time_before: %ld\n", next_heartbeat - jiffies); 246 dprintk("time_before: %ld\n", next_heartbeat - jiffies);
247
248 /* 247 /*
249 * reset event is activated by transition from 0 to 1 on 248 * reset event is activated by transition from 0 to 1 on
250 * RESET_WD1 bit and we assume that it is already zero... 249 * RESET_WD1 bit and we assume that it is already zero...
@@ -261,24 +260,21 @@ static void zf_ping(unsigned long data)
261 spin_unlock_irqrestore(&zf_port_lock, flags); 260 spin_unlock_irqrestore(&zf_port_lock, flags);
262 261
263 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO); 262 mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
264 }else{ 263 } else
265 printk(KERN_CRIT PFX ": I will reset your machine\n"); 264 printk(KERN_CRIT PFX ": I will reset your machine\n");
266 }
267} 265}
268 266
269static ssize_t zf_write(struct file *file, const char __user *buf, size_t count, 267static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
270 loff_t *ppos) 268 loff_t *ppos)
271{ 269{
272 /* See if we got the magic character */ 270 /* See if we got the magic character */
273 if(count){ 271 if (count) {
274
275 /* 272 /*
276 * no need to check for close confirmation 273 * no need to check for close confirmation
277 * no way to disable watchdog ;) 274 * no way to disable watchdog ;)
278 */ 275 */
279 if (!nowayout) { 276 if (!nowayout) {
280 size_t ofs; 277 size_t ofs;
281
282 /* 278 /*
283 * note: just in case someone wrote the magic character 279 * note: just in case someone wrote the magic character
284 * five months ago... 280 * five months ago...
@@ -286,11 +282,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
286 zf_expect_close = 0; 282 zf_expect_close = 0;
287 283
288 /* now scan */ 284 /* now scan */
289 for (ofs = 0; ofs != count; ofs++){ 285 for (ofs = 0; ofs != count; ofs++) {
290 char c; 286 char c;
291 if (get_user(c, buf + ofs)) 287 if (get_user(c, buf + ofs))
292 return -EFAULT; 288 return -EFAULT;
293 if (c == 'V'){ 289 if (c == 'V') {
294 zf_expect_close = 42; 290 zf_expect_close = 42;
295 dprintk("zf_expect_close = 42\n"); 291 dprintk("zf_expect_close = 42\n");
296 } 292 }
@@ -303,14 +299,11 @@ static ssize_t zf_write(struct file *file, const char __user *buf, size_t count,
303 */ 299 */
304 next_heartbeat = jiffies + ZF_USER_TIMEO; 300 next_heartbeat = jiffies + ZF_USER_TIMEO;
305 dprintk("user ping at %ld\n", jiffies); 301 dprintk("user ping at %ld\n", jiffies);
306
307 } 302 }
308
309 return count; 303 return count;
310} 304}
311 305
312static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 306static long zf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
313 unsigned long arg)
314{ 307{
315 void __user *argp = (void __user *)arg; 308 void __user *argp = (void __user *)arg;
316 int __user *p = argp; 309 int __user *p = argp;
@@ -319,55 +312,38 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
319 if (copy_to_user(argp, &zf_info, sizeof(zf_info))) 312 if (copy_to_user(argp, &zf_info, sizeof(zf_info)))
320 return -EFAULT; 313 return -EFAULT;
321 break; 314 break;
322
323 case WDIOC_GETSTATUS: 315 case WDIOC_GETSTATUS:
324 case WDIOC_GETBOOTSTATUS: 316 case WDIOC_GETBOOTSTATUS:
325 return put_user(0, p); 317 return put_user(0, p);
326
327 case WDIOC_KEEPALIVE: 318 case WDIOC_KEEPALIVE:
328 zf_ping(0); 319 zf_ping(0);
329 break; 320 break;
330
331 default: 321 default:
332 return -ENOTTY; 322 return -ENOTTY;
333 } 323 }
334
335 return 0; 324 return 0;
336} 325}
337 326
338static int zf_open(struct inode *inode, struct file *file) 327static int zf_open(struct inode *inode, struct file *file)
339{ 328{
340 spin_lock(&zf_lock); 329 if (test_and_set_bit(0, &zf_is_open))
341 if(test_and_set_bit(0, &zf_is_open)) {
342 spin_unlock(&zf_lock);
343 return -EBUSY; 330 return -EBUSY;
344 }
345
346 if (nowayout) 331 if (nowayout)
347 __module_get(THIS_MODULE); 332 __module_get(THIS_MODULE);
348
349 spin_unlock(&zf_lock);
350
351 zf_timer_on(); 333 zf_timer_on();
352
353 return nonseekable_open(inode, file); 334 return nonseekable_open(inode, file);
354} 335}
355 336
356static int zf_close(struct inode *inode, struct file *file) 337static int zf_close(struct inode *inode, struct file *file)
357{ 338{
358 if(zf_expect_close == 42){ 339 if (zf_expect_close == 42)
359 zf_timer_off(); 340 zf_timer_off();
360 } else { 341 else {
361 del_timer(&zf_timer); 342 del_timer(&zf_timer);
362 printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); 343 printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n");
363 } 344 }
364
365 spin_lock(&zf_lock);
366 clear_bit(0, &zf_is_open); 345 clear_bit(0, &zf_is_open);
367 spin_unlock(&zf_lock);
368
369 zf_expect_close = 0; 346 zf_expect_close = 0;
370
371 return 0; 347 return 0;
372} 348}
373 349
@@ -378,23 +354,18 @@ static int zf_close(struct inode *inode, struct file *file)
378static int zf_notify_sys(struct notifier_block *this, unsigned long code, 354static int zf_notify_sys(struct notifier_block *this, unsigned long code,
379 void *unused) 355 void *unused)
380{ 356{
381 if(code == SYS_DOWN || code == SYS_HALT){ 357 if (code == SYS_DOWN || code == SYS_HALT)
382 zf_timer_off(); 358 zf_timer_off();
383 }
384
385 return NOTIFY_DONE; 359 return NOTIFY_DONE;
386} 360}
387 361
388
389
390
391static const struct file_operations zf_fops = { 362static const struct file_operations zf_fops = {
392 .owner = THIS_MODULE, 363 .owner = THIS_MODULE,
393 .llseek = no_llseek, 364 .llseek = no_llseek,
394 .write = zf_write, 365 .write = zf_write,
395 .ioctl = zf_ioctl, 366 .unlocked_ioctl = zf_ioctl,
396 .open = zf_open, 367 .open = zf_open,
397 .release = zf_close, 368 .release = zf_close,
398}; 369};
399 370
400static struct miscdevice zf_miscdev = { 371static struct miscdevice zf_miscdev = {
@@ -402,7 +373,7 @@ static struct miscdevice zf_miscdev = {
402 .name = "watchdog", 373 .name = "watchdog",
403 .fops = &zf_fops, 374 .fops = &zf_fops,
404}; 375};
405 376
406 377
407/* 378/*
408 * The device needs to learn about soft shutdowns in order to 379 * The device needs to learn about soft shutdowns in order to
@@ -423,22 +394,23 @@ static int __init zf_init(void)
423{ 394{
424 int ret; 395 int ret;
425 396
426 printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n"); 397 printk(KERN_INFO PFX
398 ": MachZ ZF-Logic Watchdog driver initializing.\n");
427 399
428 ret = zf_get_ZFL_version(); 400 ret = zf_get_ZFL_version();
429 if ((!ret) || (ret == 0xffff)) { 401 if (!ret || ret == 0xffff) {
430 printk(KERN_WARNING PFX ": no ZF-Logic found\n"); 402 printk(KERN_WARNING PFX ": no ZF-Logic found\n");
431 return -ENODEV; 403 return -ENODEV;
432 } 404 }
433 405
434 if((action <= 3) && (action >= 0)){ 406 if (action <= 3 && action >= 0)
435 zf_action = zf_action>>action; 407 zf_action = zf_action >> action;
436 } else 408 else
437 action = 0; 409 action = 0;
438 410
439 zf_show_action(action); 411 zf_show_action(action);
440 412
441 if(!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")){ 413 if (!request_region(ZF_IOBASE, 3, "MachZ ZFL WDT")) {
442 printk(KERN_ERR "cannot reserve I/O ports at %d\n", 414 printk(KERN_ERR "cannot reserve I/O ports at %d\n",
443 ZF_IOBASE); 415 ZF_IOBASE);
444 ret = -EBUSY; 416 ret = -EBUSY;
@@ -446,14 +418,14 @@ static int __init zf_init(void)
446 } 418 }
447 419
448 ret = register_reboot_notifier(&zf_notifier); 420 ret = register_reboot_notifier(&zf_notifier);
449 if(ret){ 421 if (ret) {
450 printk(KERN_ERR "can't register reboot notifier (err=%d)\n", 422 printk(KERN_ERR "can't register reboot notifier (err=%d)\n",
451 ret); 423 ret);
452 goto no_reboot; 424 goto no_reboot;
453 } 425 }
454 426
455 ret = misc_register(&zf_miscdev); 427 ret = misc_register(&zf_miscdev);
456 if (ret){ 428 if (ret) {
457 printk(KERN_ERR "can't misc_register on minor=%d\n", 429 printk(KERN_ERR "can't misc_register on minor=%d\n",
458 WATCHDOG_MINOR); 430 WATCHDOG_MINOR);
459 goto no_misc; 431 goto no_misc;
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 1adf1d56027d..407b025cb104 100644
--- a/drivers/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
@@ -29,7 +29,8 @@
29 * - support for one more type board 29 * - support for one more type board
30 * 30 *
31 * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> 31 * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com>
32 * - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT 32 * - added nowayout module option to override
33 * CONFIG_WATCHDOG_NOWAYOUT
33 * 34 *
34 * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> 35 * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com>
35 * - make mixcomwd_opened unsigned, 36 * - make mixcomwd_opened unsigned,
@@ -53,8 +54,8 @@
53#include <linux/init.h> 54#include <linux/init.h>
54#include <linux/jiffies.h> 55#include <linux/jiffies.h>
55#include <linux/timer.h> 56#include <linux/timer.h>
56#include <asm/uaccess.h> 57#include <linux/uaccess.h>
57#include <asm/io.h> 58#include <linux/io.h>
58 59
59/* 60/*
60 * We have two types of cards that can be probed: 61 * We have two types of cards that can be probed:
@@ -108,18 +109,19 @@ static char expect_close;
108 109
109static int nowayout = WATCHDOG_NOWAYOUT; 110static int nowayout = WATCHDOG_NOWAYOUT;
110module_param(nowayout, int, 0); 111module_param(nowayout, int, 0);
111MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 112MODULE_PARM_DESC(nowayout,
113 "Watchdog cannot be stopped once started (default="
114 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
112 115
113static void mixcomwd_ping(void) 116static void mixcomwd_ping(void)
114{ 117{
115 outb_p(55,watchdog_port); 118 outb_p(55, watchdog_port);
116 return; 119 return;
117} 120}
118 121
119static void mixcomwd_timerfun(unsigned long d) 122static void mixcomwd_timerfun(unsigned long d)
120{ 123{
121 mixcomwd_ping(); 124 mixcomwd_ping();
122
123 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); 125 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
124} 126}
125 127
@@ -129,22 +131,22 @@ static void mixcomwd_timerfun(unsigned long d)
129 131
130static int mixcomwd_open(struct inode *inode, struct file *file) 132static int mixcomwd_open(struct inode *inode, struct file *file)
131{ 133{
132 if(test_and_set_bit(0,&mixcomwd_opened)) { 134 if (test_and_set_bit(0, &mixcomwd_opened))
133 return -EBUSY; 135 return -EBUSY;
134 } 136
135 mixcomwd_ping(); 137 mixcomwd_ping();
136 138
137 if (nowayout) { 139 if (nowayout)
138 /* 140 /*
139 * fops_get() code via open() has already done 141 * fops_get() code via open() has already done
140 * a try_module_get() so it is safe to do the 142 * a try_module_get() so it is safe to do the
141 * __module_get(). 143 * __module_get().
142 */ 144 */
143 __module_get(THIS_MODULE); 145 __module_get(THIS_MODULE);
144 } else { 146 else {
145 if(mixcomwd_timer_alive) { 147 if (mixcomwd_timer_alive) {
146 del_timer(&mixcomwd_timer); 148 del_timer(&mixcomwd_timer);
147 mixcomwd_timer_alive=0; 149 mixcomwd_timer_alive = 0;
148 } 150 }
149 } 151 }
150 return nonseekable_open(inode, file); 152 return nonseekable_open(inode, file);
@@ -153,26 +155,27 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
153static int mixcomwd_release(struct inode *inode, struct file *file) 155static int mixcomwd_release(struct inode *inode, struct file *file)
154{ 156{
155 if (expect_close == 42) { 157 if (expect_close == 42) {
156 if(mixcomwd_timer_alive) { 158 if (mixcomwd_timer_alive) {
157 printk(KERN_ERR PFX "release called while internal timer alive"); 159 printk(KERN_ERR PFX
160 "release called while internal timer alive");
158 return -EBUSY; 161 return -EBUSY;
159 } 162 }
160 mixcomwd_timer_alive=1; 163 mixcomwd_timer_alive = 1;
161 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); 164 mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
162 } else { 165 } else
163 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 166 printk(KERN_CRIT PFX
164 } 167 "WDT device closed unexpectedly. WDT will not stop!\n");
165 168
166 clear_bit(0,&mixcomwd_opened); 169 clear_bit(0, &mixcomwd_opened);
167 expect_close=0; 170 expect_close = 0;
168 return 0; 171 return 0;
169} 172}
170 173
171 174
172static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) 175static ssize_t mixcomwd_write(struct file *file, const char __user *data,
176 size_t len, loff_t *ppos)
173{ 177{
174 if(len) 178 if (len) {
175 {
176 if (!nowayout) { 179 if (!nowayout) {
177 size_t i; 180 size_t i;
178 181
@@ -192,8 +195,8 @@ static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t
192 return len; 195 return len;
193} 196}
194 197
195static int mixcomwd_ioctl(struct inode *inode, struct file *file, 198static long mixcomwd_ioctl(struct file *file,
196 unsigned int cmd, unsigned long arg) 199 unsigned int cmd, unsigned long arg)
197{ 200{
198 void __user *argp = (void __user *)arg; 201 void __user *argp = (void __user *)arg;
199 int __user *p = argp; 202 int __user *p = argp;
@@ -204,32 +207,23 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
204 .identity = "MixCOM watchdog", 207 .identity = "MixCOM watchdog",
205 }; 208 };
206 209
207 switch(cmd) 210 switch (cmd) {
208 { 211 case WDIOC_GETSUPPORT:
209 case WDIOC_GETSTATUS: 212 if (copy_to_user(argp, &ident, sizeof(ident)))
210 status=mixcomwd_opened; 213 return -EFAULT;
211 if (!nowayout) { 214 break;
212 status|=mixcomwd_timer_alive; 215 case WDIOC_GETSTATUS:
213 } 216 status = mixcomwd_opened;
214 if (copy_to_user(p, &status, sizeof(int))) { 217 if (!nowayout)
215 return -EFAULT; 218 status |= mixcomwd_timer_alive;
216 } 219 return put_user(status, p);
217 break; 220 case WDIOC_GETBOOTSTATUS:
218 case WDIOC_GETBOOTSTATUS: 221 return put_user(0, p);
219 if (copy_to_user(p, &status, sizeof(int))) { 222 case WDIOC_KEEPALIVE:
220 return -EFAULT; 223 mixcomwd_ping();
221 } 224 break;
222 break; 225 default:
223 case WDIOC_GETSUPPORT: 226 return -ENOTTY;
224 if (copy_to_user(argp, &ident, sizeof(ident))) {
225 return -EFAULT;
226 }
227 break;
228 case WDIOC_KEEPALIVE:
229 mixcomwd_ping();
230 break;
231 default:
232 return -ENOTTY;
233 } 227 }
234 return 0; 228 return 0;
235} 229}
@@ -238,7 +232,7 @@ static const struct file_operations mixcomwd_fops = {
238 .owner = THIS_MODULE, 232 .owner = THIS_MODULE,
239 .llseek = no_llseek, 233 .llseek = no_llseek,
240 .write = mixcomwd_write, 234 .write = mixcomwd_write,
241 .ioctl = mixcomwd_ioctl, 235 .unlocked_ioctl = mixcomwd_ioctl,
242 .open = mixcomwd_open, 236 .open = mixcomwd_open,
243 .release = mixcomwd_release, 237 .release = mixcomwd_release,
244}; 238};
@@ -253,15 +247,14 @@ static int __init checkcard(int port, int card_id)
253{ 247{
254 int id; 248 int id;
255 249
256 if (!request_region(port, 1, "MixCOM watchdog")) { 250 if (!request_region(port, 1, "MixCOM watchdog"))
257 return 0; 251 return 0;
258 }
259 252
260 id=inb_p(port); 253 id = inb_p(port);
261 if (card_id==MIXCOM_ID) 254 if (card_id == MIXCOM_ID)
262 id &= 0x3f; 255 id &= 0x3f;
263 256
264 if (id!=card_id) { 257 if (id != card_id) {
265 release_region(port, 1); 258 release_region(port, 1);
266 return 0; 259 return 0;
267 } 260 }
@@ -270,9 +263,7 @@ static int __init checkcard(int port, int card_id)
270 263
271static int __init mixcomwd_init(void) 264static int __init mixcomwd_init(void)
272{ 265{
273 int i; 266 int i, ret, found = 0;
274 int ret;
275 int found=0;
276 267
277 for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { 268 for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) {
278 if (checkcard(mixcomwd_io_info[i].ioport, 269 if (checkcard(mixcomwd_io_info[i].ioport,
@@ -283,20 +274,22 @@ static int __init mixcomwd_init(void)
283 } 274 }
284 275
285 if (!found) { 276 if (!found) {
286 printk(KERN_ERR PFX "No card detected, or port not available.\n"); 277 printk(KERN_ERR PFX
278 "No card detected, or port not available.\n");
287 return -ENODEV; 279 return -ENODEV;
288 } 280 }
289 281
290 ret = misc_register(&mixcomwd_miscdev); 282 ret = misc_register(&mixcomwd_miscdev);
291 if (ret) 283 if (ret) {
292 { 284 printk(KERN_ERR PFX
293 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 285 "cannot register miscdev on minor=%d (err=%d)\n",
294 WATCHDOG_MINOR, ret); 286 WATCHDOG_MINOR, ret);
295 goto error_misc_register_watchdog; 287 goto error_misc_register_watchdog;
296 } 288 }
297 289
298 printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", 290 printk(KERN_INFO
299 VERSION, watchdog_port); 291 "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n",
292 VERSION, watchdog_port);
300 293
301 return 0; 294 return 0;
302 295
@@ -309,15 +302,15 @@ error_misc_register_watchdog:
309static void __exit mixcomwd_exit(void) 302static void __exit mixcomwd_exit(void)
310{ 303{
311 if (!nowayout) { 304 if (!nowayout) {
312 if(mixcomwd_timer_alive) { 305 if (mixcomwd_timer_alive) {
313 printk(KERN_WARNING PFX "I quit now, hardware will" 306 printk(KERN_WARNING PFX "I quit now, hardware will"
314 " probably reboot!\n"); 307 " probably reboot!\n");
315 del_timer_sync(&mixcomwd_timer); 308 del_timer_sync(&mixcomwd_timer);
316 mixcomwd_timer_alive=0; 309 mixcomwd_timer_alive = 0;
317 } 310 }
318 } 311 }
319 misc_deregister(&mixcomwd_miscdev); 312 misc_deregister(&mixcomwd_miscdev);
320 release_region(watchdog_port,1); 313 release_region(watchdog_port, 1);
321} 314}
322 315
323module_init(mixcomwd_init); 316module_init(mixcomwd_init);
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c
index 77c1c2ae2cc2..db91892558f2 100644
--- a/drivers/watchdog/mpc5200_wdt.c
+++ b/drivers/watchdog/mpc5200_wdt.c
@@ -5,7 +5,7 @@
5#include <linux/io.h> 5#include <linux/io.h>
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/of_platform.h> 7#include <linux/of_platform.h>
8#include <asm/uaccess.h> 8#include <linux/uaccess.h>
9#include <asm/mpc52xx.h> 9#include <asm/mpc52xx.h>
10 10
11 11
@@ -57,7 +57,8 @@ static int mpc5200_wdt_start(struct mpc5200_wdt *wdt)
57 /* set timeout, with maximum prescaler */ 57 /* set timeout, with maximum prescaler */
58 out_be32(&wdt->regs->count, 0x0 | wdt->count); 58 out_be32(&wdt->regs->count, 0x0 | wdt->count);
59 /* enable watchdog */ 59 /* enable watchdog */
60 out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | GPT_MODE_MS_TIMER); 60 out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT |
61 GPT_MODE_MS_TIMER);
61 spin_unlock(&wdt->io_lock); 62 spin_unlock(&wdt->io_lock);
62 63
63 return 0; 64 return 0;
@@ -66,7 +67,8 @@ static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt)
66{ 67{
67 spin_lock(&wdt->io_lock); 68 spin_lock(&wdt->io_lock);
68 /* writing A5 to OCPW resets the watchdog */ 69 /* writing A5 to OCPW resets the watchdog */
69 out_be32(&wdt->regs->mode, 0xA5000000 | (0xffffff & in_be32(&wdt->regs->mode))); 70 out_be32(&wdt->regs->mode, 0xA5000000 |
71 (0xffffff & in_be32(&wdt->regs->mode)));
70 spin_unlock(&wdt->io_lock); 72 spin_unlock(&wdt->io_lock);
71 return 0; 73 return 0;
72} 74}
@@ -92,8 +94,8 @@ static struct watchdog_info mpc5200_wdt_info = {
92 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 94 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
93 .identity = "mpc5200 watchdog on GPT0", 95 .identity = "mpc5200 watchdog on GPT0",
94}; 96};
95static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file, 97static long mpc5200_wdt_ioctl(struct file *file, unsigned int cmd,
96 unsigned int cmd, unsigned long arg) 98 unsigned long arg)
97{ 99{
98 struct mpc5200_wdt *wdt = file->private_data; 100 struct mpc5200_wdt *wdt = file->private_data;
99 int __user *data = (int __user *)arg; 101 int __user *data = (int __user *)arg;
@@ -103,7 +105,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file,
103 switch (cmd) { 105 switch (cmd) {
104 case WDIOC_GETSUPPORT: 106 case WDIOC_GETSUPPORT:
105 ret = copy_to_user(data, &mpc5200_wdt_info, 107 ret = copy_to_user(data, &mpc5200_wdt_info,
106 sizeof(mpc5200_wdt_info)); 108 sizeof(mpc5200_wdt_info));
107 if (ret) 109 if (ret)
108 ret = -EFAULT; 110 ret = -EFAULT;
109 break; 111 break;
@@ -135,6 +137,7 @@ static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file,
135 } 137 }
136 return ret; 138 return ret;
137} 139}
140
138static int mpc5200_wdt_open(struct inode *inode, struct file *file) 141static int mpc5200_wdt_open(struct inode *inode, struct file *file)
139{ 142{
140 /* /dev/watchdog can only be opened once */ 143 /* /dev/watchdog can only be opened once */
@@ -161,13 +164,14 @@ static int mpc5200_wdt_release(struct inode *inode, struct file *file)
161static const struct file_operations mpc5200_wdt_fops = { 164static const struct file_operations mpc5200_wdt_fops = {
162 .owner = THIS_MODULE, 165 .owner = THIS_MODULE,
163 .write = mpc5200_wdt_write, 166 .write = mpc5200_wdt_write,
164 .ioctl = mpc5200_wdt_ioctl, 167 .unlocked_ioctl = mpc5200_wdt_ioctl,
165 .open = mpc5200_wdt_open, 168 .open = mpc5200_wdt_open,
166 .release = mpc5200_wdt_release, 169 .release = mpc5200_wdt_release,
167}; 170};
168 171
169/* module operations */ 172/* module operations */
170static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *match) 173static int mpc5200_wdt_probe(struct of_device *op,
174 const struct of_device_id *match)
171{ 175{
172 struct mpc5200_wdt *wdt; 176 struct mpc5200_wdt *wdt;
173 int err; 177 int err;
@@ -215,9 +219,9 @@ static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *ma
215 return 0; 219 return 0;
216 220
217 iounmap(wdt->regs); 221 iounmap(wdt->regs);
218 out_release: 222out_release:
219 release_mem_region(wdt->mem.start, size); 223 release_mem_region(wdt->mem.start, size);
220 out_free: 224out_free:
221 kfree(wdt); 225 kfree(wdt);
222 return err; 226 return err;
223} 227}
diff --git a/drivers/watchdog/mpc83xx_wdt.c b/drivers/watchdog/mpc83xx_wdt.c
deleted file mode 100644
index b16c5cd972eb..000000000000
--- a/drivers/watchdog/mpc83xx_wdt.c
+++ /dev/null
@@ -1,230 +0,0 @@
1/*
2 * mpc83xx_wdt.c - MPC83xx watchdog userspace interface
3 *
4 * Authors: Dave Updegraff <dave@cray.org>
5 * Kumar Gala <galak@kernel.crashing.org>
6 * Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org>
7 * ..and from sc520_wdt
8 *
9 * Note: it appears that you can only actually ENABLE or DISABLE the thing
10 * once after POR. Once enabled, you cannot disable, and vice versa.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/fs.h>
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/miscdevice.h>
22#include <linux/platform_device.h>
23#include <linux/module.h>
24#include <linux/watchdog.h>
25#include <asm/io.h>
26#include <asm/uaccess.h>
27
28struct mpc83xx_wdt {
29 __be32 res0;
30 __be32 swcrr; /* System watchdog control register */
31#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
32#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
33#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
34#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
35 __be32 swcnr; /* System watchdog count register */
36 u8 res1[2];
37 __be16 swsrr; /* System watchdog service register */
38 u8 res2[0xF0];
39};
40
41static struct mpc83xx_wdt __iomem *wd_base;
42
43static u16 timeout = 0xffff;
44module_param(timeout, ushort, 0);
45MODULE_PARM_DESC(timeout, "Watchdog timeout in ticks. (0<timeout<65536, default=65535");
46
47static int reset = 1;
48module_param(reset, bool, 0);
49MODULE_PARM_DESC(reset, "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
50
51/*
52 * We always prescale, but if someone really doesn't want to they can set this
53 * to 0
54 */
55static int prescale = 1;
56static unsigned int timeout_sec;
57
58static unsigned long wdt_is_open;
59static DEFINE_SPINLOCK(wdt_spinlock);
60
61static void mpc83xx_wdt_keepalive(void)
62{
63 /* Ping the WDT */
64 spin_lock(&wdt_spinlock);
65 out_be16(&wd_base->swsrr, 0x556c);
66 out_be16(&wd_base->swsrr, 0xaa39);
67 spin_unlock(&wdt_spinlock);
68}
69
70static ssize_t mpc83xx_wdt_write(struct file *file, const char __user *buf,
71 size_t count, loff_t *ppos)
72{
73 if (count)
74 mpc83xx_wdt_keepalive();
75 return count;
76}
77
78static int mpc83xx_wdt_open(struct inode *inode, struct file *file)
79{
80 u32 tmp = SWCRR_SWEN;
81 if (test_and_set_bit(0, &wdt_is_open))
82 return -EBUSY;
83
84 /* Once we start the watchdog we can't stop it */
85 __module_get(THIS_MODULE);
86
87 /* Good, fire up the show */
88 if (prescale)
89 tmp |= SWCRR_SWPR;
90 if (reset)
91 tmp |= SWCRR_SWRI;
92
93 tmp |= timeout << 16;
94
95 out_be32(&wd_base->swcrr, tmp);
96
97 return nonseekable_open(inode, file);
98}
99
100static int mpc83xx_wdt_release(struct inode *inode, struct file *file)
101{
102 printk(KERN_CRIT "Unexpected close, not stopping watchdog!\n");
103 mpc83xx_wdt_keepalive();
104 clear_bit(0, &wdt_is_open);
105 return 0;
106}
107
108static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
109 unsigned int cmd, unsigned long arg)
110{
111 void __user *argp = (void __user *)arg;
112 int __user *p = argp;
113 static struct watchdog_info ident = {
114 .options = WDIOF_KEEPALIVEPING,
115 .firmware_version = 1,
116 .identity = "MPC83xx",
117 };
118
119 switch (cmd) {
120 case WDIOC_GETSUPPORT:
121 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
122 case WDIOC_GETSTATUS:
123 case WDIOC_GETBOOTSTATUS:
124 return put_user(0, p);
125 case WDIOC_KEEPALIVE:
126 mpc83xx_wdt_keepalive();
127 return 0;
128 case WDIOC_GETTIMEOUT:
129 return put_user(timeout_sec, p);
130 default:
131 return -ENOTTY;
132 }
133}
134
135static const struct file_operations mpc83xx_wdt_fops = {
136 .owner = THIS_MODULE,
137 .llseek = no_llseek,
138 .write = mpc83xx_wdt_write,
139 .ioctl = mpc83xx_wdt_ioctl,
140 .open = mpc83xx_wdt_open,
141 .release = mpc83xx_wdt_release,
142};
143
144static struct miscdevice mpc83xx_wdt_miscdev = {
145 .minor = WATCHDOG_MINOR,
146 .name = "watchdog",
147 .fops = &mpc83xx_wdt_fops,
148};
149
150static int __devinit mpc83xx_wdt_probe(struct platform_device *dev)
151{
152 struct resource *r;
153 int ret;
154 unsigned int *freq = dev->dev.platform_data;
155
156 /* get a pointer to the register memory */
157 r = platform_get_resource(dev, IORESOURCE_MEM, 0);
158
159 if (!r) {
160 ret = -ENODEV;
161 goto err_out;
162 }
163
164 wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt));
165
166 if (wd_base == NULL) {
167 ret = -ENOMEM;
168 goto err_out;
169 }
170
171 ret = misc_register(&mpc83xx_wdt_miscdev);
172 if (ret) {
173 printk(KERN_ERR "cannot register miscdev on minor=%d "
174 "(err=%d)\n",
175 WATCHDOG_MINOR, ret);
176 goto err_unmap;
177 }
178
179 /* Calculate the timeout in seconds */
180 if (prescale)
181 timeout_sec = (timeout * 0x10000) / (*freq);
182 else
183 timeout_sec = timeout / (*freq);
184
185 printk(KERN_INFO "WDT driver for MPC83xx initialized. "
186 "mode:%s timeout=%d (%d seconds)\n",
187 reset ? "reset":"interrupt", timeout, timeout_sec);
188 return 0;
189
190err_unmap:
191 iounmap(wd_base);
192err_out:
193 return ret;
194}
195
196static int __devexit mpc83xx_wdt_remove(struct platform_device *dev)
197{
198 misc_deregister(&mpc83xx_wdt_miscdev);
199 iounmap(wd_base);
200
201 return 0;
202}
203
204static struct platform_driver mpc83xx_wdt_driver = {
205 .probe = mpc83xx_wdt_probe,
206 .remove = __devexit_p(mpc83xx_wdt_remove),
207 .driver = {
208 .name = "mpc83xx_wdt",
209 .owner = THIS_MODULE,
210 },
211};
212
213static int __init mpc83xx_wdt_init(void)
214{
215 return platform_driver_register(&mpc83xx_wdt_driver);
216}
217
218static void __exit mpc83xx_wdt_exit(void)
219{
220 platform_driver_unregister(&mpc83xx_wdt_driver);
221}
222
223module_init(mpc83xx_wdt_init);
224module_exit(mpc83xx_wdt_exit);
225
226MODULE_AUTHOR("Dave Updegraff, Kumar Gala");
227MODULE_DESCRIPTION("Driver for watchdog timer in MPC83xx uProcessor");
228MODULE_LICENSE("GPL");
229MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
230MODULE_ALIAS("platform:mpc83xx_wdt");
diff --git a/drivers/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
index 85b5734403a5..1336425acf20 100644
--- a/drivers/watchdog/mpc8xx_wdt.c
+++ b/drivers/watchdog/mpc8xx_wdt.c
@@ -16,36 +16,35 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/watchdog.h> 17#include <linux/watchdog.h>
18#include <asm/8xx_immap.h> 18#include <asm/8xx_immap.h>
19#include <asm/uaccess.h> 19#include <linux/uaccess.h>
20#include <asm/io.h> 20#include <linux/io.h>
21#include <syslib/m8xx_wdt.h> 21#include <syslib/m8xx_wdt.h>
22 22
23static unsigned long wdt_opened; 23static unsigned long wdt_opened;
24static int wdt_status; 24static int wdt_status;
25static spinlock_t wdt_lock;
25 26
26static void mpc8xx_wdt_handler_disable(void) 27static void mpc8xx_wdt_handler_disable(void)
27{ 28{
28 volatile uint __iomem *piscr; 29 volatile uint __iomem *piscr;
29 piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; 30 piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;
30 31
31 if (!m8xx_has_internal_rtc) 32 if (!m8xx_has_internal_rtc)
32 m8xx_wdt_stop_timer(); 33 m8xx_wdt_stop_timer();
33 else 34 else
34 out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE)); 35 out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE));
35
36 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); 36 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
37} 37}
38 38
39static void mpc8xx_wdt_handler_enable(void) 39static void mpc8xx_wdt_handler_enable(void)
40{ 40{
41 volatile uint __iomem *piscr; 41 volatile uint __iomem *piscr;
42 piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; 42 piscr = (uint *)&((immap_t *)IMAP_ADDR)->im_sit.sit_piscr;
43 43
44 if (!m8xx_has_internal_rtc) 44 if (!m8xx_has_internal_rtc)
45 m8xx_wdt_install_timer(); 45 m8xx_wdt_install_timer();
46 else 46 else
47 out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE); 47 out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE);
48
49 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); 48 printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
50} 49}
51 50
@@ -53,37 +52,34 @@ static int mpc8xx_wdt_open(struct inode *inode, struct file *file)
53{ 52{
54 if (test_and_set_bit(0, &wdt_opened)) 53 if (test_and_set_bit(0, &wdt_opened))
55 return -EBUSY; 54 return -EBUSY;
56
57 m8xx_wdt_reset(); 55 m8xx_wdt_reset();
58 mpc8xx_wdt_handler_disable(); 56 mpc8xx_wdt_handler_disable();
59
60 return nonseekable_open(inode, file); 57 return nonseekable_open(inode, file);
61} 58}
62 59
63static int mpc8xx_wdt_release(struct inode *inode, struct file *file) 60static int mpc8xx_wdt_release(struct inode *inode, struct file *file)
64{ 61{
65 m8xx_wdt_reset(); 62 m8xx_wdt_reset();
66
67#if !defined(CONFIG_WATCHDOG_NOWAYOUT) 63#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
68 mpc8xx_wdt_handler_enable(); 64 mpc8xx_wdt_handler_enable();
69#endif 65#endif
70
71 clear_bit(0, &wdt_opened); 66 clear_bit(0, &wdt_opened);
72
73 return 0; 67 return 0;
74} 68}
75 69
76static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len, 70static ssize_t mpc8xx_wdt_write(struct file *file, const char *data,
77 loff_t * ppos) 71 size_t len, loff_t *ppos)
78{ 72{
79 if (len) 73 if (len) {
74 spin_lock(&wdt_lock);
80 m8xx_wdt_reset(); 75 m8xx_wdt_reset();
81 76 spin_unlock(&wdt_lock);
77 }
82 return len; 78 return len;
83} 79}
84 80
85static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file, 81static long mpc8xx_wdt_ioctl(struct file *file,
86 unsigned int cmd, unsigned long arg) 82 unsigned int cmd, unsigned long arg)
87{ 83{
88 int timeout; 84 int timeout;
89 static struct watchdog_info info = { 85 static struct watchdog_info info = {
@@ -112,15 +108,19 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file,
112 return -EOPNOTSUPP; 108 return -EOPNOTSUPP;
113 109
114 case WDIOC_KEEPALIVE: 110 case WDIOC_KEEPALIVE:
111 spin_lock(&wdt_lock);
115 m8xx_wdt_reset(); 112 m8xx_wdt_reset();
116 wdt_status |= WDIOF_KEEPALIVEPING; 113 wdt_status |= WDIOF_KEEPALIVEPING;
114 spin_unlock(&wdt_lock);
117 break; 115 break;
118 116
119 case WDIOC_SETTIMEOUT: 117 case WDIOC_SETTIMEOUT:
120 return -EOPNOTSUPP; 118 return -EOPNOTSUPP;
121 119
122 case WDIOC_GETTIMEOUT: 120 case WDIOC_GETTIMEOUT:
121 spin_lock(&wdt_lock);
123 timeout = m8xx_wdt_get_timeout(); 122 timeout = m8xx_wdt_get_timeout();
123 spin_unlock(&wdt_lock);
124 if (put_user(timeout, (int *)arg)) 124 if (put_user(timeout, (int *)arg))
125 return -EFAULT; 125 return -EFAULT;
126 break; 126 break;
@@ -136,7 +136,7 @@ static const struct file_operations mpc8xx_wdt_fops = {
136 .owner = THIS_MODULE, 136 .owner = THIS_MODULE,
137 .llseek = no_llseek, 137 .llseek = no_llseek,
138 .write = mpc8xx_wdt_write, 138 .write = mpc8xx_wdt_write,
139 .ioctl = mpc8xx_wdt_ioctl, 139 .unlocked_ioctl = mpc8xx_wdt_ioctl,
140 .open = mpc8xx_wdt_open, 140 .open = mpc8xx_wdt_open,
141 .release = mpc8xx_wdt_release, 141 .release = mpc8xx_wdt_release,
142}; 142};
@@ -149,6 +149,7 @@ static struct miscdevice mpc8xx_wdt_miscdev = {
149 149
150static int __init mpc8xx_wdt_init(void) 150static int __init mpc8xx_wdt_init(void)
151{ 151{
152 spin_lock_init(&wdt_lock);
152 return misc_register(&mpc8xx_wdt_miscdev); 153 return misc_register(&mpc8xx_wdt_miscdev);
153} 154}
154 155
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
new file mode 100644
index 000000000000..f2094960e662
--- /dev/null
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -0,0 +1,316 @@
1/*
2 * mpc8xxx_wdt.c - MPC8xx/MPC83xx/MPC86xx watchdog userspace interface
3 *
4 * Authors: Dave Updegraff <dave@cray.org>
5 * Kumar Gala <galak@kernel.crashing.org>
6 * Attribution: from 83xx_wst: Florian Schirmer <jolt@tuxbox.org>
7 * ..and from sc520_wdt
8 * Copyright (c) 2008 MontaVista Software, Inc.
9 * Anton Vorontsov <avorontsov@ru.mvista.com>
10 *
11 * Note: it appears that you can only actually ENABLE or DISABLE the thing
12 * once after POR. Once enabled, you cannot disable, and vice versa.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 */
19
20#include <linux/fs.h>
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/timer.h>
24#include <linux/miscdevice.h>
25#include <linux/of_platform.h>
26#include <linux/module.h>
27#include <linux/watchdog.h>
28#include <linux/io.h>
29#include <linux/uaccess.h>
30#include <sysdev/fsl_soc.h>
31
32struct mpc8xxx_wdt {
33 __be32 res0;
34 __be32 swcrr; /* System watchdog control register */
35#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
36#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
37#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
38#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
39 __be32 swcnr; /* System watchdog count register */
40 u8 res1[2];
41 __be16 swsrr; /* System watchdog service register */
42 u8 res2[0xF0];
43};
44
45struct mpc8xxx_wdt_type {
46 int prescaler;
47 bool hw_enabled;
48};
49
50static struct mpc8xxx_wdt __iomem *wd_base;
51
52static u16 timeout = 0xffff;
53module_param(timeout, ushort, 0);
54MODULE_PARM_DESC(timeout,
55 "Watchdog timeout in ticks. (0<timeout<65536, default=65535");
56
57static int reset = 1;
58module_param(reset, bool, 0);
59MODULE_PARM_DESC(reset,
60 "Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
61
62static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
65 "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
66
67/*
68 * We always prescale, but if someone really doesn't want to they can set this
69 * to 0
70 */
71static int prescale = 1;
72static unsigned int timeout_sec;
73
74static unsigned long wdt_is_open;
75static DEFINE_SPINLOCK(wdt_spinlock);
76
77static void mpc8xxx_wdt_keepalive(void)
78{
79 /* Ping the WDT */
80 spin_lock(&wdt_spinlock);
81 out_be16(&wd_base->swsrr, 0x556c);
82 out_be16(&wd_base->swsrr, 0xaa39);
83 spin_unlock(&wdt_spinlock);
84}
85
86static void mpc8xxx_wdt_timer_ping(unsigned long arg);
87static DEFINE_TIMER(wdt_timer, mpc8xxx_wdt_timer_ping, 0, 0);
88
89static void mpc8xxx_wdt_timer_ping(unsigned long arg)
90{
91 mpc8xxx_wdt_keepalive();
92 /* We're pinging it twice faster than needed, just to be sure. */
93 mod_timer(&wdt_timer, jiffies + HZ * timeout_sec / 2);
94}
95
96static void mpc8xxx_wdt_pr_warn(const char *msg)
97{
98 pr_crit("mpc8xxx_wdt: %s, expect the %s soon!\n", msg,
99 reset ? "reset" : "machine check exception");
100}
101
102static ssize_t mpc8xxx_wdt_write(struct file *file, const char __user *buf,
103 size_t count, loff_t *ppos)
104{
105 if (count)
106 mpc8xxx_wdt_keepalive();
107 return count;
108}
109
110static int mpc8xxx_wdt_open(struct inode *inode, struct file *file)
111{
112 u32 tmp = SWCRR_SWEN;
113 if (test_and_set_bit(0, &wdt_is_open))
114 return -EBUSY;
115
116 /* Once we start the watchdog we can't stop it */
117 if (nowayout)
118 __module_get(THIS_MODULE);
119
120 /* Good, fire up the show */
121 if (prescale)
122 tmp |= SWCRR_SWPR;
123 if (reset)
124 tmp |= SWCRR_SWRI;
125
126 tmp |= timeout << 16;
127
128 out_be32(&wd_base->swcrr, tmp);
129
130 del_timer_sync(&wdt_timer);
131
132 return nonseekable_open(inode, file);
133}
134
135static int mpc8xxx_wdt_release(struct inode *inode, struct file *file)
136{
137 if (!nowayout)
138 mpc8xxx_wdt_timer_ping(0);
139 else
140 mpc8xxx_wdt_pr_warn("watchdog closed");
141 clear_bit(0, &wdt_is_open);
142 return 0;
143}
144
145static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd,
146 unsigned long arg)
147{
148 void __user *argp = (void __user *)arg;
149 int __user *p = argp;
150 static struct watchdog_info ident = {
151 .options = WDIOF_KEEPALIVEPING,
152 .firmware_version = 1,
153 .identity = "MPC8xxx",
154 };
155
156 switch (cmd) {
157 case WDIOC_GETSUPPORT:
158 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
159 case WDIOC_GETSTATUS:
160 case WDIOC_GETBOOTSTATUS:
161 return put_user(0, p);
162 case WDIOC_KEEPALIVE:
163 mpc8xxx_wdt_keepalive();
164 return 0;
165 case WDIOC_GETTIMEOUT:
166 return put_user(timeout_sec, p);
167 default:
168 return -ENOTTY;
169 }
170}
171
172static const struct file_operations mpc8xxx_wdt_fops = {
173 .owner = THIS_MODULE,
174 .llseek = no_llseek,
175 .write = mpc8xxx_wdt_write,
176 .unlocked_ioctl = mpc8xxx_wdt_ioctl,
177 .open = mpc8xxx_wdt_open,
178 .release = mpc8xxx_wdt_release,
179};
180
181static struct miscdevice mpc8xxx_wdt_miscdev = {
182 .minor = WATCHDOG_MINOR,
183 .name = "watchdog",
184 .fops = &mpc8xxx_wdt_fops,
185};
186
187static int __devinit mpc8xxx_wdt_probe(struct of_device *ofdev,
188 const struct of_device_id *match)
189{
190 int ret;
191 struct device_node *np = ofdev->node;
192 struct mpc8xxx_wdt_type *wdt_type = match->data;
193 u32 freq = fsl_get_sys_freq();
194 bool enabled;
195
196 if (!freq || freq == -1)
197 return -EINVAL;
198
199 wd_base = of_iomap(np, 0);
200 if (!wd_base)
201 return -ENOMEM;
202
203 enabled = in_be32(&wd_base->swcrr) & SWCRR_SWEN;
204 if (!enabled && wdt_type->hw_enabled) {
205 pr_info("mpc8xxx_wdt: could not be enabled in software\n");
206 ret = -ENOSYS;
207 goto err_unmap;
208 }
209
210 /* Calculate the timeout in seconds */
211 if (prescale)
212 timeout_sec = (timeout * wdt_type->prescaler) / freq;
213 else
214 timeout_sec = timeout / freq;
215
216 pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d "
217 "(%d seconds)\n", reset ? "reset" : "interrupt", timeout,
218 timeout_sec);
219
220 /*
221 * If the watchdog was previously enabled or we're running on
222 * MPC8xxx, we should ping the wdt from the kernel until the
223 * userspace handles it.
224 */
225 if (enabled)
226 mpc8xxx_wdt_timer_ping(0);
227 return 0;
228err_unmap:
229 iounmap(wd_base);
230 wd_base = NULL;
231 return ret;
232}
233
234static int __devexit mpc8xxx_wdt_remove(struct of_device *ofdev)
235{
236 mpc8xxx_wdt_pr_warn("watchdog removed");
237 del_timer_sync(&wdt_timer);
238 misc_deregister(&mpc8xxx_wdt_miscdev);
239 iounmap(wd_base);
240
241 return 0;
242}
243
244static const struct of_device_id mpc8xxx_wdt_match[] = {
245 {
246 .compatible = "mpc83xx_wdt",
247 .data = &(struct mpc8xxx_wdt_type) {
248 .prescaler = 0x10000,
249 },
250 },
251 {
252 .compatible = "fsl,mpc8610-wdt",
253 .data = &(struct mpc8xxx_wdt_type) {
254 .prescaler = 0x10000,
255 .hw_enabled = true,
256 },
257 },
258 {
259 .compatible = "fsl,mpc823-wdt",
260 .data = &(struct mpc8xxx_wdt_type) {
261 .prescaler = 0x800,
262 },
263 },
264 {},
265};
266MODULE_DEVICE_TABLE(of, mpc8xxx_wdt_match);
267
268static struct of_platform_driver mpc8xxx_wdt_driver = {
269 .match_table = mpc8xxx_wdt_match,
270 .probe = mpc8xxx_wdt_probe,
271 .remove = __devexit_p(mpc8xxx_wdt_remove),
272 .driver = {
273 .name = "mpc8xxx_wdt",
274 .owner = THIS_MODULE,
275 },
276};
277
278/*
279 * We do wdt initialization in two steps: arch_initcall probes the wdt
280 * very early to start pinging the watchdog (misc devices are not yet
281 * available), and later module_init() just registers the misc device.
282 */
283static int __init mpc8xxx_wdt_init_late(void)
284{
285 int ret;
286
287 if (!wd_base)
288 return -ENODEV;
289
290 ret = misc_register(&mpc8xxx_wdt_miscdev);
291 if (ret) {
292 pr_err("cannot register miscdev on minor=%d (err=%d)\n",
293 WATCHDOG_MINOR, ret);
294 return ret;
295 }
296 return 0;
297}
298module_init(mpc8xxx_wdt_init_late);
299
300static int __init mpc8xxx_wdt_init(void)
301{
302 return of_register_platform_driver(&mpc8xxx_wdt_driver);
303}
304arch_initcall(mpc8xxx_wdt_init);
305
306static void __exit mpc8xxx_wdt_exit(void)
307{
308 of_unregister_platform_driver(&mpc8xxx_wdt_driver);
309}
310module_exit(mpc8xxx_wdt_exit);
311
312MODULE_AUTHOR("Dave Updegraff, Kumar Gala");
313MODULE_DESCRIPTION("Driver for watchdog timer in MPC8xx/MPC83xx/MPC86xx "
314 "uProcessors");
315MODULE_LICENSE("GPL");
316MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 009573b81496..2a9bfa81f9d6 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -29,9 +29,9 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/uaccess.h>
32 33
33#include <asm/hardware/arm_twd.h> 34#include <asm/hardware/arm_twd.h>
34#include <asm/uaccess.h>
35 35
36struct mpcore_wdt { 36struct mpcore_wdt {
37 unsigned long timer_alive; 37 unsigned long timer_alive;
@@ -43,17 +43,20 @@ struct mpcore_wdt {
43}; 43};
44 44
45static struct platform_device *mpcore_wdt_dev; 45static struct platform_device *mpcore_wdt_dev;
46
47extern unsigned int mpcore_timer_rate; 46extern unsigned int mpcore_timer_rate;
48 47
49#define TIMER_MARGIN 60 48#define TIMER_MARGIN 60
50static int mpcore_margin = TIMER_MARGIN; 49static int mpcore_margin = TIMER_MARGIN;
51module_param(mpcore_margin, int, 0); 50module_param(mpcore_margin, int, 0);
52MODULE_PARM_DESC(mpcore_margin, "MPcore timer margin in seconds. (0<mpcore_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); 51MODULE_PARM_DESC(mpcore_margin,
52 "MPcore timer margin in seconds. (0 < mpcore_margin < 65536, default="
53 __MODULE_STRING(TIMER_MARGIN) ")");
53 54
54static int nowayout = WATCHDOG_NOWAYOUT; 55static int nowayout = WATCHDOG_NOWAYOUT;
55module_param(nowayout, int, 0); 56module_param(nowayout, int, 0);
56MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 57MODULE_PARM_DESC(nowayout,
58 "Watchdog cannot be stopped once started (default="
59 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
57 60
58#define ONLY_TESTING 0 61#define ONLY_TESTING 0
59static int mpcore_noboot = ONLY_TESTING; 62static int mpcore_noboot = ONLY_TESTING;
@@ -70,14 +73,12 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
70 73
71 /* Check it really was our interrupt */ 74 /* Check it really was our interrupt */
72 if (readl(wdt->base + TWD_WDOG_INTSTAT)) { 75 if (readl(wdt->base + TWD_WDOG_INTSTAT)) {
73 dev_printk(KERN_CRIT, wdt->dev, "Triggered - Reboot ignored.\n"); 76 dev_printk(KERN_CRIT, wdt->dev,
74 77 "Triggered - Reboot ignored.\n");
75 /* Clear the interrupt on the watchdog */ 78 /* Clear the interrupt on the watchdog */
76 writel(1, wdt->base + TWD_WDOG_INTSTAT); 79 writel(1, wdt->base + TWD_WDOG_INTSTAT);
77
78 return IRQ_HANDLED; 80 return IRQ_HANDLED;
79 } 81 }
80
81 return IRQ_NONE; 82 return IRQ_NONE;
82} 83}
83 84
@@ -96,22 +97,26 @@ static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
96 count = (mpcore_timer_rate / 256) * mpcore_margin; 97 count = (mpcore_timer_rate / 256) * mpcore_margin;
97 98
98 /* Reload the counter */ 99 /* Reload the counter */
100 spin_lock(&wdt_lock);
99 writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD); 101 writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
100
101 wdt->perturb = wdt->perturb ? 0 : 1; 102 wdt->perturb = wdt->perturb ? 0 : 1;
103 spin_unlock(&wdt_lock);
102} 104}
103 105
104static void mpcore_wdt_stop(struct mpcore_wdt *wdt) 106static void mpcore_wdt_stop(struct mpcore_wdt *wdt)
105{ 107{
108 spin_lock(&wdt_lock);
106 writel(0x12345678, wdt->base + TWD_WDOG_DISABLE); 109 writel(0x12345678, wdt->base + TWD_WDOG_DISABLE);
107 writel(0x87654321, wdt->base + TWD_WDOG_DISABLE); 110 writel(0x87654321, wdt->base + TWD_WDOG_DISABLE);
108 writel(0x0, wdt->base + TWD_WDOG_CONTROL); 111 writel(0x0, wdt->base + TWD_WDOG_CONTROL);
112 spin_unlock(&wdt_lock);
109} 113}
110 114
111static void mpcore_wdt_start(struct mpcore_wdt *wdt) 115static void mpcore_wdt_start(struct mpcore_wdt *wdt)
112{ 116{
113 dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n"); 117 dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
114 118
119 spin_lock(&wdt_lock);
115 /* This loads the count register but does NOT start the count yet */ 120 /* This loads the count register but does NOT start the count yet */
116 mpcore_wdt_keepalive(wdt); 121 mpcore_wdt_keepalive(wdt);
117 122
@@ -122,6 +127,7 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
122 /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */ 127 /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
123 writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL); 128 writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
124 } 129 }
130 spin_unlock(&wdt_lock);
125} 131}
126 132
127static int mpcore_wdt_set_heartbeat(int t) 133static int mpcore_wdt_set_heartbeat(int t)
@@ -164,10 +170,11 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file)
164 * Shut off the timer. 170 * Shut off the timer.
165 * Lock it in if it's a module and we set nowayout 171 * Lock it in if it's a module and we set nowayout
166 */ 172 */
167 if (wdt->expect_close == 42) { 173 if (wdt->expect_close == 42)
168 mpcore_wdt_stop(wdt); 174 mpcore_wdt_stop(wdt);
169 } else { 175 else {
170 dev_printk(KERN_CRIT, wdt->dev, "unexpected close, not stopping watchdog!\n"); 176 dev_printk(KERN_CRIT, wdt->dev,
177 "unexpected close, not stopping watchdog!\n");
171 mpcore_wdt_keepalive(wdt); 178 mpcore_wdt_keepalive(wdt);
172 } 179 }
173 clear_bit(0, &wdt->timer_alive); 180 clear_bit(0, &wdt->timer_alive);
@@ -175,7 +182,8 @@ static int mpcore_wdt_release(struct inode *inode, struct file *file)
175 return 0; 182 return 0;
176} 183}
177 184
178static ssize_t mpcore_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) 185static ssize_t mpcore_wdt_write(struct file *file, const char *data,
186 size_t len, loff_t *ppos)
179{ 187{
180 struct mpcore_wdt *wdt = file->private_data; 188 struct mpcore_wdt *wdt = file->private_data;
181 189
@@ -210,8 +218,8 @@ static struct watchdog_info ident = {
210 .identity = "MPcore Watchdog", 218 .identity = "MPcore Watchdog",
211}; 219};
212 220
213static int mpcore_wdt_ioctl(struct inode *inode, struct file *file, 221static long mpcore_wdt_ioctl(struct file *file, unsigned int cmd,
214 unsigned int cmd, unsigned long arg) 222 unsigned long arg)
215{ 223{
216 struct mpcore_wdt *wdt = file->private_data; 224 struct mpcore_wdt *wdt = file->private_data;
217 int ret; 225 int ret;
@@ -235,6 +243,12 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
235 ret = 0; 243 ret = 0;
236 break; 244 break;
237 245
246 case WDIOC_GETSTATUS:
247 case WDIOC_GETBOOTSTATUS:
248 uarg.i = 0;
249 ret = 0;
250 break;
251
238 case WDIOC_SETOPTIONS: 252 case WDIOC_SETOPTIONS:
239 ret = -EINVAL; 253 ret = -EINVAL;
240 if (uarg.i & WDIOS_DISABLECARD) { 254 if (uarg.i & WDIOS_DISABLECARD) {
@@ -247,12 +261,6 @@ static int mpcore_wdt_ioctl(struct inode *inode, struct file *file,
247 } 261 }
248 break; 262 break;
249 263
250 case WDIOC_GETSTATUS:
251 case WDIOC_GETBOOTSTATUS:
252 uarg.i = 0;
253 ret = 0;
254 break;
255
256 case WDIOC_KEEPALIVE: 264 case WDIOC_KEEPALIVE:
257 mpcore_wdt_keepalive(wdt); 265 mpcore_wdt_keepalive(wdt);
258 ret = 0; 266 ret = 0;
@@ -301,7 +309,7 @@ static const struct file_operations mpcore_wdt_fops = {
301 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
302 .llseek = no_llseek, 310 .llseek = no_llseek,
303 .write = mpcore_wdt_write, 311 .write = mpcore_wdt_write,
304 .ioctl = mpcore_wdt_ioctl, 312 .unlocked_ioctl = mpcore_wdt_ioctl,
305 .open = mpcore_wdt_open, 313 .open = mpcore_wdt_open,
306 .release = mpcore_wdt_release, 314 .release = mpcore_wdt_release,
307}; 315};
@@ -349,14 +357,17 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
349 mpcore_wdt_miscdev.parent = &dev->dev; 357 mpcore_wdt_miscdev.parent = &dev->dev;
350 ret = misc_register(&mpcore_wdt_miscdev); 358 ret = misc_register(&mpcore_wdt_miscdev);
351 if (ret) { 359 if (ret) {
352 dev_printk(KERN_ERR, _dev, "cannot register miscdev on minor=%d (err=%d)\n", 360 dev_printk(KERN_ERR, _dev,
353 WATCHDOG_MINOR, ret); 361 "cannot register miscdev on minor=%d (err=%d)\n",
362 WATCHDOG_MINOR, ret);
354 goto err_misc; 363 goto err_misc;
355 } 364 }
356 365
357 ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED, "mpcore_wdt", wdt); 366 ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED,
367 "mpcore_wdt", wdt);
358 if (ret) { 368 if (ret) {
359 dev_printk(KERN_ERR, _dev, "cannot register IRQ%d for watchdog\n", wdt->irq); 369 dev_printk(KERN_ERR, _dev,
370 "cannot register IRQ%d for watchdog\n", wdt->irq);
360 goto err_irq; 371 goto err_irq;
361 } 372 }
362 373
@@ -366,13 +377,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
366 377
367 return 0; 378 return 0;
368 379
369 err_irq: 380err_irq:
370 misc_deregister(&mpcore_wdt_miscdev); 381 misc_deregister(&mpcore_wdt_miscdev);
371 err_misc: 382err_misc:
372 iounmap(wdt->base); 383 iounmap(wdt->base);
373 err_free: 384err_free:
374 kfree(wdt); 385 kfree(wdt);
375 err_out: 386err_out:
376 return ret; 387 return ret;
377} 388}
378 389
@@ -415,7 +426,7 @@ static int __init mpcore_wdt_init(void)
415 */ 426 */
416 if (mpcore_wdt_set_heartbeat(mpcore_margin)) { 427 if (mpcore_wdt_set_heartbeat(mpcore_margin)) {
417 mpcore_wdt_set_heartbeat(TIMER_MARGIN); 428 mpcore_wdt_set_heartbeat(TIMER_MARGIN);
418 printk(KERN_INFO "mpcore_margin value must be 0<mpcore_margin<65536, using %d\n", 429 printk(KERN_INFO "mpcore_margin value must be 0 < mpcore_margin < 65536, using %d\n",
419 TIMER_MARGIN); 430 TIMER_MARGIN);
420 } 431 }
421 432
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index a8e67383784e..b4b7b0a4c119 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Driver for the MTX-1 Watchdog. 2 * Driver for the MTX-1 Watchdog.
3 * 3 *
4 * (C) Copyright 2005 4G Systems <info@4g-systems.biz>, All Rights Reserved. 4 * (C) Copyright 2005 4G Systems <info@4g-systems.biz>,
5 * All Rights Reserved.
5 * http://www.4g-systems.biz 6 * http://www.4g-systems.biz
6 * 7 *
7 * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org> 8 * (C) Copyright 2007 OpenWrt.org, Florian Fainelli <florian@openwrt.org>
@@ -46,12 +47,11 @@
46#include <linux/jiffies.h> 47#include <linux/jiffies.h>
47#include <linux/watchdog.h> 48#include <linux/watchdog.h>
48#include <linux/platform_device.h> 49#include <linux/platform_device.h>
49 50#include <linux/io.h>
50#include <asm/io.h> 51#include <linux/uaccess.h>
51#include <asm/uaccess.h> 52#include <linux/gpio.h>
52 53
53#include <asm/mach-au1x00/au1000.h> 54#include <asm/mach-au1x00/au1000.h>
54#include <asm/gpio.h>
55 55
56#define MTX1_WDT_INTERVAL (5 * HZ) 56#define MTX1_WDT_INTERVAL (5 * HZ)
57 57
@@ -59,6 +59,7 @@ static int ticks = 100 * HZ;
59 59
60static struct { 60static struct {
61 struct completion stop; 61 struct completion stop;
62 spinlock_t lock;
62 int running; 63 int running;
63 struct timer_list timer; 64 struct timer_list timer;
64 int queue; 65 int queue;
@@ -71,6 +72,7 @@ static void mtx1_wdt_trigger(unsigned long unused)
71{ 72{
72 u32 tmp; 73 u32 tmp;
73 74
75 spin_lock(&mtx1_wdt_device.lock);
74 if (mtx1_wdt_device.running) 76 if (mtx1_wdt_device.running)
75 ticks--; 77 ticks--;
76 /* 78 /*
@@ -79,13 +81,13 @@ static void mtx1_wdt_trigger(unsigned long unused)
79 tmp = au_readl(GPIO2_DIR); 81 tmp = au_readl(GPIO2_DIR);
80 tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) | 82 tmp = (tmp & ~(1 << mtx1_wdt_device.gpio)) |
81 ((~tmp) & (1 << mtx1_wdt_device.gpio)); 83 ((~tmp) & (1 << mtx1_wdt_device.gpio));
82 au_writel (tmp, GPIO2_DIR); 84 au_writel(tmp, GPIO2_DIR);
83 85
84 if (mtx1_wdt_device.queue && ticks) 86 if (mtx1_wdt_device.queue && ticks)
85 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); 87 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
86 else { 88 else
87 complete(&mtx1_wdt_device.stop); 89 complete(&mtx1_wdt_device.stop);
88 } 90 spin_unlock(&mtx1_wdt_device.lock);
89} 91}
90 92
91static void mtx1_wdt_reset(void) 93static void mtx1_wdt_reset(void)
@@ -96,23 +98,25 @@ static void mtx1_wdt_reset(void)
96 98
97static void mtx1_wdt_start(void) 99static void mtx1_wdt_start(void)
98{ 100{
101 spin_lock_irqsave(&mtx1_wdt_device.lock, flags);
99 if (!mtx1_wdt_device.queue) { 102 if (!mtx1_wdt_device.queue) {
100 mtx1_wdt_device.queue = 1; 103 mtx1_wdt_device.queue = 1;
101 gpio_set_value(mtx1_wdt_device.gpio, 1); 104 gpio_set_value(mtx1_wdt_device.gpio, 1);
102 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); 105 mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
103 } 106 }
104 mtx1_wdt_device.running++; 107 mtx1_wdt_device.running++;
108 spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);
105} 109}
106 110
107static int mtx1_wdt_stop(void) 111static int mtx1_wdt_stop(void)
108{ 112{
113 spin_lock_irqsave(&mtx1_wdt_device.lock, flags);
109 if (mtx1_wdt_device.queue) { 114 if (mtx1_wdt_device.queue) {
110 mtx1_wdt_device.queue = 0; 115 mtx1_wdt_device.queue = 0;
111 gpio_set_value(mtx1_wdt_device.gpio, 0); 116 gpio_set_value(mtx1_wdt_device.gpio, 0);
112 } 117 }
113
114 ticks = mtx1_wdt_device.default_ticks; 118 ticks = mtx1_wdt_device.default_ticks;
115 119 spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);
116 return 0; 120 return 0;
117} 121}
118 122
@@ -122,7 +126,6 @@ static int mtx1_wdt_open(struct inode *inode, struct file *file)
122{ 126{
123 if (test_and_set_bit(0, &mtx1_wdt_device.inuse)) 127 if (test_and_set_bit(0, &mtx1_wdt_device.inuse))
124 return -EBUSY; 128 return -EBUSY;
125
126 return nonseekable_open(inode, file); 129 return nonseekable_open(inode, file);
127} 130}
128 131
@@ -133,54 +136,51 @@ static int mtx1_wdt_release(struct inode *inode, struct file *file)
133 return 0; 136 return 0;
134} 137}
135 138
136static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 139static long mtx1_wdt_ioctl(struct file *file, unsigned int cmd,
140 unsigned long arg)
137{ 141{
138 void __user *argp = (void __user *)arg; 142 void __user *argp = (void __user *)arg;
143 int __user *p = (int __user *)argp;
139 unsigned int value; 144 unsigned int value;
140 static struct watchdog_info ident = 145 static const struct watchdog_info ident = {
141 {
142 .options = WDIOF_CARDRESET, 146 .options = WDIOF_CARDRESET,
143 .identity = "MTX-1 WDT", 147 .identity = "MTX-1 WDT",
144 }; 148 };
145 149
146 switch(cmd) { 150 switch (cmd) {
147 case WDIOC_KEEPALIVE: 151 case WDIOC_GETSUPPORT:
148 mtx1_wdt_reset(); 152 if (copy_to_user(argp, &ident, sizeof(ident)))
149 break; 153 return -EFAULT;
150 case WDIOC_GETSTATUS: 154 break;
151 case WDIOC_GETBOOTSTATUS: 155 case WDIOC_GETSTATUS:
152 if ( copy_to_user(argp, &value, sizeof(int)) ) 156 case WDIOC_GETBOOTSTATUS:
153 return -EFAULT; 157 put_user(0, p);
154 break; 158 break;
155 case WDIOC_GETSUPPORT: 159 case WDIOC_SETOPTIONS:
156 if ( copy_to_user(argp, &ident, sizeof(ident)) ) 160 if (get_user(value, p))
157 return -EFAULT; 161 return -EFAULT;
158 break; 162 if (value & WDIOS_ENABLECARD)
159 case WDIOC_SETOPTIONS: 163 mtx1_wdt_start();
160 if ( copy_from_user(&value, argp, sizeof(int)) ) 164 else if (value & WDIOS_DISABLECARD)
161 return -EFAULT; 165 mtx1_wdt_stop();
162 switch(value) { 166 else
163 case WDIOS_ENABLECARD: 167 return -EINVAL;
164 mtx1_wdt_start(); 168 return 0;
165 break; 169 case WDIOC_KEEPALIVE:
166 case WDIOS_DISABLECARD: 170 mtx1_wdt_reset();
167 return mtx1_wdt_stop(); 171 break;
168 default: 172 default:
169 return -EINVAL; 173 return -ENOTTY;
170 }
171 break;
172 default:
173 return -ENOTTY;
174 } 174 }
175 return 0; 175 return 0;
176} 176}
177 177
178 178
179static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 179static ssize_t mtx1_wdt_write(struct file *file, const char *buf,
180 size_t count, loff_t *ppos)
180{ 181{
181 if (!count) 182 if (!count)
182 return -EIO; 183 return -EIO;
183
184 mtx1_wdt_reset(); 184 mtx1_wdt_reset();
185 return count; 185 return count;
186} 186}
@@ -188,17 +188,17 @@ static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count,
188static const struct file_operations mtx1_wdt_fops = { 188static const struct file_operations mtx1_wdt_fops = {
189 .owner = THIS_MODULE, 189 .owner = THIS_MODULE,
190 .llseek = no_llseek, 190 .llseek = no_llseek,
191 .ioctl = mtx1_wdt_ioctl, 191 .unlocked_ioctl = mtx1_wdt_ioctl,
192 .open = mtx1_wdt_open, 192 .open = mtx1_wdt_open,
193 .write = mtx1_wdt_write, 193 .write = mtx1_wdt_write,
194 .release = mtx1_wdt_release 194 .release = mtx1_wdt_release,
195}; 195};
196 196
197 197
198static struct miscdevice mtx1_wdt_misc = { 198static struct miscdevice mtx1_wdt_misc = {
199 .minor = WATCHDOG_MINOR, 199 .minor = WATCHDOG_MINOR,
200 .name = "watchdog", 200 .name = "watchdog",
201 .fops = &mtx1_wdt_fops 201 .fops = &mtx1_wdt_fops,
202}; 202};
203 203
204 204
@@ -208,29 +208,26 @@ static int mtx1_wdt_probe(struct platform_device *pdev)
208 208
209 mtx1_wdt_device.gpio = pdev->resource[0].start; 209 mtx1_wdt_device.gpio = pdev->resource[0].start;
210 210
211 if ((ret = misc_register(&mtx1_wdt_misc)) < 0) { 211 spin_lock_init(&mtx1_wdt_device.lock);
212 printk(KERN_ERR " mtx-1_wdt : failed to register\n");
213 return ret;
214 }
215
216 init_completion(&mtx1_wdt_device.stop); 212 init_completion(&mtx1_wdt_device.stop);
217 mtx1_wdt_device.queue = 0; 213 mtx1_wdt_device.queue = 0;
218
219 clear_bit(0, &mtx1_wdt_device.inuse); 214 clear_bit(0, &mtx1_wdt_device.inuse);
220
221 setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); 215 setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L);
222
223 mtx1_wdt_device.default_ticks = ticks; 216 mtx1_wdt_device.default_ticks = ticks;
224 217
218 ret = misc_register(&mtx1_wdt_misc);
219 if (ret < 0) {
220 printk(KERN_ERR " mtx-1_wdt : failed to register\n");
221 return ret;
222 }
225 mtx1_wdt_start(); 223 mtx1_wdt_start();
226
227 printk(KERN_INFO "MTX-1 Watchdog driver\n"); 224 printk(KERN_INFO "MTX-1 Watchdog driver\n");
228
229 return 0; 225 return 0;
230} 226}
231 227
232static int mtx1_wdt_remove(struct platform_device *pdev) 228static int mtx1_wdt_remove(struct platform_device *pdev)
233{ 229{
230 /* FIXME: do we need to lock this test ? */
234 if (mtx1_wdt_device.queue) { 231 if (mtx1_wdt_device.queue) {
235 mtx1_wdt_device.queue = 0; 232 mtx1_wdt_device.queue = 0;
236 wait_for_completion(&mtx1_wdt_device.stop); 233 wait_for_completion(&mtx1_wdt_device.stop);
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index b59ca3273967..acf589dc057c 100644
--- a/drivers/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
@@ -8,7 +8,7 @@
8 * and services the watchdog. 8 * and services the watchdog.
9 * 9 *
10 * Derived from mpc8xx_wdt.c, with the following copyright. 10 * Derived from mpc8xx_wdt.c, with the following copyright.
11 * 11 *
12 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under 12 * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
13 * the terms of the GNU General Public License version 2. This program 13 * the terms of the GNU General Public License version 2. This program
14 * is licensed "as is" without any warranty of any kind, whether express 14 * is licensed "as is" without any warranty of any kind, whether express
@@ -22,10 +22,9 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/watchdog.h> 23#include <linux/watchdog.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25
26#include <linux/mv643xx.h> 25#include <linux/mv643xx.h>
27#include <asm/uaccess.h> 26#include <linux/uaccess.h>
28#include <asm/io.h> 27#include <linux/io.h>
29 28
30#define MV64x60_WDT_WDC_OFFSET 0 29#define MV64x60_WDT_WDC_OFFSET 0
31 30
@@ -61,7 +60,9 @@ static DEFINE_SPINLOCK(mv64x60_wdt_spinlock);
61 60
62static int nowayout = WATCHDOG_NOWAYOUT; 61static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 62module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 63MODULE_PARM_DESC(nowayout,
64 "Watchdog cannot be stopped once started (default="
65 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
65 66
66static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift) 67static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift)
67{ 68{
@@ -150,7 +151,7 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file)
150} 151}
151 152
152static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data, 153static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
153 size_t len, loff_t * ppos) 154 size_t len, loff_t *ppos)
154{ 155{
155 if (len) { 156 if (len) {
156 if (!nowayout) { 157 if (!nowayout) {
@@ -160,7 +161,7 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
160 161
161 for (i = 0; i != len; i++) { 162 for (i = 0; i != len; i++) {
162 char c; 163 char c;
163 if(get_user(c, data + i)) 164 if (get_user(c, data + i))
164 return -EFAULT; 165 return -EFAULT;
165 if (c == 'V') 166 if (c == 'V')
166 expect_close = 42; 167 expect_close = 42;
@@ -172,8 +173,8 @@ static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
172 return len; 173 return len;
173} 174}
174 175
175static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file, 176static long mv64x60_wdt_ioctl(struct file *file,
176 unsigned int cmd, unsigned long arg) 177 unsigned int cmd, unsigned long arg)
177{ 178{
178 int timeout; 179 int timeout;
179 int options; 180 int options;
@@ -240,7 +241,7 @@ static const struct file_operations mv64x60_wdt_fops = {
240 .owner = THIS_MODULE, 241 .owner = THIS_MODULE,
241 .llseek = no_llseek, 242 .llseek = no_llseek,
242 .write = mv64x60_wdt_write, 243 .write = mv64x60_wdt_write,
243 .ioctl = mv64x60_wdt_ioctl, 244 .unlocked_ioctl = mv64x60_wdt_ioctl,
244 .open = mv64x60_wdt_open, 245 .open = mv64x60_wdt_open,
245 .release = mv64x60_wdt_release, 246 .release = mv64x60_wdt_release,
246}; 247};
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 74bc39aa1ce8..3a11dadfd8e7 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -40,12 +40,10 @@
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/clk.h> 41#include <linux/clk.h>
42#include <linux/bitops.h> 42#include <linux/bitops.h>
43 43#include <linux/io.h>
44#include <asm/io.h> 44#include <linux/uaccess.h>
45#include <asm/uaccess.h> 45#include <mach/hardware.h>
46#include <asm/hardware.h> 46#include <mach/prcm.h>
47
48#include <asm/arch/prcm.h>
49 47
50#include "omap_wdt.h" 48#include "omap_wdt.h"
51 49
@@ -54,11 +52,12 @@ module_param(timer_margin, uint, 0);
54MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); 52MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
55 53
56static int omap_wdt_users; 54static int omap_wdt_users;
57static struct clk *armwdt_ck = NULL; 55static struct clk *armwdt_ck;
58static struct clk *mpu_wdt_ick = NULL; 56static struct clk *mpu_wdt_ick;
59static struct clk *mpu_wdt_fck = NULL; 57static struct clk *mpu_wdt_fck;
60 58
61static unsigned int wdt_trgr_pattern = 0x1234; 59static unsigned int wdt_trgr_pattern = 0x1234;
60static spinlock_t wdt_lock;
62 61
63static void omap_wdt_ping(void) 62static void omap_wdt_ping(void)
64{ 63{
@@ -174,30 +173,29 @@ static int omap_wdt_release(struct inode *inode, struct file *file)
174 return 0; 173 return 0;
175} 174}
176 175
177static ssize_t 176static ssize_t omap_wdt_write(struct file *file, const char __user *data,
178omap_wdt_write(struct file *file, const char __user *data,
179 size_t len, loff_t *ppos) 177 size_t len, loff_t *ppos)
180{ 178{
181 /* Refresh LOAD_TIME. */ 179 /* Refresh LOAD_TIME. */
182 if (len) 180 if (len) {
181 spin_lock(&wdt_lock);
183 omap_wdt_ping(); 182 omap_wdt_ping();
183 spin_unlock(&wdt_lock);
184 }
184 return len; 185 return len;
185} 186}
186 187
187static int 188static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
188omap_wdt_ioctl(struct inode *inode, struct file *file, 189 unsigned long arg)
189 unsigned int cmd, unsigned long arg)
190{ 190{
191 int new_margin; 191 int new_margin;
192 static struct watchdog_info ident = { 192 static const struct watchdog_info ident = {
193 .identity = "OMAP Watchdog", 193 .identity = "OMAP Watchdog",
194 .options = WDIOF_SETTIMEOUT, 194 .options = WDIOF_SETTIMEOUT,
195 .firmware_version = 0, 195 .firmware_version = 0,
196 }; 196 };
197 197
198 switch (cmd) { 198 switch (cmd) {
199 default:
200 return -ENOTTY;
201 case WDIOC_GETSUPPORT: 199 case WDIOC_GETSUPPORT:
202 return copy_to_user((struct watchdog_info __user *)arg, &ident, 200 return copy_to_user((struct watchdog_info __user *)arg, &ident,
203 sizeof(ident)); 201 sizeof(ident));
@@ -211,28 +209,34 @@ omap_wdt_ioctl(struct inode *inode, struct file *file,
211 return put_user(omap_prcm_get_reset_sources(), 209 return put_user(omap_prcm_get_reset_sources(),
212 (int __user *)arg); 210 (int __user *)arg);
213 case WDIOC_KEEPALIVE: 211 case WDIOC_KEEPALIVE:
212 spin_lock(&wdt_lock);
214 omap_wdt_ping(); 213 omap_wdt_ping();
214 spin_unlock(&wdt_lock);
215 return 0; 215 return 0;
216 case WDIOC_SETTIMEOUT: 216 case WDIOC_SETTIMEOUT:
217 if (get_user(new_margin, (int __user *)arg)) 217 if (get_user(new_margin, (int __user *)arg))
218 return -EFAULT; 218 return -EFAULT;
219 omap_wdt_adjust_timeout(new_margin); 219 omap_wdt_adjust_timeout(new_margin);
220 220
221 spin_lock(&wdt_lock);
221 omap_wdt_disable(); 222 omap_wdt_disable();
222 omap_wdt_set_timeout(); 223 omap_wdt_set_timeout();
223 omap_wdt_enable(); 224 omap_wdt_enable();
224 225
225 omap_wdt_ping(); 226 omap_wdt_ping();
227 spin_unlock(&wdt_lock);
226 /* Fall */ 228 /* Fall */
227 case WDIOC_GETTIMEOUT: 229 case WDIOC_GETTIMEOUT:
228 return put_user(timer_margin, (int __user *)arg); 230 return put_user(timer_margin, (int __user *)arg);
231 default:
232 return -ENOTTY;
229 } 233 }
230} 234}
231 235
232static const struct file_operations omap_wdt_fops = { 236static const struct file_operations omap_wdt_fops = {
233 .owner = THIS_MODULE, 237 .owner = THIS_MODULE,
234 .write = omap_wdt_write, 238 .write = omap_wdt_write,
235 .ioctl = omap_wdt_ioctl, 239 .unlocked_ioctl = omap_wdt_ioctl,
236 .open = omap_wdt_open, 240 .open = omap_wdt_open,
237 .release = omap_wdt_release, 241 .release = omap_wdt_release,
238}; 242};
@@ -240,7 +244,7 @@ static const struct file_operations omap_wdt_fops = {
240static struct miscdevice omap_wdt_miscdev = { 244static struct miscdevice omap_wdt_miscdev = {
241 .minor = WATCHDOG_MINOR, 245 .minor = WATCHDOG_MINOR,
242 .name = "watchdog", 246 .name = "watchdog",
243 .fops = &omap_wdt_fops 247 .fops = &omap_wdt_fops,
244}; 248};
245 249
246static int __init omap_wdt_probe(struct platform_device *pdev) 250static int __init omap_wdt_probe(struct platform_device *pdev)
@@ -373,6 +377,7 @@ static struct platform_driver omap_wdt_driver = {
373 377
374static int __init omap_wdt_init(void) 378static int __init omap_wdt_init(void)
375{ 379{
380 spin_lock_init(&wdt_lock);
376 return platform_driver_register(&omap_wdt_driver); 381 return platform_driver_register(&omap_wdt_driver);
377} 382}
378 383
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 15e4f8887a9e..e91ada72da1d 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -31,14 +31,14 @@
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
33#include <linux/version.h> 33#include <linux/version.h>
34#include <linux/io.h>
35#include <linux/uaccess.h>
34 36
35#include <asm/io.h>
36#include <asm/uaccess.h>
37#include <asm/system.h> 37#include <asm/system.h>
38 38
39/* #define DEBUG 1 */ 39/* #define DEBUG 1 */
40 40
41#define DEFAULT_TIMEOUT 1 /* 1 minute */ 41#define DEFAULT_TIMEOUT 1 /* 1 minute */
42#define MAX_TIMEOUT 255 42#define MAX_TIMEOUT 255
43 43
44#define VERSION "1.1" 44#define VERSION "1.1"
@@ -46,22 +46,22 @@
46#define PFX MODNAME ": " 46#define PFX MODNAME ": "
47#define DPFX MODNAME " - DEBUG: " 47#define DPFX MODNAME " - DEBUG: "
48 48
49#define WDT_INDEX_IO_PORT (io+0) /* I/O port base (index register) */ 49#define WDT_INDEX_IO_PORT (io+0) /* I/O port base (index register) */
50#define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1) 50#define WDT_DATA_IO_PORT (WDT_INDEX_IO_PORT+1)
51#define SWC_LDN 0x04 51#define SWC_LDN 0x04
52#define SIOCFG2 0x22 /* Serial IO register */ 52#define SIOCFG2 0x22 /* Serial IO register */
53#define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */ 53#define WDCTL 0x10 /* Watchdog-Timer-Controll-Register */
54#define WDTO 0x11 /* Watchdog timeout register */ 54#define WDTO 0x11 /* Watchdog timeout register */
55#define WDCFG 0x12 /* Watchdog config register */ 55#define WDCFG 0x12 /* Watchdog config register */
56 56
57static int io = 0x2E; /* Address used on Portwell Boards */ 57static int io = 0x2E; /* Address used on Portwell Boards */
58 58
59static int timeout = DEFAULT_TIMEOUT; /* timeout value */ 59static int timeout = DEFAULT_TIMEOUT; /* timeout value */
60static unsigned long timer_enabled = 0; /* is the timer enabled? */ 60static unsigned long timer_enabled; /* is the timer enabled? */
61 61
62static char expect_close; /* is the close expected? */ 62static char expect_close; /* is the close expected? */
63 63
64static DEFINE_SPINLOCK(io_lock);/* to guard the watchdog from io races */ 64static DEFINE_SPINLOCK(io_lock); /* to guard us from io races */
65 65
66static int nowayout = WATCHDOG_NOWAYOUT; 66static int nowayout = WATCHDOG_NOWAYOUT;
67 67
@@ -69,7 +69,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
69 69
70/* Select pins for Watchdog output */ 70/* Select pins for Watchdog output */
71 71
72static inline void pc87413_select_wdt_out (void) 72static inline void pc87413_select_wdt_out(void)
73{ 73{
74 unsigned int cr_data = 0; 74 unsigned int cr_data = 0;
75 75
@@ -77,7 +77,7 @@ static inline void pc87413_select_wdt_out (void)
77 77
78 outb_p(SIOCFG2, WDT_INDEX_IO_PORT); 78 outb_p(SIOCFG2, WDT_INDEX_IO_PORT);
79 79
80 cr_data = inb (WDT_DATA_IO_PORT); 80 cr_data = inb(WDT_DATA_IO_PORT);
81 81
82 cr_data |= 0x80; /* Set Bit7 to 1*/ 82 cr_data |= 0x80; /* Set Bit7 to 1*/
83 outb_p(SIOCFG2, WDT_INDEX_IO_PORT); 83 outb_p(SIOCFG2, WDT_INDEX_IO_PORT);
@@ -85,8 +85,9 @@ static inline void pc87413_select_wdt_out (void)
85 outb_p(cr_data, WDT_DATA_IO_PORT); 85 outb_p(cr_data, WDT_DATA_IO_PORT);
86 86
87#ifdef DEBUG 87#ifdef DEBUG
88 printk(KERN_INFO DPFX "Select multiple pin,pin55,as WDT output:" 88 printk(KERN_INFO DPFX
89 " Bit7 to 1: %d\n", cr_data); 89 "Select multiple pin,pin55,as WDT output: Bit7 to 1: %d\n",
90 cr_data);
90#endif 91#endif
91} 92}
92 93
@@ -94,18 +95,18 @@ static inline void pc87413_select_wdt_out (void)
94 95
95static inline void pc87413_enable_swc(void) 96static inline void pc87413_enable_swc(void)
96{ 97{
97 unsigned int cr_data=0; 98 unsigned int cr_data = 0;
98 99
99 /* Step 2: Enable SWC functions */ 100 /* Step 2: Enable SWC functions */
100 101
101 outb_p(0x07, WDT_INDEX_IO_PORT); /* Point SWC_LDN (LDN=4) */ 102 outb_p(0x07, WDT_INDEX_IO_PORT); /* Point SWC_LDN (LDN=4) */
102 outb_p(SWC_LDN, WDT_DATA_IO_PORT); 103 outb_p(SWC_LDN, WDT_DATA_IO_PORT);
103 104
104 outb_p(0x30, WDT_INDEX_IO_PORT); /* Read Index 0x30 First */ 105 outb_p(0x30, WDT_INDEX_IO_PORT); /* Read Index 0x30 First */
105 cr_data = inb(WDT_DATA_IO_PORT); 106 cr_data = inb(WDT_DATA_IO_PORT);
106 cr_data |= 0x01; /* Set Bit0 to 1 */ 107 cr_data |= 0x01; /* Set Bit0 to 1 */
107 outb_p(0x30, WDT_INDEX_IO_PORT); 108 outb_p(0x30, WDT_INDEX_IO_PORT);
108 outb_p(cr_data, WDT_DATA_IO_PORT); /* Index0x30_bit0P1 */ 109 outb_p(cr_data, WDT_DATA_IO_PORT); /* Index0x30_bit0P1 */
109 110
110#ifdef DEBUG 111#ifdef DEBUG
111 printk(KERN_INFO DPFX "pc87413 - Enable SWC functions\n"); 112 printk(KERN_INFO DPFX "pc87413 - Enable SWC functions\n");
@@ -121,20 +122,19 @@ static inline unsigned int pc87413_get_swc_base(void)
121 122
122 /* Step 3: Read SWC I/O Base Address */ 123 /* Step 3: Read SWC I/O Base Address */
123 124
124 outb_p(0x60, WDT_INDEX_IO_PORT); /* Read Index 0x60 */ 125 outb_p(0x60, WDT_INDEX_IO_PORT); /* Read Index 0x60 */
125 addr_h = inb(WDT_DATA_IO_PORT); 126 addr_h = inb(WDT_DATA_IO_PORT);
126 127
127 outb_p(0x61, WDT_INDEX_IO_PORT); /* Read Index 0x61 */ 128 outb_p(0x61, WDT_INDEX_IO_PORT); /* Read Index 0x61 */
128 129
129 addr_l = inb(WDT_DATA_IO_PORT); 130 addr_l = inb(WDT_DATA_IO_PORT);
130 131
131 swc_base_addr = (addr_h << 8) + addr_l; 132 swc_base_addr = (addr_h << 8) + addr_l;
132
133#ifdef DEBUG 133#ifdef DEBUG
134 printk(KERN_INFO DPFX "Read SWC I/O Base Address: low %d, high %d," 134 printk(KERN_INFO DPFX
135 " res %d\n", addr_l, addr_h, swc_base_addr); 135 "Read SWC I/O Base Address: low %d, high %d, res %d\n",
136 addr_l, addr_h, swc_base_addr);
136#endif 137#endif
137
138 return swc_base_addr; 138 return swc_base_addr;
139} 139}
140 140
@@ -143,9 +143,7 @@ static inline unsigned int pc87413_get_swc_base(void)
143static inline void pc87413_swc_bank3(unsigned int swc_base_addr) 143static inline void pc87413_swc_bank3(unsigned int swc_base_addr)
144{ 144{
145 /* Step 4: Select Bank3 of SWC */ 145 /* Step 4: Select Bank3 of SWC */
146
147 outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f); 146 outb_p(inb(swc_base_addr + 0x0f) | 0x03, swc_base_addr + 0x0f);
148
149#ifdef DEBUG 147#ifdef DEBUG
150 printk(KERN_INFO DPFX "Select Bank3 of SWC\n"); 148 printk(KERN_INFO DPFX "Select Bank3 of SWC\n");
151#endif 149#endif
@@ -157,9 +155,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr,
157 char pc87413_time) 155 char pc87413_time)
158{ 156{
159 /* Step 5: Programm WDTO, Twd. */ 157 /* Step 5: Programm WDTO, Twd. */
160
161 outb_p(pc87413_time, swc_base_addr + WDTO); 158 outb_p(pc87413_time, swc_base_addr + WDTO);
162
163#ifdef DEBUG 159#ifdef DEBUG
164 printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time); 160 printk(KERN_INFO DPFX "Set WDTO to %d minutes\n", pc87413_time);
165#endif 161#endif
@@ -170,9 +166,7 @@ static inline void pc87413_programm_wdto(unsigned int swc_base_addr,
170static inline void pc87413_enable_wden(unsigned int swc_base_addr) 166static inline void pc87413_enable_wden(unsigned int swc_base_addr)
171{ 167{
172 /* Step 6: Enable WDEN */ 168 /* Step 6: Enable WDEN */
173 169 outb_p(inb(swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL);
174 outb_p(inb (swc_base_addr + WDCTL) | 0x01, swc_base_addr + WDCTL);
175
176#ifdef DEBUG 170#ifdef DEBUG
177 printk(KERN_INFO DPFX "Enable WDEN\n"); 171 printk(KERN_INFO DPFX "Enable WDEN\n");
178#endif 172#endif
@@ -182,9 +176,7 @@ static inline void pc87413_enable_wden(unsigned int swc_base_addr)
182static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr) 176static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr)
183{ 177{
184 /* Enable SW_WD_TREN */ 178 /* Enable SW_WD_TREN */
185 179 outb_p(inb(swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG);
186 outb_p(inb (swc_base_addr + WDCFG) | 0x80, swc_base_addr + WDCFG);
187
188#ifdef DEBUG 180#ifdef DEBUG
189 printk(KERN_INFO DPFX "Enable SW_WD_TREN\n"); 181 printk(KERN_INFO DPFX "Enable SW_WD_TREN\n");
190#endif 182#endif
@@ -195,9 +187,7 @@ static inline void pc87413_enable_sw_wd_tren(unsigned int swc_base_addr)
195static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr) 187static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr)
196{ 188{
197 /* Disable SW_WD_TREN */ 189 /* Disable SW_WD_TREN */
198 190 outb_p(inb(swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG);
199 outb_p(inb (swc_base_addr + WDCFG) & 0x7f, swc_base_addr + WDCFG);
200
201#ifdef DEBUG 191#ifdef DEBUG
202 printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n"); 192 printk(KERN_INFO DPFX "pc87413 - Disable SW_WD_TREN\n");
203#endif 193#endif
@@ -208,9 +198,7 @@ static inline void pc87413_disable_sw_wd_tren(unsigned int swc_base_addr)
208static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr) 198static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr)
209{ 199{
210 /* Enable SW_WD_TRG */ 200 /* Enable SW_WD_TRG */
211 201 outb_p(inb(swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL);
212 outb_p(inb (swc_base_addr + WDCTL) | 0x80, swc_base_addr + WDCTL);
213
214#ifdef DEBUG 202#ifdef DEBUG
215 printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n"); 203 printk(KERN_INFO DPFX "pc87413 - Enable SW_WD_TRG\n");
216#endif 204#endif
@@ -221,9 +209,7 @@ static inline void pc87413_enable_sw_wd_trg(unsigned int swc_base_addr)
221static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr) 209static inline void pc87413_disable_sw_wd_trg(unsigned int swc_base_addr)
222{ 210{
223 /* Disable SW_WD_TRG */ 211 /* Disable SW_WD_TRG */
224 212 outb_p(inb(swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL);
225 outb_p(inb (swc_base_addr + WDCTL) & 0x7f, swc_base_addr + WDCTL);
226
227#ifdef DEBUG 213#ifdef DEBUG
228 printk(KERN_INFO DPFX "Disable SW_WD_TRG\n"); 214 printk(KERN_INFO DPFX "Disable SW_WD_TRG\n");
229#endif 215#endif
@@ -314,8 +300,8 @@ static int pc87413_open(struct inode *inode, struct file *file)
314 /* Reload and activate timer */ 300 /* Reload and activate timer */
315 pc87413_refresh(); 301 pc87413_refresh();
316 302
317 printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to" 303 printk(KERN_INFO MODNAME
318 " %d minute(s).\n", timeout); 304 "Watchdog enabled. Timeout set to %d minute(s).\n", timeout);
319 305
320 return nonseekable_open(inode, file); 306 return nonseekable_open(inode, file);
321} 307}
@@ -338,17 +324,15 @@ static int pc87413_release(struct inode *inode, struct file *file)
338 324
339 if (expect_close == 42) { 325 if (expect_close == 42) {
340 pc87413_disable(); 326 pc87413_disable();
341 printk(KERN_INFO MODNAME "Watchdog disabled," 327 printk(KERN_INFO MODNAME
342 " sleeping again...\n"); 328 "Watchdog disabled, sleeping again...\n");
343 } else { 329 } else {
344 printk(KERN_CRIT MODNAME "Unexpected close, not stopping" 330 printk(KERN_CRIT MODNAME
345 " watchdog!\n"); 331 "Unexpected close, not stopping watchdog!\n");
346 pc87413_refresh(); 332 pc87413_refresh();
347 } 333 }
348
349 clear_bit(0, &timer_enabled); 334 clear_bit(0, &timer_enabled);
350 expect_close = 0; 335 expect_close = 0;
351
352 return 0; 336 return 0;
353} 337}
354 338
@@ -386,10 +370,11 @@ static ssize_t pc87413_write(struct file *file, const char __user *data,
386 /* reset expect flag */ 370 /* reset expect flag */
387 expect_close = 0; 371 expect_close = 0;
388 372
389 /* scan to see whether or not we got the magic character */ 373 /* scan to see whether or not we got the
374 magic character */
390 for (i = 0; i != len; i++) { 375 for (i = 0; i != len; i++) {
391 char c; 376 char c;
392 if (get_user(c, data+i)) 377 if (get_user(c, data + i))
393 return -EFAULT; 378 return -EFAULT;
394 if (c == 'V') 379 if (c == 'V')
395 expect_close = 42; 380 expect_close = 42;
@@ -404,7 +389,6 @@ static ssize_t pc87413_write(struct file *file, const char __user *data,
404 389
405/** 390/**
406 * pc87413_ioctl: 391 * pc87413_ioctl:
407 * @inode: inode of the device
408 * @file: file handle to the device 392 * @file: file handle to the device
409 * @cmd: watchdog command 393 * @cmd: watchdog command
410 * @arg: argument pointer 394 * @arg: argument pointer
@@ -414,8 +398,8 @@ static ssize_t pc87413_write(struct file *file, const char __user *data,
414 * querying capabilities and current status. 398 * querying capabilities and current status.
415 */ 399 */
416 400
417static int pc87413_ioctl(struct inode *inode, struct file *file, 401static long pc87413_ioctl(struct file *file, unsigned int cmd,
418 unsigned int cmd, unsigned long arg) 402 unsigned long arg)
419{ 403{
420 int new_timeout; 404 int new_timeout;
421 405
@@ -426,75 +410,58 @@ static int pc87413_ioctl(struct inode *inode, struct file *file,
426 410
427 static struct watchdog_info ident = { 411 static struct watchdog_info ident = {
428 .options = WDIOF_KEEPALIVEPING | 412 .options = WDIOF_KEEPALIVEPING |
429 WDIOF_SETTIMEOUT | 413 WDIOF_SETTIMEOUT |
430 WDIOF_MAGICCLOSE, 414 WDIOF_MAGICCLOSE,
431 .firmware_version = 1, 415 .firmware_version = 1,
432 .identity = "PC87413(HF/F) watchdog" 416 .identity = "PC87413(HF/F) watchdog",
433 }; 417 };
434 418
435 uarg.i = (int __user *)arg; 419 uarg.i = (int __user *)arg;
436 420
437 switch(cmd) { 421 switch (cmd) {
438 default: 422 case WDIOC_GETSUPPORT:
439 return -ENOTTY; 423 return copy_to_user(uarg.ident, &ident,
440 424 sizeof(ident)) ? -EFAULT : 0;
441 case WDIOC_GETSUPPORT: 425 case WDIOC_GETSTATUS:
442 return copy_to_user(uarg.ident, &ident, 426 return put_user(pc87413_status(), uarg.i);
443 sizeof(ident)) ? -EFAULT : 0; 427 case WDIOC_GETBOOTSTATUS:
444 428 return put_user(0, uarg.i);
445 case WDIOC_GETSTATUS: 429 case WDIOC_SETOPTIONS:
446 return put_user(pc87413_status(), uarg.i); 430 {
447 431 int options, retval = -EINVAL;
448 case WDIOC_GETBOOTSTATUS: 432 if (get_user(options, uarg.i))
449 return put_user(0, uarg.i); 433 return -EFAULT;
450 434 if (options & WDIOS_DISABLECARD) {
451 case WDIOC_KEEPALIVE: 435 pc87413_disable();
452 pc87413_refresh(); 436 retval = 0;
437 }
438 if (options & WDIOS_ENABLECARD) {
439 pc87413_enable();
440 retval = 0;
441 }
442 return retval;
443 }
444 case WDIOC_KEEPALIVE:
445 pc87413_refresh();
453#ifdef DEBUG 446#ifdef DEBUG
454 printk(KERN_INFO DPFX "keepalive\n"); 447 printk(KERN_INFO DPFX "keepalive\n");
455#endif 448#endif
456 return 0; 449 return 0;
457 450 case WDIOC_SETTIMEOUT:
458 case WDIOC_SETTIMEOUT: 451 if (get_user(new_timeout, uarg.i))
459 if (get_user(new_timeout, uarg.i)) 452 return -EFAULT;
460 return -EFAULT; 453 /* the API states this is given in secs */
461 454 new_timeout /= 60;
462 // the API states this is given in secs 455 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
463 new_timeout /= 60; 456 return -EINVAL;
464 457 timeout = new_timeout;
465 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) 458 pc87413_refresh();
466 return -EINVAL; 459 /* fall through and return the new timeout... */
467 460 case WDIOC_GETTIMEOUT:
468 timeout = new_timeout; 461 new_timeout = timeout * 60;
469 pc87413_refresh(); 462 return put_user(new_timeout, uarg.i);
470 463 default:
471 // fall through and return the new timeout... 464 return -ENOTTY;
472
473 case WDIOC_GETTIMEOUT:
474
475 new_timeout = timeout * 60;
476
477 return put_user(new_timeout, uarg.i);
478
479 case WDIOC_SETOPTIONS:
480 {
481 int options, retval = -EINVAL;
482
483 if (get_user(options, uarg.i))
484 return -EFAULT;
485
486 if (options & WDIOS_DISABLECARD) {
487 pc87413_disable();
488 retval = 0;
489 }
490
491 if (options & WDIOS_ENABLECARD) {
492 pc87413_enable();
493 retval = 0;
494 }
495
496 return retval;
497 }
498 } 465 }
499} 466}
500 467
@@ -517,10 +484,8 @@ static int pc87413_notify_sys(struct notifier_block *this,
517 void *unused) 484 void *unused)
518{ 485{
519 if (code == SYS_DOWN || code == SYS_HALT) 486 if (code == SYS_DOWN || code == SYS_HALT)
520 {
521 /* Turn the card off */ 487 /* Turn the card off */
522 pc87413_disable(); 488 pc87413_disable();
523 }
524 return NOTIFY_DONE; 489 return NOTIFY_DONE;
525} 490}
526 491
@@ -530,21 +495,19 @@ static const struct file_operations pc87413_fops = {
530 .owner = THIS_MODULE, 495 .owner = THIS_MODULE,
531 .llseek = no_llseek, 496 .llseek = no_llseek,
532 .write = pc87413_write, 497 .write = pc87413_write,
533 .ioctl = pc87413_ioctl, 498 .unlocked_ioctl = pc87413_ioctl,
534 .open = pc87413_open, 499 .open = pc87413_open,
535 .release = pc87413_release, 500 .release = pc87413_release,
536}; 501};
537 502
538static struct notifier_block pc87413_notifier = 503static struct notifier_block pc87413_notifier = {
539{
540 .notifier_call = pc87413_notify_sys, 504 .notifier_call = pc87413_notify_sys,
541}; 505};
542 506
543static struct miscdevice pc87413_miscdev= 507static struct miscdevice pc87413_miscdev = {
544{
545 .minor = WATCHDOG_MINOR, 508 .minor = WATCHDOG_MINOR,
546 .name = "watchdog", 509 .name = "watchdog",
547 .fops = &pc87413_fops 510 .fops = &pc87413_fops,
548}; 511};
549 512
550/* -- Module init functions -------------------------------------*/ 513/* -- Module init functions -------------------------------------*/
@@ -561,29 +524,26 @@ static int __init pc87413_init(void)
561{ 524{
562 int ret; 525 int ret;
563 526
564 printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n", WDT_INDEX_IO_PORT); 527 printk(KERN_INFO PFX "Version " VERSION " at io 0x%X\n",
528 WDT_INDEX_IO_PORT);
565 529
566 /* request_region(io, 2, "pc87413"); */ 530 /* request_region(io, 2, "pc87413"); */
567 531
568 ret = register_reboot_notifier(&pc87413_notifier); 532 ret = register_reboot_notifier(&pc87413_notifier);
569 if (ret != 0) { 533 if (ret != 0) {
570 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 534 printk(KERN_ERR PFX
571 ret); 535 "cannot register reboot notifier (err=%d)\n", ret);
572 } 536 }
573 537
574 ret = misc_register(&pc87413_miscdev); 538 ret = misc_register(&pc87413_miscdev);
575
576 if (ret != 0) { 539 if (ret != 0) {
577 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 540 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
578 WATCHDOG_MINOR, ret); 541 WATCHDOG_MINOR, ret);
579 unregister_reboot_notifier(&pc87413_notifier); 542 unregister_reboot_notifier(&pc87413_notifier);
580 return ret; 543 return ret;
581 } 544 }
582
583 printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout); 545 printk(KERN_INFO PFX "initialized. timeout=%d min \n", timeout);
584
585 pc87413_enable(); 546 pc87413_enable();
586
587 return 0; 547 return 0;
588} 548}
589 549
@@ -600,17 +560,16 @@ static int __init pc87413_init(void)
600static void __exit pc87413_exit(void) 560static void __exit pc87413_exit(void)
601{ 561{
602 /* Stop the timer before we leave */ 562 /* Stop the timer before we leave */
603 if (!nowayout) 563 if (!nowayout) {
604 {
605 pc87413_disable(); 564 pc87413_disable();
606 printk(KERN_INFO MODNAME "Watchdog disabled.\n"); 565 printk(KERN_INFO MODNAME "Watchdog disabled.\n");
607 } 566 }
608 567
609 misc_deregister(&pc87413_miscdev); 568 misc_deregister(&pc87413_miscdev);
610 unregister_reboot_notifier(&pc87413_notifier); 569 unregister_reboot_notifier(&pc87413_notifier);
611 /* release_region(io,2); */ 570 /* release_region(io, 2); */
612 571
613 printk(MODNAME " watchdog component driver removed.\n"); 572 printk(KERN_INFO MODNAME " watchdog component driver removed.\n");
614} 573}
615 574
616module_init(pc87413_init); 575module_init(pc87413_init);
@@ -626,8 +585,12 @@ module_param(io, int, 0);
626MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ")."); 585MODULE_PARM_DESC(io, MODNAME " I/O port (default: " __MODULE_STRING(io) ").");
627 586
628module_param(timeout, int, 0); 587module_param(timeout, int, 0);
629MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ")."); 588MODULE_PARM_DESC(timeout,
589 "Watchdog timeout in minutes (default="
590 __MODULE_STRING(timeout) ").");
630 591
631module_param(nowayout, int, 0); 592module_param(nowayout, int, 0);
632MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 593MODULE_PARM_DESC(nowayout,
594 "Watchdog cannot be stopped once started (default="
595 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
633 596
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index 7b41434fac8c..9e1331a3b215 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -40,13 +40,15 @@
40 * fairly useless proc entry. 40 * fairly useless proc entry.
41 * 990610 removed said useless proc code for the merge <alan> 41 * 990610 removed said useless proc code for the merge <alan>
42 * 000403 Removed last traces of proc code. <davej> 42 * 000403 Removed last traces of proc code. <davej>
43 * 011214 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com> 43 * 011214 Added nowayout module option to override
44 * CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com>
44 * Added timeout module option to override default 45 * Added timeout module option to override default
45 */ 46 */
46 47
47/* 48/*
48 * A bells and whistles driver is available from http://www.pcwd.de/ 49 * A bells and whistles driver is available from http://www.pcwd.de/
49 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ 50 * More info available at http://www.berkprod.com/ or
51 * http://www.pcwatchdog.com/
50 */ 52 */
51 53
52#include <linux/module.h> /* For module specific items */ 54#include <linux/module.h> /* For module specific items */
@@ -65,9 +67,8 @@
65#include <linux/isa.h> /* For isa devices */ 67#include <linux/isa.h> /* For isa devices */
66#include <linux/ioport.h> /* For io-port access */ 68#include <linux/ioport.h> /* For io-port access */
67#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 69#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
68 70#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
69#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 71#include <linux/io.h> /* For inb/outb/... */
70#include <asm/io.h> /* For inb/outb/... */
71 72
72/* Module and version information */ 73/* Module and version information */
73#define WATCHDOG_VERSION "1.20" 74#define WATCHDOG_VERSION "1.20"
@@ -111,14 +112,16 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
111#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ 112#define WD_REVC_WTRP 0x01 /* Watchdog Trip status */
112#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ 113#define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */
113#define WD_REVC_TTRP 0x04 /* Temperature Trip status */ 114#define WD_REVC_TTRP 0x04 /* Temperature Trip status */
114#define WD_REVC_RL2A 0x08 /* Relay 2 activated by on-board processor */ 115#define WD_REVC_RL2A 0x08 /* Relay 2 activated by
116 on-board processor */
115#define WD_REVC_RL1A 0x10 /* Relay 1 active */ 117#define WD_REVC_RL1A 0x10 /* Relay 1 active */
116#define WD_REVC_R2DS 0x40 /* Relay 2 disable */ 118#define WD_REVC_R2DS 0x40 /* Relay 2 disable */
117#define WD_REVC_RLY2 0x80 /* Relay 2 activated? */ 119#define WD_REVC_RLY2 0x80 /* Relay 2 activated? */
118/* Port 2 : Control Status #2 */ 120/* Port 2 : Control Status #2 */
119#define WD_WDIS 0x10 /* Watchdog Disabled */ 121#define WD_WDIS 0x10 /* Watchdog Disabled */
120#define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ 122#define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */
121#define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */ 123#define WD_SSEL 0x40 /* Watchdog Switch Select
124 (1:SW1 <-> 0:SW2) */
122#define WD_WCMD 0x80 /* Watchdog Command Mode */ 125#define WD_WCMD 0x80 /* Watchdog Command Mode */
123 126
124/* max. time we give an ISA watchdog card to process a command */ 127/* max. time we give an ISA watchdog card to process a command */
@@ -142,7 +145,7 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
142#define CMD_ISA_RESET_RELAYS 0x0D 145#define CMD_ISA_RESET_RELAYS 0x0D
143 146
144/* Watchdog's Dip Switch heartbeat values */ 147/* Watchdog's Dip Switch heartbeat values */
145static const int heartbeat_tbl [] = { 148static const int heartbeat_tbl[] = {
146 20, /* OFF-OFF-OFF = 20 Sec */ 149 20, /* OFF-OFF-OFF = 20 Sec */
147 40, /* OFF-OFF-ON = 40 Sec */ 150 40, /* OFF-OFF-ON = 40 Sec */
148 60, /* OFF-ON-OFF = 1 Min */ 151 60, /* OFF-ON-OFF = 1 Min */
@@ -165,14 +168,18 @@ static const int heartbeat_tbl [] = {
165static int cards_found; 168static int cards_found;
166 169
167/* internal variables */ 170/* internal variables */
168static atomic_t open_allowed = ATOMIC_INIT(1); 171static unsigned long open_allowed;
169static char expect_close; 172static char expect_close;
170static int temp_panic; 173static int temp_panic;
171static struct { /* this is private data for each ISA-PC watchdog card */ 174
175/* this is private data for each ISA-PC watchdog card */
176static struct {
172 char fw_ver_str[6]; /* The cards firmware version */ 177 char fw_ver_str[6]; /* The cards firmware version */
173 int revision; /* The card's revision */ 178 int revision; /* The card's revision */
174 int supports_temp; /* Wether or not the card has a temperature device */ 179 int supports_temp; /* Whether or not the card has
175 int command_mode; /* Wether or not the card is in command mode */ 180 a temperature device */
181 int command_mode; /* Whether or not the card is in
182 command mode */
176 int boot_status; /* The card's boot status */ 183 int boot_status; /* The card's boot status */
177 int io_addr; /* The cards I/O address */ 184 int io_addr; /* The cards I/O address */
178 spinlock_t io_lock; /* the lock for io operations */ 185 spinlock_t io_lock; /* the lock for io operations */
@@ -186,16 +193,20 @@ static struct { /* this is private data for each ISA-PC watchdog card */
186#define DEBUG 2 /* print fancy stuff too */ 193#define DEBUG 2 /* print fancy stuff too */
187static int debug = QUIET; 194static int debug = QUIET;
188module_param(debug, int, 0); 195module_param(debug, int, 0);
189MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); 196MODULE_PARM_DESC(debug,
197 "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
190 198
191#define WATCHDOG_HEARTBEAT 0 /* default heartbeat = delay-time from dip-switches */ 199/* default heartbeat = delay-time from dip-switches */
200#define WATCHDOG_HEARTBEAT 0
192static int heartbeat = WATCHDOG_HEARTBEAT; 201static int heartbeat = WATCHDOG_HEARTBEAT;
193module_param(heartbeat, int, 0); 202module_param(heartbeat, int, 0);
194MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 203MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2 <= heartbeat <= 7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
195 204
196static int nowayout = WATCHDOG_NOWAYOUT; 205static int nowayout = WATCHDOG_NOWAYOUT;
197module_param(nowayout, int, 0); 206module_param(nowayout, int, 0);
198MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 207MODULE_PARM_DESC(nowayout,
208 "Watchdog cannot be stopped once started (default="
209 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
199 210
200/* 211/*
201 * Internal functions 212 * Internal functions
@@ -224,7 +235,7 @@ static int send_isa_command(int cmd)
224 if (port0 == last_port0) 235 if (port0 == last_port0)
225 break; /* Data is stable */ 236 break; /* Data is stable */
226 237
227 udelay (250); 238 udelay(250);
228 } 239 }
229 240
230 if (debug >= DEBUG) 241 if (debug >= DEBUG)
@@ -236,7 +247,7 @@ static int send_isa_command(int cmd)
236 247
237static int set_command_mode(void) 248static int set_command_mode(void)
238{ 249{
239 int i, found=0, count=0; 250 int i, found = 0, count = 0;
240 251
241 /* Set the card into command mode */ 252 /* Set the card into command mode */
242 spin_lock(&pcwd_private.io_lock); 253 spin_lock(&pcwd_private.io_lock);
@@ -261,7 +272,7 @@ static int set_command_mode(void)
261 printk(KERN_DEBUG PFX "command_mode=%d\n", 272 printk(KERN_DEBUG PFX "command_mode=%d\n",
262 pcwd_private.command_mode); 273 pcwd_private.command_mode);
263 274
264 return(found); 275 return found;
265} 276}
266 277
267static void unset_command_mode(void) 278static void unset_command_mode(void)
@@ -296,7 +307,8 @@ static inline void pcwd_get_firmware(void)
296 ten = send_isa_command(CMD_ISA_VERSION_TENTH); 307 ten = send_isa_command(CMD_ISA_VERSION_TENTH);
297 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); 308 hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH);
298 minor = send_isa_command(CMD_ISA_VERSION_MINOR); 309 minor = send_isa_command(CMD_ISA_VERSION_MINOR);
299 sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", one, ten, hund, minor); 310 sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c",
311 one, ten, hund, minor);
300 } 312 }
301 unset_command_mode(); 313 unset_command_mode();
302 314
@@ -305,7 +317,7 @@ static inline void pcwd_get_firmware(void)
305 317
306static inline int pcwd_get_option_switches(void) 318static inline int pcwd_get_option_switches(void)
307{ 319{
308 int option_switches=0; 320 int option_switches = 0;
309 321
310 if (set_command_mode()) { 322 if (set_command_mode()) {
311 /* Get switch settings */ 323 /* Get switch settings */
@@ -313,7 +325,7 @@ static inline int pcwd_get_option_switches(void)
313 } 325 }
314 326
315 unset_command_mode(); 327 unset_command_mode();
316 return(option_switches); 328 return option_switches;
317} 329}
318 330
319static void pcwd_show_card_info(void) 331static void pcwd_show_card_info(void)
@@ -322,7 +334,9 @@ static void pcwd_show_card_info(void)
322 334
323 /* Get some extra info from the hardware (in command/debug/diag mode) */ 335 /* Get some extra info from the hardware (in command/debug/diag mode) */
324 if (pcwd_private.revision == PCWD_REVISION_A) 336 if (pcwd_private.revision == PCWD_REVISION_A)
325 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); 337 printk(KERN_INFO PFX
338 "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n",
339 pcwd_private.io_addr);
326 else if (pcwd_private.revision == PCWD_REVISION_C) { 340 else if (pcwd_private.revision == PCWD_REVISION_C) {
327 pcwd_get_firmware(); 341 pcwd_get_firmware();
328 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", 342 printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n",
@@ -347,12 +361,15 @@ static void pcwd_show_card_info(void)
347 printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); 361 printk(KERN_INFO PFX "Previous reboot was caused by the card\n");
348 362
349 if (pcwd_private.boot_status & WDIOF_OVERHEAT) { 363 if (pcwd_private.boot_status & WDIOF_OVERHEAT) {
350 printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); 364 printk(KERN_EMERG PFX
351 printk(KERN_EMERG PFX "CPU Overheat\n"); 365 "Card senses a CPU Overheat. Panicking!\n");
366 printk(KERN_EMERG PFX
367 "CPU Overheat\n");
352 } 368 }
353 369
354 if (pcwd_private.boot_status == 0) 370 if (pcwd_private.boot_status == 0)
355 printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); 371 printk(KERN_INFO PFX
372 "No previous trip detected - Cold boot or reset\n");
356} 373}
357 374
358static void pcwd_timer_ping(unsigned long data) 375static void pcwd_timer_ping(unsigned long data)
@@ -361,11 +378,12 @@ static void pcwd_timer_ping(unsigned long data)
361 378
362 /* If we got a heartbeat pulse within the WDT_INTERVAL 379 /* If we got a heartbeat pulse within the WDT_INTERVAL
363 * we agree to ping the WDT */ 380 * we agree to ping the WDT */
364 if(time_before(jiffies, pcwd_private.next_heartbeat)) { 381 if (time_before(jiffies, pcwd_private.next_heartbeat)) {
365 /* Ping the watchdog */ 382 /* Ping the watchdog */
366 spin_lock(&pcwd_private.io_lock); 383 spin_lock(&pcwd_private.io_lock);
367 if (pcwd_private.revision == PCWD_REVISION_A) { 384 if (pcwd_private.revision == PCWD_REVISION_A) {
368 /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ 385 /* Rev A cards are reset by setting the
386 WD_WDRST bit in register 1 */
369 wdrst_stat = inb_p(pcwd_private.io_addr); 387 wdrst_stat = inb_p(pcwd_private.io_addr);
370 wdrst_stat &= 0x0F; 388 wdrst_stat &= 0x0F;
371 wdrst_stat |= WD_WDRST; 389 wdrst_stat |= WD_WDRST;
@@ -381,7 +399,8 @@ static void pcwd_timer_ping(unsigned long data)
381 399
382 spin_unlock(&pcwd_private.io_lock); 400 spin_unlock(&pcwd_private.io_lock);
383 } else { 401 } else {
384 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 402 printk(KERN_WARNING PFX
403 "Heartbeat lost! Will not ping the watchdog\n");
385 } 404 }
386} 405}
387 406
@@ -454,7 +473,7 @@ static int pcwd_keepalive(void)
454 473
455static int pcwd_set_heartbeat(int t) 474static int pcwd_set_heartbeat(int t)
456{ 475{
457 if ((t < 2) || (t > 7200)) /* arbitrary upper limit */ 476 if (t < 2 || t > 7200) /* arbitrary upper limit */
458 return -EINVAL; 477 return -EINVAL;
459 478
460 heartbeat = t; 479 heartbeat = t;
@@ -470,7 +489,7 @@ static int pcwd_get_status(int *status)
470{ 489{
471 int control_status; 490 int control_status;
472 491
473 *status=0; 492 *status = 0;
474 spin_lock(&pcwd_private.io_lock); 493 spin_lock(&pcwd_private.io_lock);
475 if (pcwd_private.revision == PCWD_REVISION_A) 494 if (pcwd_private.revision == PCWD_REVISION_A)
476 /* Rev A cards return status information from 495 /* Rev A cards return status information from
@@ -494,9 +513,9 @@ static int pcwd_get_status(int *status)
494 if (control_status & WD_T110) { 513 if (control_status & WD_T110) {
495 *status |= WDIOF_OVERHEAT; 514 *status |= WDIOF_OVERHEAT;
496 if (temp_panic) { 515 if (temp_panic) {
497 printk(KERN_INFO PFX "Temperature overheat trip!\n"); 516 printk(KERN_INFO PFX
517 "Temperature overheat trip!\n");
498 kernel_power_off(); 518 kernel_power_off();
499 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
500 } 519 }
501 } 520 }
502 } else { 521 } else {
@@ -506,9 +525,9 @@ static int pcwd_get_status(int *status)
506 if (control_status & WD_REVC_TTRP) { 525 if (control_status & WD_REVC_TTRP) {
507 *status |= WDIOF_OVERHEAT; 526 *status |= WDIOF_OVERHEAT;
508 if (temp_panic) { 527 if (temp_panic) {
509 printk(KERN_INFO PFX "Temperature overheat trip!\n"); 528 printk(KERN_INFO PFX
529 "Temperature overheat trip!\n");
510 kernel_power_off(); 530 kernel_power_off();
511 /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */
512 } 531 }
513 } 532 }
514 } 533 }
@@ -524,18 +543,21 @@ static int pcwd_clear_status(void)
524 spin_lock(&pcwd_private.io_lock); 543 spin_lock(&pcwd_private.io_lock);
525 544
526 if (debug >= VERBOSE) 545 if (debug >= VERBOSE)
527 printk(KERN_INFO PFX "clearing watchdog trip status\n"); 546 printk(KERN_INFO PFX
547 "clearing watchdog trip status\n");
528 548
529 control_status = inb_p(pcwd_private.io_addr + 1); 549 control_status = inb_p(pcwd_private.io_addr + 1);
530 550
531 if (debug >= DEBUG) { 551 if (debug >= DEBUG) {
532 printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status); 552 printk(KERN_DEBUG PFX "status was: 0x%02x\n",
553 control_status);
533 printk(KERN_DEBUG PFX "sending: 0x%02x\n", 554 printk(KERN_DEBUG PFX "sending: 0x%02x\n",
534 (control_status & WD_REVC_R2DS)); 555 (control_status & WD_REVC_R2DS));
535 } 556 }
536 557
537 /* clear reset status & Keep Relay 2 disable state as it is */ 558 /* clear reset status & Keep Relay 2 disable state as it is */
538 outb_p((control_status & WD_REVC_R2DS), pcwd_private.io_addr + 1); 559 outb_p((control_status & WD_REVC_R2DS),
560 pcwd_private.io_addr + 1);
539 561
540 spin_unlock(&pcwd_private.io_lock); 562 spin_unlock(&pcwd_private.io_lock);
541 } 563 }
@@ -572,8 +594,7 @@ static int pcwd_get_temperature(int *temperature)
572 * /dev/watchdog handling 594 * /dev/watchdog handling
573 */ 595 */
574 596
575static int pcwd_ioctl(struct inode *inode, struct file *file, 597static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
576 unsigned int cmd, unsigned long arg)
577{ 598{
578 int rv; 599 int rv;
579 int status; 600 int status;
@@ -590,12 +611,9 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
590 .identity = "PCWD", 611 .identity = "PCWD",
591 }; 612 };
592 613
593 switch(cmd) { 614 switch (cmd) {
594 default:
595 return -ENOTTY;
596
597 case WDIOC_GETSUPPORT: 615 case WDIOC_GETSUPPORT:
598 if(copy_to_user(argp, &ident, sizeof(ident))) 616 if (copy_to_user(argp, &ident, sizeof(ident)))
599 return -EFAULT; 617 return -EFAULT;
600 return 0; 618 return 0;
601 619
@@ -613,25 +631,22 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
613 return put_user(temperature, argp); 631 return put_user(temperature, argp);
614 632
615 case WDIOC_SETOPTIONS: 633 case WDIOC_SETOPTIONS:
616 if (pcwd_private.revision == PCWD_REVISION_C) 634 if (pcwd_private.revision == PCWD_REVISION_C) {
617 { 635 if (get_user(rv, argp))
618 if(copy_from_user(&rv, argp, sizeof(int)))
619 return -EFAULT; 636 return -EFAULT;
620 637
621 if (rv & WDIOS_DISABLECARD) 638 if (rv & WDIOS_DISABLECARD) {
622 { 639 status = pcwd_stop();
623 return pcwd_stop(); 640 if (status < 0)
641 return status;
624 } 642 }
625 643 if (rv & WDIOS_ENABLECARD) {
626 if (rv & WDIOS_ENABLECARD) 644 status = pcwd_start();
627 { 645 if (status < 0)
628 return pcwd_start(); 646 return status;
629 } 647 }
630
631 if (rv & WDIOS_TEMPPANIC) 648 if (rv & WDIOS_TEMPPANIC)
632 {
633 temp_panic = 1; 649 temp_panic = 1;
634 }
635 } 650 }
636 return -EINVAL; 651 return -EINVAL;
637 652
@@ -651,6 +666,9 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
651 666
652 case WDIOC_GETTIMEOUT: 667 case WDIOC_GETTIMEOUT:
653 return put_user(heartbeat, argp); 668 return put_user(heartbeat, argp);
669
670 default:
671 return -ENOTTY;
654 } 672 }
655 673
656 return 0; 674 return 0;
@@ -682,16 +700,10 @@ static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len,
682 700
683static int pcwd_open(struct inode *inode, struct file *file) 701static int pcwd_open(struct inode *inode, struct file *file)
684{ 702{
685 if (!atomic_dec_and_test(&open_allowed) ) { 703 if (test_and_set_bit(0, &open_allowed))
686 if (debug >= VERBOSE)
687 printk(KERN_ERR PFX "Attempt to open already opened device.\n");
688 atomic_inc( &open_allowed );
689 return -EBUSY; 704 return -EBUSY;
690 }
691
692 if (nowayout) 705 if (nowayout)
693 __module_get(THIS_MODULE); 706 __module_get(THIS_MODULE);
694
695 /* Activate */ 707 /* Activate */
696 pcwd_start(); 708 pcwd_start();
697 pcwd_keepalive(); 709 pcwd_keepalive();
@@ -700,14 +712,15 @@ static int pcwd_open(struct inode *inode, struct file *file)
700 712
701static int pcwd_close(struct inode *inode, struct file *file) 713static int pcwd_close(struct inode *inode, struct file *file)
702{ 714{
703 if (expect_close == 42) { 715 if (expect_close == 42)
704 pcwd_stop(); 716 pcwd_stop();
705 } else { 717 else {
706 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 718 printk(KERN_CRIT PFX
719 "Unexpected close, not stopping watchdog!\n");
707 pcwd_keepalive(); 720 pcwd_keepalive();
708 } 721 }
709 expect_close = 0; 722 expect_close = 0;
710 atomic_inc( &open_allowed ); 723 clear_bit(0, &open_allowed);
711 return 0; 724 return 0;
712} 725}
713 726
@@ -750,7 +763,7 @@ static const struct file_operations pcwd_fops = {
750 .owner = THIS_MODULE, 763 .owner = THIS_MODULE,
751 .llseek = no_llseek, 764 .llseek = no_llseek,
752 .write = pcwd_write, 765 .write = pcwd_write,
753 .ioctl = pcwd_ioctl, 766 .unlocked_ioctl = pcwd_ioctl,
754 .open = pcwd_open, 767 .open = pcwd_open,
755 .release = pcwd_close, 768 .release = pcwd_close,
756}; 769};
@@ -788,7 +801,7 @@ static inline int get_revision(void)
788 * presumes a floating bus reads as 0xff. */ 801 * presumes a floating bus reads as 0xff. */
789 if ((inb(pcwd_private.io_addr + 2) == 0xFF) || 802 if ((inb(pcwd_private.io_addr + 2) == 0xFF) ||
790 (inb(pcwd_private.io_addr + 3) == 0xFF)) 803 (inb(pcwd_private.io_addr + 3) == 0xFF))
791 r=PCWD_REVISION_A; 804 r = PCWD_REVISION_A;
792 spin_unlock(&pcwd_private.io_lock); 805 spin_unlock(&pcwd_private.io_lock);
793 806
794 return r; 807 return r;
@@ -803,7 +816,7 @@ static inline int get_revision(void)
803 */ 816 */
804static int __devinit pcwd_isa_match(struct device *dev, unsigned int id) 817static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
805{ 818{
806 int base_addr=pcwd_ioports[id]; 819 int base_addr = pcwd_ioports[id];
807 int port0, last_port0; /* Reg 0, in case it's REV A */ 820 int port0, last_port0; /* Reg 0, in case it's REV A */
808 int port1, last_port1; /* Register 1 for REV C cards */ 821 int port1, last_port1; /* Register 1 for REV C cards */
809 int i; 822 int i;
@@ -813,7 +826,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
813 printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n", 826 printk(KERN_DEBUG PFX "pcwd_isa_match id=%d\n",
814 id); 827 id);
815 828
816 if (!request_region (base_addr, 4, "PCWD")) { 829 if (!request_region(base_addr, 4, "PCWD")) {
817 printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr); 830 printk(KERN_INFO PFX "Port 0x%04x unavailable\n", base_addr);
818 return 0; 831 return 0;
819 } 832 }
@@ -842,7 +855,7 @@ static int __devinit pcwd_isa_match(struct device *dev, unsigned int id)
842 } 855 }
843 } 856 }
844 } 857 }
845 release_region (base_addr, 4); 858 release_region(base_addr, 4);
846 859
847 return retval; 860 return retval;
848} 861}
@@ -857,7 +870,8 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
857 870
858 cards_found++; 871 cards_found++;
859 if (cards_found == 1) 872 if (cards_found == 1)
860 printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); 873 printk(KERN_INFO PFX "v%s Ken Hollis (kenji@bitgate.com)\n",
874 WD_VER);
861 875
862 if (cards_found > 1) { 876 if (cards_found > 1) {
863 printk(KERN_ERR PFX "This driver only supports 1 device\n"); 877 printk(KERN_ERR PFX "This driver only supports 1 device\n");
@@ -875,10 +889,11 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
875 /* Check card's revision */ 889 /* Check card's revision */
876 pcwd_private.revision = get_revision(); 890 pcwd_private.revision = get_revision();
877 891
878 if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { 892 if (!request_region(pcwd_private.io_addr,
893 (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) {
879 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 894 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
880 pcwd_private.io_addr); 895 pcwd_private.io_addr);
881 ret=-EIO; 896 ret = -EIO;
882 goto error_request_region; 897 goto error_request_region;
883 } 898 }
884 899
@@ -908,26 +923,30 @@ static int __devinit pcwd_isa_probe(struct device *dev, unsigned int id)
908 if (heartbeat == 0) 923 if (heartbeat == 0)
909 heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)]; 924 heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)];
910 925
911 /* Check that the heartbeat value is within it's range ; if not reset to the default */ 926 /* Check that the heartbeat value is within it's range;
927 if not reset to the default */
912 if (pcwd_set_heartbeat(heartbeat)) { 928 if (pcwd_set_heartbeat(heartbeat)) {
913 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); 929 pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
914 printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", 930 printk(KERN_INFO PFX
915 WATCHDOG_HEARTBEAT); 931 "heartbeat value must be 2 <= heartbeat <= 7200, using %d\n",
932 WATCHDOG_HEARTBEAT);
916 } 933 }
917 934
918 if (pcwd_private.supports_temp) { 935 if (pcwd_private.supports_temp) {
919 ret = misc_register(&temp_miscdev); 936 ret = misc_register(&temp_miscdev);
920 if (ret) { 937 if (ret) {
921 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 938 printk(KERN_ERR PFX
922 TEMP_MINOR, ret); 939 "cannot register miscdev on minor=%d (err=%d)\n",
940 TEMP_MINOR, ret);
923 goto error_misc_register_temp; 941 goto error_misc_register_temp;
924 } 942 }
925 } 943 }
926 944
927 ret = misc_register(&pcwd_miscdev); 945 ret = misc_register(&pcwd_miscdev);
928 if (ret) { 946 if (ret) {
929 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 947 printk(KERN_ERR PFX
930 WATCHDOG_MINOR, ret); 948 "cannot register miscdev on minor=%d (err=%d)\n",
949 WATCHDOG_MINOR, ret);
931 goto error_misc_register_watchdog; 950 goto error_misc_register_watchdog;
932 } 951 }
933 952
@@ -940,7 +959,8 @@ error_misc_register_watchdog:
940 if (pcwd_private.supports_temp) 959 if (pcwd_private.supports_temp)
941 misc_deregister(&temp_miscdev); 960 misc_deregister(&temp_miscdev);
942error_misc_register_temp: 961error_misc_register_temp:
943 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 962 release_region(pcwd_private.io_addr,
963 (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
944error_request_region: 964error_request_region:
945 pcwd_private.io_addr = 0x0000; 965 pcwd_private.io_addr = 0x0000;
946 cards_found--; 966 cards_found--;
@@ -964,7 +984,8 @@ static int __devexit pcwd_isa_remove(struct device *dev, unsigned int id)
964 misc_deregister(&pcwd_miscdev); 984 misc_deregister(&pcwd_miscdev);
965 if (pcwd_private.supports_temp) 985 if (pcwd_private.supports_temp)
966 misc_deregister(&temp_miscdev); 986 misc_deregister(&temp_miscdev);
967 release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); 987 release_region(pcwd_private.io_addr,
988 (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4);
968 pcwd_private.io_addr = 0x0000; 989 pcwd_private.io_addr = 0x0000;
969 cards_found--; 990 cards_found--;
970 991
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index 61a89e959642..90eb1d4271d7 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -46,9 +46,8 @@
46#include <linux/pci.h> /* For pci functions */ 46#include <linux/pci.h> /* For pci functions */
47#include <linux/ioport.h> /* For io-port access */ 47#include <linux/ioport.h> /* For io-port access */
48#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ 48#include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
49 49#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
50#include <asm/uaccess.h> /* For copy_to_user/put_user/... */ 50#include <linux/io.h> /* For inb/outb/... */
51#include <asm/io.h> /* For inb/outb/... */
52 51
53/* Module and version information */ 52/* Module and version information */
54#define WATCHDOG_VERSION "1.03" 53#define WATCHDOG_VERSION "1.03"
@@ -97,7 +96,7 @@
97#define CMD_GET_CLEAR_RESET_COUNT 0x84 96#define CMD_GET_CLEAR_RESET_COUNT 0x84
98 97
99/* Watchdog's Dip Switch heartbeat values */ 98/* Watchdog's Dip Switch heartbeat values */
100static const int heartbeat_tbl [] = { 99static const int heartbeat_tbl[] = {
101 5, /* OFF-OFF-OFF = 5 Sec */ 100 5, /* OFF-OFF-OFF = 5 Sec */
102 10, /* OFF-OFF-ON = 10 Sec */ 101 10, /* OFF-OFF-ON = 10 Sec */
103 30, /* OFF-ON-OFF = 30 Sec */ 102 30, /* OFF-ON-OFF = 30 Sec */
@@ -220,11 +219,10 @@ static void pcipcwd_show_card_info(void)
220 int option_switches; 219 int option_switches;
221 220
222 got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); 221 got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
223 if (got_fw_rev) { 222 if (got_fw_rev)
224 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); 223 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
225 } else { 224 else
226 sprintf(fw_ver_str, "<card no answer>"); 225 sprintf(fw_ver_str, "<card no answer>");
227 }
228 226
229 /* Get switch settings */ 227 /* Get switch settings */
230 option_switches = pcipcwd_get_option_switches(); 228 option_switches = pcipcwd_get_option_switches();
@@ -331,7 +329,7 @@ static int pcipcwd_get_status(int *status)
331{ 329{
332 int control_status; 330 int control_status;
333 331
334 *status=0; 332 *status = 0;
335 control_status = inb_p(pcipcwd_private.io_addr + 1); 333 control_status = inb_p(pcipcwd_private.io_addr + 1);
336 if (control_status & WD_PCI_WTRP) 334 if (control_status & WD_PCI_WTRP)
337 *status |= WDIOF_CARDRESET; 335 *status |= WDIOF_CARDRESET;
@@ -369,8 +367,8 @@ static int pcipcwd_clear_status(void)
369 outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1); 367 outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1);
370 368
371 /* clear reset counter */ 369 /* clear reset counter */
372 msb=0; 370 msb = 0;
373 reset_counter=0xff; 371 reset_counter = 0xff;
374 send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter); 372 send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter);
375 373
376 if (debug >= DEBUG) { 374 if (debug >= DEBUG) {
@@ -442,7 +440,7 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data,
442 /* scan to see whether or not we got the magic character */ 440 /* scan to see whether or not we got the magic character */
443 for (i = 0; i != len; i++) { 441 for (i = 0; i != len; i++) {
444 char c; 442 char c;
445 if(get_user(c, data+i)) 443 if (get_user(c, data + i))
446 return -EFAULT; 444 return -EFAULT;
447 if (c == 'V') 445 if (c == 'V')
448 expect_release = 42; 446 expect_release = 42;
@@ -455,8 +453,8 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data,
455 return len; 453 return len;
456} 454}
457 455
458static int pcipcwd_ioctl(struct inode *inode, struct file *file, 456static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
459 unsigned int cmd, unsigned long arg) 457 unsigned long arg)
460{ 458{
461 void __user *argp = (void __user *)arg; 459 void __user *argp = (void __user *)arg;
462 int __user *p = argp; 460 int __user *p = argp;
@@ -471,92 +469,89 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
471 }; 469 };
472 470
473 switch (cmd) { 471 switch (cmd) {
474 case WDIOC_GETSUPPORT: 472 case WDIOC_GETSUPPORT:
475 return copy_to_user(argp, &ident, 473 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
476 sizeof (ident)) ? -EFAULT : 0; 474
475 case WDIOC_GETSTATUS:
476 {
477 int status;
478 pcipcwd_get_status(&status);
479 return put_user(status, p);
480 }
477 481
478 case WDIOC_GETSTATUS: 482 case WDIOC_GETBOOTSTATUS:
479 { 483 return put_user(pcipcwd_private.boot_status, p);
480 int status;
481 484
482 pcipcwd_get_status(&status); 485 case WDIOC_GETTEMP:
486 {
487 int temperature;
483 488
484 return put_user(status, p); 489 if (pcipcwd_get_temperature(&temperature))
485 } 490 return -EFAULT;
486 491
487 case WDIOC_GETBOOTSTATUS: 492 return put_user(temperature, p);
488 return put_user(pcipcwd_private.boot_status, p); 493 }
489 494
490 case WDIOC_GETTEMP: 495 case WDIOC_SETOPTIONS:
491 { 496 {
492 int temperature; 497 int new_options, retval = -EINVAL;
493 498
494 if (pcipcwd_get_temperature(&temperature)) 499 if (get_user(new_options, p))
495 return -EFAULT; 500 return -EFAULT;
496 501
497 return put_user(temperature, p); 502 if (new_options & WDIOS_DISABLECARD) {
503 if (pcipcwd_stop())
504 return -EIO;
505 retval = 0;
498 } 506 }
499 507
500 case WDIOC_KEEPALIVE: 508 if (new_options & WDIOS_ENABLECARD) {
501 pcipcwd_keepalive(); 509 if (pcipcwd_start())
502 return 0; 510 return -EIO;
503 511 retval = 0;
504 case WDIOC_SETOPTIONS: 512 }
505 {
506 int new_options, retval = -EINVAL;
507
508 if (get_user (new_options, p))
509 return -EFAULT;
510
511 if (new_options & WDIOS_DISABLECARD) {
512 if (pcipcwd_stop())
513 return -EIO;
514 retval = 0;
515 }
516 513
517 if (new_options & WDIOS_ENABLECARD) { 514 if (new_options & WDIOS_TEMPPANIC) {
518 if (pcipcwd_start()) 515 temp_panic = 1;
519 return -EIO; 516 retval = 0;
520 retval = 0; 517 }
521 }
522 518
523 if (new_options & WDIOS_TEMPPANIC) { 519 return retval;
524 temp_panic = 1; 520 }
525 retval = 0;
526 }
527 521
528 return retval; 522 case WDIOC_KEEPALIVE:
529 } 523 pcipcwd_keepalive();
524 return 0;
530 525
531 case WDIOC_SETTIMEOUT: 526 case WDIOC_SETTIMEOUT:
532 { 527 {
533 int new_heartbeat; 528 int new_heartbeat;
534 529
535 if (get_user(new_heartbeat, p)) 530 if (get_user(new_heartbeat, p))
536 return -EFAULT; 531 return -EFAULT;
537 532
538 if (pcipcwd_set_heartbeat(new_heartbeat)) 533 if (pcipcwd_set_heartbeat(new_heartbeat))
539 return -EINVAL; 534 return -EINVAL;
540 535
541 pcipcwd_keepalive(); 536 pcipcwd_keepalive();
542 /* Fall */ 537 /* Fall */
543 } 538 }
544 539
545 case WDIOC_GETTIMEOUT: 540 case WDIOC_GETTIMEOUT:
546 return put_user(heartbeat, p); 541 return put_user(heartbeat, p);
547 542
548 case WDIOC_GETTIMELEFT: 543 case WDIOC_GETTIMELEFT:
549 { 544 {
550 int time_left; 545 int time_left;
551 546
552 if (pcipcwd_get_timeleft(&time_left)) 547 if (pcipcwd_get_timeleft(&time_left))
553 return -EFAULT; 548 return -EFAULT;
554 549
555 return put_user(time_left, p); 550 return put_user(time_left, p);
556 } 551 }
557 552
558 default: 553 default:
559 return -ENOTTY; 554 return -ENOTTY;
560 } 555 }
561} 556}
562 557
@@ -603,7 +598,7 @@ static ssize_t pcipcwd_temp_read(struct file *file, char __user *data,
603 if (pcipcwd_get_temperature(&temperature)) 598 if (pcipcwd_get_temperature(&temperature))
604 return -EFAULT; 599 return -EFAULT;
605 600
606 if (copy_to_user (data, &temperature, 1)) 601 if (copy_to_user(data, &temperature, 1))
607 return -EFAULT; 602 return -EFAULT;
608 603
609 return 1; 604 return 1;
@@ -628,10 +623,8 @@ static int pcipcwd_temp_release(struct inode *inode, struct file *file)
628 623
629static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 624static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
630{ 625{
631 if (code==SYS_DOWN || code==SYS_HALT) { 626 if (code == SYS_DOWN || code == SYS_HALT)
632 /* Turn the WDT off */ 627 pcipcwd_stop(); /* Turn the WDT off */
633 pcipcwd_stop();
634 }
635 628
636 return NOTIFY_DONE; 629 return NOTIFY_DONE;
637} 630}
@@ -644,7 +637,7 @@ static const struct file_operations pcipcwd_fops = {
644 .owner = THIS_MODULE, 637 .owner = THIS_MODULE,
645 .llseek = no_llseek, 638 .llseek = no_llseek,
646 .write = pcipcwd_write, 639 .write = pcipcwd_write,
647 .ioctl = pcipcwd_ioctl, 640 .unlocked_ioctl = pcipcwd_ioctl,
648 .open = pcipcwd_open, 641 .open = pcipcwd_open,
649 .release = pcipcwd_release, 642 .release = pcipcwd_release,
650}; 643};
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index bf443d077a1e..c1685c942de6 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -40,8 +40,7 @@
40#include <linux/slab.h> /* For kmalloc, ... */ 40#include <linux/slab.h> /* For kmalloc, ... */
41#include <linux/mutex.h> /* For mutex locking */ 41#include <linux/mutex.h> /* For mutex locking */
42#include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ 42#include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */
43 43#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
44#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
45 44
46 45
47#ifdef CONFIG_USB_DEBUG 46#ifdef CONFIG_USB_DEBUG
@@ -88,7 +87,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" _
88#define USB_PCWD_PRODUCT_ID 0x1140 87#define USB_PCWD_PRODUCT_ID 0x1140
89 88
90/* table of devices that work with this driver */ 89/* table of devices that work with this driver */
91static struct usb_device_id usb_pcwd_table [] = { 90static struct usb_device_id usb_pcwd_table[] = {
92 { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) }, 91 { USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) },
93 { } /* Terminating entry */ 92 { } /* Terminating entry */
94}; 93};
@@ -110,7 +109,7 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
110#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG 109#define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG
111 110
112/* Watchdog's Dip Switch heartbeat values */ 111/* Watchdog's Dip Switch heartbeat values */
113static const int heartbeat_tbl [] = { 112static const int heartbeat_tbl[] = {
114 5, /* OFF-OFF-OFF = 5 Sec */ 113 5, /* OFF-OFF-OFF = 5 Sec */
115 10, /* OFF-OFF-ON = 10 Sec */ 114 10, /* OFF-OFF-ON = 10 Sec */
116 30, /* OFF-ON-OFF = 30 Sec */ 115 30, /* OFF-ON-OFF = 30 Sec */
@@ -130,15 +129,15 @@ static char expect_release;
130 129
131/* Structure to hold all of our device specific stuff */ 130/* Structure to hold all of our device specific stuff */
132struct usb_pcwd_private { 131struct usb_pcwd_private {
133 struct usb_device * udev; /* save off the usb device pointer */ 132 struct usb_device *udev; /* save off the usb device pointer */
134 struct usb_interface * interface; /* the interface for this device */ 133 struct usb_interface *interface; /* the interface for this device */
135 134
136 unsigned int interface_number; /* the interface number used for cmd's */ 135 unsigned int interface_number; /* the interface number used for cmd's */
137 136
138 unsigned char * intr_buffer; /* the buffer to intr data */ 137 unsigned char *intr_buffer; /* the buffer to intr data */
139 dma_addr_t intr_dma; /* the dma address for the intr buffer */ 138 dma_addr_t intr_dma; /* the dma address for the intr buffer */
140 size_t intr_size; /* the size of the intr buffer */ 139 size_t intr_size; /* the size of the intr buffer */
141 struct urb * intr_urb; /* the urb used for the intr pipe */ 140 struct urb *intr_urb; /* the urb used for the intr pipe */
142 141
143 unsigned char cmd_command; /* The command that is reported back */ 142 unsigned char cmd_command; /* The command that is reported back */
144 unsigned char cmd_data_msb; /* The data MSB that is reported back */ 143 unsigned char cmd_data_msb; /* The data MSB that is reported back */
@@ -154,8 +153,8 @@ static struct usb_pcwd_private *usb_pcwd_device;
154static DEFINE_MUTEX(disconnect_mutex); 153static DEFINE_MUTEX(disconnect_mutex);
155 154
156/* local function prototypes */ 155/* local function prototypes */
157static int usb_pcwd_probe (struct usb_interface *interface, const struct usb_device_id *id); 156static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_device_id *id);
158static void usb_pcwd_disconnect (struct usb_interface *interface); 157static void usb_pcwd_disconnect(struct usb_interface *interface);
159 158
160/* usb specific object needed to register this driver with the usb subsystem */ 159/* usb specific object needed to register this driver with the usb subsystem */
161static struct usb_driver usb_pcwd_driver = { 160static struct usb_driver usb_pcwd_driver = {
@@ -195,10 +194,10 @@ static void usb_pcwd_intr_done(struct urb *urb)
195 usb_pcwd->cmd_data_lsb = data[2]; 194 usb_pcwd->cmd_data_lsb = data[2];
196 195
197 /* notify anyone waiting that the cmd has finished */ 196 /* notify anyone waiting that the cmd has finished */
198 atomic_set (&usb_pcwd->cmd_received, 1); 197 atomic_set(&usb_pcwd->cmd_received, 1);
199 198
200resubmit: 199resubmit:
201 retval = usb_submit_urb (urb, GFP_ATOMIC); 200 retval = usb_submit_urb(urb, GFP_ATOMIC);
202 if (retval) 201 if (retval)
203 printk(KERN_ERR PFX "can't resubmit intr, usb_submit_urb failed with result %d\n", 202 printk(KERN_ERR PFX "can't resubmit intr, usb_submit_urb failed with result %d\n",
204 retval); 203 retval);
@@ -224,7 +223,7 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha
224 dbg("sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x", 223 dbg("sending following data cmd=0x%02x msb=0x%02x lsb=0x%02x",
225 buf[0], buf[1], buf[2]); 224 buf[0], buf[1], buf[2]);
226 225
227 atomic_set (&usb_pcwd->cmd_received, 0); 226 atomic_set(&usb_pcwd->cmd_received, 0);
228 227
229 if (usb_control_msg(usb_pcwd->udev, usb_sndctrlpipe(usb_pcwd->udev, 0), 228 if (usb_control_msg(usb_pcwd->udev, usb_sndctrlpipe(usb_pcwd->udev, 0),
230 HID_REQ_SET_REPORT, HID_DT_REPORT, 229 HID_REQ_SET_REPORT, HID_DT_REPORT,
@@ -237,7 +236,7 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha
237 got_response = 0; 236 got_response = 0;
238 for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response); count++) { 237 for (count = 0; (count < USB_COMMAND_TIMEOUT) && (!got_response); count++) {
239 mdelay(1); 238 mdelay(1);
240 if (atomic_read (&usb_pcwd->cmd_received)) 239 if (atomic_read(&usb_pcwd->cmd_received))
241 got_response = 1; 240 got_response = 1;
242 } 241 }
243 242
@@ -356,7 +355,7 @@ static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
356 /* scan to see whether or not we got the magic character */ 355 /* scan to see whether or not we got the magic character */
357 for (i = 0; i != len; i++) { 356 for (i = 0; i != len; i++) {
358 char c; 357 char c;
359 if(get_user(c, data+i)) 358 if (get_user(c, data + i))
360 return -EFAULT; 359 return -EFAULT;
361 if (c == 'V') 360 if (c == 'V')
362 expect_release = 42; 361 expect_release = 42;
@@ -369,8 +368,8 @@ static ssize_t usb_pcwd_write(struct file *file, const char __user *data,
369 return len; 368 return len;
370} 369}
371 370
372static int usb_pcwd_ioctl(struct inode *inode, struct file *file, 371static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
373 unsigned int cmd, unsigned long arg) 372 unsigned long arg)
374{ 373{
375 void __user *argp = (void __user *)arg; 374 void __user *argp = (void __user *)arg;
376 int __user *p = argp; 375 int __user *p = argp;
@@ -383,77 +382,76 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file,
383 }; 382 };
384 383
385 switch (cmd) { 384 switch (cmd) {
386 case WDIOC_GETSUPPORT: 385 case WDIOC_GETSUPPORT:
387 return copy_to_user(argp, &ident, 386 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
388 sizeof (ident)) ? -EFAULT : 0;
389 387
390 case WDIOC_GETSTATUS: 388 case WDIOC_GETSTATUS:
391 case WDIOC_GETBOOTSTATUS: 389 case WDIOC_GETBOOTSTATUS:
392 return put_user(0, p); 390 return put_user(0, p);
393 391
394 case WDIOC_GETTEMP: 392 case WDIOC_GETTEMP:
395 { 393 {
396 int temperature; 394 int temperature;
397 395
398 if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) 396 if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature))
399 return -EFAULT; 397 return -EFAULT;
400 398
401 return put_user(temperature, p); 399 return put_user(temperature, p);
402 } 400 }
403 401
404 case WDIOC_KEEPALIVE: 402 case WDIOC_SETOPTIONS:
405 usb_pcwd_keepalive(usb_pcwd_device); 403 {
406 return 0; 404 int new_options, retval = -EINVAL;
407 405
408 case WDIOC_SETOPTIONS: 406 if (get_user(new_options, p))
409 { 407 return -EFAULT;
410 int new_options, retval = -EINVAL;
411 408
412 if (get_user (new_options, p)) 409 if (new_options & WDIOS_DISABLECARD) {
413 return -EFAULT; 410 usb_pcwd_stop(usb_pcwd_device);
411 retval = 0;
412 }
414 413
415 if (new_options & WDIOS_DISABLECARD) { 414 if (new_options & WDIOS_ENABLECARD) {
416 usb_pcwd_stop(usb_pcwd_device); 415 usb_pcwd_start(usb_pcwd_device);
417 retval = 0; 416 retval = 0;
418 } 417 }
419 418
420 if (new_options & WDIOS_ENABLECARD) { 419 return retval;
421 usb_pcwd_start(usb_pcwd_device); 420 }
422 retval = 0;
423 }
424 421
425 return retval; 422 case WDIOC_KEEPALIVE:
426 } 423 usb_pcwd_keepalive(usb_pcwd_device);
424 return 0;
427 425
428 case WDIOC_SETTIMEOUT: 426 case WDIOC_SETTIMEOUT:
429 { 427 {
430 int new_heartbeat; 428 int new_heartbeat;
431 429
432 if (get_user(new_heartbeat, p)) 430 if (get_user(new_heartbeat, p))
433 return -EFAULT; 431 return -EFAULT;
434 432
435 if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat)) 433 if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat))
436 return -EINVAL; 434 return -EINVAL;
437 435
438 usb_pcwd_keepalive(usb_pcwd_device); 436 usb_pcwd_keepalive(usb_pcwd_device);
439 /* Fall */ 437 /* Fall */
440 } 438 }
441 439
442 case WDIOC_GETTIMEOUT: 440 case WDIOC_GETTIMEOUT:
443 return put_user(heartbeat, p); 441 return put_user(heartbeat, p);
444 442
445 case WDIOC_GETTIMELEFT: 443 case WDIOC_GETTIMELEFT:
446 { 444 {
447 int time_left; 445 int time_left;
448 446
449 if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) 447 if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left))
450 return -EFAULT; 448 return -EFAULT;
451 449
452 return put_user(time_left, p); 450 return put_user(time_left, p);
453 } 451 }
454 452
455 default: 453 default:
456 return -ENOTTY; 454 return -ENOTTY;
457 } 455 }
458} 456}
459 457
@@ -519,10 +517,8 @@ static int usb_pcwd_temperature_release(struct inode *inode, struct file *file)
519 517
520static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 518static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
521{ 519{
522 if (code==SYS_DOWN || code==SYS_HALT) { 520 if (code == SYS_DOWN || code == SYS_HALT)
523 /* Turn the WDT off */ 521 usb_pcwd_stop(usb_pcwd_device); /* Turn the WDT off */
524 usb_pcwd_stop(usb_pcwd_device);
525 }
526 522
527 return NOTIFY_DONE; 523 return NOTIFY_DONE;
528} 524}
@@ -535,7 +531,7 @@ static const struct file_operations usb_pcwd_fops = {
535 .owner = THIS_MODULE, 531 .owner = THIS_MODULE,
536 .llseek = no_llseek, 532 .llseek = no_llseek,
537 .write = usb_pcwd_write, 533 .write = usb_pcwd_write,
538 .ioctl = usb_pcwd_ioctl, 534 .unlocked_ioctl = usb_pcwd_ioctl,
539 .open = usb_pcwd_open, 535 .open = usb_pcwd_open,
540 .release = usb_pcwd_release, 536 .release = usb_pcwd_release,
541}; 537};
@@ -567,13 +563,13 @@ static struct notifier_block usb_pcwd_notifier = {
567/** 563/**
568 * usb_pcwd_delete 564 * usb_pcwd_delete
569 */ 565 */
570static inline void usb_pcwd_delete (struct usb_pcwd_private *usb_pcwd) 566static inline void usb_pcwd_delete(struct usb_pcwd_private *usb_pcwd)
571{ 567{
572 usb_free_urb(usb_pcwd->intr_urb); 568 usb_free_urb(usb_pcwd->intr_urb);
573 if (usb_pcwd->intr_buffer != NULL) 569 if (usb_pcwd->intr_buffer != NULL)
574 usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size, 570 usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size,
575 usb_pcwd->intr_buffer, usb_pcwd->intr_dma); 571 usb_pcwd->intr_buffer, usb_pcwd->intr_dma);
576 kfree (usb_pcwd); 572 kfree(usb_pcwd);
577} 573}
578 574
579/** 575/**
@@ -626,7 +622,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
626 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); 622 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
627 623
628 /* allocate memory for our device and initialize it */ 624 /* allocate memory for our device and initialize it */
629 usb_pcwd = kzalloc (sizeof(struct usb_pcwd_private), GFP_KERNEL); 625 usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL);
630 if (usb_pcwd == NULL) { 626 if (usb_pcwd == NULL) {
631 printk(KERN_ERR PFX "Out of memory\n"); 627 printk(KERN_ERR PFX "Out of memory\n");
632 goto error; 628 goto error;
@@ -641,7 +637,8 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
641 usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); 637 usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8);
642 638
643 /* set up the memory buffer's */ 639 /* set up the memory buffer's */
644 if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma))) { 640 usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma);
641 if (!usb_pcwd->intr_buffer) {
645 printk(KERN_ERR PFX "Out of memory\n"); 642 printk(KERN_ERR PFX "Out of memory\n");
646 goto error; 643 goto error;
647 } 644 }
@@ -675,11 +672,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
675 672
676 /* Get the Firmware Version */ 673 /* Get the Firmware Version */
677 got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); 674 got_fw_rev = usb_pcwd_send_command(usb_pcwd, CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor);
678 if (got_fw_rev) { 675 if (got_fw_rev)
679 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); 676 sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor);
680 } else { 677 else
681 sprintf(fw_ver_str, "<card no answer>"); 678 sprintf(fw_ver_str, "<card no answer>");
682 }
683 679
684 printk(KERN_INFO PFX "Found card (Firmware: %s) with temp option\n", 680 printk(KERN_INFO PFX "Found card (Firmware: %s) with temp option\n",
685 fw_ver_str); 681 fw_ver_str);
@@ -725,7 +721,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
725 } 721 }
726 722
727 /* we can register the device now, as it is ready */ 723 /* we can register the device now, as it is ready */
728 usb_set_intfdata (interface, usb_pcwd); 724 usb_set_intfdata(interface, usb_pcwd);
729 725
730 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", 726 printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
731 heartbeat, nowayout); 727 heartbeat, nowayout);
@@ -759,8 +755,8 @@ static void usb_pcwd_disconnect(struct usb_interface *interface)
759 /* prevent races with open() */ 755 /* prevent races with open() */
760 mutex_lock(&disconnect_mutex); 756 mutex_lock(&disconnect_mutex);
761 757
762 usb_pcwd = usb_get_intfdata (interface); 758 usb_pcwd = usb_get_intfdata(interface);
763 usb_set_intfdata (interface, NULL); 759 usb_set_intfdata(interface, NULL);
764 760
765 mutex_lock(&usb_pcwd->mtx); 761 mutex_lock(&usb_pcwd->mtx);
766 762
@@ -820,5 +816,5 @@ static void __exit usb_pcwd_exit(void)
820} 816}
821 817
822 818
823module_init (usb_pcwd_init); 819module_init(usb_pcwd_init);
824module_exit (usb_pcwd_exit); 820module_exit(usb_pcwd_exit);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 6b8483d3c783..0ed84162437b 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -28,10 +28,9 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/clk.h> 29#include <linux/clk.h>
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31 31#include <linux/uaccess.h>
32#include <asm/hardware.h> 32#include <linux/io.h>
33#include <asm/uaccess.h> 33#include <mach/hardware.h>
34#include <asm/io.h>
35 34
36#define MODULE_NAME "PNX4008-WDT: " 35#define MODULE_NAME "PNX4008-WDT: "
37 36
@@ -144,9 +143,8 @@ static int pnx4008_wdt_open(struct inode *inode, struct file *file)
144 return nonseekable_open(inode, file); 143 return nonseekable_open(inode, file);
145} 144}
146 145
147static ssize_t 146static ssize_t pnx4008_wdt_write(struct file *file, const char *data,
148pnx4008_wdt_write(struct file *file, const char *data, size_t len, 147 size_t len, loff_t *ppos)
149 loff_t * ppos)
150{ 148{
151 if (len) { 149 if (len) {
152 if (!nowayout) { 150 if (!nowayout) {
@@ -169,15 +167,14 @@ pnx4008_wdt_write(struct file *file, const char *data, size_t len,
169 return len; 167 return len;
170} 168}
171 169
172static struct watchdog_info ident = { 170static const struct watchdog_info ident = {
173 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 171 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
174 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 172 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
175 .identity = "PNX4008 Watchdog", 173 .identity = "PNX4008 Watchdog",
176}; 174};
177 175
178static int 176static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file,
179pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 177 unsigned int cmd, unsigned long arg)
180 unsigned long arg)
181{ 178{
182 int ret = -ENOTTY; 179 int ret = -ENOTTY;
183 int time; 180 int time;
@@ -196,6 +193,11 @@ pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
196 ret = put_user(boot_status, (int *)arg); 193 ret = put_user(boot_status, (int *)arg);
197 break; 194 break;
198 195
196 case WDIOC_KEEPALIVE:
197 wdt_enable();
198 ret = 0;
199 break;
200
199 case WDIOC_SETTIMEOUT: 201 case WDIOC_SETTIMEOUT:
200 ret = get_user(time, (int *)arg); 202 ret = get_user(time, (int *)arg);
201 if (ret) 203 if (ret)
@@ -213,11 +215,6 @@ pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
213 case WDIOC_GETTIMEOUT: 215 case WDIOC_GETTIMEOUT:
214 ret = put_user(heartbeat, (int *)arg); 216 ret = put_user(heartbeat, (int *)arg);
215 break; 217 break;
216
217 case WDIOC_KEEPALIVE:
218 wdt_enable();
219 ret = 0;
220 break;
221 } 218 }
222 return ret; 219 return ret;
223} 220}
@@ -238,7 +235,7 @@ static const struct file_operations pnx4008_wdt_fops = {
238 .owner = THIS_MODULE, 235 .owner = THIS_MODULE,
239 .llseek = no_llseek, 236 .llseek = no_llseek,
240 .write = pnx4008_wdt_write, 237 .write = pnx4008_wdt_write,
241 .ioctl = pnx4008_wdt_ioctl, 238 .unlocked_ioctl = pnx4008_wdt_ioctl,
242 .open = pnx4008_wdt_open, 239 .open = pnx4008_wdt_open,
243 .release = pnx4008_wdt_release, 240 .release = pnx4008_wdt_release,
244}; 241};
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index 5c921e471564..f1ae3729a19e 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -29,10 +29,10 @@
29#include <linux/notifier.h> 29#include <linux/notifier.h>
30#include <linux/miscdevice.h> 30#include <linux/miscdevice.h>
31#include <linux/watchdog.h> 31#include <linux/watchdog.h>
32#include <asm/io.h> 32#include <linux/io.h>
33#include <linux/uaccess.h>
33#include <asm/atomic.h> 34#include <asm/atomic.h>
34#include <asm/processor.h> 35#include <asm/processor.h>
35#include <asm/uaccess.h>
36#include <asm/system.h> 36#include <asm/system.h>
37#include <asm/rm9k-ocd.h> 37#include <asm/rm9k-ocd.h>
38 38
@@ -53,10 +53,12 @@ static void wdt_gpi_stop(void);
53static void wdt_gpi_set_timeout(unsigned int); 53static void wdt_gpi_set_timeout(unsigned int);
54static int wdt_gpi_open(struct inode *, struct file *); 54static int wdt_gpi_open(struct inode *, struct file *);
55static int wdt_gpi_release(struct inode *, struct file *); 55static int wdt_gpi_release(struct inode *, struct file *);
56static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, loff_t *); 56static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t,
57 loff_t *);
57static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); 58static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long);
58static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); 59static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *);
59static const struct resource *wdt_gpi_get_resource(struct platform_device *, const char *, unsigned int); 60static const struct resource *wdt_gpi_get_resource(struct platform_device *,
61 const char *, unsigned int);
60static int __init wdt_gpi_probe(struct device *); 62static int __init wdt_gpi_probe(struct device *);
61static int __exit wdt_gpi_remove(struct device *); 63static int __exit wdt_gpi_remove(struct device *);
62 64
@@ -68,7 +70,7 @@ static int locked;
68 70
69 71
70/* These are set from device resources */ 72/* These are set from device resources */
71static void __iomem * wd_regs; 73static void __iomem *wd_regs;
72static unsigned int wd_irq, wd_ctr; 74static unsigned int wd_irq, wd_ctr;
73 75
74 76
@@ -216,7 +218,8 @@ static int wdt_gpi_release(struct inode *inode, struct file *file)
216 if (expect_close) { 218 if (expect_close) {
217 wdt_gpi_stop(); 219 wdt_gpi_stop();
218 free_irq(wd_irq, &miscdev); 220 free_irq(wd_irq, &miscdev);
219 printk(KERN_INFO "%s: watchdog stopped\n", wdt_gpi_name); 221 printk(KERN_INFO "%s: watchdog stopped\n",
222 wdt_gpi_name);
220 } else { 223 } else {
221 printk(KERN_CRIT "%s: unexpected close() -" 224 printk(KERN_CRIT "%s: unexpected close() -"
222 " watchdog left running\n", 225 " watchdog left running\n",
@@ -231,8 +234,8 @@ static int wdt_gpi_release(struct inode *inode, struct file *file)
231 return 0; 234 return 0;
232} 235}
233 236
234static ssize_t 237static ssize_t wdt_gpi_write(struct file *f, const char __user *d, size_t s,
235wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o) 238 loff_t *o)
236{ 239{
237 char val; 240 char val;
238 241
@@ -241,8 +244,7 @@ wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o)
241 return s ? 1 : 0; 244 return s ? 1 : 0;
242} 245}
243 246
244static long 247static long wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
245wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
246{ 248{
247 long res = -ENOTTY; 249 long res = -ENOTTY;
248 const long size = _IOC_SIZE(cmd); 250 const long size = _IOC_SIZE(cmd);
@@ -271,7 +273,8 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
271 case WDIOC_GETSUPPORT: 273 case WDIOC_GETSUPPORT:
272 wdinfo.options = nowayout ? 274 wdinfo.options = nowayout ?
273 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING : 275 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING :
274 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE; 276 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
277 WDIOF_MAGICCLOSE;
275 res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size; 278 res = __copy_to_user(argp, &wdinfo, size) ? -EFAULT : size;
276 break; 279 break;
277 280
@@ -322,8 +325,8 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
322 325
323 326
324/* Shutdown notifier */ 327/* Shutdown notifier */
325static int 328static int wdt_gpi_notify(struct notifier_block *this, unsigned long code,
326wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused) 329 void *unused)
327{ 330{
328 if (code == SYS_DOWN || code == SYS_HALT) 331 if (code == SYS_DOWN || code == SYS_HALT)
329 wdt_gpi_stop(); 332 wdt_gpi_stop();
@@ -333,9 +336,8 @@ wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused)
333 336
334 337
335/* Init & exit procedures */ 338/* Init & exit procedures */
336static const struct resource * 339static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
337wdt_gpi_get_resource(struct platform_device *pdv, const char *name, 340 const char *name, unsigned int type)
338 unsigned int type)
339{ 341{
340 char buf[80]; 342 char buf[80];
341 if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf) 343 if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf)
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 97b4a2e8eb09..22715e3be5e7 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -49,7 +49,7 @@
49#include <linux/uaccess.h> 49#include <linux/uaccess.h>
50#include <linux/io.h> 50#include <linux/io.h>
51 51
52#include <asm/arch/map.h> 52#include <mach/map.h>
53 53
54#undef S3C_VA_WATCHDOG 54#undef S3C_VA_WATCHDOG
55#define S3C_VA_WATCHDOG (0) 55#define S3C_VA_WATCHDOG (0)
@@ -119,17 +119,6 @@ static void __s3c2410wdt_stop(void)
119{ 119{
120 unsigned long wtcon; 120 unsigned long wtcon;
121 121
122 spin_lock(&wdt_lock);
123 wtcon = readl(wdt_base + S3C2410_WTCON);
124 wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN);
125 writel(wtcon, wdt_base + S3C2410_WTCON);
126 spin_unlock(&wdt_lock);
127}
128
129static void __s3c2410wdt_stop(void)
130{
131 unsigned long wtcon;
132
133 wtcon = readl(wdt_base + S3C2410_WTCON); 122 wtcon = readl(wdt_base + S3C2410_WTCON);
134 wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); 123 wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN);
135 writel(wtcon, wdt_base + S3C2410_WTCON); 124 writel(wtcon, wdt_base + S3C2410_WTCON);
@@ -168,8 +157,6 @@ static void s3c2410wdt_start(void)
168 writel(wdt_count, wdt_base + S3C2410_WTCNT); 157 writel(wdt_count, wdt_base + S3C2410_WTCNT);
169 writel(wtcon, wdt_base + S3C2410_WTCON); 158 writel(wtcon, wdt_base + S3C2410_WTCON);
170 spin_unlock(&wdt_lock); 159 spin_unlock(&wdt_lock);
171
172 return 0;
173} 160}
174 161
175static int s3c2410wdt_set_heartbeat(int timeout) 162static int s3c2410wdt_set_heartbeat(int timeout)
@@ -305,8 +292,6 @@ static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd,
305 int new_margin; 292 int new_margin;
306 293
307 switch (cmd) { 294 switch (cmd) {
308 default:
309 return -ENOTTY;
310 case WDIOC_GETSUPPORT: 295 case WDIOC_GETSUPPORT:
311 return copy_to_user(argp, &s3c2410_wdt_ident, 296 return copy_to_user(argp, &s3c2410_wdt_ident,
312 sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0; 297 sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0;
@@ -325,6 +310,8 @@ static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd,
325 return put_user(tmr_margin, p); 310 return put_user(tmr_margin, p);
326 case WDIOC_GETTIMEOUT: 311 case WDIOC_GETTIMEOUT:
327 return put_user(tmr_margin, p); 312 return put_user(tmr_margin, p);
313 default:
314 return -ENOTTY;
328 } 315 }
329} 316}
330 317
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index 34a2b3b81800..31a48437dc3d 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -26,13 +26,14 @@
26#include <linux/watchdog.h> 26#include <linux/watchdog.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/uaccess.h>
29 30
30#ifdef CONFIG_ARCH_PXA 31#ifdef CONFIG_ARCH_PXA
31#include <asm/arch/pxa-regs.h> 32#include <mach/pxa-regs.h>
32#endif 33#endif
33 34
34#include <asm/hardware.h> 35#include <mach/reset.h>
35#include <asm/uaccess.h> 36#include <mach/hardware.h>
36 37
37#define OSCR_FREQ CLOCK_TICK_RATE 38#define OSCR_FREQ CLOCK_TICK_RATE
38 39
@@ -45,7 +46,7 @@ static int boot_status;
45 */ 46 */
46static int sa1100dog_open(struct inode *inode, struct file *file) 47static int sa1100dog_open(struct inode *inode, struct file *file)
47{ 48{
48 if (test_and_set_bit(1,&sa1100wdt_users)) 49 if (test_and_set_bit(1, &sa1100wdt_users))
49 return -EBUSY; 50 return -EBUSY;
50 51
51 /* Activate SA1100 Watchdog timer */ 52 /* Activate SA1100 Watchdog timer */
@@ -66,28 +67,27 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
66static int sa1100dog_release(struct inode *inode, struct file *file) 67static int sa1100dog_release(struct inode *inode, struct file *file)
67{ 68{
68 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); 69 printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
69
70 clear_bit(1, &sa1100wdt_users); 70 clear_bit(1, &sa1100wdt_users);
71
72 return 0; 71 return 0;
73} 72}
74 73
75static ssize_t sa1100dog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) 74static ssize_t sa1100dog_write(struct file *file, const char __user *data,
75 size_t len, loff_t *ppos)
76{ 76{
77 if (len) 77 if (len)
78 /* Refresh OSMR3 timer. */ 78 /* Refresh OSMR3 timer. */
79 OSMR3 = OSCR + pre_margin; 79 OSMR3 = OSCR + pre_margin;
80
81 return len; 80 return len;
82} 81}
83 82
84static struct watchdog_info ident = { 83static const struct watchdog_info ident = {
85 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 84 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT
85 | WDIOF_KEEPALIVEPING,
86 .identity = "SA1100/PXA255 Watchdog", 86 .identity = "SA1100/PXA255 Watchdog",
87}; 87};
88 88
89static int sa1100dog_ioctl(struct inode *inode, struct file *file, 89static long sa1100dog_ioctl(struct file *file, unsigned int cmd,
90 unsigned int cmd, unsigned long arg) 90 unsigned long arg)
91{ 91{
92 int ret = -ENOTTY; 92 int ret = -ENOTTY;
93 int time; 93 int time;
@@ -108,6 +108,11 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
108 ret = put_user(boot_status, p); 108 ret = put_user(boot_status, p);
109 break; 109 break;
110 110
111 case WDIOC_KEEPALIVE:
112 OSMR3 = OSCR + pre_margin;
113 ret = 0;
114 break;
115
111 case WDIOC_SETTIMEOUT: 116 case WDIOC_SETTIMEOUT:
112 ret = get_user(time, p); 117 ret = get_user(time, p);
113 if (ret) 118 if (ret)
@@ -125,27 +130,20 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
125 case WDIOC_GETTIMEOUT: 130 case WDIOC_GETTIMEOUT:
126 ret = put_user(pre_margin / OSCR_FREQ, p); 131 ret = put_user(pre_margin / OSCR_FREQ, p);
127 break; 132 break;
128
129 case WDIOC_KEEPALIVE:
130 OSMR3 = OSCR + pre_margin;
131 ret = 0;
132 break;
133 } 133 }
134 return ret; 134 return ret;
135} 135}
136 136
137static const struct file_operations sa1100dog_fops = 137static const struct file_operations sa1100dog_fops = {
138{
139 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
140 .llseek = no_llseek, 139 .llseek = no_llseek,
141 .write = sa1100dog_write, 140 .write = sa1100dog_write,
142 .ioctl = sa1100dog_ioctl, 141 .unlocked_ioctl = sa1100dog_ioctl,
143 .open = sa1100dog_open, 142 .open = sa1100dog_open,
144 .release = sa1100dog_release, 143 .release = sa1100dog_release,
145}; 144};
146 145
147static struct miscdevice sa1100dog_miscdev = 146static struct miscdevice sa1100dog_miscdev = {
148{
149 .minor = WATCHDOG_MINOR, 147 .minor = WATCHDOG_MINOR,
150 .name = "watchdog", 148 .name = "watchdog",
151 .fops = &sa1100dog_fops, 149 .fops = &sa1100dog_fops,
@@ -162,13 +160,15 @@ static int __init sa1100dog_init(void)
162 * we suspend, RCSR will be cleared, and the watchdog 160 * we suspend, RCSR will be cleared, and the watchdog
163 * reset reason will be lost. 161 * reset reason will be lost.
164 */ 162 */
165 boot_status = (RCSR & RCSR_WDR) ? WDIOF_CARDRESET : 0; 163 boot_status = (reset_status & RESET_STATUS_WATCHDOG) ?
164 WDIOF_CARDRESET : 0;
166 pre_margin = OSCR_FREQ * margin; 165 pre_margin = OSCR_FREQ * margin;
167 166
168 ret = misc_register(&sa1100dog_miscdev); 167 ret = misc_register(&sa1100dog_miscdev);
169 if (ret == 0) 168 if (ret == 0)
170 printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", 169 printk(KERN_INFO
171 margin); 170 "SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
171 margin);
172 return ret; 172 return ret;
173} 173}
174 174
diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c
index b94431433695..27e526a07c9a 100644
--- a/drivers/watchdog/sb_wdog.c
+++ b/drivers/watchdog/sb_wdog.c
@@ -57,6 +57,7 @@
57#include <asm/sibyte/sb1250_int.h> 57#include <asm/sibyte/sb1250_int.h>
58#include <asm/sibyte/sb1250_scd.h> 58#include <asm/sibyte/sb1250_scd.h>
59 59
60static DEFINE_SPINLOCK(sbwd_lock);
60 61
61/* 62/*
62 * set the initial count value of a timer 63 * set the initial count value of a timer
@@ -65,8 +66,10 @@
65 */ 66 */
66void sbwdog_set(char __iomem *wdog, unsigned long t) 67void sbwdog_set(char __iomem *wdog, unsigned long t)
67{ 68{
69 spin_lock(&sbwd_lock);
68 __raw_writeb(0, wdog - 0x10); 70 __raw_writeb(0, wdog - 0x10);
69 __raw_writeq(t & 0x7fffffUL, wdog); 71 __raw_writeq(t & 0x7fffffUL, wdog);
72 spin_unlock(&sbwd_lock);
70} 73}
71 74
72/* 75/*
@@ -77,7 +80,9 @@ void sbwdog_set(char __iomem *wdog, unsigned long t)
77 */ 80 */
78void sbwdog_pet(char __iomem *wdog) 81void sbwdog_pet(char __iomem *wdog)
79{ 82{
83 spin_lock(&sbwd_lock);
80 __raw_writeb(__raw_readb(wdog) | 1, wdog); 84 __raw_writeb(__raw_readb(wdog) | 1, wdog);
85 spin_unlock(&sbwd_lock);
81} 86}
82 87
83static unsigned long sbwdog_gate; /* keeps it to one thread only */ 88static unsigned long sbwdog_gate; /* keeps it to one thread only */
@@ -86,8 +91,9 @@ static char __iomem *user_dog = (char __iomem *)(IO_BASE + (A_SCD_WDOG_CFG_1));
86static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */ 91static unsigned long timeout = 0x7fffffUL; /* useconds: 8.3ish secs. */
87static int expect_close; 92static int expect_close;
88 93
89static struct watchdog_info ident = { 94static const struct watchdog_info ident = {
90 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 95 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
96 WDIOF_KEEPALIVEPING,
91 .identity = "SiByte Watchdog", 97 .identity = "SiByte Watchdog",
92}; 98};
93 99
@@ -97,9 +103,8 @@ static struct watchdog_info ident = {
97static int sbwdog_open(struct inode *inode, struct file *file) 103static int sbwdog_open(struct inode *inode, struct file *file)
98{ 104{
99 nonseekable_open(inode, file); 105 nonseekable_open(inode, file);
100 if (test_and_set_bit(0, &sbwdog_gate)) { 106 if (test_and_set_bit(0, &sbwdog_gate))
101 return -EBUSY; 107 return -EBUSY;
102 }
103 __module_get(THIS_MODULE); 108 __module_get(THIS_MODULE);
104 109
105 /* 110 /*
@@ -120,8 +125,9 @@ static int sbwdog_release(struct inode *inode, struct file *file)
120 __raw_writeb(0, user_dog); 125 __raw_writeb(0, user_dog);
121 module_put(THIS_MODULE); 126 module_put(THIS_MODULE);
122 } else { 127 } else {
123 printk(KERN_CRIT "%s: Unexpected close, not stopping watchdog!\n", 128 printk(KERN_CRIT
124 ident.identity); 129 "%s: Unexpected close, not stopping watchdog!\n",
130 ident.identity);
125 sbwdog_pet(user_dog); 131 sbwdog_pet(user_dog);
126 } 132 }
127 clear_bit(0, &sbwdog_gate); 133 clear_bit(0, &sbwdog_gate);
@@ -147,12 +153,10 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data,
147 for (i = 0; i != len; i++) { 153 for (i = 0; i != len; i++) {
148 char c; 154 char c;
149 155
150 if (get_user(c, data + i)) { 156 if (get_user(c, data + i))
151 return -EFAULT; 157 return -EFAULT;
152 } 158 if (c == 'V')
153 if (c == 'V') {
154 expect_close = 42; 159 expect_close = 42;
155 }
156 } 160 }
157 sbwdog_pet(user_dog); 161 sbwdog_pet(user_dog);
158 } 162 }
@@ -160,8 +164,8 @@ static ssize_t sbwdog_write(struct file *file, const char __user *data,
160 return len; 164 return len;
161} 165}
162 166
163static int sbwdog_ioctl(struct inode *inode, struct file *file, 167static long sbwdog_ioctl(struct file *file, unsigned int cmd,
164 unsigned int cmd, unsigned long arg) 168 unsigned long arg)
165{ 169{
166 int ret = -ENOTTY; 170 int ret = -ENOTTY;
167 unsigned long time; 171 unsigned long time;
@@ -178,11 +182,15 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file,
178 ret = put_user(0, p); 182 ret = put_user(0, p);
179 break; 183 break;
180 184
185 case WDIOC_KEEPALIVE:
186 sbwdog_pet(user_dog);
187 ret = 0;
188 break;
189
181 case WDIOC_SETTIMEOUT: 190 case WDIOC_SETTIMEOUT:
182 ret = get_user(time, p); 191 ret = get_user(time, p);
183 if (ret) { 192 if (ret)
184 break; 193 break;
185 }
186 194
187 time *= 1000000; 195 time *= 1000000;
188 if (time > 0x7fffffUL) { 196 if (time > 0x7fffffUL) {
@@ -200,11 +208,6 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file,
200 */ 208 */
201 ret = put_user(__raw_readq(user_dog - 8) / 1000000, p); 209 ret = put_user(__raw_readq(user_dog - 8) / 1000000, p);
202 break; 210 break;
203
204 case WDIOC_KEEPALIVE:
205 sbwdog_pet(user_dog);
206 ret = 0;
207 break;
208 } 211 }
209 return ret; 212 return ret;
210} 213}
@@ -212,8 +215,8 @@ static int sbwdog_ioctl(struct inode *inode, struct file *file,
212/* 215/*
213 * Notifier for system down 216 * Notifier for system down
214 */ 217 */
215static int 218static int sbwdog_notify_sys(struct notifier_block *this, unsigned long code,
216sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf) 219 void *erf)
217{ 220{
218 if (code == SYS_DOWN || code == SYS_HALT) { 221 if (code == SYS_DOWN || code == SYS_HALT) {
219 /* 222 /*
@@ -226,18 +229,16 @@ sbwdog_notify_sys(struct notifier_block *this, unsigned long code, void *erf)
226 return NOTIFY_DONE; 229 return NOTIFY_DONE;
227} 230}
228 231
229static const struct file_operations sbwdog_fops = 232static const struct file_operations sbwdog_fops = {
230{
231 .owner = THIS_MODULE, 233 .owner = THIS_MODULE,
232 .llseek = no_llseek, 234 .llseek = no_llseek,
233 .write = sbwdog_write, 235 .write = sbwdog_write,
234 .ioctl = sbwdog_ioctl, 236 .unlocked_ioctl = sbwdog_ioctl,
235 .open = sbwdog_open, 237 .open = sbwdog_open,
236 .release = sbwdog_release, 238 .release = sbwdog_release,
237}; 239};
238 240
239static struct miscdevice sbwdog_miscdev = 241static struct miscdevice sbwdog_miscdev = {
240{
241 .minor = WATCHDOG_MINOR, 242 .minor = WATCHDOG_MINOR,
242 .name = "watchdog", 243 .name = "watchdog",
243 .fops = &sbwdog_fops, 244 .fops = &sbwdog_fops,
@@ -267,13 +268,12 @@ irqreturn_t sbwdog_interrupt(int irq, void *addr)
267 /* 268 /*
268 * if it's the second watchdog timer, it's for those users 269 * if it's the second watchdog timer, it's for those users
269 */ 270 */
270 if (wd_cfg_reg == user_dog) { 271 if (wd_cfg_reg == user_dog)
271 printk(KERN_CRIT 272 printk(KERN_CRIT
272 "%s in danger of initiating system reset in %ld.%01ld seconds\n", 273 "%s in danger of initiating system reset in %ld.%01ld seconds\n",
273 ident.identity, wd_init / 1000000, (wd_init / 100000) % 10); 274 ident.identity, wd_init / 1000000, (wd_init / 100000) % 10);
274 } else { 275 else
275 cfg |= 1; 276 cfg |= 1;
276 }
277 277
278 __raw_writeb(cfg, wd_cfg_reg); 278 __raw_writeb(cfg, wd_cfg_reg);
279 279
@@ -289,28 +289,31 @@ static int __init sbwdog_init(void)
289 */ 289 */
290 ret = register_reboot_notifier(&sbwdog_notifier); 290 ret = register_reboot_notifier(&sbwdog_notifier);
291 if (ret) { 291 if (ret) {
292 printk (KERN_ERR "%s: cannot register reboot notifier (err=%d)\n", 292 printk(KERN_ERR
293 ident.identity, ret); 293 "%s: cannot register reboot notifier (err=%d)\n",
294 ident.identity, ret);
294 return ret; 295 return ret;
295 } 296 }
296 297
297 /* 298 /*
298 * get the resources 299 * get the resources
299 */ 300 */
300 ret = misc_register(&sbwdog_miscdev);
301 if (ret == 0) {
302 printk(KERN_INFO "%s: timeout is %ld.%ld secs\n", ident.identity,
303 timeout / 1000000, (timeout / 100000) % 10);
304 }
305 301
306 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, 302 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
307 ident.identity, (void *)user_dog); 303 ident.identity, (void *)user_dog);
308 if (ret) { 304 if (ret) {
309 printk(KERN_ERR "%s: failed to request irq 1 - %d\n", ident.identity, 305 printk(KERN_ERR "%s: failed to request irq 1 - %d\n",
310 ret); 306 ident.identity, ret);
311 misc_deregister(&sbwdog_miscdev); 307 return ret;
312 } 308 }
313 309
310 ret = misc_register(&sbwdog_miscdev);
311 if (ret == 0) {
312 printk(KERN_INFO "%s: timeout is %ld.%ld secs\n",
313 ident.identity,
314 timeout / 1000000, (timeout / 100000) % 10);
315 } else
316 free_irq(1, (void *)user_dog);
314 return ret; 317 return ret;
315} 318}
316 319
@@ -327,7 +330,7 @@ MODULE_DESCRIPTION("SiByte Watchdog");
327 330
328module_param(timeout, ulong, 0); 331module_param(timeout, ulong, 0);
329MODULE_PARM_DESC(timeout, 332MODULE_PARM_DESC(timeout,
330 "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)"); 333 "Watchdog timeout in microseconds (max/default 8388607 or 8.3ish secs)");
331 334
332MODULE_LICENSE("GPL"); 335MODULE_LICENSE("GPL");
333MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 336MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
@@ -336,16 +339,15 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
336 * example code that can be put in a platform code area to utilize the 339 * example code that can be put in a platform code area to utilize the
337 * first watchdog timer for the kernels own purpose. 340 * first watchdog timer for the kernels own purpose.
338 341
339 void 342void platform_wd_setup(void)
340platform_wd_setup(void)
341{ 343{
342 int ret; 344 int ret;
343 345
344 ret = request_irq(0, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED, 346 ret = request_irq(1, sbwdog_interrupt, IRQF_DISABLED | IRQF_SHARED,
345 "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0)); 347 "Kernel Watchdog", IOADDR(A_SCD_WDOG_CFG_0));
346 if (ret) { 348 if (ret) {
347 printk(KERN_CRIT "Watchdog IRQ zero(0) failed to be requested - %d\n", 349 printk(KERN_CRIT
348 ret); 350 "Watchdog IRQ zero(0) failed to be requested - %d\n", ret);
349 } 351 }
350} 352}
351 353
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
index ef76f01625e7..3266daaaecf8 100644
--- a/drivers/watchdog/sbc60xxwdt.c
+++ b/drivers/watchdog/sbc60xxwdt.c
@@ -16,19 +16,23 @@
16 * 16 *
17 * 12/4 - 2000 [Initial revision] 17 * 12/4 - 2000 [Initial revision]
18 * 25/4 - 2000 Added /dev/watchdog support 18 * 25/4 - 2000 Added /dev/watchdog support
19 * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1" on success 19 * 09/5 - 2001 [smj@oro.net] fixed fop_write to "return 1"
20 * on success
20 * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read 21 * 12/4 - 2002 [rob@osinvestor.com] eliminate fop_read
21 * fix possible wdt_is_open race 22 * fix possible wdt_is_open race
22 * add CONFIG_WATCHDOG_NOWAYOUT support 23 * add CONFIG_WATCHDOG_NOWAYOUT support
23 * remove lock_kernel/unlock_kernel pairs 24 * remove lock_kernel/unlock_kernel pairs
24 * added KERN_* to printk's 25 * added KERN_* to printk's
25 * got rid of extraneous comments 26 * got rid of extraneous comments
26 * changed watchdog_info to correctly reflect what the driver offers 27 * changed watchdog_info to correctly reflect what
27 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, 28 * the driver offers
28 * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls 29 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS,
30 * WDIOC_SETTIMEOUT, WDIOC_GETTIMEOUT, and
31 * WDIOC_SETOPTIONS ioctls
29 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces 32 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces
30 * use module_param 33 * use module_param
31 * made timeout (the emulated heartbeat) a module_param 34 * made timeout (the emulated heartbeat) a
35 * module_param
32 * made the keepalive ping an internal subroutine 36 * made the keepalive ping an internal subroutine
33 * made wdt_stop and wdt_start module params 37 * made wdt_stop and wdt_start module params
34 * added extra printk's for startup problems 38 * added extra printk's for startup problems
@@ -56,9 +60,9 @@
56#include <linux/notifier.h> 60#include <linux/notifier.h>
57#include <linux/reboot.h> 61#include <linux/reboot.h>
58#include <linux/init.h> 62#include <linux/init.h>
63#include <linux/io.h>
64#include <linux/uaccess.h>
59 65
60#include <asm/io.h>
61#include <asm/uaccess.h>
62#include <asm/system.h> 66#include <asm/system.h>
63 67
64#define OUR_NAME "sbc60xxwdt" 68#define OUR_NAME "sbc60xxwdt"
@@ -94,13 +98,18 @@ MODULE_PARM_DESC(wdt_start, "SBC60xx WDT 'start' io port (default 0x443)");
94 */ 98 */
95 99
96#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 100#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
97static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 101static int timeout = WATCHDOG_TIMEOUT; /* in seconds, multiplied by HZ to
102 get seconds to wait for a ping */
98module_param(timeout, int, 0); 103module_param(timeout, int, 0);
99MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 104MODULE_PARM_DESC(timeout,
105 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
106 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
100 107
101static int nowayout = WATCHDOG_NOWAYOUT; 108static int nowayout = WATCHDOG_NOWAYOUT;
102module_param(nowayout, int, 0); 109module_param(nowayout, int, 0);
103MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 110MODULE_PARM_DESC(nowayout,
111 "Watchdog cannot be stopped once started (default="
112 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
104 113
105static void wdt_timer_ping(unsigned long); 114static void wdt_timer_ping(unsigned long);
106static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); 115static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
@@ -117,15 +126,14 @@ static void wdt_timer_ping(unsigned long data)
117 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 126 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
118 * we agree to ping the WDT 127 * we agree to ping the WDT
119 */ 128 */
120 if(time_before(jiffies, next_heartbeat)) 129 if (time_before(jiffies, next_heartbeat)) {
121 {
122 /* Ping the WDT by reading from wdt_start */ 130 /* Ping the WDT by reading from wdt_start */
123 inb_p(wdt_start); 131 inb_p(wdt_start);
124 /* Re-set the timer interval */ 132 /* Re-set the timer interval */
125 mod_timer(&timer, jiffies + WDT_INTERVAL); 133 mod_timer(&timer, jiffies + WDT_INTERVAL);
126 } else { 134 } else
127 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 135 printk(KERN_WARNING PFX
128 } 136 "Heartbeat lost! Will not ping the watchdog\n");
129} 137}
130 138
131/* 139/*
@@ -159,40 +167,40 @@ static void wdt_keepalive(void)
159 * /dev/watchdog handling 167 * /dev/watchdog handling
160 */ 168 */
161 169
162static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 170static ssize_t fop_write(struct file *file, const char __user *buf,
171 size_t count, loff_t *ppos)
163{ 172{
164 /* See if we got the magic character 'V' and reload the timer */ 173 /* See if we got the magic character 'V' and reload the timer */
165 if(count) 174 if (count) {
166 { 175 if (!nowayout) {
167 if (!nowayout)
168 {
169 size_t ofs; 176 size_t ofs;
170 177
171 /* note: just in case someone wrote the magic character 178 /* note: just in case someone wrote the
172 * five months ago... */ 179 magic character five months ago... */
173 wdt_expect_close = 0; 180 wdt_expect_close = 0;
174 181
175 /* scan to see whether or not we got the magic character */ 182 /* scan to see whether or not we got the
176 for(ofs = 0; ofs != count; ofs++) 183 magic character */
177 { 184 for (ofs = 0; ofs != count; ofs++) {
178 char c; 185 char c;
179 if(get_user(c, buf+ofs)) 186 if (get_user(c, buf + ofs))
180 return -EFAULT; 187 return -EFAULT;
181 if(c == 'V') 188 if (c == 'V')
182 wdt_expect_close = 42; 189 wdt_expect_close = 42;
183 } 190 }
184 } 191 }
185 192
186 /* Well, anyhow someone wrote to us, we should return that favour */ 193 /* Well, anyhow someone wrote to us, we should
194 return that favour */
187 wdt_keepalive(); 195 wdt_keepalive();
188 } 196 }
189 return count; 197 return count;
190} 198}
191 199
192static int fop_open(struct inode * inode, struct file * file) 200static int fop_open(struct inode *inode, struct file *file)
193{ 201{
194 /* Just in case we're already talking to someone... */ 202 /* Just in case we're already talking to someone... */
195 if(test_and_set_bit(0, &wdt_is_open)) 203 if (test_and_set_bit(0, &wdt_is_open))
196 return -EBUSY; 204 return -EBUSY;
197 205
198 if (nowayout) 206 if (nowayout)
@@ -203,78 +211,72 @@ static int fop_open(struct inode * inode, struct file * file)
203 return nonseekable_open(inode, file); 211 return nonseekable_open(inode, file);
204} 212}
205 213
206static int fop_close(struct inode * inode, struct file * file) 214static int fop_close(struct inode *inode, struct file *file)
207{ 215{
208 if(wdt_expect_close == 42) 216 if (wdt_expect_close == 42)
209 wdt_turnoff(); 217 wdt_turnoff();
210 else { 218 else {
211 del_timer(&timer); 219 del_timer(&timer);
212 printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); 220 printk(KERN_CRIT PFX
221 "device file closed unexpectedly. Will not stop the WDT!\n");
213 } 222 }
214 clear_bit(0, &wdt_is_open); 223 clear_bit(0, &wdt_is_open);
215 wdt_expect_close = 0; 224 wdt_expect_close = 0;
216 return 0; 225 return 0;
217} 226}
218 227
219static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 228static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
220 unsigned long arg)
221{ 229{
222 void __user *argp = (void __user *)arg; 230 void __user *argp = (void __user *)arg;
223 int __user *p = argp; 231 int __user *p = argp;
224 static struct watchdog_info ident= 232 static const struct watchdog_info ident = {
225 { 233 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
226 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 234 WDIOF_MAGICCLOSE,
227 .firmware_version = 1, 235 .firmware_version = 1,
228 .identity = "SBC60xx", 236 .identity = "SBC60xx",
229 }; 237 };
230 238
231 switch(cmd) 239 switch (cmd) {
240 case WDIOC_GETSUPPORT:
241 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
242 case WDIOC_GETSTATUS:
243 case WDIOC_GETBOOTSTATUS:
244 return put_user(0, p);
245 case WDIOC_SETOPTIONS:
232 { 246 {
233 default: 247 int new_options, retval = -EINVAL;
234 return -ENOTTY; 248 if (get_user(new_options, p))
235 case WDIOC_GETSUPPORT: 249 return -EFAULT;
236 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; 250 if (new_options & WDIOS_DISABLECARD) {
237 case WDIOC_GETSTATUS: 251 wdt_turnoff();
238 case WDIOC_GETBOOTSTATUS: 252 retval = 0;
239 return put_user(0, p);
240 case WDIOC_KEEPALIVE:
241 wdt_keepalive();
242 return 0;
243 case WDIOC_SETOPTIONS:
244 {
245 int new_options, retval = -EINVAL;
246
247 if(get_user(new_options, p))
248 return -EFAULT;
249
250 if(new_options & WDIOS_DISABLECARD) {
251 wdt_turnoff();
252 retval = 0;
253 }
254
255 if(new_options & WDIOS_ENABLECARD) {
256 wdt_startup();
257 retval = 0;
258 }
259
260 return retval;
261 } 253 }
262 case WDIOC_SETTIMEOUT: 254 if (new_options & WDIOS_ENABLECARD) {
263 { 255 wdt_startup();
264 int new_timeout; 256 retval = 0;
265
266 if(get_user(new_timeout, p))
267 return -EFAULT;
268
269 if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
270 return -EINVAL;
271
272 timeout = new_timeout;
273 wdt_keepalive();
274 /* Fall through */
275 } 257 }
276 case WDIOC_GETTIMEOUT: 258 return retval;
277 return put_user(timeout, p); 259 }
260 case WDIOC_KEEPALIVE:
261 wdt_keepalive();
262 return 0;
263 case WDIOC_SETTIMEOUT:
264 {
265 int new_timeout;
266 if (get_user(new_timeout, p))
267 return -EFAULT;
268 /* arbitrary upper limit */
269 if (new_timeout < 1 || new_timeout > 3600)
270 return -EINVAL;
271
272 timeout = new_timeout;
273 wdt_keepalive();
274 /* Fall through */
275 }
276 case WDIOC_GETTIMEOUT:
277 return put_user(timeout, p);
278 default:
279 return -ENOTTY;
278 } 280 }
279} 281}
280 282
@@ -284,7 +286,7 @@ static const struct file_operations wdt_fops = {
284 .write = fop_write, 286 .write = fop_write,
285 .open = fop_open, 287 .open = fop_open,
286 .release = fop_close, 288 .release = fop_close,
287 .ioctl = fop_ioctl, 289 .unlocked_ioctl = fop_ioctl,
288}; 290};
289 291
290static struct miscdevice wdt_miscdev = { 292static struct miscdevice wdt_miscdev = {
@@ -300,7 +302,7 @@ static struct miscdevice wdt_miscdev = {
300static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 302static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
301 void *unused) 303 void *unused)
302{ 304{
303 if(code==SYS_DOWN || code==SYS_HALT) 305 if (code == SYS_DOWN || code == SYS_HALT)
304 wdt_turnoff(); 306 wdt_turnoff();
305 return NOTIFY_DONE; 307 return NOTIFY_DONE;
306} 308}
@@ -310,8 +312,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
310 * turn the timebomb registers off. 312 * turn the timebomb registers off.
311 */ 313 */
312 314
313static struct notifier_block wdt_notifier= 315static struct notifier_block wdt_notifier = {
314{
315 .notifier_call = wdt_notify_sys, 316 .notifier_call = wdt_notify_sys,
316}; 317};
317 318
@@ -324,23 +325,22 @@ static void __exit sbc60xxwdt_unload(void)
324 325
325 unregister_reboot_notifier(&wdt_notifier); 326 unregister_reboot_notifier(&wdt_notifier);
326 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) 327 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start))
327 release_region(wdt_stop,1); 328 release_region(wdt_stop, 1);
328 release_region(wdt_start,1); 329 release_region(wdt_start, 1);
329} 330}
330 331
331static int __init sbc60xxwdt_init(void) 332static int __init sbc60xxwdt_init(void)
332{ 333{
333 int rc = -EBUSY; 334 int rc = -EBUSY;
334 335
335 if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ 336 if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */
336 {
337 timeout = WATCHDOG_TIMEOUT; 337 timeout = WATCHDOG_TIMEOUT;
338 printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", 338 printk(KERN_INFO PFX
339 timeout); 339 "timeout value must be 1 <= x <= 3600, using %d\n",
340 } 340 timeout);
341 }
341 342
342 if (!request_region(wdt_start, 1, "SBC 60XX WDT")) 343 if (!request_region(wdt_start, 1, "SBC 60XX WDT")) {
343 {
344 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 344 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
345 wdt_start); 345 wdt_start);
346 rc = -EIO; 346 rc = -EIO;
@@ -348,33 +348,30 @@ static int __init sbc60xxwdt_init(void)
348 } 348 }
349 349
350 /* We cannot reserve 0x45 - the kernel already has! */ 350 /* We cannot reserve 0x45 - the kernel already has! */
351 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) 351 if (wdt_stop != 0x45 && wdt_stop != wdt_start) {
352 { 352 if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) {
353 if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) 353 printk(KERN_ERR PFX
354 { 354 "I/O address 0x%04x already in use\n",
355 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 355 wdt_stop);
356 wdt_stop);
357 rc = -EIO; 356 rc = -EIO;
358 goto err_out_region1; 357 goto err_out_region1;
359 } 358 }
360 } 359 }
361 360
362 rc = register_reboot_notifier(&wdt_notifier); 361 rc = register_reboot_notifier(&wdt_notifier);
363 if (rc) 362 if (rc) {
364 { 363 printk(KERN_ERR PFX
365 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 364 "cannot register reboot notifier (err=%d)\n", rc);
366 rc);
367 goto err_out_region2; 365 goto err_out_region2;
368 } 366 }
369 367
370 rc = misc_register(&wdt_miscdev); 368 rc = misc_register(&wdt_miscdev);
371 if (rc) 369 if (rc) {
372 { 370 printk(KERN_ERR PFX
373 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 371 "cannot register miscdev on minor=%d (err=%d)\n",
374 wdt_miscdev.minor, rc); 372 wdt_miscdev.minor, rc);
375 goto err_out_reboot; 373 goto err_out_reboot;
376 } 374 }
377
378 printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n", 375 printk(KERN_INFO PFX "WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n",
379 timeout, nowayout); 376 timeout, nowayout);
380 377
@@ -383,10 +380,10 @@ static int __init sbc60xxwdt_init(void)
383err_out_reboot: 380err_out_reboot:
384 unregister_reboot_notifier(&wdt_notifier); 381 unregister_reboot_notifier(&wdt_notifier);
385err_out_region2: 382err_out_region2:
386 if ((wdt_stop != 0x45) && (wdt_stop != wdt_start)) 383 if (wdt_stop != 0x45 && wdt_stop != wdt_start)
387 release_region(wdt_stop,1); 384 release_region(wdt_stop, 1);
388err_out_region1: 385err_out_region1:
389 release_region(wdt_start,1); 386 release_region(wdt_start, 1);
390err_out: 387err_out:
391 return rc; 388 return rc;
392} 389}
diff --git a/drivers/watchdog/sbc7240_wdt.c b/drivers/watchdog/sbc7240_wdt.c
index 4c8cefbd8627..67ddeb1c830a 100644
--- a/drivers/watchdog/sbc7240_wdt.c
+++ b/drivers/watchdog/sbc7240_wdt.c
@@ -27,10 +27,10 @@
27#include <linux/reboot.h> 27#include <linux/reboot.h>
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/watchdog.h> 29#include <linux/watchdog.h>
30#include <linux/io.h>
31#include <linux/uaccess.h>
30#include <asm/atomic.h> 32#include <asm/atomic.h>
31#include <asm/io.h>
32#include <asm/system.h> 33#include <asm/system.h>
33#include <asm/uaccess.h>
34 34
35#define SBC7240_PREFIX "sbc7240_wdt: " 35#define SBC7240_PREFIX "sbc7240_wdt: "
36 36
@@ -159,7 +159,7 @@ static int fop_close(struct inode *inode, struct file *file)
159 return 0; 159 return 0;
160} 160}
161 161
162static struct watchdog_info ident = { 162static const struct watchdog_info ident = {
163 .options = WDIOF_KEEPALIVEPING| 163 .options = WDIOF_KEEPALIVEPING|
164 WDIOF_SETTIMEOUT| 164 WDIOF_SETTIMEOUT|
165 WDIOF_MAGICCLOSE, 165 WDIOF_MAGICCLOSE,
@@ -168,50 +168,50 @@ static struct watchdog_info ident = {
168}; 168};
169 169
170 170
171static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 171static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
172 unsigned long arg)
173{ 172{
174 switch (cmd) { 173 switch (cmd) {
175 case WDIOC_GETSUPPORT: 174 case WDIOC_GETSUPPORT:
176 return copy_to_user 175 return copy_to_user((void __user *)arg, &ident, sizeof(ident))
177 ((void __user *)arg, &ident, sizeof(ident)) 176 ? -EFAULT : 0;
178 ? -EFAULT : 0;
179 case WDIOC_GETSTATUS: 177 case WDIOC_GETSTATUS:
180 case WDIOC_GETBOOTSTATUS: 178 case WDIOC_GETBOOTSTATUS:
181 return put_user(0, (int __user *)arg); 179 return put_user(0, (int __user *)arg);
182 case WDIOC_KEEPALIVE: 180 case WDIOC_SETOPTIONS:
183 wdt_keepalive(); 181 {
184 return 0; 182 int options;
185 case WDIOC_SETOPTIONS:{ 183 int retval = -EINVAL;
186 int options;
187 int retval = -EINVAL;
188 184
189 if (get_user(options, (int __user *)arg)) 185 if (get_user(options, (int __user *)arg))
190 return -EFAULT; 186 return -EFAULT;
191 187
192 if (options & WDIOS_DISABLECARD) { 188 if (options & WDIOS_DISABLECARD) {
193 wdt_disable(); 189 wdt_disable();
194 retval = 0; 190 retval = 0;
195 } 191 }
196
197 if (options & WDIOS_ENABLECARD) {
198 wdt_enable();
199 retval = 0;
200 }
201 192
202 return retval; 193 if (options & WDIOS_ENABLECARD) {
194 wdt_enable();
195 retval = 0;
203 } 196 }
204 case WDIOC_SETTIMEOUT:{
205 int new_timeout;
206 197
207 if (get_user(new_timeout, (int __user *)arg)) 198 return retval;
208 return -EFAULT; 199 }
200 case WDIOC_KEEPALIVE:
201 wdt_keepalive();
202 return 0;
203 case WDIOC_SETTIMEOUT:
204 {
205 int new_timeout;
209 206
210 if (wdt_set_timeout(new_timeout)) 207 if (get_user(new_timeout, (int __user *)arg))
211 return -EINVAL; 208 return -EFAULT;
212 209
213 /* Fall through */ 210 if (wdt_set_timeout(new_timeout))
214 } 211 return -EINVAL;
212
213 /* Fall through */
214 }
215 case WDIOC_GETTIMEOUT: 215 case WDIOC_GETTIMEOUT:
216 return put_user(timeout, (int __user *)arg); 216 return put_user(timeout, (int __user *)arg);
217 default: 217 default:
@@ -225,7 +225,7 @@ static const struct file_operations wdt_fops = {
225 .write = fop_write, 225 .write = fop_write,
226 .open = fop_open, 226 .open = fop_open,
227 .release = fop_close, 227 .release = fop_close,
228 .ioctl = fop_ioctl, 228 .unlocked_ioctl = fop_ioctl,
229}; 229};
230 230
231static struct miscdevice wdt_miscdev = { 231static struct miscdevice wdt_miscdev = {
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
index 2ee2677f3648..fd83dd052d8c 100644
--- a/drivers/watchdog/sbc8360.c
+++ b/drivers/watchdog/sbc8360.c
@@ -48,13 +48,12 @@
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/spinlock.h> 49#include <linux/spinlock.h>
50#include <linux/moduleparam.h> 50#include <linux/moduleparam.h>
51#include <linux/io.h>
52#include <linux/uaccess.h>
51 53
52#include <asm/io.h>
53#include <asm/uaccess.h>
54#include <asm/system.h> 54#include <asm/system.h>
55 55
56static unsigned long sbc8360_is_open; 56static unsigned long sbc8360_is_open;
57static DEFINE_SPINLOCK(sbc8360_lock);
58static char expect_close; 57static char expect_close;
59 58
60#define PFX "sbc8360: " 59#define PFX "sbc8360: "
@@ -204,7 +203,8 @@ module_param(timeout, int, 0);
204MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); 203MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
205module_param(nowayout, int, 0); 204module_param(nowayout, int, 0);
206MODULE_PARM_DESC(nowayout, 205MODULE_PARM_DESC(nowayout,
207 "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 206 "Watchdog cannot be stopped once started (default="
207 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
208 208
209/* 209/*
210 * Kernel methods. 210 * Kernel methods.
@@ -231,9 +231,16 @@ static void sbc8360_ping(void)
231 outb(wd_margin, SBC8360_BASETIME); 231 outb(wd_margin, SBC8360_BASETIME);
232} 232}
233 233
234/* stop watchdog */
235static void sbc8360_stop(void)
236{
237 /* De-activate the watchdog */
238 outb(0, SBC8360_ENABLE);
239}
240
234/* Userspace pings kernel driver, or requests clean close */ 241/* Userspace pings kernel driver, or requests clean close */
235static ssize_t sbc8360_write(struct file *file, const char __user * buf, 242static ssize_t sbc8360_write(struct file *file, const char __user *buf,
236 size_t count, loff_t * ppos) 243 size_t count, loff_t *ppos)
237{ 244{
238 if (count) { 245 if (count) {
239 if (!nowayout) { 246 if (!nowayout) {
@@ -257,16 +264,12 @@ static ssize_t sbc8360_write(struct file *file, const char __user * buf,
257 264
258static int sbc8360_open(struct inode *inode, struct file *file) 265static int sbc8360_open(struct inode *inode, struct file *file)
259{ 266{
260 spin_lock(&sbc8360_lock); 267 if (test_and_set_bit(0, &sbc8360_is_open))
261 if (test_and_set_bit(0, &sbc8360_is_open)) {
262 spin_unlock(&sbc8360_lock);
263 return -EBUSY; 268 return -EBUSY;
264 }
265 if (nowayout) 269 if (nowayout)
266 __module_get(THIS_MODULE); 270 __module_get(THIS_MODULE);
267 271
268 /* Activate and ping once to start the countdown */ 272 /* Activate and ping once to start the countdown */
269 spin_unlock(&sbc8360_lock);
270 sbc8360_activate(); 273 sbc8360_activate();
271 sbc8360_ping(); 274 sbc8360_ping();
272 return nonseekable_open(inode, file); 275 return nonseekable_open(inode, file);
@@ -274,16 +277,14 @@ static int sbc8360_open(struct inode *inode, struct file *file)
274 277
275static int sbc8360_close(struct inode *inode, struct file *file) 278static int sbc8360_close(struct inode *inode, struct file *file)
276{ 279{
277 spin_lock(&sbc8360_lock);
278 if (expect_close == 42) 280 if (expect_close == 42)
279 outb(0, SBC8360_ENABLE); 281 sbc8360_stop();
280 else 282 else
281 printk(KERN_CRIT PFX 283 printk(KERN_CRIT PFX
282 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n"); 284 "SBC8360 device closed unexpectedly. SBC8360 will not stop!\n");
283 285
284 clear_bit(0, &sbc8360_is_open); 286 clear_bit(0, &sbc8360_is_open);
285 expect_close = 0; 287 expect_close = 0;
286 spin_unlock(&sbc8360_lock);
287 return 0; 288 return 0;
288} 289}
289 290
@@ -294,10 +295,9 @@ static int sbc8360_close(struct inode *inode, struct file *file)
294static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code, 295static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code,
295 void *unused) 296 void *unused)
296{ 297{
297 if (code == SYS_DOWN || code == SYS_HALT) { 298 if (code == SYS_DOWN || code == SYS_HALT)
298 /* Disable the SBC8360 Watchdog */ 299 sbc8360_stop(); /* Disable the SBC8360 Watchdog */
299 outb(0, SBC8360_ENABLE); 300
300 }
301 return NOTIFY_DONE; 301 return NOTIFY_DONE;
302} 302}
303 303
@@ -382,13 +382,13 @@ static int __init sbc8360_init(void)
382 382
383 return 0; 383 return 0;
384 384
385 out_nomisc: 385out_nomisc:
386 unregister_reboot_notifier(&sbc8360_notifier); 386 unregister_reboot_notifier(&sbc8360_notifier);
387 out_noreboot: 387out_noreboot:
388 release_region(SBC8360_BASETIME, 1); 388 release_region(SBC8360_BASETIME, 1);
389 out_nobasetimereg: 389out_nobasetimereg:
390 release_region(SBC8360_ENABLE, 1); 390 release_region(SBC8360_ENABLE, 1);
391 out: 391out:
392 return res; 392 return res;
393} 393}
394 394
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
index 82cbd8809a69..e5e470ca7759 100644
--- a/drivers/watchdog/sbc_epx_c3.c
+++ b/drivers/watchdog/sbc_epx_c3.c
@@ -25,8 +25,8 @@
25#include <linux/reboot.h> 25#include <linux/reboot.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <asm/uaccess.h> 28#include <linux/uaccess.h>
29#include <asm/io.h> 29#include <linux/io.h>
30 30
31#define PFX "epx_c3: " 31#define PFX "epx_c3: "
32static int epx_c3_alive; 32static int epx_c3_alive;
@@ -100,12 +100,12 @@ static ssize_t epx_c3_write(struct file *file, const char __user *data,
100 return len; 100 return len;
101} 101}
102 102
103static int epx_c3_ioctl(struct inode *inode, struct file *file, 103static long epx_c3_ioctl(struct file *file, unsigned int cmd,
104 unsigned int cmd, unsigned long arg) 104 unsigned long arg)
105{ 105{
106 int options, retval = -EINVAL; 106 int options, retval = -EINVAL;
107 int __user *argp = (void __user *)arg; 107 int __user *argp = (void __user *)arg;
108 static struct watchdog_info ident = { 108 static const struct watchdog_info ident = {
109 .options = WDIOF_KEEPALIVEPING | 109 .options = WDIOF_KEEPALIVEPING |
110 WDIOF_MAGICCLOSE, 110 WDIOF_MAGICCLOSE,
111 .firmware_version = 0, 111 .firmware_version = 0,
@@ -120,11 +120,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
120 case WDIOC_GETSTATUS: 120 case WDIOC_GETSTATUS:
121 case WDIOC_GETBOOTSTATUS: 121 case WDIOC_GETBOOTSTATUS:
122 return put_user(0, argp); 122 return put_user(0, argp);
123 case WDIOC_KEEPALIVE:
124 epx_c3_pet();
125 return 0;
126 case WDIOC_GETTIMEOUT:
127 return put_user(WATCHDOG_TIMEOUT, argp);
128 case WDIOC_SETOPTIONS: 123 case WDIOC_SETOPTIONS:
129 if (get_user(options, argp)) 124 if (get_user(options, argp))
130 return -EFAULT; 125 return -EFAULT;
@@ -140,6 +135,11 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
140 } 135 }
141 136
142 return retval; 137 return retval;
138 case WDIOC_KEEPALIVE:
139 epx_c3_pet();
140 return 0;
141 case WDIOC_GETTIMEOUT:
142 return put_user(WATCHDOG_TIMEOUT, argp);
143 default: 143 default:
144 return -ENOTTY; 144 return -ENOTTY;
145 } 145 }
@@ -158,7 +158,7 @@ static const struct file_operations epx_c3_fops = {
158 .owner = THIS_MODULE, 158 .owner = THIS_MODULE,
159 .llseek = no_llseek, 159 .llseek = no_llseek,
160 .write = epx_c3_write, 160 .write = epx_c3_write,
161 .ioctl = epx_c3_ioctl, 161 .unlocked_ioctl = epx_c3_ioctl,
162 .open = epx_c3_open, 162 .open = epx_c3_open,
163 .release = epx_c3_release, 163 .release = epx_c3_release,
164}; 164};
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
index 621ebad56d86..23da3ccd832a 100644
--- a/drivers/watchdog/sc1200wdt.c
+++ b/drivers/watchdog/sc1200wdt.c
@@ -196,7 +196,6 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
196 }; 196 };
197 197
198 switch (cmd) { 198 switch (cmd) {
199
200 case WDIOC_GETSUPPORT: 199 case WDIOC_GETSUPPORT:
201 if (copy_to_user(argp, &ident, sizeof ident)) 200 if (copy_to_user(argp, &ident, sizeof ident))
202 return -EFAULT; 201 return -EFAULT;
@@ -208,24 +207,6 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
208 case WDIOC_GETBOOTSTATUS: 207 case WDIOC_GETBOOTSTATUS:
209 return put_user(0, p); 208 return put_user(0, p);
210 209
211 case WDIOC_KEEPALIVE:
212 sc1200wdt_write_data(WDTO, timeout);
213 return 0;
214
215 case WDIOC_SETTIMEOUT:
216 if (get_user(new_timeout, p))
217 return -EFAULT;
218 /* the API states this is given in secs */
219 new_timeout /= 60;
220 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
221 return -EINVAL;
222 timeout = new_timeout;
223 sc1200wdt_write_data(WDTO, timeout);
224 /* fall through and return the new timeout */
225
226 case WDIOC_GETTIMEOUT:
227 return put_user(timeout * 60, p);
228
229 case WDIOC_SETOPTIONS: 210 case WDIOC_SETOPTIONS:
230 { 211 {
231 int options, retval = -EINVAL; 212 int options, retval = -EINVAL;
@@ -245,6 +226,24 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
245 226
246 return retval; 227 return retval;
247 } 228 }
229 case WDIOC_KEEPALIVE:
230 sc1200wdt_write_data(WDTO, timeout);
231 return 0;
232
233 case WDIOC_SETTIMEOUT:
234 if (get_user(new_timeout, p))
235 return -EFAULT;
236 /* the API states this is given in secs */
237 new_timeout /= 60;
238 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
239 return -EINVAL;
240 timeout = new_timeout;
241 sc1200wdt_write_data(WDTO, timeout);
242 /* fall through and return the new timeout */
243
244 case WDIOC_GETTIMEOUT:
245 return put_user(timeout * 60, p);
246
248 default: 247 default:
249 return -ENOTTY; 248 return -ENOTTY;
250 } 249 }
@@ -280,7 +279,7 @@ static ssize_t sc1200wdt_write(struct file *file, const char __user *data,
280 for (i = 0; i != len; i++) { 279 for (i = 0; i != len; i++) {
281 char c; 280 char c;
282 281
283 if (get_user(c, data+i)) 282 if (get_user(c, data + i))
284 return -EFAULT; 283 return -EFAULT;
285 if (c == 'V') 284 if (c == 'V')
286 expect_close = 42; 285 expect_close = 42;
diff --git a/drivers/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
index 2847324a2be2..a2b6c1067ec5 100644
--- a/drivers/watchdog/sc520_wdt.c
+++ b/drivers/watchdog/sc520_wdt.c
@@ -64,9 +64,9 @@
64#include <linux/reboot.h> 64#include <linux/reboot.h>
65#include <linux/init.h> 65#include <linux/init.h>
66#include <linux/jiffies.h> 66#include <linux/jiffies.h>
67#include <linux/io.h>
68#include <linux/uaccess.h>
67 69
68#include <asm/io.h>
69#include <asm/uaccess.h>
70#include <asm/system.h> 70#include <asm/system.h>
71 71
72#define OUR_NAME "sc520_wdt" 72#define OUR_NAME "sc520_wdt"
@@ -91,13 +91,18 @@
91 */ 91 */
92 92
93#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 93#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
94static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 94/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
95static int timeout = WATCHDOG_TIMEOUT;
95module_param(timeout, int, 0); 96module_param(timeout, int, 0);
96MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 97MODULE_PARM_DESC(timeout,
98 "Watchdog timeout in seconds. (1 <= timeout <= 3600, default="
99 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
97 100
98static int nowayout = WATCHDOG_NOWAYOUT; 101static int nowayout = WATCHDOG_NOWAYOUT;
99module_param(nowayout, int, 0); 102module_param(nowayout, int, 0);
100MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 103MODULE_PARM_DESC(nowayout,
104 "Watchdog cannot be stopped once started (default="
105 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
101 106
102/* 107/*
103 * AMD Elan SC520 - Watchdog Timer Registers 108 * AMD Elan SC520 - Watchdog Timer Registers
@@ -136,8 +141,7 @@ static void wdt_timer_ping(unsigned long data)
136 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 141 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
137 * we agree to ping the WDT 142 * we agree to ping the WDT
138 */ 143 */
139 if(time_before(jiffies, next_heartbeat)) 144 if (time_before(jiffies, next_heartbeat)) {
140 {
141 /* Ping the WDT */ 145 /* Ping the WDT */
142 spin_lock(&wdt_spinlock); 146 spin_lock(&wdt_spinlock);
143 writew(0xAAAA, wdtmrctl); 147 writew(0xAAAA, wdtmrctl);
@@ -146,9 +150,9 @@ static void wdt_timer_ping(unsigned long data)
146 150
147 /* Re-set the timer interval */ 151 /* Re-set the timer interval */
148 mod_timer(&timer, jiffies + WDT_INTERVAL); 152 mod_timer(&timer, jiffies + WDT_INTERVAL);
149 } else { 153 } else
150 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 154 printk(KERN_WARNING PFX
151 } 155 "Heartbeat lost! Will not ping the watchdog\n");
152} 156}
153 157
154/* 158/*
@@ -162,7 +166,7 @@ static void wdt_config(int writeval)
162 166
163 /* buy some time (ping) */ 167 /* buy some time (ping) */
164 spin_lock_irqsave(&wdt_spinlock, flags); 168 spin_lock_irqsave(&wdt_spinlock, flags);
165 dummy=readw(wdtmrctl); /* ensure write synchronization */ 169 dummy = readw(wdtmrctl); /* ensure write synchronization */
166 writew(0xAAAA, wdtmrctl); 170 writew(0xAAAA, wdtmrctl);
167 writew(0x5555, wdtmrctl); 171 writew(0x5555, wdtmrctl);
168 /* unlock WDT = make WDT configuration register writable one time */ 172 /* unlock WDT = make WDT configuration register writable one time */
@@ -219,10 +223,11 @@ static int wdt_set_heartbeat(int t)
219 * /dev/watchdog handling 223 * /dev/watchdog handling
220 */ 224 */
221 225
222static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 226static ssize_t fop_write(struct file *file, const char __user *buf,
227 size_t count, loff_t *ppos)
223{ 228{
224 /* See if we got the magic character 'V' and reload the timer */ 229 /* See if we got the magic character 'V' and reload the timer */
225 if(count) { 230 if (count) {
226 if (!nowayout) { 231 if (!nowayout) {
227 size_t ofs; 232 size_t ofs;
228 233
@@ -231,25 +236,26 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
231 wdt_expect_close = 0; 236 wdt_expect_close = 0;
232 237
233 /* now scan */ 238 /* now scan */
234 for(ofs = 0; ofs != count; ofs++) { 239 for (ofs = 0; ofs != count; ofs++) {
235 char c; 240 char c;
236 if (get_user(c, buf + ofs)) 241 if (get_user(c, buf + ofs))
237 return -EFAULT; 242 return -EFAULT;
238 if(c == 'V') 243 if (c == 'V')
239 wdt_expect_close = 42; 244 wdt_expect_close = 42;
240 } 245 }
241 } 246 }
242 247
243 /* Well, anyhow someone wrote to us, we should return that favour */ 248 /* Well, anyhow someone wrote to us, we should
249 return that favour */
244 wdt_keepalive(); 250 wdt_keepalive();
245 } 251 }
246 return count; 252 return count;
247} 253}
248 254
249static int fop_open(struct inode * inode, struct file * file) 255static int fop_open(struct inode *inode, struct file *file)
250{ 256{
251 /* Just in case we're already talking to someone... */ 257 /* Just in case we're already talking to someone... */
252 if(test_and_set_bit(0, &wdt_is_open)) 258 if (test_and_set_bit(0, &wdt_is_open))
253 return -EBUSY; 259 return -EBUSY;
254 if (nowayout) 260 if (nowayout)
255 __module_get(THIS_MODULE); 261 __module_get(THIS_MODULE);
@@ -259,12 +265,13 @@ static int fop_open(struct inode * inode, struct file * file)
259 return nonseekable_open(inode, file); 265 return nonseekable_open(inode, file);
260} 266}
261 267
262static int fop_close(struct inode * inode, struct file * file) 268static int fop_close(struct inode *inode, struct file *file)
263{ 269{
264 if(wdt_expect_close == 42) { 270 if (wdt_expect_close == 42)
265 wdt_turnoff(); 271 wdt_turnoff();
266 } else { 272 else {
267 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 273 printk(KERN_CRIT PFX
274 "Unexpected close, not stopping watchdog!\n");
268 wdt_keepalive(); 275 wdt_keepalive();
269 } 276 }
270 clear_bit(0, &wdt_is_open); 277 clear_bit(0, &wdt_is_open);
@@ -272,63 +279,62 @@ static int fop_close(struct inode * inode, struct file * file)
272 return 0; 279 return 0;
273} 280}
274 281
275static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 282static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
276 unsigned long arg)
277{ 283{
278 void __user *argp = (void __user *)arg; 284 void __user *argp = (void __user *)arg;
279 int __user *p = argp; 285 int __user *p = argp;
280 static struct watchdog_info ident = { 286 static const struct watchdog_info ident = {
281 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 287 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
288 | WDIOF_MAGICCLOSE,
282 .firmware_version = 1, 289 .firmware_version = 1,
283 .identity = "SC520", 290 .identity = "SC520",
284 }; 291 };
285 292
286 switch(cmd) 293 switch (cmd) {
294 case WDIOC_GETSUPPORT:
295 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
296 case WDIOC_GETSTATUS:
297 case WDIOC_GETBOOTSTATUS:
298 return put_user(0, p);
299 case WDIOC_SETOPTIONS:
287 { 300 {
288 default: 301 int new_options, retval = -EINVAL;
289 return -ENOTTY;
290 case WDIOC_GETSUPPORT:
291 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
292 case WDIOC_GETSTATUS:
293 case WDIOC_GETBOOTSTATUS:
294 return put_user(0, p);
295 case WDIOC_KEEPALIVE:
296 wdt_keepalive();
297 return 0;
298 case WDIOC_SETOPTIONS:
299 {
300 int new_options, retval = -EINVAL;
301
302 if(get_user(new_options, p))
303 return -EFAULT;
304
305 if(new_options & WDIOS_DISABLECARD) {
306 wdt_turnoff();
307 retval = 0;
308 }
309 302
310 if(new_options & WDIOS_ENABLECARD) { 303 if (get_user(new_options, p))
311 wdt_startup(); 304 return -EFAULT;
312 retval = 0;
313 }
314 305
315 return retval; 306 if (new_options & WDIOS_DISABLECARD) {
307 wdt_turnoff();
308 retval = 0;
316 } 309 }
317 case WDIOC_SETTIMEOUT:
318 {
319 int new_timeout;
320 310
321 if(get_user(new_timeout, p)) 311 if (new_options & WDIOS_ENABLECARD) {
322 return -EFAULT; 312 wdt_startup();
313 retval = 0;
314 }
323 315
324 if(wdt_set_heartbeat(new_timeout)) 316 return retval;
325 return -EINVAL; 317 }
318 case WDIOC_KEEPALIVE:
319 wdt_keepalive();
320 return 0;
321 case WDIOC_SETTIMEOUT:
322 {
323 int new_timeout;
326 324
327 wdt_keepalive(); 325 if (get_user(new_timeout, p))
328 /* Fall through */ 326 return -EFAULT;
329 } 327
330 case WDIOC_GETTIMEOUT: 328 if (wdt_set_heartbeat(new_timeout))
331 return put_user(timeout, p); 329 return -EINVAL;
330
331 wdt_keepalive();
332 /* Fall through */
333 }
334 case WDIOC_GETTIMEOUT:
335 return put_user(timeout, p);
336 default:
337 return -ENOTTY;
332 } 338 }
333} 339}
334 340
@@ -338,7 +344,7 @@ static const struct file_operations wdt_fops = {
338 .write = fop_write, 344 .write = fop_write,
339 .open = fop_open, 345 .open = fop_open,
340 .release = fop_close, 346 .release = fop_close,
341 .ioctl = fop_ioctl, 347 .unlocked_ioctl = fop_ioctl,
342}; 348};
343 349
344static struct miscdevice wdt_miscdev = { 350static struct miscdevice wdt_miscdev = {
@@ -354,7 +360,7 @@ static struct miscdevice wdt_miscdev = {
354static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 360static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
355 void *unused) 361 void *unused)
356{ 362{
357 if(code==SYS_DOWN || code==SYS_HALT) 363 if (code == SYS_DOWN || code == SYS_HALT)
358 wdt_turnoff(); 364 wdt_turnoff();
359 return NOTIFY_DONE; 365 return NOTIFY_DONE;
360} 366}
@@ -383,11 +389,13 @@ static int __init sc520_wdt_init(void)
383{ 389{
384 int rc = -EBUSY; 390 int rc = -EBUSY;
385 391
386 /* Check that the timeout value is within it's range ; if not reset to the default */ 392 /* Check that the timeout value is within it's range ;
393 if not reset to the default */
387 if (wdt_set_heartbeat(timeout)) { 394 if (wdt_set_heartbeat(timeout)) {
388 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 395 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
389 printk(KERN_INFO PFX "timeout value must be 1<=timeout<=3600, using %d\n", 396 printk(KERN_INFO PFX
390 WATCHDOG_TIMEOUT); 397 "timeout value must be 1 <= timeout <= 3600, using %d\n",
398 WATCHDOG_TIMEOUT);
391 } 399 }
392 400
393 wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2); 401 wdtmrctl = ioremap((unsigned long)(MMCR_BASE + OFFS_WDTMRCTL), 2);
@@ -399,20 +407,22 @@ static int __init sc520_wdt_init(void)
399 407
400 rc = register_reboot_notifier(&wdt_notifier); 408 rc = register_reboot_notifier(&wdt_notifier);
401 if (rc) { 409 if (rc) {
402 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 410 printk(KERN_ERR PFX
403 rc); 411 "cannot register reboot notifier (err=%d)\n", rc);
404 goto err_out_ioremap; 412 goto err_out_ioremap;
405 } 413 }
406 414
407 rc = misc_register(&wdt_miscdev); 415 rc = misc_register(&wdt_miscdev);
408 if (rc) { 416 if (rc) {
409 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 417 printk(KERN_ERR PFX
410 WATCHDOG_MINOR, rc); 418 "cannot register miscdev on minor=%d (err=%d)\n",
419 WATCHDOG_MINOR, rc);
411 goto err_out_notifier; 420 goto err_out_notifier;
412 } 421 }
413 422
414 printk(KERN_INFO PFX "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n", 423 printk(KERN_INFO PFX
415 timeout,nowayout); 424 "WDT driver for SC520 initialised. timeout=%d sec (nowayout=%d)\n",
425 timeout, nowayout);
416 426
417 return 0; 427 return 0;
418 428
diff --git a/drivers/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c
index d55882bca319..9e19a10a5bb9 100644
--- a/drivers/watchdog/scx200_wdt.c
+++ b/drivers/watchdog/scx200_wdt.c
@@ -27,9 +27,8 @@
27#include <linux/fs.h> 27#include <linux/fs.h>
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/scx200.h> 29#include <linux/scx200.h>
30 30#include <linux/uaccess.h>
31#include <asm/uaccess.h> 31#include <linux/io.h>
32#include <asm/io.h>
33 32
34#define NAME "scx200_wdt" 33#define NAME "scx200_wdt"
35 34
@@ -47,8 +46,9 @@ module_param(nowayout, int, 0);
47MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); 46MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
48 47
49static u16 wdto_restart; 48static u16 wdto_restart;
50static struct semaphore open_semaphore;
51static char expect_close; 49static char expect_close;
50static unsigned long open_lock;
51static DEFINE_SPINLOCK(scx_lock);
52 52
53/* Bits of the WDCNFG register */ 53/* Bits of the WDCNFG register */
54#define W_ENABLE 0x00fa /* Enable watchdog */ 54#define W_ENABLE 0x00fa /* Enable watchdog */
@@ -59,7 +59,9 @@ static char expect_close;
59 59
60static void scx200_wdt_ping(void) 60static void scx200_wdt_ping(void)
61{ 61{
62 spin_lock(&scx_lock);
62 outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO); 63 outw(wdto_restart, scx200_cb_base + SCx200_WDT_WDTO);
64 spin_unlock(&scx_lock);
63} 65}
64 66
65static void scx200_wdt_update_margin(void) 67static void scx200_wdt_update_margin(void)
@@ -73,9 +75,11 @@ static void scx200_wdt_enable(void)
73 printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", 75 printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n",
74 wdto_restart); 76 wdto_restart);
75 77
78 spin_lock(&scx_lock);
76 outw(0, scx200_cb_base + SCx200_WDT_WDTO); 79 outw(0, scx200_cb_base + SCx200_WDT_WDTO);
77 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); 80 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS);
78 outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG); 81 outw(W_ENABLE, scx200_cb_base + SCx200_WDT_WDCNFG);
82 spin_unlock(&scx_lock);
79 83
80 scx200_wdt_ping(); 84 scx200_wdt_ping();
81} 85}
@@ -84,15 +88,17 @@ static void scx200_wdt_disable(void)
84{ 88{
85 printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); 89 printk(KERN_DEBUG NAME ": disabling watchdog timer\n");
86 90
91 spin_lock(&scx_lock);
87 outw(0, scx200_cb_base + SCx200_WDT_WDTO); 92 outw(0, scx200_cb_base + SCx200_WDT_WDTO);
88 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS); 93 outb(SCx200_WDT_WDSTS_WDOVF, scx200_cb_base + SCx200_WDT_WDSTS);
89 outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG); 94 outw(W_DISABLE, scx200_cb_base + SCx200_WDT_WDCNFG);
95 spin_unlock(&scx_lock);
90} 96}
91 97
92static int scx200_wdt_open(struct inode *inode, struct file *file) 98static int scx200_wdt_open(struct inode *inode, struct file *file)
93{ 99{
94 /* only allow one at a time */ 100 /* only allow one at a time */
95 if (down_trylock(&open_semaphore)) 101 if (test_and_set_bit(0, &open_lock))
96 return -EBUSY; 102 return -EBUSY;
97 scx200_wdt_enable(); 103 scx200_wdt_enable();
98 104
@@ -101,13 +107,12 @@ static int scx200_wdt_open(struct inode *inode, struct file *file)
101 107
102static int scx200_wdt_release(struct inode *inode, struct file *file) 108static int scx200_wdt_release(struct inode *inode, struct file *file)
103{ 109{
104 if (expect_close != 42) { 110 if (expect_close != 42)
105 printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); 111 printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n");
106 } else if (!nowayout) { 112 else if (!nowayout)
107 scx200_wdt_disable(); 113 scx200_wdt_disable();
108 }
109 expect_close = 0; 114 expect_close = 0;
110 up(&open_semaphore); 115 clear_bit(0, &open_lock);
111 116
112 return 0; 117 return 0;
113} 118}
@@ -122,8 +127,7 @@ static int scx200_wdt_notify_sys(struct notifier_block *this,
122 return NOTIFY_DONE; 127 return NOTIFY_DONE;
123} 128}
124 129
125static struct notifier_block scx200_wdt_notifier = 130static struct notifier_block scx200_wdt_notifier = {
126{
127 .notifier_call = scx200_wdt_notify_sys, 131 .notifier_call = scx200_wdt_notify_sys,
128}; 132};
129 133
@@ -131,8 +135,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
131 size_t len, loff_t *ppos) 135 size_t len, loff_t *ppos)
132{ 136{
133 /* check for a magic close character */ 137 /* check for a magic close character */
134 if (len) 138 if (len) {
135 {
136 size_t i; 139 size_t i;
137 140
138 scx200_wdt_ping(); 141 scx200_wdt_ping();
@@ -140,7 +143,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
140 expect_close = 0; 143 expect_close = 0;
141 for (i = 0; i < len; ++i) { 144 for (i = 0; i < len; ++i) {
142 char c; 145 char c;
143 if (get_user(c, data+i)) 146 if (get_user(c, data + i))
144 return -EFAULT; 147 return -EFAULT;
145 if (c == 'V') 148 if (c == 'V')
146 expect_close = 42; 149 expect_close = 42;
@@ -152,23 +155,21 @@ static ssize_t scx200_wdt_write(struct file *file, const char __user *data,
152 return 0; 155 return 0;
153} 156}
154 157
155static int scx200_wdt_ioctl(struct inode *inode, struct file *file, 158static long scx200_wdt_ioctl(struct file *file, unsigned int cmd,
156 unsigned int cmd, unsigned long arg) 159 unsigned long arg)
157{ 160{
158 void __user *argp = (void __user *)arg; 161 void __user *argp = (void __user *)arg;
159 int __user *p = argp; 162 int __user *p = argp;
160 static struct watchdog_info ident = { 163 static const struct watchdog_info ident = {
161 .identity = "NatSemi SCx200 Watchdog", 164 .identity = "NatSemi SCx200 Watchdog",
162 .firmware_version = 1, 165 .firmware_version = 1,
163 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), 166 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
164 }; 167 };
165 int new_margin; 168 int new_margin;
166 169
167 switch (cmd) { 170 switch (cmd) {
168 default:
169 return -ENOTTY;
170 case WDIOC_GETSUPPORT: 171 case WDIOC_GETSUPPORT:
171 if(copy_to_user(argp, &ident, sizeof(ident))) 172 if (copy_to_user(argp, &ident, sizeof(ident)))
172 return -EFAULT; 173 return -EFAULT;
173 return 0; 174 return 0;
174 case WDIOC_GETSTATUS: 175 case WDIOC_GETSTATUS:
@@ -191,22 +192,24 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
191 if (put_user(margin, p)) 192 if (put_user(margin, p))
192 return -EFAULT; 193 return -EFAULT;
193 return 0; 194 return 0;
195 default:
196 return -ENOTTY;
194 } 197 }
195} 198}
196 199
197static const struct file_operations scx200_wdt_fops = { 200static const struct file_operations scx200_wdt_fops = {
198 .owner = THIS_MODULE, 201 .owner = THIS_MODULE,
199 .llseek = no_llseek, 202 .llseek = no_llseek,
200 .write = scx200_wdt_write, 203 .write = scx200_wdt_write,
201 .ioctl = scx200_wdt_ioctl, 204 .unlocked_ioctl = scx200_wdt_ioctl,
202 .open = scx200_wdt_open, 205 .open = scx200_wdt_open,
203 .release = scx200_wdt_release, 206 .release = scx200_wdt_release,
204}; 207};
205 208
206static struct miscdevice scx200_wdt_miscdev = { 209static struct miscdevice scx200_wdt_miscdev = {
207 .minor = WATCHDOG_MINOR, 210 .minor = WATCHDOG_MINOR,
208 .name = "watchdog", 211 .name = "watchdog",
209 .fops = &scx200_wdt_fops, 212 .fops = &scx200_wdt_fops,
210}; 213};
211 214
212static int __init scx200_wdt_init(void) 215static int __init scx200_wdt_init(void)
@@ -229,8 +232,6 @@ static int __init scx200_wdt_init(void)
229 scx200_wdt_update_margin(); 232 scx200_wdt_update_margin();
230 scx200_wdt_disable(); 233 scx200_wdt_disable();
231 234
232 sema_init(&open_semaphore, 1);
233
234 r = register_reboot_notifier(&scx200_wdt_notifier); 235 r = register_reboot_notifier(&scx200_wdt_notifier);
235 if (r) { 236 if (r) {
236 printk(KERN_ERR NAME ": unable to register reboot notifier"); 237 printk(KERN_ERR NAME ": unable to register reboot notifier");
@@ -263,7 +264,7 @@ module_exit(scx200_wdt_cleanup);
263 264
264/* 265/*
265 Local variables: 266 Local variables:
266 compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" 267 compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules"
267 c-basic-offset: 8 268 c-basic-offset: 8
268 End: 269 End:
269*/ 270*/
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 1277f7e9cc54..cdc7138be301 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -28,8 +28,8 @@
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <asm/io.h> 31#include <linux/io.h>
32#include <asm/uaccess.h> 32#include <linux/uaccess.h>
33#include <asm/watchdog.h> 33#include <asm/watchdog.h>
34 34
35#define PFX "shwdt: " 35#define PFX "shwdt: "
@@ -68,10 +68,11 @@ static int clock_division_ratio = WTCSR_CKS_4096;
68static void sh_wdt_ping(unsigned long data); 68static void sh_wdt_ping(unsigned long data);
69 69
70static unsigned long shwdt_is_open; 70static unsigned long shwdt_is_open;
71static struct watchdog_info sh_wdt_info; 71static const struct watchdog_info sh_wdt_info;
72static char shwdt_expect_close; 72static char shwdt_expect_close;
73static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0); 73static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0);
74static unsigned long next_heartbeat; 74static unsigned long next_heartbeat;
75static DEFINE_SPINLOCK(shwdt_lock);
75 76
76#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ 77#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */
77static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ 78static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
@@ -86,6 +87,9 @@ static int nowayout = WATCHDOG_NOWAYOUT;
86static void sh_wdt_start(void) 87static void sh_wdt_start(void)
87{ 88{
88 __u8 csr; 89 __u8 csr;
90 unsigned long flags;
91
92 spin_lock_irqsave(&shwdt_lock, flags);
89 93
90 next_heartbeat = jiffies + (heartbeat * HZ); 94 next_heartbeat = jiffies + (heartbeat * HZ);
91 mod_timer(&timer, next_ping_period(clock_division_ratio)); 95 mod_timer(&timer, next_ping_period(clock_division_ratio));
@@ -123,6 +127,7 @@ static void sh_wdt_start(void)
123 csr &= ~RSTCSR_RSTS; 127 csr &= ~RSTCSR_RSTS;
124 sh_wdt_write_rstcsr(csr); 128 sh_wdt_write_rstcsr(csr);
125#endif 129#endif
130 spin_unlock_irqrestore(&shwdt_lock, flags);
126} 131}
127 132
128/** 133/**
@@ -132,12 +137,16 @@ static void sh_wdt_start(void)
132static void sh_wdt_stop(void) 137static void sh_wdt_stop(void)
133{ 138{
134 __u8 csr; 139 __u8 csr;
140 unsigned long flags;
141
142 spin_lock_irqsave(&shwdt_lock, flags);
135 143
136 del_timer(&timer); 144 del_timer(&timer);
137 145
138 csr = sh_wdt_read_csr(); 146 csr = sh_wdt_read_csr();
139 csr &= ~WTCSR_TME; 147 csr &= ~WTCSR_TME;
140 sh_wdt_write_csr(csr); 148 sh_wdt_write_csr(csr);
149 spin_unlock_irqrestore(&shwdt_lock, flags);
141} 150}
142 151
143/** 152/**
@@ -146,7 +155,11 @@ static void sh_wdt_stop(void)
146 */ 155 */
147static inline void sh_wdt_keepalive(void) 156static inline void sh_wdt_keepalive(void)
148{ 157{
158 unsigned long flags;
159
160 spin_lock_irqsave(&shwdt_lock, flags);
149 next_heartbeat = jiffies + (heartbeat * HZ); 161 next_heartbeat = jiffies + (heartbeat * HZ);
162 spin_unlock_irqrestore(&shwdt_lock, flags);
150} 163}
151 164
152/** 165/**
@@ -155,10 +168,14 @@ static inline void sh_wdt_keepalive(void)
155 */ 168 */
156static int sh_wdt_set_heartbeat(int t) 169static int sh_wdt_set_heartbeat(int t)
157{ 170{
158 if (unlikely((t < 1) || (t > 3600))) /* arbitrary upper limit */ 171 unsigned long flags;
172
173 if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */
159 return -EINVAL; 174 return -EINVAL;
160 175
176 spin_lock_irqsave(&shwdt_lock, flags);
161 heartbeat = t; 177 heartbeat = t;
178 spin_unlock_irqrestore(&shwdt_lock, flags);
162 return 0; 179 return 0;
163} 180}
164 181
@@ -170,6 +187,9 @@ static int sh_wdt_set_heartbeat(int t)
170 */ 187 */
171static void sh_wdt_ping(unsigned long data) 188static void sh_wdt_ping(unsigned long data)
172{ 189{
190 unsigned long flags;
191
192 spin_lock_irqsave(&shwdt_lock, flags);
173 if (time_before(jiffies, next_heartbeat)) { 193 if (time_before(jiffies, next_heartbeat)) {
174 __u8 csr; 194 __u8 csr;
175 195
@@ -183,6 +203,7 @@ static void sh_wdt_ping(unsigned long data)
183 } else 203 } else
184 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping " 204 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping "
185 "the watchdog\n"); 205 "the watchdog\n");
206 spin_unlock_irqrestore(&shwdt_lock, flags);
186} 207}
187 208
188/** 209/**
@@ -310,7 +331,6 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma)
310 331
311/** 332/**
312 * sh_wdt_ioctl - Query Device 333 * sh_wdt_ioctl - Query Device
313 * @inode: inode of device
314 * @file: file handle of device 334 * @file: file handle of device
315 * @cmd: watchdog command 335 * @cmd: watchdog command
316 * @arg: argument 336 * @arg: argument
@@ -318,53 +338,51 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma)
318 * Query basic information from the device or ping it, as outlined by the 338 * Query basic information from the device or ping it, as outlined by the
319 * watchdog API. 339 * watchdog API.
320 */ 340 */
321static int sh_wdt_ioctl(struct inode *inode, struct file *file, 341static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
322 unsigned int cmd, unsigned long arg) 342 unsigned long arg)
323{ 343{
324 int new_heartbeat; 344 int new_heartbeat;
325 int options, retval = -EINVAL; 345 int options, retval = -EINVAL;
326 346
327 switch (cmd) { 347 switch (cmd) {
328 case WDIOC_GETSUPPORT: 348 case WDIOC_GETSUPPORT:
329 return copy_to_user((struct watchdog_info *)arg, 349 return copy_to_user((struct watchdog_info *)arg,
330 &sh_wdt_info, 350 &sh_wdt_info, sizeof(sh_wdt_info)) ? -EFAULT : 0;
331 sizeof(sh_wdt_info)) ? -EFAULT : 0; 351 case WDIOC_GETSTATUS:
332 case WDIOC_GETSTATUS: 352 case WDIOC_GETBOOTSTATUS:
333 case WDIOC_GETBOOTSTATUS: 353 return put_user(0, (int *)arg);
334 return put_user(0, (int *)arg); 354 case WDIOC_SETOPTIONS:
335 case WDIOC_KEEPALIVE: 355 if (get_user(options, (int *)arg))
336 sh_wdt_keepalive(); 356 return -EFAULT;
337 return 0; 357
338 case WDIOC_SETTIMEOUT: 358 if (options & WDIOS_DISABLECARD) {
339 if (get_user(new_heartbeat, (int *)arg)) 359 sh_wdt_stop();
340 return -EFAULT; 360 retval = 0;
341 361 }
342 if (sh_wdt_set_heartbeat(new_heartbeat))
343 return -EINVAL;
344
345 sh_wdt_keepalive();
346 /* Fall */
347 case WDIOC_GETTIMEOUT:
348 return put_user(heartbeat, (int *)arg);
349 case WDIOC_SETOPTIONS:
350 if (get_user(options, (int *)arg))
351 return -EFAULT;
352
353 if (options & WDIOS_DISABLECARD) {
354 sh_wdt_stop();
355 retval = 0;
356 }
357 362
358 if (options & WDIOS_ENABLECARD) { 363 if (options & WDIOS_ENABLECARD) {
359 sh_wdt_start(); 364 sh_wdt_start();
360 retval = 0; 365 retval = 0;
361 } 366 }
362 367
363 return retval; 368 return retval;
364 default: 369 case WDIOC_KEEPALIVE:
365 return -ENOTTY; 370 sh_wdt_keepalive();
366 } 371 return 0;
372 case WDIOC_SETTIMEOUT:
373 if (get_user(new_heartbeat, (int *)arg))
374 return -EFAULT;
367 375
376 if (sh_wdt_set_heartbeat(new_heartbeat))
377 return -EINVAL;
378
379 sh_wdt_keepalive();
380 /* Fall */
381 case WDIOC_GETTIMEOUT:
382 return put_user(heartbeat, (int *)arg);
383 default:
384 return -ENOTTY;
385 }
368 return 0; 386 return 0;
369} 387}
370 388
@@ -390,13 +408,13 @@ static const struct file_operations sh_wdt_fops = {
390 .owner = THIS_MODULE, 408 .owner = THIS_MODULE,
391 .llseek = no_llseek, 409 .llseek = no_llseek,
392 .write = sh_wdt_write, 410 .write = sh_wdt_write,
393 .ioctl = sh_wdt_ioctl, 411 .unlocked_ioctl = sh_wdt_ioctl,
394 .open = sh_wdt_open, 412 .open = sh_wdt_open,
395 .release = sh_wdt_close, 413 .release = sh_wdt_close,
396 .mmap = sh_wdt_mmap, 414 .mmap = sh_wdt_mmap,
397}; 415};
398 416
399static struct watchdog_info sh_wdt_info = { 417static const struct watchdog_info sh_wdt_info = {
400 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 418 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
401 WDIOF_MAGICCLOSE, 419 WDIOF_MAGICCLOSE,
402 .firmware_version = 1, 420 .firmware_version = 1,
@@ -422,30 +440,33 @@ static int __init sh_wdt_init(void)
422{ 440{
423 int rc; 441 int rc;
424 442
425 if ((clock_division_ratio < 0x5) || (clock_division_ratio > 0x7)) { 443 if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) {
426 clock_division_ratio = WTCSR_CKS_4096; 444 clock_division_ratio = WTCSR_CKS_4096;
427 printk(KERN_INFO PFX "clock_division_ratio value must " 445 printk(KERN_INFO PFX
428 "be 0x5<=x<=0x7, using %d\n", clock_division_ratio); 446 "clock_division_ratio value must be 0x5<=x<=0x7, using %d\n",
447 clock_division_ratio);
429 } 448 }
430 449
431 rc = sh_wdt_set_heartbeat(heartbeat); 450 rc = sh_wdt_set_heartbeat(heartbeat);
432 if (unlikely(rc)) { 451 if (unlikely(rc)) {
433 heartbeat = WATCHDOG_HEARTBEAT; 452 heartbeat = WATCHDOG_HEARTBEAT;
434 printk(KERN_INFO PFX "heartbeat value must " 453 printk(KERN_INFO PFX
435 "be 1<=x<=3600, using %d\n", heartbeat); 454 "heartbeat value must be 1<=x<=3600, using %d\n",
455 heartbeat);
436 } 456 }
437 457
438 rc = register_reboot_notifier(&sh_wdt_notifier); 458 rc = register_reboot_notifier(&sh_wdt_notifier);
439 if (unlikely(rc)) { 459 if (unlikely(rc)) {
440 printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n", 460 printk(KERN_ERR PFX
441 rc); 461 "Can't register reboot notifier (err=%d)\n", rc);
442 return rc; 462 return rc;
443 } 463 }
444 464
445 rc = misc_register(&sh_wdt_miscdev); 465 rc = misc_register(&sh_wdt_miscdev);
446 if (unlikely(rc)) { 466 if (unlikely(rc)) {
447 printk(KERN_ERR PFX "Can't register miscdev on " 467 printk(KERN_ERR PFX
448 "minor=%d (err=%d)\n", sh_wdt_miscdev.minor, rc); 468 "Can't register miscdev on minor=%d (err=%d)\n",
469 sh_wdt_miscdev.minor, rc);
449 unregister_reboot_notifier(&sh_wdt_notifier); 470 unregister_reboot_notifier(&sh_wdt_notifier);
450 return rc; 471 return rc;
451 } 472 }
@@ -476,10 +497,14 @@ module_param(clock_division_ratio, int, 0);
476MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")"); 497MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")");
477 498
478module_param(heartbeat, int, 0); 499module_param(heartbeat, int, 0);
479MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<=heartbeat<=3600, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); 500MODULE_PARM_DESC(heartbeat,
501 "Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default="
502 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
480 503
481module_param(nowayout, int, 0); 504module_param(nowayout, int, 0);
482MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 505MODULE_PARM_DESC(nowayout,
506 "Watchdog cannot be stopped once started (default="
507 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
483 508
484module_init(sh_wdt_init); 509module_init(sh_wdt_init);
485module_exit(sh_wdt_exit); 510module_exit(sh_wdt_exit);
diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c
index 5d2b5ba61414..988ff1d5b4be 100644
--- a/drivers/watchdog/smsc37b787_wdt.c
+++ b/drivers/watchdog/smsc37b787_wdt.c
@@ -18,7 +18,7 @@
18 * History: 18 * History:
19 * 2003 - Created version 1.0 for Linux 2.4.x. 19 * 2003 - Created version 1.0 for Linux 2.4.x.
20 * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE 20 * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE
21 * features. Released version 1.1 21 * features. Released version 1.1
22 * 22 *
23 * Theory of operation: 23 * Theory of operation:
24 * 24 *
@@ -55,9 +55,9 @@
55#include <linux/reboot.h> 55#include <linux/reboot.h>
56#include <linux/init.h> 56#include <linux/init.h>
57#include <linux/spinlock.h> 57#include <linux/spinlock.h>
58#include <linux/io.h>
59#include <linux/uaccess.h>
58 60
59#include <asm/io.h>
60#include <asm/uaccess.h>
61#include <asm/system.h> 61#include <asm/system.h>
62 62
63/* enable support for minutes as units? */ 63/* enable support for minutes as units? */
@@ -71,15 +71,15 @@
71#define UNIT_MINUTE 1 71#define UNIT_MINUTE 1
72 72
73#define MODNAME "smsc37b787_wdt: " 73#define MODNAME "smsc37b787_wdt: "
74#define VERSION "1.1" 74#define VERSION "1.1"
75 75
76#define IOPORT 0x3F0 76#define IOPORT 0x3F0
77#define IOPORT_SIZE 2 77#define IOPORT_SIZE 2
78#define IODEV_NO 8 78#define IODEV_NO 8
79 79
80static int unit = UNIT_SECOND; /* timer's unit */ 80static int unit = UNIT_SECOND; /* timer's unit */
81static int timeout = 60; /* timeout value: default is 60 "units" */ 81static int timeout = 60; /* timeout value: default is 60 "units" */
82static unsigned long timer_enabled = 0; /* is the timer enabled? */ 82static unsigned long timer_enabled; /* is the timer enabled? */
83 83
84static char expect_close; /* is the close expected? */ 84static char expect_close; /* is the close expected? */
85 85
@@ -93,114 +93,121 @@ static int nowayout = WATCHDOG_NOWAYOUT;
93 93
94static inline void open_io_config(void) 94static inline void open_io_config(void)
95{ 95{
96 outb(0x55, IOPORT); 96 outb(0x55, IOPORT);
97 mdelay(1); 97 mdelay(1);
98 outb(0x55, IOPORT); 98 outb(0x55, IOPORT);
99} 99}
100 100
101/* lock the IO chip */ 101/* lock the IO chip */
102static inline void close_io_config(void) 102static inline void close_io_config(void)
103{ 103{
104 outb(0xAA, IOPORT); 104 outb(0xAA, IOPORT);
105} 105}
106 106
107/* select the IO device */ 107/* select the IO device */
108static inline void select_io_device(unsigned char devno) 108static inline void select_io_device(unsigned char devno)
109{ 109{
110 outb(0x07, IOPORT); 110 outb(0x07, IOPORT);
111 outb(devno, IOPORT+1); 111 outb(devno, IOPORT+1);
112} 112}
113 113
114/* write to the control register */ 114/* write to the control register */
115static inline void write_io_cr(unsigned char reg, unsigned char data) 115static inline void write_io_cr(unsigned char reg, unsigned char data)
116{ 116{
117 outb(reg, IOPORT); 117 outb(reg, IOPORT);
118 outb(data, IOPORT+1); 118 outb(data, IOPORT+1);
119} 119}
120 120
121/* read from the control register */ 121/* read from the control register */
122static inline char read_io_cr(unsigned char reg) 122static inline char read_io_cr(unsigned char reg)
123{ 123{
124 outb(reg, IOPORT); 124 outb(reg, IOPORT);
125 return inb(IOPORT+1); 125 return inb(IOPORT+1);
126} 126}
127 127
128/* -- Medium level functions ------------------------------------*/ 128/* -- Medium level functions ------------------------------------*/
129 129
130static inline void gpio_bit12(unsigned char reg) 130static inline void gpio_bit12(unsigned char reg)
131{ 131{
132 // -- General Purpose I/O Bit 1.2 -- 132 /* -- General Purpose I/O Bit 1.2 --
133 // Bit 0, In/Out: 0 = Output, 1 = Input 133 * Bit 0, In/Out: 0 = Output, 1 = Input
134 // Bit 1, Polarity: 0 = No Invert, 1 = Invert 134 * Bit 1, Polarity: 0 = No Invert, 1 = Invert
135 // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable 135 * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
136 // Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, 136 * Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17,
137 // 11 = Either Edge Triggered Intr. 2 137 * 11 = Either Edge Triggered Intr. 2
138 // Bit 5/6 (Reserved) 138 * Bit 5/6 (Reserved)
139 // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain 139 * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
140 write_io_cr(0xE2, reg); 140 */
141 write_io_cr(0xE2, reg);
141} 142}
142 143
143static inline void gpio_bit13(unsigned char reg) 144static inline void gpio_bit13(unsigned char reg)
144{ 145{
145 // -- General Purpose I/O Bit 1.3 -- 146 /* -- General Purpose I/O Bit 1.3 --
146 // Bit 0, In/Out: 0 = Output, 1 = Input 147 * Bit 0, In/Out: 0 = Output, 1 = Input
147 // Bit 1, Polarity: 0 = No Invert, 1 = Invert 148 * Bit 1, Polarity: 0 = No Invert, 1 = Invert
148 // Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable 149 * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
149 // Bit 3, Function select: 0 = GPI/O, 1 = LED 150 * Bit 3, Function select: 0 = GPI/O, 1 = LED
150 // Bit 4-6 (Reserved) 151 * Bit 4-6 (Reserved)
151 // Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain 152 * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
152 write_io_cr(0xE3, reg); 153 */
154 write_io_cr(0xE3, reg);
153} 155}
154 156
155static inline void wdt_timer_units(unsigned char new_units) 157static inline void wdt_timer_units(unsigned char new_units)
156{ 158{
157 // -- Watchdog timer units -- 159 /* -- Watchdog timer units --
158 // Bit 0-6 (Reserved) 160 * Bit 0-6 (Reserved)
159 // Bit 7, WDT Time-out Value Units Select 161 * Bit 7, WDT Time-out Value Units Select
160 // (0 = Minutes, 1 = Seconds) 162 * (0 = Minutes, 1 = Seconds)
161 write_io_cr(0xF1, new_units); 163 */
164 write_io_cr(0xF1, new_units);
162} 165}
163 166
164static inline void wdt_timeout_value(unsigned char new_timeout) 167static inline void wdt_timeout_value(unsigned char new_timeout)
165{ 168{
166 // -- Watchdog Timer Time-out Value -- 169 /* -- Watchdog Timer Time-out Value --
167 // Bit 0-7 Binary coded units (0=Disabled, 1..255) 170 * Bit 0-7 Binary coded units (0=Disabled, 1..255)
168 write_io_cr(0xF2, new_timeout); 171 */
172 write_io_cr(0xF2, new_timeout);
169} 173}
170 174
171static inline void wdt_timer_conf(unsigned char conf) 175static inline void wdt_timer_conf(unsigned char conf)
172{ 176{
173 // -- Watchdog timer configuration -- 177 /* -- Watchdog timer configuration --
174 // Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O 178 * Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon
175 // Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. 179 * Gameport I/O
176 // Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr. 180 * Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr.
177 // Bit 3 Reset the timer 181 * Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr
178 // (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled) 182 * Bit 3 Reset the timer
179 // Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, 183 * (Wrong in SMsC documentation? Given as: PowerLED Timout
180 // 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) 184 * Enabled)
181 write_io_cr(0xF3, conf); 185 * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled,
186 * 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15)
187 */
188 write_io_cr(0xF3, conf);
182} 189}
183 190
184static inline void wdt_timer_ctrl(unsigned char reg) 191static inline void wdt_timer_ctrl(unsigned char reg)
185{ 192{
186 // -- Watchdog timer control -- 193 /* -- Watchdog timer control --
187 // Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured 194 * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured
188 // Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz 195 * Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz
189 // Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) 196 * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning)
190 // Bit 3 P20 Force Timeout enabled: 197 * Bit 3 P20 Force Timeout enabled:
191 // 0 = P20 activity does not generate the WD timeout event 198 * 0 = P20 activity does not generate the WD timeout event
192 // 1 = P20 Allows rising edge of P20, from the keyboard 199 * 1 = P20 Allows rising edge of P20, from the keyboard
193 // controller, to force the WD timeout event. 200 * controller, to force the WD timeout event.
194 // Bit 4 (Reserved) 201 * Bit 4 (Reserved)
195 // -- Soft power management -- 202 * -- Soft power management --
196 // Bit 5 Stop Counter: 1 = Stop software power down counter 203 * Bit 5 Stop Counter: 1 = Stop software power down counter
197 // set via register 0xB8, (self-cleaning) 204 * set via register 0xB8, (self-cleaning)
198 // (Upon read: 0 = Counter running, 1 = Counter stopped) 205 * (Upon read: 0 = Counter running, 1 = Counter stopped)
199 // Bit 6 Restart Counter: 1 = Restart software power down counter 206 * Bit 6 Restart Counter: 1 = Restart software power down counter
200 // set via register 0xB8, (self-cleaning) 207 * set via register 0xB8, (self-cleaning)
201 // Bit 7 SPOFF: 1 = Force software power down (self-cleaning) 208 * Bit 7 SPOFF: 1 = Force software power down (self-cleaning)
202 209 */
203 write_io_cr(0xF4, reg); 210 write_io_cr(0xF4, reg);
204} 211}
205 212
206/* -- Higher level functions ------------------------------------*/ 213/* -- Higher level functions ------------------------------------*/
@@ -209,33 +216,34 @@ static inline void wdt_timer_ctrl(unsigned char reg)
209 216
210static void wb_smsc_wdt_initialize(void) 217static void wb_smsc_wdt_initialize(void)
211{ 218{
212 unsigned char old; 219 unsigned char old;
213 220
214 spin_lock(&io_lock); 221 spin_lock(&io_lock);
215 open_io_config(); 222 open_io_config();
216 select_io_device(IODEV_NO); 223 select_io_device(IODEV_NO);
217 224
218 // enable the watchdog 225 /* enable the watchdog */
219 gpio_bit13(0x08); // Select pin 80 = LED not GPIO 226 gpio_bit13(0x08); /* Select pin 80 = LED not GPIO */
220 gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert 227 gpio_bit12(0x0A); /* Set pin 79 = WDT not
228 GPIO/Output/Polarity=Invert */
229 /* disable the timeout */
230 wdt_timeout_value(0);
221 231
222 // disable the timeout 232 /* reset control register */
223 wdt_timeout_value(0); 233 wdt_timer_ctrl(0x00);
224 234
225 // reset control register 235 /* reset configuration register */
226 wdt_timer_ctrl(0x00);
227
228 // reset configuration register
229 wdt_timer_conf(0x00); 236 wdt_timer_conf(0x00);
230 237
231 // read old (timer units) register 238 /* read old (timer units) register */
232 old = read_io_cr(0xF1) & 0x7F; 239 old = read_io_cr(0xF1) & 0x7F;
233 if (unit == UNIT_SECOND) old |= 0x80; // set to seconds 240 if (unit == UNIT_SECOND)
241 old |= 0x80; /* set to seconds */
234 242
235 // set the watchdog timer units 243 /* set the watchdog timer units */
236 wdt_timer_units(old); 244 wdt_timer_units(old);
237 245
238 close_io_config(); 246 close_io_config();
239 spin_unlock(&io_lock); 247 spin_unlock(&io_lock);
240} 248}
241 249
@@ -244,23 +252,23 @@ static void wb_smsc_wdt_initialize(void)
244static void wb_smsc_wdt_shutdown(void) 252static void wb_smsc_wdt_shutdown(void)
245{ 253{
246 spin_lock(&io_lock); 254 spin_lock(&io_lock);
247 open_io_config(); 255 open_io_config();
248 select_io_device(IODEV_NO); 256 select_io_device(IODEV_NO);
249 257
250 // disable the watchdog 258 /* disable the watchdog */
251 gpio_bit13(0x09); 259 gpio_bit13(0x09);
252 gpio_bit12(0x09); 260 gpio_bit12(0x09);
253 261
254 // reset watchdog config register 262 /* reset watchdog config register */
255 wdt_timer_conf(0x00); 263 wdt_timer_conf(0x00);
256 264
257 // reset watchdog control register 265 /* reset watchdog control register */
258 wdt_timer_ctrl(0x00); 266 wdt_timer_ctrl(0x00);
259 267
260 // disable timeout 268 /* disable timeout */
261 wdt_timeout_value(0x00); 269 wdt_timeout_value(0x00);
262 270
263 close_io_config(); 271 close_io_config();
264 spin_unlock(&io_lock); 272 spin_unlock(&io_lock);
265} 273}
266 274
@@ -269,16 +277,16 @@ static void wb_smsc_wdt_shutdown(void)
269static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) 277static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
270{ 278{
271 spin_lock(&io_lock); 279 spin_lock(&io_lock);
272 open_io_config(); 280 open_io_config();
273 select_io_device(IODEV_NO); 281 select_io_device(IODEV_NO);
274 282
275 // set Power LED to blink, if we enable the timeout 283 /* set Power LED to blink, if we enable the timeout */
276 wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); 284 wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02);
277 285
278 // set timeout value 286 /* set timeout value */
279 wdt_timeout_value(new_timeout); 287 wdt_timeout_value(new_timeout);
280 288
281 close_io_config(); 289 close_io_config();
282 spin_unlock(&io_lock); 290 spin_unlock(&io_lock);
283} 291}
284 292
@@ -286,32 +294,32 @@ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
286 294
287static unsigned char wb_smsc_wdt_get_timeout(void) 295static unsigned char wb_smsc_wdt_get_timeout(void)
288{ 296{
289 unsigned char set_timeout; 297 unsigned char set_timeout;
290 298
291 spin_lock(&io_lock); 299 spin_lock(&io_lock);
292 open_io_config(); 300 open_io_config();
293 select_io_device(IODEV_NO); 301 select_io_device(IODEV_NO);
294 set_timeout = read_io_cr(0xF2); 302 set_timeout = read_io_cr(0xF2);
295 close_io_config(); 303 close_io_config();
296 spin_unlock(&io_lock); 304 spin_unlock(&io_lock);
297 305
298 return set_timeout; 306 return set_timeout;
299} 307}
300 308
301/* disable watchdog */ 309/* disable watchdog */
302 310
303static void wb_smsc_wdt_disable(void) 311static void wb_smsc_wdt_disable(void)
304{ 312{
305 // set the timeout to 0 to disable the watchdog 313 /* set the timeout to 0 to disable the watchdog */
306 wb_smsc_wdt_set_timeout(0); 314 wb_smsc_wdt_set_timeout(0);
307} 315}
308 316
309/* enable watchdog by setting the current timeout */ 317/* enable watchdog by setting the current timeout */
310 318
311static void wb_smsc_wdt_enable(void) 319static void wb_smsc_wdt_enable(void)
312{ 320{
313 // set the current timeout... 321 /* set the current timeout... */
314 wb_smsc_wdt_set_timeout(timeout); 322 wb_smsc_wdt_set_timeout(timeout);
315} 323}
316 324
317/* reset the timer */ 325/* reset the timer */
@@ -319,14 +327,14 @@ static void wb_smsc_wdt_enable(void)
319static void wb_smsc_wdt_reset_timer(void) 327static void wb_smsc_wdt_reset_timer(void)
320{ 328{
321 spin_lock(&io_lock); 329 spin_lock(&io_lock);
322 open_io_config(); 330 open_io_config();
323 select_io_device(IODEV_NO); 331 select_io_device(IODEV_NO);
324 332
325 // reset the timer 333 /* reset the timer */
326 wdt_timeout_value(timeout); 334 wdt_timeout_value(timeout);
327 wdt_timer_conf(0x08); 335 wdt_timer_conf(0x08);
328 336
329 close_io_config(); 337 close_io_config();
330 spin_unlock(&io_lock); 338 spin_unlock(&io_lock);
331} 339}
332 340
@@ -355,7 +363,9 @@ static int wb_smsc_wdt_open(struct inode *inode, struct file *file)
355 /* Reload and activate timer */ 363 /* Reload and activate timer */
356 wb_smsc_wdt_enable(); 364 wb_smsc_wdt_enable();
357 365
358 printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); 366 printk(KERN_INFO MODNAME
367 "Watchdog enabled. Timeout set to %d %s.\n",
368 timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
359 369
360 return nonseekable_open(inode, file); 370 return nonseekable_open(inode, file);
361} 371}
@@ -367,10 +377,12 @@ static int wb_smsc_wdt_release(struct inode *inode, struct file *file)
367 /* Shut off the timer. */ 377 /* Shut off the timer. */
368 378
369 if (expect_close == 42) { 379 if (expect_close == 42) {
370 wb_smsc_wdt_disable(); 380 wb_smsc_wdt_disable();
371 printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n"); 381 printk(KERN_INFO MODNAME
382 "Watchdog disabled, sleeping again...\n");
372 } else { 383 } else {
373 printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n"); 384 printk(KERN_CRIT MODNAME
385 "Unexpected close, not stopping watchdog!\n");
374 wb_smsc_wdt_reset_timer(); 386 wb_smsc_wdt_reset_timer();
375 } 387 }
376 388
@@ -392,10 +404,11 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
392 /* reset expect flag */ 404 /* reset expect flag */
393 expect_close = 0; 405 expect_close = 0;
394 406
395 /* scan to see whether or not we got the magic character */ 407 /* scan to see whether or not we got the
408 magic character */
396 for (i = 0; i != len; i++) { 409 for (i = 0; i != len; i++) {
397 char c; 410 char c;
398 if (get_user(c, data+i)) 411 if (get_user(c, data + i))
399 return -EFAULT; 412 return -EFAULT;
400 if (c == 'V') 413 if (c == 'V')
401 expect_close = 42; 414 expect_close = 42;
@@ -410,8 +423,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
410 423
411/* ioctl => control interface */ 424/* ioctl => control interface */
412 425
413static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, 426static long wb_smsc_wdt_ioctl(struct file *file,
414 unsigned int cmd, unsigned long arg) 427 unsigned int cmd, unsigned long arg)
415{ 428{
416 int new_timeout; 429 int new_timeout;
417 430
@@ -420,89 +433,73 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
420 int __user *i; 433 int __user *i;
421 } uarg; 434 } uarg;
422 435
423 static struct watchdog_info ident = { 436 static const struct watchdog_info ident = {
424 .options = WDIOF_KEEPALIVEPING | 437 .options = WDIOF_KEEPALIVEPING |
425 WDIOF_SETTIMEOUT | 438 WDIOF_SETTIMEOUT |
426 WDIOF_MAGICCLOSE, 439 WDIOF_MAGICCLOSE,
427 .firmware_version = 0, 440 .firmware_version = 0,
428 .identity = "SMsC 37B787 Watchdog" 441 .identity = "SMsC 37B787 Watchdog",
429 }; 442 };
430 443
431 uarg.i = (int __user *)arg; 444 uarg.i = (int __user *)arg;
432 445
433 switch (cmd) { 446 switch (cmd) {
434 default: 447 case WDIOC_GETSUPPORT:
435 return -ENOTTY; 448 return copy_to_user(uarg.ident, &ident, sizeof(ident))
436 449 ? -EFAULT : 0;
437 case WDIOC_GETSUPPORT: 450 case WDIOC_GETSTATUS:
438 return copy_to_user(uarg.ident, &ident, 451 return put_user(wb_smsc_wdt_status(), uarg.i);
439 sizeof(ident)) ? -EFAULT : 0; 452 case WDIOC_GETBOOTSTATUS:
440 453 return put_user(0, uarg.i);
441 case WDIOC_GETSTATUS: 454 case WDIOC_SETOPTIONS:
442 return put_user(wb_smsc_wdt_status(), uarg.i); 455 {
443 456 int options, retval = -EINVAL;
444 case WDIOC_GETBOOTSTATUS:
445 return put_user(0, uarg.i);
446
447 case WDIOC_KEEPALIVE:
448 wb_smsc_wdt_reset_timer();
449 return 0;
450
451 case WDIOC_SETTIMEOUT:
452 if (get_user(new_timeout, uarg.i))
453 return -EFAULT;
454
455 // the API states this is given in secs
456 if (unit == UNIT_MINUTE)
457 new_timeout /= 60;
458
459 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
460 return -EINVAL;
461
462 timeout = new_timeout;
463 wb_smsc_wdt_set_timeout(timeout);
464
465 // fall through and return the new timeout...
466
467 case WDIOC_GETTIMEOUT:
468
469 new_timeout = timeout;
470
471 if (unit == UNIT_MINUTE)
472 new_timeout *= 60;
473
474 return put_user(new_timeout, uarg.i);
475
476 case WDIOC_SETOPTIONS:
477 {
478 int options, retval = -EINVAL;
479
480 if (get_user(options, uarg.i))
481 return -EFAULT;
482
483 if (options & WDIOS_DISABLECARD) {
484 wb_smsc_wdt_disable();
485 retval = 0;
486 }
487 457
488 if (options & WDIOS_ENABLECARD) { 458 if (get_user(options, uarg.i))
489 wb_smsc_wdt_enable(); 459 return -EFAULT;
490 retval = 0;
491 }
492 460
493 return retval; 461 if (options & WDIOS_DISABLECARD) {
462 wb_smsc_wdt_disable();
463 retval = 0;
464 }
465 if (options & WDIOS_ENABLECARD) {
466 wb_smsc_wdt_enable();
467 retval = 0;
494 } 468 }
469 return retval;
470 }
471 case WDIOC_KEEPALIVE:
472 wb_smsc_wdt_reset_timer();
473 return 0;
474 case WDIOC_SETTIMEOUT:
475 if (get_user(new_timeout, uarg.i))
476 return -EFAULT;
477 /* the API states this is given in secs */
478 if (unit == UNIT_MINUTE)
479 new_timeout /= 60;
480 if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
481 return -EINVAL;
482 timeout = new_timeout;
483 wb_smsc_wdt_set_timeout(timeout);
484 /* fall through and return the new timeout... */
485 case WDIOC_GETTIMEOUT:
486 new_timeout = timeout;
487 if (unit == UNIT_MINUTE)
488 new_timeout *= 60;
489 return put_user(new_timeout, uarg.i);
490 default:
491 return -ENOTTY;
495 } 492 }
496} 493}
497 494
498/* -- Notifier funtions -----------------------------------------*/ 495/* -- Notifier funtions -----------------------------------------*/
499 496
500static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 497static int wb_smsc_wdt_notify_sys(struct notifier_block *this,
498 unsigned long code, void *unused)
501{ 499{
502 if (code == SYS_DOWN || code == SYS_HALT) 500 if (code == SYS_DOWN || code == SYS_HALT) {
503 { 501 /* set timeout to 0, to avoid possible race-condition */
504 // set timeout to 0, to avoid possible race-condition 502 timeout = 0;
505 timeout = 0;
506 wb_smsc_wdt_disable(); 503 wb_smsc_wdt_disable();
507 } 504 }
508 return NOTIFY_DONE; 505 return NOTIFY_DONE;
@@ -510,23 +507,20 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long cod
510 507
511/* -- Module's structures ---------------------------------------*/ 508/* -- Module's structures ---------------------------------------*/
512 509
513static const struct file_operations wb_smsc_wdt_fops = 510static const struct file_operations wb_smsc_wdt_fops = {
514{ 511 .owner = THIS_MODULE,
515 .owner = THIS_MODULE,
516 .llseek = no_llseek, 512 .llseek = no_llseek,
517 .write = wb_smsc_wdt_write, 513 .write = wb_smsc_wdt_write,
518 .ioctl = wb_smsc_wdt_ioctl, 514 .unlocked_ioctl = wb_smsc_wdt_ioctl,
519 .open = wb_smsc_wdt_open, 515 .open = wb_smsc_wdt_open,
520 .release = wb_smsc_wdt_release, 516 .release = wb_smsc_wdt_release,
521}; 517};
522 518
523static struct notifier_block wb_smsc_wdt_notifier = 519static struct notifier_block wb_smsc_wdt_notifier = {
524{
525 .notifier_call = wb_smsc_wdt_notify_sys, 520 .notifier_call = wb_smsc_wdt_notify_sys,
526}; 521};
527 522
528static struct miscdevice wb_smsc_wdt_miscdev = 523static struct miscdevice wb_smsc_wdt_miscdev = {
529{
530 .minor = WATCHDOG_MINOR, 524 .minor = WATCHDOG_MINOR,
531 .name = "watchdog", 525 .name = "watchdog",
532 .fops = &wb_smsc_wdt_fops, 526 .fops = &wb_smsc_wdt_fops,
@@ -540,39 +534,44 @@ static int __init wb_smsc_wdt_init(void)
540{ 534{
541 int ret; 535 int ret;
542 536
543 printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); 537 printk(KERN_INFO "SMsC 37B787 watchdog component driver "
538 VERSION " initialising...\n");
544 539
545 if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { 540 if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) {
546 printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT); 541 printk(KERN_ERR MODNAME "Unable to register IO port %#x\n",
542 IOPORT);
547 ret = -EBUSY; 543 ret = -EBUSY;
548 goto out_pnp; 544 goto out_pnp;
549 } 545 }
550 546
551 // set new maximum, if it's too big 547 /* set new maximum, if it's too big */
552 if (timeout > MAX_TIMEOUT) 548 if (timeout > MAX_TIMEOUT)
553 timeout = MAX_TIMEOUT; 549 timeout = MAX_TIMEOUT;
554 550
555 // init the watchdog timer 551 /* init the watchdog timer */
556 wb_smsc_wdt_initialize(); 552 wb_smsc_wdt_initialize();
557 553
558 ret = register_reboot_notifier(&wb_smsc_wdt_notifier); 554 ret = register_reboot_notifier(&wb_smsc_wdt_notifier);
559 if (ret) { 555 if (ret) {
560 printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); 556 printk(KERN_ERR MODNAME
557 "Unable to register reboot notifier err = %d\n", ret);
561 goto out_io; 558 goto out_io;
562 } 559 }
563 560
564 ret = misc_register(&wb_smsc_wdt_miscdev); 561 ret = misc_register(&wb_smsc_wdt_miscdev);
565 if (ret) { 562 if (ret) {
566 printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); 563 printk(KERN_ERR MODNAME
564 "Unable to register miscdev on minor %d\n",
565 WATCHDOG_MINOR);
567 goto out_rbt; 566 goto out_rbt;
568 } 567 }
569 568
570 // output info 569 /* output info */
571 printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); 570 printk(KERN_INFO MODNAME "Timeout set to %d %s.\n",
572 printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); 571 timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
573 572 printk(KERN_INFO MODNAME
574 // ret = 0 573 "Watchdog initialized and sleeping (nowayout=%d)...\n",
575 574 nowayout);
576out_clean: 575out_clean:
577 return ret; 576 return ret;
578 577
@@ -591,8 +590,7 @@ out_pnp:
591static void __exit wb_smsc_wdt_exit(void) 590static void __exit wb_smsc_wdt_exit(void)
592{ 591{
593 /* Stop the timer before we leave */ 592 /* Stop the timer before we leave */
594 if (!nowayout) 593 if (!nowayout) {
595 {
596 wb_smsc_wdt_shutdown(); 594 wb_smsc_wdt_shutdown();
597 printk(KERN_INFO MODNAME "Watchdog disabled.\n"); 595 printk(KERN_INFO MODNAME "Watchdog disabled.\n");
598 } 596 }
@@ -601,25 +599,29 @@ static void __exit wb_smsc_wdt_exit(void)
601 unregister_reboot_notifier(&wb_smsc_wdt_notifier); 599 unregister_reboot_notifier(&wb_smsc_wdt_notifier);
602 release_region(IOPORT, IOPORT_SIZE); 600 release_region(IOPORT, IOPORT_SIZE);
603 601
604 printk("SMsC 37B787 watchdog component driver removed.\n"); 602 printk(KERN_INFO "SMsC 37B787 watchdog component driver removed.\n");
605} 603}
606 604
607module_init(wb_smsc_wdt_init); 605module_init(wb_smsc_wdt_init);
608module_exit(wb_smsc_wdt_exit); 606module_exit(wb_smsc_wdt_exit);
609 607
610MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); 608MODULE_AUTHOR("Sven Anders <anders@anduras.de>");
611MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); 609MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version "
610 VERSION ")");
612MODULE_LICENSE("GPL"); 611MODULE_LICENSE("GPL");
613 612
614MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 613MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
615 614
616#ifdef SMSC_SUPPORT_MINUTES 615#ifdef SMSC_SUPPORT_MINUTES
617module_param(unit, int, 0); 616module_param(unit, int, 0);
618MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); 617MODULE_PARM_DESC(unit,
618 "set unit to use, 0=seconds or 1=minutes, default is 0");
619#endif 619#endif
620 620
621module_param(timeout, int, 0); 621module_param(timeout, int, 0);
622MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); 622MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
623 623
624module_param(nowayout, int, 0); 624module_param(nowayout, int, 0);
625MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 625MODULE_PARM_DESC(nowayout,
626 "Watchdog cannot be stopped once started (default="
627 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index 9c3694909243..c650464c5c63 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -47,19 +47,22 @@
47#include <linux/reboot.h> 47#include <linux/reboot.h>
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/jiffies.h> 49#include <linux/jiffies.h>
50 50#include <linux/uaccess.h>
51#include <asm/uaccess.h>
52 51
53#define PFX "SoftDog: " 52#define PFX "SoftDog: "
54 53
55#define TIMER_MARGIN 60 /* Default is 60 seconds */ 54#define TIMER_MARGIN 60 /* Default is 60 seconds */
56static int soft_margin = TIMER_MARGIN; /* in seconds */ 55static int soft_margin = TIMER_MARGIN; /* in seconds */
57module_param(soft_margin, int, 0); 56module_param(soft_margin, int, 0);
58MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")"); 57MODULE_PARM_DESC(soft_margin,
58 "Watchdog soft_margin in seconds. (0 < soft_margin < 65536, default="
59 __MODULE_STRING(TIMER_MARGIN) ")");
59 60
60static int nowayout = WATCHDOG_NOWAYOUT; 61static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 62module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 63MODULE_PARM_DESC(nowayout,
64 "Watchdog cannot be stopped once started (default="
65 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 66
64#ifdef ONLY_TESTING 67#ifdef ONLY_TESTING
65static int soft_noboot = 1; 68static int soft_noboot = 1;
@@ -93,8 +96,7 @@ static void watchdog_fire(unsigned long data)
93 96
94 if (soft_noboot) 97 if (soft_noboot)
95 printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n"); 98 printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n");
96 else 99 else {
97 {
98 printk(KERN_CRIT PFX "Initiating system reboot.\n"); 100 printk(KERN_CRIT PFX "Initiating system reboot.\n");
99 emergency_restart(); 101 emergency_restart();
100 printk(KERN_CRIT PFX "Reboot didn't ?????\n"); 102 printk(KERN_CRIT PFX "Reboot didn't ?????\n");
@@ -153,7 +155,8 @@ static int softdog_release(struct inode *inode, struct file *file)
153 softdog_stop(); 155 softdog_stop();
154 module_put(THIS_MODULE); 156 module_put(THIS_MODULE);
155 } else { 157 } else {
156 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 158 printk(KERN_CRIT PFX
159 "Unexpected close, not stopping watchdog!\n");
157 set_bit(0, &orphan_timer); 160 set_bit(0, &orphan_timer);
158 softdog_keepalive(); 161 softdog_keepalive();
159 } 162 }
@@ -162,12 +165,13 @@ static int softdog_release(struct inode *inode, struct file *file)
162 return 0; 165 return 0;
163} 166}
164 167
165static ssize_t softdog_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) 168static ssize_t softdog_write(struct file *file, const char __user *data,
169 size_t len, loff_t *ppos)
166{ 170{
167 /* 171 /*
168 * Refresh the timer. 172 * Refresh the timer.
169 */ 173 */
170 if(len) { 174 if (len) {
171 if (!nowayout) { 175 if (!nowayout) {
172 size_t i; 176 size_t i;
173 177
@@ -188,13 +192,13 @@ static ssize_t softdog_write(struct file *file, const char __user *data, size_t
188 return len; 192 return len;
189} 193}
190 194
191static int softdog_ioctl(struct inode *inode, struct file *file, 195static long softdog_ioctl(struct file *file, unsigned int cmd,
192 unsigned int cmd, unsigned long arg) 196 unsigned long arg)
193{ 197{
194 void __user *argp = (void __user *)arg; 198 void __user *argp = (void __user *)arg;
195 int __user *p = argp; 199 int __user *p = argp;
196 int new_margin; 200 int new_margin;
197 static struct watchdog_info ident = { 201 static const struct watchdog_info ident = {
198 .options = WDIOF_SETTIMEOUT | 202 .options = WDIOF_SETTIMEOUT |
199 WDIOF_KEEPALIVEPING | 203 WDIOF_KEEPALIVEPING |
200 WDIOF_MAGICCLOSE, 204 WDIOF_MAGICCLOSE,
@@ -202,26 +206,25 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
202 .identity = "Software Watchdog", 206 .identity = "Software Watchdog",
203 }; 207 };
204 switch (cmd) { 208 switch (cmd) {
205 default: 209 case WDIOC_GETSUPPORT:
206 return -ENOTTY; 210 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
207 case WDIOC_GETSUPPORT: 211 case WDIOC_GETSTATUS:
208 return copy_to_user(argp, &ident, 212 case WDIOC_GETBOOTSTATUS:
209 sizeof(ident)) ? -EFAULT : 0; 213 return put_user(0, p);
210 case WDIOC_GETSTATUS: 214 case WDIOC_KEEPALIVE:
211 case WDIOC_GETBOOTSTATUS: 215 softdog_keepalive();
212 return put_user(0, p); 216 return 0;
213 case WDIOC_KEEPALIVE: 217 case WDIOC_SETTIMEOUT:
214 softdog_keepalive(); 218 if (get_user(new_margin, p))
215 return 0; 219 return -EFAULT;
216 case WDIOC_SETTIMEOUT: 220 if (softdog_set_heartbeat(new_margin))
217 if (get_user(new_margin, p)) 221 return -EINVAL;
218 return -EFAULT; 222 softdog_keepalive();
219 if (softdog_set_heartbeat(new_margin)) 223 /* Fall */
220 return -EINVAL; 224 case WDIOC_GETTIMEOUT:
221 softdog_keepalive(); 225 return put_user(soft_margin, p);
222 /* Fall */ 226 default:
223 case WDIOC_GETTIMEOUT: 227 return -ENOTTY;
224 return put_user(soft_margin, p);
225 } 228 }
226} 229}
227 230
@@ -232,10 +235,9 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
232static int softdog_notify_sys(struct notifier_block *this, unsigned long code, 235static int softdog_notify_sys(struct notifier_block *this, unsigned long code,
233 void *unused) 236 void *unused)
234{ 237{
235 if(code==SYS_DOWN || code==SYS_HALT) { 238 if (code == SYS_DOWN || code == SYS_HALT)
236 /* Turn the WDT off */ 239 /* Turn the WDT off */
237 softdog_stop(); 240 softdog_stop();
238 }
239 return NOTIFY_DONE; 241 return NOTIFY_DONE;
240} 242}
241 243
@@ -247,7 +249,7 @@ static const struct file_operations softdog_fops = {
247 .owner = THIS_MODULE, 249 .owner = THIS_MODULE,
248 .llseek = no_llseek, 250 .llseek = no_llseek,
249 .write = softdog_write, 251 .write = softdog_write,
250 .ioctl = softdog_ioctl, 252 .unlocked_ioctl = softdog_ioctl,
251 .open = softdog_open, 253 .open = softdog_open,
252 .release = softdog_release, 254 .release = softdog_release,
253}; 255};
@@ -268,24 +270,27 @@ static int __init watchdog_init(void)
268{ 270{
269 int ret; 271 int ret;
270 272
271 /* Check that the soft_margin value is within it's range ; if not reset to the default */ 273 /* Check that the soft_margin value is within it's range;
274 if not reset to the default */
272 if (softdog_set_heartbeat(soft_margin)) { 275 if (softdog_set_heartbeat(soft_margin)) {
273 softdog_set_heartbeat(TIMER_MARGIN); 276 softdog_set_heartbeat(TIMER_MARGIN);
274 printk(KERN_INFO PFX "soft_margin value must be 0<soft_margin<65536, using %d\n", 277 printk(KERN_INFO PFX
278 "soft_margin must be 0 < soft_margin < 65536, using %d\n",
275 TIMER_MARGIN); 279 TIMER_MARGIN);
276 } 280 }
277 281
278 ret = register_reboot_notifier(&softdog_notifier); 282 ret = register_reboot_notifier(&softdog_notifier);
279 if (ret) { 283 if (ret) {
280 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 284 printk(KERN_ERR PFX
281 ret); 285 "cannot register reboot notifier (err=%d)\n", ret);
282 return ret; 286 return ret;
283 } 287 }
284 288
285 ret = misc_register(&softdog_miscdev); 289 ret = misc_register(&softdog_miscdev);
286 if (ret) { 290 if (ret) {
287 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 291 printk(KERN_ERR PFX
288 WATCHDOG_MINOR, ret); 292 "cannot register miscdev on minor=%d (err=%d)\n",
293 WATCHDOG_MINOR, ret);
289 unregister_reboot_notifier(&softdog_notifier); 294 unregister_reboot_notifier(&softdog_notifier);
290 return ret; 295 return ret;
291 } 296 }
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 57cefef27ce3..6adab77fbbb0 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -45,27 +45,34 @@ static unsigned long txx9wdt_alive;
45static int expect_close; 45static int expect_close;
46static struct txx9_tmr_reg __iomem *txx9wdt_reg; 46static struct txx9_tmr_reg __iomem *txx9wdt_reg;
47static struct clk *txx9_imclk; 47static struct clk *txx9_imclk;
48static DEFINE_SPINLOCK(txx9_lock);
48 49
49static void txx9wdt_ping(void) 50static void txx9wdt_ping(void)
50{ 51{
52 spin_lock(&txx9_lock);
51 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); 53 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr);
54 spin_unlock(&txx9_lock);
52} 55}
53 56
54static void txx9wdt_start(void) 57static void txx9wdt_start(void)
55{ 58{
59 spin_lock(&txx9_lock);
56 __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra); 60 __raw_writel(WD_TIMER_CLK * timeout, &txx9wdt_reg->cpra);
57 __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr); 61 __raw_writel(WD_TIMER_CCD, &txx9wdt_reg->ccdr);
58 __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */ 62 __raw_writel(0, &txx9wdt_reg->tisr); /* clear pending interrupt */
59 __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG, 63 __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG,
60 &txx9wdt_reg->tcr); 64 &txx9wdt_reg->tcr);
61 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr); 65 __raw_writel(TXx9_TMWTMR_TWIE | TXx9_TMWTMR_TWC, &txx9wdt_reg->wtmr);
66 spin_unlock(&txx9_lock);
62} 67}
63 68
64static void txx9wdt_stop(void) 69static void txx9wdt_stop(void)
65{ 70{
71 spin_lock(&txx9_lock);
66 __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr); 72 __raw_writel(TXx9_TMWTMR_WDIS, &txx9wdt_reg->wtmr);
67 __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE, 73 __raw_writel(__raw_readl(&txx9wdt_reg->tcr) & ~TXx9_TMTCR_TCE,
68 &txx9wdt_reg->tcr); 74 &txx9wdt_reg->tcr);
75 spin_unlock(&txx9_lock);
69} 76}
70 77
71static int txx9wdt_open(struct inode *inode, struct file *file) 78static int txx9wdt_open(struct inode *inode, struct file *file)
@@ -120,13 +127,13 @@ static ssize_t txx9wdt_write(struct file *file, const char __user *data,
120 return len; 127 return len;
121} 128}
122 129
123static int txx9wdt_ioctl(struct inode *inode, struct file *file, 130static long txx9wdt_ioctl(struct file *file, unsigned int cmd,
124 unsigned int cmd, unsigned long arg) 131 unsigned long arg)
125{ 132{
126 void __user *argp = (void __user *)arg; 133 void __user *argp = (void __user *)arg;
127 int __user *p = argp; 134 int __user *p = argp;
128 int new_timeout; 135 int new_timeout;
129 static struct watchdog_info ident = { 136 static const struct watchdog_info ident = {
130 .options = WDIOF_SETTIMEOUT | 137 .options = WDIOF_SETTIMEOUT |
131 WDIOF_KEEPALIVEPING | 138 WDIOF_KEEPALIVEPING |
132 WDIOF_MAGICCLOSE, 139 WDIOF_MAGICCLOSE,
@@ -135,8 +142,6 @@ static int txx9wdt_ioctl(struct inode *inode, struct file *file,
135 }; 142 };
136 143
137 switch (cmd) { 144 switch (cmd) {
138 default:
139 return -ENOTTY;
140 case WDIOC_GETSUPPORT: 145 case WDIOC_GETSUPPORT:
141 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 146 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
142 case WDIOC_GETSTATUS: 147 case WDIOC_GETSTATUS:
@@ -156,6 +161,8 @@ static int txx9wdt_ioctl(struct inode *inode, struct file *file,
156 /* Fall */ 161 /* Fall */
157 case WDIOC_GETTIMEOUT: 162 case WDIOC_GETTIMEOUT:
158 return put_user(timeout, p); 163 return put_user(timeout, p);
164 default:
165 return -ENOTTY;
159 } 166 }
160} 167}
161 168
@@ -168,22 +175,22 @@ static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code,
168} 175}
169 176
170static const struct file_operations txx9wdt_fops = { 177static const struct file_operations txx9wdt_fops = {
171 .owner = THIS_MODULE, 178 .owner = THIS_MODULE,
172 .llseek = no_llseek, 179 .llseek = no_llseek,
173 .write = txx9wdt_write, 180 .write = txx9wdt_write,
174 .ioctl = txx9wdt_ioctl, 181 .unlocked_ioctl = txx9wdt_ioctl,
175 .open = txx9wdt_open, 182 .open = txx9wdt_open,
176 .release = txx9wdt_release, 183 .release = txx9wdt_release,
177}; 184};
178 185
179static struct miscdevice txx9wdt_miscdev = { 186static struct miscdevice txx9wdt_miscdev = {
180 .minor = WATCHDOG_MINOR, 187 .minor = WATCHDOG_MINOR,
181 .name = "watchdog", 188 .name = "watchdog",
182 .fops = &txx9wdt_fops, 189 .fops = &txx9wdt_fops,
183}; 190};
184 191
185static struct notifier_block txx9wdt_notifier = { 192static struct notifier_block txx9wdt_notifier = {
186 .notifier_call = txx9wdt_notify_sys 193 .notifier_call = txx9wdt_notify_sys,
187}; 194};
188 195
189static int __init txx9wdt_probe(struct platform_device *dev) 196static int __init txx9wdt_probe(struct platform_device *dev)
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index 386492821fc2..69396adaa5c3 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -37,9 +37,9 @@
37#include <linux/reboot.h> 37#include <linux/reboot.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40#include <linux/io.h>
41#include <linux/uaccess.h>
40 42
41#include <asm/io.h>
42#include <asm/uaccess.h>
43#include <asm/system.h> 43#include <asm/system.h>
44 44
45#define WATCHDOG_NAME "w83627hf/thf/hg WDT" 45#define WATCHDOG_NAME "w83627hf/thf/hg WDT"
@@ -57,22 +57,26 @@ MODULE_PARM_DESC(wdt_io, "w83627hf/thf WDT io port (default 0x2E)");
57 57
58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
59module_param(timeout, int, 0); 59module_param(timeout, int, 0);
60MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) "."); 60MODULE_PARM_DESC(timeout,
61 "Watchdog timeout in seconds. 1 <= timeout <= 255, default="
62 __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
61 63
62static int nowayout = WATCHDOG_NOWAYOUT; 64static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 65module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 66MODULE_PARM_DESC(nowayout,
67 "Watchdog cannot be stopped once started (default="
68 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
65 69
66/* 70/*
67 * Kernel methods. 71 * Kernel methods.
68 */ 72 */
69 73
70#define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */ 74#define WDT_EFER (wdt_io+0) /* Extended Function Enable Registers */
71#define WDT_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ 75#define WDT_EFIR (wdt_io+0) /* Extended Function Index Register
76 (same as EFER) */
72#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ 77#define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */
73 78
74static void 79static void w83627hf_select_wd_register(void)
75w83627hf_select_wd_register(void)
76{ 80{
77 unsigned char c; 81 unsigned char c;
78 outb_p(0x87, WDT_EFER); /* Enter extended function mode */ 82 outb_p(0x87, WDT_EFER); /* Enter extended function mode */
@@ -93,43 +97,45 @@ w83627hf_select_wd_register(void)
93 outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ 97 outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */
94} 98}
95 99
96static void 100static void w83627hf_unselect_wd_register(void)
97w83627hf_unselect_wd_register(void)
98{ 101{
99 outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ 102 outb_p(0xAA, WDT_EFER); /* Leave extended function mode */
100} 103}
101 104
102/* tyan motherboards seem to set F5 to 0x4C ? 105/* tyan motherboards seem to set F5 to 0x4C ?
103 * So explicitly init to appropriate value. */ 106 * So explicitly init to appropriate value. */
104static void 107
105w83627hf_init(void) 108static void w83627hf_init(void)
106{ 109{
107 unsigned char t; 110 unsigned char t;
108 111
109 w83627hf_select_wd_register(); 112 w83627hf_select_wd_register();
110 113
111 outb_p(0xF6, WDT_EFER); /* Select CRF6 */ 114 outb_p(0xF6, WDT_EFER); /* Select CRF6 */
112 t=inb_p(WDT_EFDR); /* read CRF6 */ 115 t = inb_p(WDT_EFDR); /* read CRF6 */
113 if (t != 0) { 116 if (t != 0) {
114 printk (KERN_INFO PFX "Watchdog already running. Resetting timeout to %d sec\n", timeout); 117 printk(KERN_INFO PFX
118 "Watchdog already running. Resetting timeout to %d sec\n",
119 timeout);
115 outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */ 120 outb_p(timeout, WDT_EFDR); /* Write back to CRF6 */
116 } 121 }
117 122
118 outb_p(0xF5, WDT_EFER); /* Select CRF5 */ 123 outb_p(0xF5, WDT_EFER); /* Select CRF5 */
119 t=inb_p(WDT_EFDR); /* read CRF5 */ 124 t = inb_p(WDT_EFDR); /* read CRF5 */
120 t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ 125 t &= ~0x0C; /* set second mode & disable keyboard
126 turning off watchdog */
121 outb_p(t, WDT_EFDR); /* Write back to CRF5 */ 127 outb_p(t, WDT_EFDR); /* Write back to CRF5 */
122 128
123 outb_p(0xF7, WDT_EFER); /* Select CRF7 */ 129 outb_p(0xF7, WDT_EFER); /* Select CRF7 */
124 t=inb_p(WDT_EFDR); /* read CRF7 */ 130 t = inb_p(WDT_EFDR); /* read CRF7 */
125 t&=~0xC0; /* disable keyboard & mouse turning off watchdog */ 131 t &= ~0xC0; /* disable keyboard & mouse turning off
132 watchdog */
126 outb_p(t, WDT_EFDR); /* Write back to CRF7 */ 133 outb_p(t, WDT_EFDR); /* Write back to CRF7 */
127 134
128 w83627hf_unselect_wd_register(); 135 w83627hf_unselect_wd_register();
129} 136}
130 137
131static void 138static void wdt_ctrl(int timeout)
132wdt_ctrl(int timeout)
133{ 139{
134 spin_lock(&io_lock); 140 spin_lock(&io_lock);
135 141
@@ -143,32 +149,28 @@ wdt_ctrl(int timeout)
143 spin_unlock(&io_lock); 149 spin_unlock(&io_lock);
144} 150}
145 151
146static int 152static int wdt_ping(void)
147wdt_ping(void)
148{ 153{
149 wdt_ctrl(timeout); 154 wdt_ctrl(timeout);
150 return 0; 155 return 0;
151} 156}
152 157
153static int 158static int wdt_disable(void)
154wdt_disable(void)
155{ 159{
156 wdt_ctrl(0); 160 wdt_ctrl(0);
157 return 0; 161 return 0;
158} 162}
159 163
160static int 164static int wdt_set_heartbeat(int t)
161wdt_set_heartbeat(int t)
162{ 165{
163 if ((t < 1) || (t > 255)) 166 if (t < 1 || t > 255)
164 return -EINVAL; 167 return -EINVAL;
165
166 timeout = t; 168 timeout = t;
167 return 0; 169 return 0;
168} 170}
169 171
170static ssize_t 172static ssize_t wdt_write(struct file *file, const char __user *buf,
171wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 173 size_t count, loff_t *ppos)
172{ 174{
173 if (count) { 175 if (count) {
174 if (!nowayout) { 176 if (!nowayout) {
@@ -178,7 +180,7 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
178 180
179 for (i = 0; i != count; i++) { 181 for (i = 0; i != count; i++) {
180 char c; 182 char c;
181 if (get_user(c, buf+i)) 183 if (get_user(c, buf + i))
182 return -EFAULT; 184 return -EFAULT;
183 if (c == 'V') 185 if (c == 'V')
184 expect_close = 42; 186 expect_close = 42;
@@ -189,72 +191,61 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
189 return count; 191 return count;
190} 192}
191 193
192static int 194static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
193wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
194 unsigned long arg)
195{ 195{
196 void __user *argp = (void __user *)arg; 196 void __user *argp = (void __user *)arg;
197 int __user *p = argp; 197 int __user *p = argp;
198 int new_timeout; 198 int new_timeout;
199 static struct watchdog_info ident = { 199 static struct watchdog_info ident = {
200 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 200 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
201 WDIOF_MAGICCLOSE,
201 .firmware_version = 1, 202 .firmware_version = 1,
202 .identity = "W83627HF WDT", 203 .identity = "W83627HF WDT",
203 }; 204 };
204 205
205 switch (cmd) { 206 switch (cmd) {
206 case WDIOC_GETSUPPORT: 207 case WDIOC_GETSUPPORT:
207 if (copy_to_user(argp, &ident, sizeof(ident))) 208 if (copy_to_user(argp, &ident, sizeof(ident)))
208 return -EFAULT; 209 return -EFAULT;
209 break; 210 break;
210
211 case WDIOC_GETSTATUS: 211 case WDIOC_GETSTATUS:
212 case WDIOC_GETBOOTSTATUS: 212 case WDIOC_GETBOOTSTATUS:
213 return put_user(0, p); 213 return put_user(0, p);
214
215 case WDIOC_KEEPALIVE:
216 wdt_ping();
217 break;
218
219 case WDIOC_SETTIMEOUT:
220 if (get_user(new_timeout, p))
221 return -EFAULT;
222 if (wdt_set_heartbeat(new_timeout))
223 return -EINVAL;
224 wdt_ping();
225 /* Fall */
226
227 case WDIOC_GETTIMEOUT:
228 return put_user(timeout, p);
229
230 case WDIOC_SETOPTIONS: 214 case WDIOC_SETOPTIONS:
231 { 215 {
232 int options, retval = -EINVAL; 216 int options, retval = -EINVAL;
233
234 if (get_user(options, p))
235 return -EFAULT;
236
237 if (options & WDIOS_DISABLECARD) {
238 wdt_disable();
239 retval = 0;
240 }
241
242 if (options & WDIOS_ENABLECARD) {
243 wdt_ping();
244 retval = 0;
245 }
246 217
247 return retval; 218 if (get_user(options, p))
219 return -EFAULT;
220 if (options & WDIOS_DISABLECARD) {
221 wdt_disable();
222 retval = 0;
223 }
224 if (options & WDIOS_ENABLECARD) {
225 wdt_ping();
226 retval = 0;
227 }
228 return retval;
248 } 229 }
249 230 case WDIOC_KEEPALIVE:
231 wdt_ping();
232 break;
233 case WDIOC_SETTIMEOUT:
234 if (get_user(new_timeout, p))
235 return -EFAULT;
236 if (wdt_set_heartbeat(new_timeout))
237 return -EINVAL;
238 wdt_ping();
239 /* Fall */
240 case WDIOC_GETTIMEOUT:
241 return put_user(timeout, p);
250 default: 242 default:
251 return -ENOTTY; 243 return -ENOTTY;
252 } 244 }
253 return 0; 245 return 0;
254} 246}
255 247
256static int 248static int wdt_open(struct inode *inode, struct file *file)
257wdt_open(struct inode *inode, struct file *file)
258{ 249{
259 if (test_and_set_bit(0, &wdt_is_open)) 250 if (test_and_set_bit(0, &wdt_is_open))
260 return -EBUSY; 251 return -EBUSY;
@@ -266,13 +257,13 @@ wdt_open(struct inode *inode, struct file *file)
266 return nonseekable_open(inode, file); 257 return nonseekable_open(inode, file);
267} 258}
268 259
269static int 260static int wdt_close(struct inode *inode, struct file *file)
270wdt_close(struct inode *inode, struct file *file)
271{ 261{
272 if (expect_close == 42) { 262 if (expect_close == 42)
273 wdt_disable(); 263 wdt_disable();
274 } else { 264 else {
275 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 265 printk(KERN_CRIT PFX
266 "Unexpected close, not stopping watchdog!\n");
276 wdt_ping(); 267 wdt_ping();
277 } 268 }
278 expect_close = 0; 269 expect_close = 0;
@@ -284,14 +275,12 @@ wdt_close(struct inode *inode, struct file *file)
284 * Notifier for system down 275 * Notifier for system down
285 */ 276 */
286 277
287static int 278static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
288wdt_notify_sys(struct notifier_block *this, unsigned long code,
289 void *unused) 279 void *unused)
290{ 280{
291 if (code == SYS_DOWN || code == SYS_HALT) { 281 if (code == SYS_DOWN || code == SYS_HALT)
292 /* Turn the WDT off */ 282 wdt_disable(); /* Turn the WDT off */
293 wdt_disable(); 283
294 }
295 return NOTIFY_DONE; 284 return NOTIFY_DONE;
296} 285}
297 286
@@ -303,7 +292,7 @@ static const struct file_operations wdt_fops = {
303 .owner = THIS_MODULE, 292 .owner = THIS_MODULE,
304 .llseek = no_llseek, 293 .llseek = no_llseek,
305 .write = wdt_write, 294 .write = wdt_write,
306 .ioctl = wdt_ioctl, 295 .unlocked_ioctl = wdt_ioctl,
307 .open = wdt_open, 296 .open = wdt_open,
308 .release = wdt_close, 297 .release = wdt_close,
309}; 298};
@@ -323,8 +312,7 @@ static struct notifier_block wdt_notifier = {
323 .notifier_call = wdt_notify_sys, 312 .notifier_call = wdt_notify_sys,
324}; 313};
325 314
326static int __init 315static int __init wdt_init(void)
327wdt_init(void)
328{ 316{
329 int ret; 317 int ret;
330 318
@@ -332,12 +320,13 @@ wdt_init(void)
332 320
333 if (wdt_set_heartbeat(timeout)) { 321 if (wdt_set_heartbeat(timeout)) {
334 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 322 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
335 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", 323 printk(KERN_INFO PFX
336 WATCHDOG_TIMEOUT); 324 "timeout value must be 1 <= timeout <= 255, using %d\n",
325 WATCHDOG_TIMEOUT);
337 } 326 }
338 327
339 if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { 328 if (!request_region(wdt_io, 1, WATCHDOG_NAME)) {
340 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 329 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
341 wdt_io); 330 wdt_io);
342 ret = -EIO; 331 ret = -EIO;
343 goto out; 332 goto out;
@@ -347,20 +336,22 @@ wdt_init(void)
347 336
348 ret = register_reboot_notifier(&wdt_notifier); 337 ret = register_reboot_notifier(&wdt_notifier);
349 if (ret != 0) { 338 if (ret != 0) {
350 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 339 printk(KERN_ERR PFX
351 ret); 340 "cannot register reboot notifier (err=%d)\n", ret);
352 goto unreg_regions; 341 goto unreg_regions;
353 } 342 }
354 343
355 ret = misc_register(&wdt_miscdev); 344 ret = misc_register(&wdt_miscdev);
356 if (ret != 0) { 345 if (ret != 0) {
357 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 346 printk(KERN_ERR PFX
358 WATCHDOG_MINOR, ret); 347 "cannot register miscdev on minor=%d (err=%d)\n",
348 WATCHDOG_MINOR, ret);
359 goto unreg_reboot; 349 goto unreg_reboot;
360 } 350 }
361 351
362 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 352 printk(KERN_INFO PFX
363 timeout, nowayout); 353 "initialized. timeout=%d sec (nowayout=%d)\n",
354 timeout, nowayout);
364 355
365out: 356out:
366 return ret; 357 return ret;
@@ -371,12 +362,11 @@ unreg_regions:
371 goto out; 362 goto out;
372} 363}
373 364
374static void __exit 365static void __exit wdt_exit(void)
375wdt_exit(void)
376{ 366{
377 misc_deregister(&wdt_miscdev); 367 misc_deregister(&wdt_miscdev);
378 unregister_reboot_notifier(&wdt_notifier); 368 unregister_reboot_notifier(&wdt_notifier);
379 release_region(wdt_io,1); 369 release_region(wdt_io, 1);
380} 370}
381 371
382module_init(wdt_init); 372module_init(wdt_init);
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index 528b882420b6..445d30a01ed3 100644
--- a/drivers/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
@@ -36,9 +36,9 @@
36#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <linux/io.h>
40#include <linux/uaccess.h>
39 41
40#include <asm/io.h>
41#include <asm/uaccess.h>
42#include <asm/system.h> 42#include <asm/system.h>
43 43
44#define WATCHDOG_NAME "w83697hf/hg WDT" 44#define WATCHDOG_NAME "w83697hf/hg WDT"
@@ -53,37 +53,43 @@ static DEFINE_SPINLOCK(io_lock);
53/* You must set this - there is no sane way to probe for this board. */ 53/* You must set this - there is no sane way to probe for this board. */
54static int wdt_io = 0x2e; 54static int wdt_io = 0x2e;
55module_param(wdt_io, int, 0); 55module_param(wdt_io, int, 0);
56MODULE_PARM_DESC(wdt_io, "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)"); 56MODULE_PARM_DESC(wdt_io,
57 "w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)");
57 58
58static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ 59static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
59module_param(timeout, int, 0); 60module_param(timeout, int, 0);
60MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255 (default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 61MODULE_PARM_DESC(timeout,
62 "Watchdog timeout in seconds. 1<= timeout <=255 (default="
63 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
61 64
62static int nowayout = WATCHDOG_NOWAYOUT; 65static int nowayout = WATCHDOG_NOWAYOUT;
63module_param(nowayout, int, 0); 66module_param(nowayout, int, 0);
64MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 67MODULE_PARM_DESC(nowayout,
68 "Watchdog cannot be stopped once started (default="
69 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
65 70
66static int early_disable = WATCHDOG_EARLY_DISABLE; 71static int early_disable = WATCHDOG_EARLY_DISABLE;
67module_param(early_disable, int, 0); 72module_param(early_disable, int, 0);
68MODULE_PARM_DESC(early_disable, "Watchdog gets disabled at boot time (default=" __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")"); 73MODULE_PARM_DESC(early_disable,
74 "Watchdog gets disabled at boot time (default="
75 __MODULE_STRING(WATCHDOG_EARLY_DISABLE) ")");
69 76
70/* 77/*
71 * Kernel methods. 78 * Kernel methods.
72 */ 79 */
73 80
74#define W83697HF_EFER (wdt_io+0) /* Extended Function Enable Register */ 81#define W83697HF_EFER (wdt_io + 0) /* Extended Function Enable Register */
75#define W83697HF_EFIR (wdt_io+0) /* Extended Function Index Register (same as EFER) */ 82#define W83697HF_EFIR (wdt_io + 0) /* Extended Function Index Register
76#define W83697HF_EFDR (wdt_io+1) /* Extended Function Data Register */ 83 (same as EFER) */
84#define W83697HF_EFDR (wdt_io + 1) /* Extended Function Data Register */
77 85
78static inline void 86static inline void w83697hf_unlock(void)
79w83697hf_unlock(void)
80{ 87{
81 outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */ 88 outb_p(0x87, W83697HF_EFER); /* Enter extended function mode */
82 outb_p(0x87, W83697HF_EFER); /* Again according to manual */ 89 outb_p(0x87, W83697HF_EFER); /* Again according to manual */
83} 90}
84 91
85static inline void 92static inline void w83697hf_lock(void)
86w83697hf_lock(void)
87{ 93{
88 outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */ 94 outb_p(0xAA, W83697HF_EFER); /* Leave extended function mode */
89} 95}
@@ -93,41 +99,36 @@ w83697hf_lock(void)
93 * w83697hf_write_timeout() must be called with the device unlocked. 99 * w83697hf_write_timeout() must be called with the device unlocked.
94 */ 100 */
95 101
96static unsigned char 102static unsigned char w83697hf_get_reg(unsigned char reg)
97w83697hf_get_reg(unsigned char reg)
98{ 103{
99 outb_p(reg, W83697HF_EFIR); 104 outb_p(reg, W83697HF_EFIR);
100 return inb_p(W83697HF_EFDR); 105 return inb_p(W83697HF_EFDR);
101} 106}
102 107
103static void 108static void w83697hf_set_reg(unsigned char reg, unsigned char data)
104w83697hf_set_reg(unsigned char reg, unsigned char data)
105{ 109{
106 outb_p(reg, W83697HF_EFIR); 110 outb_p(reg, W83697HF_EFIR);
107 outb_p(data, W83697HF_EFDR); 111 outb_p(data, W83697HF_EFDR);
108} 112}
109 113
110static void 114static void w83697hf_write_timeout(int timeout)
111w83697hf_write_timeout(int timeout)
112{ 115{
113 w83697hf_set_reg(0xF4, timeout); /* Write Timeout counter to CRF4 */ 116 /* Write Timeout counter to CRF4 */
117 w83697hf_set_reg(0xF4, timeout);
114} 118}
115 119
116static void 120static void w83697hf_select_wdt(void)
117w83697hf_select_wdt(void)
118{ 121{
119 w83697hf_unlock(); 122 w83697hf_unlock();
120 w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */ 123 w83697hf_set_reg(0x07, 0x08); /* Switch to logic device 8 (GPIO2) */
121} 124}
122 125
123static inline void 126static inline void w83697hf_deselect_wdt(void)
124w83697hf_deselect_wdt(void)
125{ 127{
126 w83697hf_lock(); 128 w83697hf_lock();
127} 129}
128 130
129static void 131static void w83697hf_init(void)
130w83697hf_init(void)
131{ 132{
132 unsigned char bbuf; 133 unsigned char bbuf;
133 134
@@ -136,7 +137,9 @@ w83697hf_init(void)
136 bbuf = w83697hf_get_reg(0x29); 137 bbuf = w83697hf_get_reg(0x29);
137 bbuf &= ~0x60; 138 bbuf &= ~0x60;
138 bbuf |= 0x20; 139 bbuf |= 0x20;
139 w83697hf_set_reg(0x29, bbuf); /* Set pin 119 to WDTO# mode (= CR29, WDT0) */ 140
141 /* Set pin 119 to WDTO# mode (= CR29, WDT0) */
142 w83697hf_set_reg(0x29, bbuf);
140 143
141 bbuf = w83697hf_get_reg(0xF3); 144 bbuf = w83697hf_get_reg(0xF3);
142 bbuf &= ~0x04; 145 bbuf &= ~0x04;
@@ -145,8 +148,7 @@ w83697hf_init(void)
145 w83697hf_deselect_wdt(); 148 w83697hf_deselect_wdt();
146} 149}
147 150
148static void 151static void wdt_ping(void)
149wdt_ping(void)
150{ 152{
151 spin_lock(&io_lock); 153 spin_lock(&io_lock);
152 w83697hf_select_wdt(); 154 w83697hf_select_wdt();
@@ -157,8 +159,7 @@ wdt_ping(void)
157 spin_unlock(&io_lock); 159 spin_unlock(&io_lock);
158} 160}
159 161
160static void 162static void wdt_enable(void)
161wdt_enable(void)
162{ 163{
163 spin_lock(&io_lock); 164 spin_lock(&io_lock);
164 w83697hf_select_wdt(); 165 w83697hf_select_wdt();
@@ -170,8 +171,7 @@ wdt_enable(void)
170 spin_unlock(&io_lock); 171 spin_unlock(&io_lock);
171} 172}
172 173
173static void 174static void wdt_disable(void)
174wdt_disable(void)
175{ 175{
176 spin_lock(&io_lock); 176 spin_lock(&io_lock);
177 w83697hf_select_wdt(); 177 w83697hf_select_wdt();
@@ -183,8 +183,7 @@ wdt_disable(void)
183 spin_unlock(&io_lock); 183 spin_unlock(&io_lock);
184} 184}
185 185
186static unsigned char 186static unsigned char wdt_running(void)
187wdt_running(void)
188{ 187{
189 unsigned char t; 188 unsigned char t;
190 189
@@ -199,18 +198,17 @@ wdt_running(void)
199 return t; 198 return t;
200} 199}
201 200
202static int 201static int wdt_set_heartbeat(int t)
203wdt_set_heartbeat(int t)
204{ 202{
205 if ((t < 1) || (t > 255)) 203 if (t < 1 || t > 255)
206 return -EINVAL; 204 return -EINVAL;
207 205
208 timeout = t; 206 timeout = t;
209 return 0; 207 return 0;
210} 208}
211 209
212static ssize_t 210static ssize_t wdt_write(struct file *file, const char __user *buf,
213wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 211 size_t count, loff_t *ppos)
214{ 212{
215 if (count) { 213 if (count) {
216 if (!nowayout) { 214 if (!nowayout) {
@@ -220,7 +218,7 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
220 218
221 for (i = 0; i != count; i++) { 219 for (i = 0; i != count; i++) {
222 char c; 220 char c;
223 if (get_user(c, buf+i)) 221 if (get_user(c, buf + i))
224 return -EFAULT; 222 return -EFAULT;
225 if (c == 'V') 223 if (c == 'V')
226 expect_close = 42; 224 expect_close = 42;
@@ -231,15 +229,14 @@ wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
231 return count; 229 return count;
232} 230}
233 231
234static int 232static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
235wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
236 unsigned long arg)
237{ 233{
238 void __user *argp = (void __user *)arg; 234 void __user *argp = (void __user *)arg;
239 int __user *p = argp; 235 int __user *p = argp;
240 int new_timeout; 236 int new_timeout;
241 static struct watchdog_info ident = { 237 static const struct watchdog_info ident = {
242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 238 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
239 | WDIOF_MAGICCLOSE,
243 .firmware_version = 1, 240 .firmware_version = 1,
244 .identity = "W83697HF WDT", 241 .identity = "W83697HF WDT",
245 }; 242 };
@@ -254,21 +251,6 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
254 case WDIOC_GETBOOTSTATUS: 251 case WDIOC_GETBOOTSTATUS:
255 return put_user(0, p); 252 return put_user(0, p);
256 253
257 case WDIOC_KEEPALIVE:
258 wdt_ping();
259 break;
260
261 case WDIOC_SETTIMEOUT:
262 if (get_user(new_timeout, p))
263 return -EFAULT;
264 if (wdt_set_heartbeat(new_timeout))
265 return -EINVAL;
266 wdt_ping();
267 /* Fall */
268
269 case WDIOC_GETTIMEOUT:
270 return put_user(timeout, p);
271
272 case WDIOC_SETOPTIONS: 254 case WDIOC_SETOPTIONS:
273 { 255 {
274 int options, retval = -EINVAL; 256 int options, retval = -EINVAL;
@@ -289,14 +271,28 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
289 return retval; 271 return retval;
290 } 272 }
291 273
274 case WDIOC_KEEPALIVE:
275 wdt_ping();
276 break;
277
278 case WDIOC_SETTIMEOUT:
279 if (get_user(new_timeout, p))
280 return -EFAULT;
281 if (wdt_set_heartbeat(new_timeout))
282 return -EINVAL;
283 wdt_ping();
284 /* Fall */
285
286 case WDIOC_GETTIMEOUT:
287 return put_user(timeout, p);
288
292 default: 289 default:
293 return -ENOTTY; 290 return -ENOTTY;
294 } 291 }
295 return 0; 292 return 0;
296} 293}
297 294
298static int 295static int wdt_open(struct inode *inode, struct file *file)
299wdt_open(struct inode *inode, struct file *file)
300{ 296{
301 if (test_and_set_bit(0, &wdt_is_open)) 297 if (test_and_set_bit(0, &wdt_is_open))
302 return -EBUSY; 298 return -EBUSY;
@@ -308,13 +304,13 @@ wdt_open(struct inode *inode, struct file *file)
308 return nonseekable_open(inode, file); 304 return nonseekable_open(inode, file);
309} 305}
310 306
311static int 307static int wdt_close(struct inode *inode, struct file *file)
312wdt_close(struct inode *inode, struct file *file)
313{ 308{
314 if (expect_close == 42) { 309 if (expect_close == 42)
315 wdt_disable(); 310 wdt_disable();
316 } else { 311 else {
317 printk (KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 312 printk(KERN_CRIT PFX
313 "Unexpected close, not stopping watchdog!\n");
318 wdt_ping(); 314 wdt_ping();
319 } 315 }
320 expect_close = 0; 316 expect_close = 0;
@@ -326,14 +322,12 @@ wdt_close(struct inode *inode, struct file *file)
326 * Notifier for system down 322 * Notifier for system down
327 */ 323 */
328 324
329static int 325static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
330wdt_notify_sys(struct notifier_block *this, unsigned long code,
331 void *unused) 326 void *unused)
332{ 327{
333 if (code == SYS_DOWN || code == SYS_HALT) { 328 if (code == SYS_DOWN || code == SYS_HALT)
334 /* Turn the WDT off */ 329 wdt_disable(); /* Turn the WDT off */
335 wdt_disable(); 330
336 }
337 return NOTIFY_DONE; 331 return NOTIFY_DONE;
338} 332}
339 333
@@ -345,7 +339,7 @@ static const struct file_operations wdt_fops = {
345 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
346 .llseek = no_llseek, 340 .llseek = no_llseek,
347 .write = wdt_write, 341 .write = wdt_write,
348 .ioctl = wdt_ioctl, 342 .unlocked_ioctl = wdt_ioctl,
349 .open = wdt_open, 343 .open = wdt_open,
350 .release = wdt_close, 344 .release = wdt_close,
351}; 345};
@@ -365,36 +359,38 @@ static struct notifier_block wdt_notifier = {
365 .notifier_call = wdt_notify_sys, 359 .notifier_call = wdt_notify_sys,
366}; 360};
367 361
368static int 362static int w83697hf_check_wdt(void)
369w83697hf_check_wdt(void)
370{ 363{
371 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) { 364 if (!request_region(wdt_io, 2, WATCHDOG_NAME)) {
372 printk (KERN_ERR PFX "I/O address 0x%x already in use\n", wdt_io); 365 printk(KERN_ERR PFX
366 "I/O address 0x%x already in use\n", wdt_io);
373 return -EIO; 367 return -EIO;
374 } 368 }
375 369
376 printk (KERN_DEBUG PFX "Looking for watchdog at address 0x%x\n", wdt_io); 370 printk(KERN_DEBUG PFX
371 "Looking for watchdog at address 0x%x\n", wdt_io);
377 w83697hf_unlock(); 372 w83697hf_unlock();
378 if (w83697hf_get_reg(0x20) == 0x60) { 373 if (w83697hf_get_reg(0x20) == 0x60) {
379 printk (KERN_INFO PFX "watchdog found at address 0x%x\n", wdt_io); 374 printk(KERN_INFO PFX
375 "watchdog found at address 0x%x\n", wdt_io);
380 w83697hf_lock(); 376 w83697hf_lock();
381 return 0; 377 return 0;
382 } 378 }
383 w83697hf_lock(); /* Reprotect in case it was a compatible device */ 379 /* Reprotect in case it was a compatible device */
380 w83697hf_lock();
384 381
385 printk (KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io); 382 printk(KERN_INFO PFX "watchdog not found at address 0x%x\n", wdt_io);
386 release_region(wdt_io, 2); 383 release_region(wdt_io, 2);
387 return -EIO; 384 return -EIO;
388} 385}
389 386
390static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 }; 387static int w83697hf_ioports[] = { 0x2e, 0x4e, 0x00 };
391 388
392static int __init 389static int __init wdt_init(void)
393wdt_init(void)
394{ 390{
395 int ret, i, found = 0; 391 int ret, i, found = 0;
396 392
397 printk (KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n"); 393 printk(KERN_INFO PFX "WDT driver for W83697HF/HG initializing\n");
398 394
399 if (wdt_io == 0) { 395 if (wdt_io == 0) {
400 /* we will autodetect the W83697HF/HG watchdog */ 396 /* we will autodetect the W83697HF/HG watchdog */
@@ -409,7 +405,7 @@ wdt_init(void)
409 } 405 }
410 406
411 if (!found) { 407 if (!found) {
412 printk (KERN_ERR PFX "No W83697HF/HG could be found\n"); 408 printk(KERN_ERR PFX "No W83697HF/HG could be found\n");
413 ret = -EIO; 409 ret = -EIO;
414 goto out; 410 goto out;
415 } 411 }
@@ -417,31 +413,33 @@ wdt_init(void)
417 w83697hf_init(); 413 w83697hf_init();
418 if (early_disable) { 414 if (early_disable) {
419 if (wdt_running()) 415 if (wdt_running())
420 printk (KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n"); 416 printk(KERN_WARNING PFX "Stopping previously enabled watchdog until userland kicks in\n");
421 wdt_disable(); 417 wdt_disable();
422 } 418 }
423 419
424 if (wdt_set_heartbeat(timeout)) { 420 if (wdt_set_heartbeat(timeout)) {
425 wdt_set_heartbeat(WATCHDOG_TIMEOUT); 421 wdt_set_heartbeat(WATCHDOG_TIMEOUT);
426 printk (KERN_INFO PFX "timeout value must be 1<=timeout<=255, using %d\n", 422 printk(KERN_INFO PFX
427 WATCHDOG_TIMEOUT); 423 "timeout value must be 1 <= timeout <= 255, using %d\n",
424 WATCHDOG_TIMEOUT);
428 } 425 }
429 426
430 ret = register_reboot_notifier(&wdt_notifier); 427 ret = register_reboot_notifier(&wdt_notifier);
431 if (ret != 0) { 428 if (ret != 0) {
432 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 429 printk(KERN_ERR PFX
433 ret); 430 "cannot register reboot notifier (err=%d)\n", ret);
434 goto unreg_regions; 431 goto unreg_regions;
435 } 432 }
436 433
437 ret = misc_register(&wdt_miscdev); 434 ret = misc_register(&wdt_miscdev);
438 if (ret != 0) { 435 if (ret != 0) {
439 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 436 printk(KERN_ERR PFX
440 WATCHDOG_MINOR, ret); 437 "cannot register miscdev on minor=%d (err=%d)\n",
438 WATCHDOG_MINOR, ret);
441 goto unreg_reboot; 439 goto unreg_reboot;
442 } 440 }
443 441
444 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 442 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
445 timeout, nowayout); 443 timeout, nowayout);
446 444
447out: 445out:
@@ -453,8 +451,7 @@ unreg_regions:
453 goto out; 451 goto out;
454} 452}
455 453
456static void __exit 454static void __exit wdt_exit(void)
457wdt_exit(void)
458{ 455{
459 misc_deregister(&wdt_miscdev); 456 misc_deregister(&wdt_miscdev);
460 unregister_reboot_notifier(&wdt_notifier); 457 unregister_reboot_notifier(&wdt_notifier);
diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c
index f510a3a595e6..24587d2060c4 100644
--- a/drivers/watchdog/w83877f_wdt.c
+++ b/drivers/watchdog/w83877f_wdt.c
@@ -23,13 +23,16 @@
23 * Added KERN_* tags to printks 23 * Added KERN_* tags to printks
24 * add CONFIG_WATCHDOG_NOWAYOUT support 24 * add CONFIG_WATCHDOG_NOWAYOUT support
25 * fix possible wdt_is_open race 25 * fix possible wdt_is_open race
26 * changed watchdog_info to correctly reflect what the driver offers 26 * changed watchdog_info to correctly reflect what
27 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS, WDIOC_SETTIMEOUT, 27 * the driver offers
28 * added WDIOC_GETSTATUS, WDIOC_GETBOOTSTATUS,
29 * WDIOC_SETTIMEOUT,
28 * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls 30 * WDIOC_GETTIMEOUT, and WDIOC_SETOPTIONS ioctls
29 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces 31 * 09/8 - 2003 [wim@iguana.be] cleanup of trailing spaces
30 * added extra printk's for startup problems 32 * added extra printk's for startup problems
31 * use module_param 33 * use module_param
32 * made timeout (the emulated heartbeat) a module_param 34 * made timeout (the emulated heartbeat) a
35 * module_param
33 * made the keepalive ping an internal subroutine 36 * made the keepalive ping an internal subroutine
34 * 37 *
35 * This WDT driver is different from most other Linux WDT 38 * This WDT driver is different from most other Linux WDT
@@ -51,8 +54,8 @@
51#include <linux/notifier.h> 54#include <linux/notifier.h>
52#include <linux/reboot.h> 55#include <linux/reboot.h>
53#include <linux/init.h> 56#include <linux/init.h>
54#include <asm/io.h> 57#include <linux/io.h>
55#include <asm/uaccess.h> 58#include <linux/uaccess.h>
56#include <asm/system.h> 59#include <asm/system.h>
57 60
58#define OUR_NAME "w83877f_wdt" 61#define OUR_NAME "w83877f_wdt"
@@ -80,14 +83,19 @@
80 */ 83 */
81 84
82#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */ 85#define WATCHDOG_TIMEOUT 30 /* 30 sec default timeout */
83static int timeout = WATCHDOG_TIMEOUT; /* in seconds, will be multiplied by HZ to get seconds to wait for a ping */ 86/* in seconds, will be multiplied by HZ to get seconds to wait for a ping */
87static int timeout = WATCHDOG_TIMEOUT;
84module_param(timeout, int, 0); 88module_param(timeout, int, 0);
85MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); 89MODULE_PARM_DESC(timeout,
90 "Watchdog timeout in seconds. (1<=timeout<=3600, default="
91 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
86 92
87 93
88static int nowayout = WATCHDOG_NOWAYOUT; 94static int nowayout = WATCHDOG_NOWAYOUT;
89module_param(nowayout, int, 0); 95module_param(nowayout, int, 0);
90MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 96MODULE_PARM_DESC(nowayout,
97 "Watchdog cannot be stopped once started (default="
98 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
91 99
92static void wdt_timer_ping(unsigned long); 100static void wdt_timer_ping(unsigned long);
93static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0); 101static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
@@ -105,8 +113,7 @@ static void wdt_timer_ping(unsigned long data)
105 /* If we got a heartbeat pulse within the WDT_US_INTERVAL 113 /* If we got a heartbeat pulse within the WDT_US_INTERVAL
106 * we agree to ping the WDT 114 * we agree to ping the WDT
107 */ 115 */
108 if(time_before(jiffies, next_heartbeat)) 116 if (time_before(jiffies, next_heartbeat)) {
109 {
110 /* Ping the WDT */ 117 /* Ping the WDT */
111 spin_lock(&wdt_spinlock); 118 spin_lock(&wdt_spinlock);
112 119
@@ -118,9 +125,9 @@ static void wdt_timer_ping(unsigned long data)
118 125
119 spin_unlock(&wdt_spinlock); 126 spin_unlock(&wdt_spinlock);
120 127
121 } else { 128 } else
122 printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); 129 printk(KERN_WARNING PFX
123 } 130 "Heartbeat lost! Will not ping the watchdog\n");
124} 131}
125 132
126/* 133/*
@@ -181,22 +188,21 @@ static void wdt_keepalive(void)
181 * /dev/watchdog handling 188 * /dev/watchdog handling
182 */ 189 */
183 190
184static ssize_t fop_write(struct file * file, const char __user * buf, size_t count, loff_t * ppos) 191static ssize_t fop_write(struct file *file, const char __user *buf,
192 size_t count, loff_t *ppos)
185{ 193{
186 /* See if we got the magic character 'V' and reload the timer */ 194 /* See if we got the magic character 'V' and reload the timer */
187 if(count) 195 if (count) {
188 { 196 if (!nowayout) {
189 if (!nowayout)
190 {
191 size_t ofs; 197 size_t ofs;
192 198
193 /* note: just in case someone wrote the magic character 199 /* note: just in case someone wrote the magic
194 * five months ago... */ 200 character five months ago... */
195 wdt_expect_close = 0; 201 wdt_expect_close = 0;
196 202
197 /* scan to see whether or not we got the magic character */ 203 /* scan to see whether or not we got the
198 for(ofs = 0; ofs != count; ofs++) 204 magic character */
199 { 205 for (ofs = 0; ofs != count; ofs++) {
200 char c; 206 char c;
201 if (get_user(c, buf + ofs)) 207 if (get_user(c, buf + ofs))
202 return -EFAULT; 208 return -EFAULT;
@@ -211,10 +217,10 @@ static ssize_t fop_write(struct file * file, const char __user * buf, size_t cou
211 return count; 217 return count;
212} 218}
213 219
214static int fop_open(struct inode * inode, struct file * file) 220static int fop_open(struct inode *inode, struct file *file)
215{ 221{
216 /* Just in case we're already talking to someone... */ 222 /* Just in case we're already talking to someone... */
217 if(test_and_set_bit(0, &wdt_is_open)) 223 if (test_and_set_bit(0, &wdt_is_open))
218 return -EBUSY; 224 return -EBUSY;
219 225
220 /* Good, fire up the show */ 226 /* Good, fire up the show */
@@ -222,78 +228,78 @@ static int fop_open(struct inode * inode, struct file * file)
222 return nonseekable_open(inode, file); 228 return nonseekable_open(inode, file);
223} 229}
224 230
225static int fop_close(struct inode * inode, struct file * file) 231static int fop_close(struct inode *inode, struct file *file)
226{ 232{
227 if(wdt_expect_close == 42) 233 if (wdt_expect_close == 42)
228 wdt_turnoff(); 234 wdt_turnoff();
229 else { 235 else {
230 del_timer(&timer); 236 del_timer(&timer);
231 printk(KERN_CRIT PFX "device file closed unexpectedly. Will not stop the WDT!\n"); 237 printk(KERN_CRIT PFX
238 "device file closed unexpectedly. Will not stop the WDT!\n");
232 } 239 }
233 clear_bit(0, &wdt_is_open); 240 clear_bit(0, &wdt_is_open);
234 wdt_expect_close = 0; 241 wdt_expect_close = 0;
235 return 0; 242 return 0;
236} 243}
237 244
238static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 245static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
239 unsigned long arg)
240{ 246{
241 void __user *argp = (void __user *)arg; 247 void __user *argp = (void __user *)arg;
242 int __user *p = argp; 248 int __user *p = argp;
243 static struct watchdog_info ident= 249 static const struct watchdog_info ident = {
244 { 250 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
245 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 251 | WDIOF_MAGICCLOSE,
246 .firmware_version = 1, 252 .firmware_version = 1,
247 .identity = "W83877F", 253 .identity = "W83877F",
248 }; 254 };
249 255
250 switch(cmd) 256 switch (cmd) {
257 case WDIOC_GETSUPPORT:
258 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
259 case WDIOC_GETSTATUS:
260 case WDIOC_GETBOOTSTATUS:
261 return put_user(0, p);
262 case WDIOC_SETOPTIONS:
251 { 263 {
252 default: 264 int new_options, retval = -EINVAL;
253 return -ENOTTY;
254 case WDIOC_GETSUPPORT:
255 return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0;
256 case WDIOC_GETSTATUS:
257 case WDIOC_GETBOOTSTATUS:
258 return put_user(0, p);
259 case WDIOC_KEEPALIVE:
260 wdt_keepalive();
261 return 0;
262 case WDIOC_SETOPTIONS:
263 {
264 int new_options, retval = -EINVAL;
265
266 if(get_user(new_options, p))
267 return -EFAULT;
268
269 if(new_options & WDIOS_DISABLECARD) {
270 wdt_turnoff();
271 retval = 0;
272 }
273 265
274 if(new_options & WDIOS_ENABLECARD) { 266 if (get_user(new_options, p))
275 wdt_startup(); 267 return -EFAULT;
276 retval = 0;
277 }
278 268
279 return retval; 269 if (new_options & WDIOS_DISABLECARD) {
270 wdt_turnoff();
271 retval = 0;
280 } 272 }
281 case WDIOC_SETTIMEOUT:
282 {
283 int new_timeout;
284 273
285 if(get_user(new_timeout, p)) 274 if (new_options & WDIOS_ENABLECARD) {
286 return -EFAULT; 275 wdt_startup();
276 retval = 0;
277 }
287 278
288 if(new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */ 279 return retval;
289 return -EINVAL; 280 }
281 case WDIOC_KEEPALIVE:
282 wdt_keepalive();
283 return 0;
284 case WDIOC_SETTIMEOUT:
285 {
286 int new_timeout;
290 287
291 timeout = new_timeout; 288 if (get_user(new_timeout, p))
292 wdt_keepalive(); 289 return -EFAULT;
293 /* Fall through */ 290
294 } 291 /* arbitrary upper limit */
295 case WDIOC_GETTIMEOUT: 292 if (new_timeout < 1 || new_timeout > 3600)
296 return put_user(timeout, p); 293 return -EINVAL;
294
295 timeout = new_timeout;
296 wdt_keepalive();
297 /* Fall through */
298 }
299 case WDIOC_GETTIMEOUT:
300 return put_user(timeout, p);
301 default:
302 return -ENOTTY;
297 } 303 }
298} 304}
299 305
@@ -303,7 +309,7 @@ static const struct file_operations wdt_fops = {
303 .write = fop_write, 309 .write = fop_write,
304 .open = fop_open, 310 .open = fop_open,
305 .release = fop_close, 311 .release = fop_close,
306 .ioctl = fop_ioctl, 312 .unlocked_ioctl = fop_ioctl,
307}; 313};
308 314
309static struct miscdevice wdt_miscdev = { 315static struct miscdevice wdt_miscdev = {
@@ -319,7 +325,7 @@ static struct miscdevice wdt_miscdev = {
319static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 325static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
320 void *unused) 326 void *unused)
321{ 327{
322 if(code==SYS_DOWN || code==SYS_HALT) 328 if (code == SYS_DOWN || code == SYS_HALT)
323 wdt_turnoff(); 329 wdt_turnoff();
324 return NOTIFY_DONE; 330 return NOTIFY_DONE;
325} 331}
@@ -329,8 +335,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
329 * turn the timebomb registers off. 335 * turn the timebomb registers off.
330 */ 336 */
331 337
332static struct notifier_block wdt_notifier= 338static struct notifier_block wdt_notifier = {
333{
334 .notifier_call = wdt_notify_sys, 339 .notifier_call = wdt_notify_sys,
335}; 340};
336 341
@@ -342,31 +347,29 @@ static void __exit w83877f_wdt_unload(void)
342 misc_deregister(&wdt_miscdev); 347 misc_deregister(&wdt_miscdev);
343 348
344 unregister_reboot_notifier(&wdt_notifier); 349 unregister_reboot_notifier(&wdt_notifier);
345 release_region(WDT_PING,1); 350 release_region(WDT_PING, 1);
346 release_region(ENABLE_W83877F_PORT,2); 351 release_region(ENABLE_W83877F_PORT, 2);
347} 352}
348 353
349static int __init w83877f_wdt_init(void) 354static int __init w83877f_wdt_init(void)
350{ 355{
351 int rc = -EBUSY; 356 int rc = -EBUSY;
352 357
353 if(timeout < 1 || timeout > 3600) /* arbitrary upper limit */ 358 if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */
354 {
355 timeout = WATCHDOG_TIMEOUT; 359 timeout = WATCHDOG_TIMEOUT;
356 printk(KERN_INFO PFX "timeout value must be 1<=x<=3600, using %d\n", 360 printk(KERN_INFO PFX
357 timeout); 361 "timeout value must be 1 <= x <= 3600, using %d\n",
362 timeout);
358 } 363 }
359 364
360 if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) 365 if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT")) {
361 {
362 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 366 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
363 ENABLE_W83877F_PORT); 367 ENABLE_W83877F_PORT);
364 rc = -EIO; 368 rc = -EIO;
365 goto err_out; 369 goto err_out;
366 } 370 }
367 371
368 if (!request_region(WDT_PING, 1, "W8387FF WDT")) 372 if (!request_region(WDT_PING, 1, "W8387FF WDT")) {
369 {
370 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 373 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
371 WDT_PING); 374 WDT_PING);
372 rc = -EIO; 375 rc = -EIO;
@@ -374,22 +377,22 @@ static int __init w83877f_wdt_init(void)
374 } 377 }
375 378
376 rc = register_reboot_notifier(&wdt_notifier); 379 rc = register_reboot_notifier(&wdt_notifier);
377 if (rc) 380 if (rc) {
378 { 381 printk(KERN_ERR PFX
379 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 382 "cannot register reboot notifier (err=%d)\n", rc);
380 rc);
381 goto err_out_region2; 383 goto err_out_region2;
382 } 384 }
383 385
384 rc = misc_register(&wdt_miscdev); 386 rc = misc_register(&wdt_miscdev);
385 if (rc) 387 if (rc) {
386 { 388 printk(KERN_ERR PFX
387 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 389 "cannot register miscdev on minor=%d (err=%d)\n",
388 wdt_miscdev.minor, rc); 390 wdt_miscdev.minor, rc);
389 goto err_out_reboot; 391 goto err_out_reboot;
390 } 392 }
391 393
392 printk(KERN_INFO PFX "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n", 394 printk(KERN_INFO PFX
395 "WDT driver for W83877F initialised. timeout=%d sec (nowayout=%d)\n",
393 timeout, nowayout); 396 timeout, nowayout);
394 397
395 return 0; 398 return 0;
@@ -397,9 +400,9 @@ static int __init w83877f_wdt_init(void)
397err_out_reboot: 400err_out_reboot:
398 unregister_reboot_notifier(&wdt_notifier); 401 unregister_reboot_notifier(&wdt_notifier);
399err_out_region2: 402err_out_region2:
400 release_region(WDT_PING,1); 403 release_region(WDT_PING, 1);
401err_out_region1: 404err_out_region1:
402 release_region(ENABLE_W83877F_PORT,2); 405 release_region(ENABLE_W83877F_PORT, 2);
403err_out: 406err_out:
404 return rc; 407 return rc;
405} 408}
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
index b209bcd7f789..2525da5080ca 100644
--- a/drivers/watchdog/w83977f_wdt.c
+++ b/drivers/watchdog/w83977f_wdt.c
@@ -26,10 +26,10 @@
26#include <linux/watchdog.h> 26#include <linux/watchdog.h>
27#include <linux/notifier.h> 27#include <linux/notifier.h>
28#include <linux/reboot.h> 28#include <linux/reboot.h>
29#include <linux/uaccess.h>
30#include <linux/io.h>
29 31
30#include <asm/io.h>
31#include <asm/system.h> 32#include <asm/system.h>
32#include <asm/uaccess.h>
33 33
34#define WATCHDOG_VERSION "1.00" 34#define WATCHDOG_VERSION "1.00"
35#define WATCHDOG_NAME "W83977F WDT" 35#define WATCHDOG_NAME "W83977F WDT"
@@ -53,13 +53,17 @@ static char expect_close;
53static DEFINE_SPINLOCK(spinlock); 53static DEFINE_SPINLOCK(spinlock);
54 54
55module_param(timeout, int, 0); 55module_param(timeout, int, 0);
56MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); 56MODULE_PARM_DESC(timeout,
57 "Watchdog timeout in seconds (15..7635), default="
58 __MODULE_STRING(DEFAULT_TIMEOUT) ")");
57module_param(testmode, int, 0); 59module_param(testmode, int, 0);
58MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); 60MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0");
59 61
60static int nowayout = WATCHDOG_NOWAYOUT; 62static int nowayout = WATCHDOG_NOWAYOUT;
61module_param(nowayout, int, 0); 63module_param(nowayout, int, 0);
62MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 64MODULE_PARM_DESC(nowayout,
65 "Watchdog cannot be stopped once started (default="
66 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
63 67
64/* 68/*
65 * Start the watchdog 69 * Start the watchdog
@@ -72,8 +76,8 @@ static int wdt_start(void)
72 spin_lock_irqsave(&spinlock, flags); 76 spin_lock_irqsave(&spinlock, flags);
73 77
74 /* Unlock the SuperIO chip */ 78 /* Unlock the SuperIO chip */
75 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 79 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
76 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 80 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
77 81
78 /* 82 /*
79 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. 83 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
@@ -81,50 +85,49 @@ static int wdt_start(void)
81 * F3 is set to enable watchdog LED blink at timeout. 85 * F3 is set to enable watchdog LED blink at timeout.
82 * F4 is used to just clear the TIMEOUT'ed state (bit 0). 86 * F4 is used to just clear the TIMEOUT'ed state (bit 0).
83 */ 87 */
84 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 88 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
85 outb_p(0x08,IO_DATA_PORT); 89 outb_p(0x08, IO_DATA_PORT);
86 outb_p(0xF2,IO_INDEX_PORT); 90 outb_p(0xF2, IO_INDEX_PORT);
87 outb_p(timeoutW,IO_DATA_PORT); 91 outb_p(timeoutW, IO_DATA_PORT);
88 outb_p(0xF3,IO_INDEX_PORT); 92 outb_p(0xF3, IO_INDEX_PORT);
89 outb_p(0x08,IO_DATA_PORT); 93 outb_p(0x08, IO_DATA_PORT);
90 outb_p(0xF4,IO_INDEX_PORT); 94 outb_p(0xF4, IO_INDEX_PORT);
91 outb_p(0x00,IO_DATA_PORT); 95 outb_p(0x00, IO_DATA_PORT);
92 96
93 /* Set device Aux2 active */ 97 /* Set device Aux2 active */
94 outb_p(0x30,IO_INDEX_PORT); 98 outb_p(0x30, IO_INDEX_PORT);
95 outb_p(0x01,IO_DATA_PORT); 99 outb_p(0x01, IO_DATA_PORT);
96 100
97 /* 101 /*
98 * Select device Aux1 (dev=7) to set GP16 as the watchdog output 102 * Select device Aux1 (dev=7) to set GP16 as the watchdog output
99 * (in reg E6) and GP13 as the watchdog LED output (in reg E3). 103 * (in reg E6) and GP13 as the watchdog LED output (in reg E3).
100 * Map GP16 at pin 119. 104 * Map GP16 at pin 119.
101 * In test mode watch the bit 0 on F4 to indicate "triggered" or 105 * In test mode watch the bit 0 on F4 to indicate "triggered" or
102 * check watchdog LED on SBC. 106 * check watchdog LED on SBC.
103 */ 107 */
104 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 108 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
105 outb_p(0x07,IO_DATA_PORT); 109 outb_p(0x07, IO_DATA_PORT);
106 if (!testmode) 110 if (!testmode) {
107 {
108 unsigned pin_map; 111 unsigned pin_map;
109 112
110 outb_p(0xE6,IO_INDEX_PORT); 113 outb_p(0xE6, IO_INDEX_PORT);
111 outb_p(0x0A,IO_DATA_PORT); 114 outb_p(0x0A, IO_DATA_PORT);
112 outb_p(0x2C,IO_INDEX_PORT); 115 outb_p(0x2C, IO_INDEX_PORT);
113 pin_map = inb_p(IO_DATA_PORT); 116 pin_map = inb_p(IO_DATA_PORT);
114 pin_map |= 0x10; 117 pin_map |= 0x10;
115 pin_map &= ~(0x20); 118 pin_map &= ~(0x20);
116 outb_p(0x2C,IO_INDEX_PORT); 119 outb_p(0x2C, IO_INDEX_PORT);
117 outb_p(pin_map,IO_DATA_PORT); 120 outb_p(pin_map, IO_DATA_PORT);
118 } 121 }
119 outb_p(0xE3,IO_INDEX_PORT); 122 outb_p(0xE3, IO_INDEX_PORT);
120 outb_p(0x08,IO_DATA_PORT); 123 outb_p(0x08, IO_DATA_PORT);
121 124
122 /* Set device Aux1 active */ 125 /* Set device Aux1 active */
123 outb_p(0x30,IO_INDEX_PORT); 126 outb_p(0x30, IO_INDEX_PORT);
124 outb_p(0x01,IO_DATA_PORT); 127 outb_p(0x01, IO_DATA_PORT);
125 128
126 /* Lock the SuperIO chip */ 129 /* Lock the SuperIO chip */
127 outb_p(LOCK_DATA,IO_INDEX_PORT); 130 outb_p(LOCK_DATA, IO_INDEX_PORT);
128 131
129 spin_unlock_irqrestore(&spinlock, flags); 132 spin_unlock_irqrestore(&spinlock, flags);
130 133
@@ -144,42 +147,41 @@ static int wdt_stop(void)
144 spin_lock_irqsave(&spinlock, flags); 147 spin_lock_irqsave(&spinlock, flags);
145 148
146 /* Unlock the SuperIO chip */ 149 /* Unlock the SuperIO chip */
147 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 150 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
148 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 151 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
149 152
150 /* 153 /*
151 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4. 154 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
152 * F2 is reset to its default value (watchdog timer disabled). 155 * F2 is reset to its default value (watchdog timer disabled).
153 * F3 is reset to its default state. 156 * F3 is reset to its default state.
154 * F4 clears the TIMEOUT'ed state (bit 0) - back to default. 157 * F4 clears the TIMEOUT'ed state (bit 0) - back to default.
155 */ 158 */
156 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 159 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
157 outb_p(0x08,IO_DATA_PORT); 160 outb_p(0x08, IO_DATA_PORT);
158 outb_p(0xF2,IO_INDEX_PORT); 161 outb_p(0xF2, IO_INDEX_PORT);
159 outb_p(0xFF,IO_DATA_PORT); 162 outb_p(0xFF, IO_DATA_PORT);
160 outb_p(0xF3,IO_INDEX_PORT); 163 outb_p(0xF3, IO_INDEX_PORT);
161 outb_p(0x00,IO_DATA_PORT); 164 outb_p(0x00, IO_DATA_PORT);
162 outb_p(0xF4,IO_INDEX_PORT); 165 outb_p(0xF4, IO_INDEX_PORT);
163 outb_p(0x00,IO_DATA_PORT); 166 outb_p(0x00, IO_DATA_PORT);
164 outb_p(0xF2,IO_INDEX_PORT); 167 outb_p(0xF2, IO_INDEX_PORT);
165 outb_p(0x00,IO_DATA_PORT); 168 outb_p(0x00, IO_DATA_PORT);
166 169
167 /* 170 /*
168 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and 171 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and
169 * Gp13 (in reg E3) as inputs. 172 * Gp13 (in reg E3) as inputs.
170 */ 173 */
171 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 174 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
172 outb_p(0x07,IO_DATA_PORT); 175 outb_p(0x07, IO_DATA_PORT);
173 if (!testmode) 176 if (!testmode) {
174 { 177 outb_p(0xE6, IO_INDEX_PORT);
175 outb_p(0xE6,IO_INDEX_PORT); 178 outb_p(0x01, IO_DATA_PORT);
176 outb_p(0x01,IO_DATA_PORT);
177 } 179 }
178 outb_p(0xE3,IO_INDEX_PORT); 180 outb_p(0xE3, IO_INDEX_PORT);
179 outb_p(0x01,IO_DATA_PORT); 181 outb_p(0x01, IO_DATA_PORT);
180 182
181 /* Lock the SuperIO chip */ 183 /* Lock the SuperIO chip */
182 outb_p(LOCK_DATA,IO_INDEX_PORT); 184 outb_p(LOCK_DATA, IO_INDEX_PORT);
183 185
184 spin_unlock_irqrestore(&spinlock, flags); 186 spin_unlock_irqrestore(&spinlock, flags);
185 187
@@ -200,17 +202,17 @@ static int wdt_keepalive(void)
200 spin_lock_irqsave(&spinlock, flags); 202 spin_lock_irqsave(&spinlock, flags);
201 203
202 /* Unlock the SuperIO chip */ 204 /* Unlock the SuperIO chip */
203 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 205 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
204 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 206 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
205 207
206 /* Select device Aux2 (device=8) to kick watchdog reg F2 */ 208 /* Select device Aux2 (device=8) to kick watchdog reg F2 */
207 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 209 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
208 outb_p(0x08,IO_DATA_PORT); 210 outb_p(0x08, IO_DATA_PORT);
209 outb_p(0xF2,IO_INDEX_PORT); 211 outb_p(0xF2, IO_INDEX_PORT);
210 outb_p(timeoutW,IO_DATA_PORT); 212 outb_p(timeoutW, IO_DATA_PORT);
211 213
212 /* Lock the SuperIO chip */ 214 /* Lock the SuperIO chip */
213 outb_p(LOCK_DATA,IO_INDEX_PORT); 215 outb_p(LOCK_DATA, IO_INDEX_PORT);
214 216
215 spin_unlock_irqrestore(&spinlock, flags); 217 spin_unlock_irqrestore(&spinlock, flags);
216 218
@@ -227,7 +229,7 @@ static int wdt_set_timeout(int t)
227 229
228 /* 230 /*
229 * Convert seconds to watchdog counter time units, rounding up. 231 * Convert seconds to watchdog counter time units, rounding up.
230 * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup 232 * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup
231 * value. This information is supplied in the PCM-5335 manual and was 233 * value. This information is supplied in the PCM-5335 manual and was
232 * checked by me on a real board. This is a bit strange because W83977f 234 * checked by me on a real board. This is a bit strange because W83977f
233 * datasheet says counter unit is in minutes! 235 * datasheet says counter unit is in minutes!
@@ -241,7 +243,7 @@ static int wdt_set_timeout(int t)
241 return -EINVAL; 243 return -EINVAL;
242 244
243 /* 245 /*
244 * timeout is the timeout in seconds, 246 * timeout is the timeout in seconds,
245 * timeoutW is the timeout in watchdog counter units. 247 * timeoutW is the timeout in watchdog counter units.
246 */ 248 */
247 timeoutW = tmrval; 249 timeoutW = tmrval;
@@ -261,17 +263,17 @@ static int wdt_get_status(int *status)
261 spin_lock_irqsave(&spinlock, flags); 263 spin_lock_irqsave(&spinlock, flags);
262 264
263 /* Unlock the SuperIO chip */ 265 /* Unlock the SuperIO chip */
264 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 266 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
265 outb_p(UNLOCK_DATA,IO_INDEX_PORT); 267 outb_p(UNLOCK_DATA, IO_INDEX_PORT);
266 268
267 /* Select device Aux2 (device=8) to read watchdog reg F4 */ 269 /* Select device Aux2 (device=8) to read watchdog reg F4 */
268 outb_p(DEVICE_REGISTER,IO_INDEX_PORT); 270 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
269 outb_p(0x08,IO_DATA_PORT); 271 outb_p(0x08, IO_DATA_PORT);
270 outb_p(0xF4,IO_INDEX_PORT); 272 outb_p(0xF4, IO_INDEX_PORT);
271 new_status = inb_p(IO_DATA_PORT); 273 new_status = inb_p(IO_DATA_PORT);
272 274
273 /* Lock the SuperIO chip */ 275 /* Lock the SuperIO chip */
274 outb_p(LOCK_DATA,IO_INDEX_PORT); 276 outb_p(LOCK_DATA, IO_INDEX_PORT);
275 277
276 spin_unlock_irqrestore(&spinlock, flags); 278 spin_unlock_irqrestore(&spinlock, flags);
277 279
@@ -290,7 +292,7 @@ static int wdt_get_status(int *status)
290static int wdt_open(struct inode *inode, struct file *file) 292static int wdt_open(struct inode *inode, struct file *file)
291{ 293{
292 /* If the watchdog is alive we don't need to start it again */ 294 /* If the watchdog is alive we don't need to start it again */
293 if( test_and_set_bit(0, &timer_alive) ) 295 if (test_and_set_bit(0, &timer_alive))
294 return -EBUSY; 296 return -EBUSY;
295 297
296 if (nowayout) 298 if (nowayout)
@@ -306,13 +308,13 @@ static int wdt_release(struct inode *inode, struct file *file)
306 * Shut off the timer. 308 * Shut off the timer.
307 * Lock it in if it's a module and we set nowayout 309 * Lock it in if it's a module and we set nowayout
308 */ 310 */
309 if (expect_close == 42) 311 if (expect_close == 42) {
310 {
311 wdt_stop(); 312 wdt_stop();
312 clear_bit(0, &timer_alive); 313 clear_bit(0, &timer_alive);
313 } else { 314 } else {
314 wdt_keepalive(); 315 wdt_keepalive();
315 printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); 316 printk(KERN_CRIT PFX
317 "unexpected close, not stopping watchdog!\n");
316 } 318 }
317 expect_close = 0; 319 expect_close = 0;
318 return 0; 320 return 0;
@@ -333,24 +335,22 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
333 size_t count, loff_t *ppos) 335 size_t count, loff_t *ppos)
334{ 336{
335 /* See if we got the magic character 'V' and reload the timer */ 337 /* See if we got the magic character 'V' and reload the timer */
336 if(count) 338 if (count) {
337 { 339 if (!nowayout) {
338 if (!nowayout)
339 {
340 size_t ofs; 340 size_t ofs;
341 341
342 /* note: just in case someone wrote the magic character long ago */ 342 /* note: just in case someone wrote the
343 magic character long ago */
343 expect_close = 0; 344 expect_close = 0;
344 345
345 /* scan to see whether or not we got the magic character */ 346 /* scan to see whether or not we got the
346 for(ofs = 0; ofs != count; ofs++) 347 magic character */
347 { 348 for (ofs = 0; ofs != count; ofs++) {
348 char c; 349 char c;
349 if (get_user(c, buf + ofs)) 350 if (get_user(c, buf + ofs))
350 return -EFAULT; 351 return -EFAULT;
351 if (c == 'V') { 352 if (c == 'V')
352 expect_close = 42; 353 expect_close = 42;
353 }
354 } 354 }
355 } 355 }
356 356
@@ -377,8 +377,7 @@ static struct watchdog_info ident = {
377 .identity = WATCHDOG_NAME, 377 .identity = WATCHDOG_NAME,
378}; 378};
379 379
380static int wdt_ioctl(struct inode *inode, struct file *file, 380static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
381 unsigned int cmd, unsigned long arg)
382{ 381{
383 int status; 382 int status;
384 int new_options, retval = -EINVAL; 383 int new_options, retval = -EINVAL;
@@ -390,13 +389,10 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
390 389
391 uarg.i = (int __user *)arg; 390 uarg.i = (int __user *)arg;
392 391
393 switch(cmd) 392 switch (cmd) {
394 {
395 default:
396 return -ENOTTY;
397
398 case WDIOC_GETSUPPORT: 393 case WDIOC_GETSUPPORT:
399 return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0; 394 return copy_to_user(uarg.ident, &ident,
395 sizeof(ident)) ? -EFAULT : 0;
400 396
401 case WDIOC_GETSTATUS: 397 case WDIOC_GETSTATUS:
402 wdt_get_status(&status); 398 wdt_get_status(&status);
@@ -405,12 +401,8 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
405 case WDIOC_GETBOOTSTATUS: 401 case WDIOC_GETBOOTSTATUS:
406 return put_user(0, uarg.i); 402 return put_user(0, uarg.i);
407 403
408 case WDIOC_KEEPALIVE:
409 wdt_keepalive();
410 return 0;
411
412 case WDIOC_SETOPTIONS: 404 case WDIOC_SETOPTIONS:
413 if (get_user (new_options, uarg.i)) 405 if (get_user(new_options, uarg.i))
414 return -EFAULT; 406 return -EFAULT;
415 407
416 if (new_options & WDIOS_DISABLECARD) { 408 if (new_options & WDIOS_DISABLECARD) {
@@ -425,6 +417,10 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
425 417
426 return retval; 418 return retval;
427 419
420 case WDIOC_KEEPALIVE:
421 wdt_keepalive();
422 return 0;
423
428 case WDIOC_SETTIMEOUT: 424 case WDIOC_SETTIMEOUT:
429 if (get_user(new_timeout, uarg.i)) 425 if (get_user(new_timeout, uarg.i))
430 return -EFAULT; 426 return -EFAULT;
@@ -438,29 +434,30 @@ static int wdt_ioctl(struct inode *inode, struct file *file,
438 case WDIOC_GETTIMEOUT: 434 case WDIOC_GETTIMEOUT:
439 return put_user(timeout, uarg.i); 435 return put_user(timeout, uarg.i);
440 436
437 default:
438 return -ENOTTY;
439
441 } 440 }
442} 441}
443 442
444static int wdt_notify_sys(struct notifier_block *this, unsigned long code, 443static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
445 void *unused) 444 void *unused)
446{ 445{
447 if (code==SYS_DOWN || code==SYS_HALT) 446 if (code == SYS_DOWN || code == SYS_HALT)
448 wdt_stop(); 447 wdt_stop();
449 return NOTIFY_DONE; 448 return NOTIFY_DONE;
450} 449}
451 450
452static const struct file_operations wdt_fops= 451static const struct file_operations wdt_fops = {
453{
454 .owner = THIS_MODULE, 452 .owner = THIS_MODULE,
455 .llseek = no_llseek, 453 .llseek = no_llseek,
456 .write = wdt_write, 454 .write = wdt_write,
457 .ioctl = wdt_ioctl, 455 .unlocked_ioctl = wdt_ioctl,
458 .open = wdt_open, 456 .open = wdt_open,
459 .release = wdt_release, 457 .release = wdt_release,
460}; 458};
461 459
462static struct miscdevice wdt_miscdev= 460static struct miscdevice wdt_miscdev = {
463{
464 .minor = WATCHDOG_MINOR, 461 .minor = WATCHDOG_MINOR,
465 .name = "watchdog", 462 .name = "watchdog",
466 .fops = &wdt_fops, 463 .fops = &wdt_fops,
@@ -474,20 +471,20 @@ static int __init w83977f_wdt_init(void)
474{ 471{
475 int rc; 472 int rc;
476 473
477 printk(KERN_INFO PFX DRIVER_VERSION); 474 printk(KERN_INFO PFX DRIVER_VERSION);
478 475
479 /* 476 /*
480 * Check that the timeout value is within it's range ; 477 * Check that the timeout value is within it's range;
481 * if not reset to the default 478 * if not reset to the default
482 */ 479 */
483 if (wdt_set_timeout(timeout)) { 480 if (wdt_set_timeout(timeout)) {
484 wdt_set_timeout(DEFAULT_TIMEOUT); 481 wdt_set_timeout(DEFAULT_TIMEOUT);
485 printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n", 482 printk(KERN_INFO PFX
486 DEFAULT_TIMEOUT); 483 "timeout value must be 15 <= timeout <= 7635, using %d\n",
484 DEFAULT_TIMEOUT);
487 } 485 }
488 486
489 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) 487 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) {
490 {
491 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 488 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
492 IO_INDEX_PORT); 489 IO_INDEX_PORT);
493 rc = -EIO; 490 rc = -EIO;
@@ -495,30 +492,30 @@ static int __init w83977f_wdt_init(void)
495 } 492 }
496 493
497 rc = register_reboot_notifier(&wdt_notifier); 494 rc = register_reboot_notifier(&wdt_notifier);
498 if (rc) 495 if (rc) {
499 { 496 printk(KERN_ERR PFX
500 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 497 "cannot register reboot notifier (err=%d)\n", rc);
501 rc);
502 goto err_out_region; 498 goto err_out_region;
503 } 499 }
504 500
505 rc = misc_register(&wdt_miscdev); 501 rc = misc_register(&wdt_miscdev);
506 if (rc) 502 if (rc) {
507 { 503 printk(KERN_ERR PFX
508 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 504 "cannot register miscdev on minor=%d (err=%d)\n",
509 wdt_miscdev.minor, rc); 505 wdt_miscdev.minor, rc);
510 goto err_out_reboot; 506 goto err_out_reboot;
511 } 507 }
512 508
513 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n", 509 printk(KERN_INFO PFX
514 timeout, nowayout, testmode); 510 "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
511 timeout, nowayout, testmode);
515 512
516 return 0; 513 return 0;
517 514
518err_out_reboot: 515err_out_reboot:
519 unregister_reboot_notifier(&wdt_notifier); 516 unregister_reboot_notifier(&wdt_notifier);
520err_out_region: 517err_out_region:
521 release_region(IO_INDEX_PORT,2); 518 release_region(IO_INDEX_PORT, 2);
522err_out: 519err_out:
523 return rc; 520 return rc;
524} 521}
@@ -528,7 +525,7 @@ static void __exit w83977f_wdt_exit(void)
528 wdt_stop(); 525 wdt_stop();
529 misc_deregister(&wdt_miscdev); 526 misc_deregister(&wdt_miscdev);
530 unregister_reboot_notifier(&wdt_notifier); 527 unregister_reboot_notifier(&wdt_notifier);
531 release_region(IO_INDEX_PORT,2); 528 release_region(IO_INDEX_PORT, 2);
532} 529}
533 530
534module_init(w83977f_wdt_init); 531module_init(w83977f_wdt_init);
diff --git a/drivers/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c
index 9e368091f799..68377ae171ff 100644
--- a/drivers/watchdog/wafer5823wdt.c
+++ b/drivers/watchdog/wafer5823wdt.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * ICP Wafer 5823 Single Board Computer WDT driver 2 * ICP Wafer 5823 Single Board Computer WDT driver
3 * http://www.icpamerica.com/wafer_5823.php 3 * http://www.icpamerica.com/wafer_5823.php
4 * May also work on other similar models 4 * May also work on other similar models
5 * 5 *
6 * (c) Copyright 2002 Justin Cormack <justin@street-vision.com> 6 * (c) Copyright 2002 Justin Cormack <justin@street-vision.com>
7 * 7 *
8 * Release 0.02 8 * Release 0.02
9 * 9 *
10 * Based on advantechwdt.c which is based on wdt.c. 10 * Based on advantechwdt.c which is based on wdt.c.
11 * Original copyright messages: 11 * Original copyright messages:
@@ -36,8 +36,8 @@
36#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <asm/io.h> 39#include <linux/io.h>
40#include <asm/uaccess.h> 40#include <linux/uaccess.h>
41 41
42#define WATCHDOG_NAME "Wafer 5823 WDT" 42#define WATCHDOG_NAME "Wafer 5823 WDT"
43#define PFX WATCHDOG_NAME ": " 43#define PFX WATCHDOG_NAME ": "
@@ -50,10 +50,10 @@ static DEFINE_SPINLOCK(wafwdt_lock);
50/* 50/*
51 * You must set these - there is no sane way to probe for this board. 51 * You must set these - there is no sane way to probe for this board.
52 * 52 *
53 * To enable, write the timeout value in seconds (1 to 255) to I/O 53 * To enable, write the timeout value in seconds (1 to 255) to I/O
54 * port WDT_START, then read the port to start the watchdog. To pat 54 * port WDT_START, then read the port to start the watchdog. To pat
55 * the dog, read port WDT_STOP to stop the timer, then read WDT_START 55 * the dog, read port WDT_STOP to stop the timer, then read WDT_START
56 * to restart it again. 56 * to restart it again.
57 */ 57 */
58 58
59static int wdt_stop = 0x843; 59static int wdt_stop = 0x843;
@@ -61,11 +61,15 @@ static int wdt_start = 0x443;
61 61
62static int timeout = WD_TIMO; /* in seconds */ 62static int timeout = WD_TIMO; /* in seconds */
63module_param(timeout, int, 0); 63module_param(timeout, int, 0);
64MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WD_TIMO) "."); 64MODULE_PARM_DESC(timeout,
65 "Watchdog timeout in seconds. 1 <= timeout <= 255, default="
66 __MODULE_STRING(WD_TIMO) ".");
65 67
66static int nowayout = WATCHDOG_NOWAYOUT; 68static int nowayout = WATCHDOG_NOWAYOUT;
67module_param(nowayout, int, 0); 69module_param(nowayout, int, 0);
68MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 70MODULE_PARM_DESC(nowayout,
71 "Watchdog cannot be stopped once started (default="
72 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
69 73
70static void wafwdt_ping(void) 74static void wafwdt_ping(void)
71{ 75{
@@ -83,14 +87,14 @@ static void wafwdt_start(void)
83 inb_p(wdt_start); 87 inb_p(wdt_start);
84} 88}
85 89
86static void 90static void wafwdt_stop(void)
87wafwdt_stop(void)
88{ 91{
89 /* stop watchdog */ 92 /* stop watchdog */
90 inb_p(wdt_stop); 93 inb_p(wdt_stop);
91} 94}
92 95
93static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) 96static ssize_t wafwdt_write(struct file *file, const char __user *buf,
97 size_t count, loff_t *ppos)
94{ 98{
95 /* See if we got the magic character 'V' and reload the timer */ 99 /* See if we got the magic character 'V' and reload the timer */
96 if (count) { 100 if (count) {
@@ -100,7 +104,8 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co
100 /* In case it was set long ago */ 104 /* In case it was set long ago */
101 expect_close = 0; 105 expect_close = 0;
102 106
103 /* scan to see whether or not we got the magic character */ 107 /* scan to see whether or not we got the magic
108 character */
104 for (i = 0; i != count; i++) { 109 for (i = 0; i != count; i++) {
105 char c; 110 char c;
106 if (get_user(c, buf + i)) 111 if (get_user(c, buf + i))
@@ -109,27 +114,29 @@ static ssize_t wafwdt_write(struct file *file, const char __user *buf, size_t co
109 expect_close = 42; 114 expect_close = 42;
110 } 115 }
111 } 116 }
112 /* Well, anyhow someone wrote to us, we should return that favour */ 117 /* Well, anyhow someone wrote to us, we should
118 return that favour */
113 wafwdt_ping(); 119 wafwdt_ping();
114 } 120 }
115 return count; 121 return count;
116} 122}
117 123
118static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 124static long wafwdt_ioctl(struct file *file, unsigned int cmd,
119 unsigned long arg) 125 unsigned long arg)
120{ 126{
121 int new_timeout; 127 int new_timeout;
122 void __user *argp = (void __user *)arg; 128 void __user *argp = (void __user *)arg;
123 int __user *p = argp; 129 int __user *p = argp;
124 static struct watchdog_info ident = { 130 static const struct watchdog_info ident = {
125 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, 131 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
132 WDIOF_MAGICCLOSE,
126 .firmware_version = 1, 133 .firmware_version = 1,
127 .identity = "Wafer 5823 WDT", 134 .identity = "Wafer 5823 WDT",
128 }; 135 };
129 136
130 switch (cmd) { 137 switch (cmd) {
131 case WDIOC_GETSUPPORT: 138 case WDIOC_GETSUPPORT:
132 if (copy_to_user(argp, &ident, sizeof (ident))) 139 if (copy_to_user(argp, &ident, sizeof(ident)))
133 return -EFAULT; 140 return -EFAULT;
134 break; 141 break;
135 142
@@ -137,22 +144,6 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
137 case WDIOC_GETBOOTSTATUS: 144 case WDIOC_GETBOOTSTATUS:
138 return put_user(0, p); 145 return put_user(0, p);
139 146
140 case WDIOC_KEEPALIVE:
141 wafwdt_ping();
142 break;
143
144 case WDIOC_SETTIMEOUT:
145 if (get_user(new_timeout, p))
146 return -EFAULT;
147 if ((new_timeout < 1) || (new_timeout > 255))
148 return -EINVAL;
149 timeout = new_timeout;
150 wafwdt_stop();
151 wafwdt_start();
152 /* Fall */
153 case WDIOC_GETTIMEOUT:
154 return put_user(timeout, p);
155
156 case WDIOC_SETOPTIONS: 147 case WDIOC_SETOPTIONS:
157 { 148 {
158 int options, retval = -EINVAL; 149 int options, retval = -EINVAL;
@@ -173,6 +164,22 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
173 return retval; 164 return retval;
174 } 165 }
175 166
167 case WDIOC_KEEPALIVE:
168 wafwdt_ping();
169 break;
170
171 case WDIOC_SETTIMEOUT:
172 if (get_user(new_timeout, p))
173 return -EFAULT;
174 if ((new_timeout < 1) || (new_timeout > 255))
175 return -EINVAL;
176 timeout = new_timeout;
177 wafwdt_stop();
178 wafwdt_start();
179 /* Fall */
180 case WDIOC_GETTIMEOUT:
181 return put_user(timeout, p);
182
176 default: 183 default:
177 return -ENOTTY; 184 return -ENOTTY;
178 } 185 }
@@ -191,13 +198,13 @@ static int wafwdt_open(struct inode *inode, struct file *file)
191 return nonseekable_open(inode, file); 198 return nonseekable_open(inode, file);
192} 199}
193 200
194static int 201static int wafwdt_close(struct inode *inode, struct file *file)
195wafwdt_close(struct inode *inode, struct file *file)
196{ 202{
197 if (expect_close == 42) { 203 if (expect_close == 42)
198 wafwdt_stop(); 204 wafwdt_stop();
199 } else { 205 else {
200 printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); 206 printk(KERN_CRIT PFX
207 "WDT device closed unexpectedly. WDT will not stop!\n");
201 wafwdt_ping(); 208 wafwdt_ping();
202 } 209 }
203 clear_bit(0, &wafwdt_is_open); 210 clear_bit(0, &wafwdt_is_open);
@@ -209,12 +216,11 @@ wafwdt_close(struct inode *inode, struct file *file)
209 * Notifier for system down 216 * Notifier for system down
210 */ 217 */
211 218
212static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 219static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code,
220 void *unused)
213{ 221{
214 if (code == SYS_DOWN || code == SYS_HALT) { 222 if (code == SYS_DOWN || code == SYS_HALT)
215 /* Turn the WDT off */
216 wafwdt_stop(); 223 wafwdt_stop();
217 }
218 return NOTIFY_DONE; 224 return NOTIFY_DONE;
219} 225}
220 226
@@ -226,7 +232,7 @@ static const struct file_operations wafwdt_fops = {
226 .owner = THIS_MODULE, 232 .owner = THIS_MODULE,
227 .llseek = no_llseek, 233 .llseek = no_llseek,
228 .write = wafwdt_write, 234 .write = wafwdt_write,
229 .ioctl = wafwdt_ioctl, 235 .unlocked_ioctl = wafwdt_ioctl,
230 .open = wafwdt_open, 236 .open = wafwdt_open,
231 .release = wafwdt_close, 237 .release = wafwdt_close,
232}; 238};
@@ -250,25 +256,28 @@ static int __init wafwdt_init(void)
250{ 256{
251 int ret; 257 int ret;
252 258
253 printk(KERN_INFO "WDT driver for Wafer 5823 single board computer initialising.\n"); 259 printk(KERN_INFO
260 "WDT driver for Wafer 5823 single board computer initialising.\n");
254 261
255 if (timeout < 1 || timeout > 255) { 262 if (timeout < 1 || timeout > 255) {
256 timeout = WD_TIMO; 263 timeout = WD_TIMO;
257 printk (KERN_INFO PFX "timeout value must be 1<=x<=255, using %d\n", 264 printk(KERN_INFO PFX
258 timeout); 265 "timeout value must be 1 <= x <= 255, using %d\n",
266 timeout);
259 } 267 }
260 268
261 if (wdt_stop != wdt_start) { 269 if (wdt_stop != wdt_start) {
262 if(!request_region(wdt_stop, 1, "Wafer 5823 WDT")) { 270 if (!request_region(wdt_stop, 1, "Wafer 5823 WDT")) {
263 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 271 printk(KERN_ERR PFX
264 wdt_stop); 272 "I/O address 0x%04x already in use\n",
273 wdt_stop);
265 ret = -EIO; 274 ret = -EIO;
266 goto error; 275 goto error;
267 } 276 }
268 } 277 }
269 278
270 if(!request_region(wdt_start, 1, "Wafer 5823 WDT")) { 279 if (!request_region(wdt_start, 1, "Wafer 5823 WDT")) {
271 printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", 280 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
272 wdt_start); 281 wdt_start);
273 ret = -EIO; 282 ret = -EIO;
274 goto error2; 283 goto error2;
@@ -276,19 +285,20 @@ static int __init wafwdt_init(void)
276 285
277 ret = register_reboot_notifier(&wafwdt_notifier); 286 ret = register_reboot_notifier(&wafwdt_notifier);
278 if (ret != 0) { 287 if (ret != 0) {
279 printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 288 printk(KERN_ERR PFX
280 ret); 289 "cannot register reboot notifier (err=%d)\n", ret);
281 goto error3; 290 goto error3;
282 } 291 }
283 292
284 ret = misc_register(&wafwdt_miscdev); 293 ret = misc_register(&wafwdt_miscdev);
285 if (ret != 0) { 294 if (ret != 0) {
286 printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 295 printk(KERN_ERR PFX
287 WATCHDOG_MINOR, ret); 296 "cannot register miscdev on minor=%d (err=%d)\n",
297 WATCHDOG_MINOR, ret);
288 goto error4; 298 goto error4;
289 } 299 }
290 300
291 printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n", 301 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
292 timeout, nowayout); 302 timeout, nowayout);
293 303
294 return ret; 304 return ret;
@@ -307,7 +317,7 @@ static void __exit wafwdt_exit(void)
307{ 317{
308 misc_deregister(&wafwdt_miscdev); 318 misc_deregister(&wafwdt_miscdev);
309 unregister_reboot_notifier(&wafwdt_notifier); 319 unregister_reboot_notifier(&wafwdt_notifier);
310 if(wdt_stop != wdt_start) 320 if (wdt_stop != wdt_start)
311 release_region(wdt_stop, 1); 321 release_region(wdt_stop, 1);
312 release_region(wdt_start, 1); 322 release_region(wdt_start, 1);
313} 323}
diff --git a/drivers/watchdog/wd501p.h b/drivers/watchdog/wd501p.h
index a4504f40394d..db34853c28ae 100644
--- a/drivers/watchdog/wd501p.h
+++ b/drivers/watchdog/wd501p.h
@@ -12,7 +12,7 @@
12 * http://www.cymru.net 12 * http://www.cymru.net
13 * 13 *
14 * This driver is provided under the GNU General Public License, incorporated 14 * This driver is provided under the GNU General Public License, incorporated
15 * herein by reference. The driver is provided without warranty or 15 * herein by reference. The driver is provided without warranty or
16 * support. 16 * support.
17 * 17 *
18 * Release 0.04. 18 * Release 0.04.
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 1d64e277567d..5d3b1a8e28b0 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -35,9 +35,9 @@
35#include <linux/reboot.h> 35#include <linux/reboot.h>
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/watchdog.h> 37#include <linux/watchdog.h>
38#include <linux/uaccess.h>
38 39
39#include <asm/rtas.h> 40#include <asm/rtas.h>
40#include <asm/uaccess.h>
41 41
42#define WDRTAS_MAGIC_CHAR 42 42#define WDRTAS_MAGIC_CHAR 42
43#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ 43#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \
@@ -56,7 +56,7 @@ static int wdrtas_nowayout = 0;
56#endif 56#endif
57 57
58static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); 58static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
59static char wdrtas_expect_close = 0; 59static char wdrtas_expect_close;
60 60
61static int wdrtas_interval; 61static int wdrtas_interval;
62 62
@@ -86,8 +86,8 @@ static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN];
86 * RTAS function set-indicator (surveillance). The unit of interval is 86 * RTAS function set-indicator (surveillance). The unit of interval is
87 * seconds. 87 * seconds.
88 */ 88 */
89static int 89
90wdrtas_set_interval(int interval) 90static int wdrtas_set_interval(int interval)
91{ 91{
92 long result; 92 long result;
93 static int print_msg = 10; 93 static int print_msg = 10;
@@ -97,7 +97,7 @@ wdrtas_set_interval(int interval)
97 97
98 result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, 98 result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL,
99 WDRTAS_SURVEILLANCE_IND, 0, interval); 99 WDRTAS_SURVEILLANCE_IND, 0, interval);
100 if ( (result < 0) && (print_msg) ) { 100 if (result < 0 && print_msg) {
101 printk(KERN_ERR "wdrtas: setting the watchdog to %i " 101 printk(KERN_ERR "wdrtas: setting the watchdog to %i "
102 "timeout failed: %li\n", interval, result); 102 "timeout failed: %li\n", interval, result);
103 print_msg--; 103 print_msg--;
@@ -116,16 +116,14 @@ wdrtas_set_interval(int interval)
116 * as reported by the RTAS function ibm,get-system-parameter. The unit 116 * as reported by the RTAS function ibm,get-system-parameter. The unit
117 * of the return value is seconds. 117 * of the return value is seconds.
118 */ 118 */
119static int 119static int wdrtas_get_interval(int fallback_value)
120wdrtas_get_interval(int fallback_value)
121{ 120{
122 long result; 121 long result;
123 char value[4]; 122 char value[4];
124 123
125 result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, 124 result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
126 WDRTAS_SP_SPI, (void *)__pa(&value), 4); 125 WDRTAS_SP_SPI, (void *)__pa(&value), 4);
127 if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) || 126 if (value[0] != 0 || value[1] != 2 || value[3] != 0 || result < 0) {
128 (result < 0) ) {
129 printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " 127 printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
130 "timeout (%li). Continuing\n", result); 128 "timeout (%li). Continuing\n", result);
131 return fallback_value; 129 return fallback_value;
@@ -141,8 +139,7 @@ wdrtas_get_interval(int fallback_value)
141 * wdrtas_timer_start starts the watchdog by calling the RTAS function 139 * wdrtas_timer_start starts the watchdog by calling the RTAS function
142 * set-interval (surveillance) 140 * set-interval (surveillance)
143 */ 141 */
144static void 142static void wdrtas_timer_start(void)
145wdrtas_timer_start(void)
146{ 143{
147 wdrtas_set_interval(wdrtas_interval); 144 wdrtas_set_interval(wdrtas_interval);
148} 145}
@@ -153,8 +150,7 @@ wdrtas_timer_start(void)
153 * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function 150 * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function
154 * set-interval (surveillance) 151 * set-interval (surveillance)
155 */ 152 */
156static void 153static void wdrtas_timer_stop(void)
157wdrtas_timer_stop(void)
158{ 154{
159 wdrtas_set_interval(0); 155 wdrtas_set_interval(0);
160} 156}
@@ -165,8 +161,7 @@ wdrtas_timer_stop(void)
165 * wdrtas_log_scanned_event prints a message to the log buffer dumping 161 * wdrtas_log_scanned_event prints a message to the log buffer dumping
166 * the results of the last event-scan call 162 * the results of the last event-scan call
167 */ 163 */
168static void 164static void wdrtas_log_scanned_event(void)
169wdrtas_log_scanned_event(void)
170{ 165{
171 int i; 166 int i;
172 167
@@ -175,13 +170,13 @@ wdrtas_log_scanned_event(void)
175 "%02x %02x %02x %02x %02x %02x %02x %02x " 170 "%02x %02x %02x %02x %02x %02x %02x %02x "
176 "%02x %02x %02x %02x %02x %02x %02x %02x\n", 171 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
177 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), 172 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
178 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], 173 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1],
179 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], 174 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3],
180 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], 175 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5],
181 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], 176 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7],
182 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], 177 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9],
183 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], 178 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11],
184 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], 179 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13],
185 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); 180 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
186} 181}
187 182
@@ -192,8 +187,7 @@ wdrtas_log_scanned_event(void)
192 * RTAS function event-scan and repeats these calls as long as there are 187 * RTAS function event-scan and repeats these calls as long as there are
193 * events available. All events will be dumped. 188 * events available. All events will be dumped.
194 */ 189 */
195static void 190static void wdrtas_timer_keepalive(void)
196wdrtas_timer_keepalive(void)
197{ 191{
198 long result; 192 long result;
199 193
@@ -218,8 +212,7 @@ wdrtas_timer_keepalive(void)
218 * wdrtas_get_temperature returns the current temperature in Fahrenheit. It 212 * wdrtas_get_temperature returns the current temperature in Fahrenheit. It
219 * uses the RTAS call get-sensor-state, token 3 to do so 213 * uses the RTAS call get-sensor-state, token 3 to do so
220 */ 214 */
221static int 215static int wdrtas_get_temperature(void)
222wdrtas_get_temperature(void)
223{ 216{
224 long result; 217 long result;
225 int temperature = 0; 218 int temperature = 0;
@@ -243,8 +236,7 @@ wdrtas_get_temperature(void)
243 * returns a bitmask of defines WDIOF_... as defined in 236 * returns a bitmask of defines WDIOF_... as defined in
244 * include/linux/watchdog.h 237 * include/linux/watchdog.h
245 */ 238 */
246static int 239static int wdrtas_get_status(void)
247wdrtas_get_status(void)
248{ 240{
249 return 0; /* TODO */ 241 return 0; /* TODO */
250} 242}
@@ -255,8 +247,7 @@ wdrtas_get_status(void)
255 * returns a bitmask of defines WDIOF_... as defined in 247 * returns a bitmask of defines WDIOF_... as defined in
256 * include/linux/watchdog.h, indicating why the watchdog rebooted the system 248 * include/linux/watchdog.h, indicating why the watchdog rebooted the system
257 */ 249 */
258static int 250static int wdrtas_get_boot_status(void)
259wdrtas_get_boot_status(void)
260{ 251{
261 return 0; /* TODO */ 252 return 0; /* TODO */
262} 253}
@@ -276,8 +267,7 @@ wdrtas_get_boot_status(void)
276 * character 'V'. This character allows the watchdog device to be closed 267 * character 'V'. This character allows the watchdog device to be closed
277 * properly. 268 * properly.
278 */ 269 */
279static ssize_t 270static ssize_t wdrtas_write(struct file *file, const char __user *buf,
280wdrtas_write(struct file *file, const char __user *buf,
281 size_t len, loff_t *ppos) 271 size_t len, loff_t *ppos)
282{ 272{
283 int i; 273 int i;
@@ -306,7 +296,6 @@ out:
306 296
307/** 297/**
308 * wdrtas_ioctl - ioctl function for the watchdog device 298 * wdrtas_ioctl - ioctl function for the watchdog device
309 * @inode: inode structure
310 * @file: file structure 299 * @file: file structure
311 * @cmd: command for ioctl 300 * @cmd: command for ioctl
312 * @arg: argument pointer 301 * @arg: argument pointer
@@ -315,16 +304,16 @@ out:
315 * 304 *
316 * wdrtas_ioctl implements the watchdog API ioctls 305 * wdrtas_ioctl implements the watchdog API ioctls
317 */ 306 */
318static int 307
319wdrtas_ioctl(struct inode *inode, struct file *file, 308static long wdrtas_ioctl(struct file *file, unsigned int cmd,
320 unsigned int cmd, unsigned long arg) 309 unsigned long arg)
321{ 310{
322 int __user *argp = (void __user *)arg; 311 int __user *argp = (void __user *)arg;
323 int i; 312 int i;
324 static struct watchdog_info wdinfo = { 313 static struct watchdog_info wdinfo = {
325 .options = WDRTAS_SUPPORTED_MASK, 314 .options = WDRTAS_SUPPORTED_MASK,
326 .firmware_version = 0, 315 .firmware_version = 0,
327 .identity = "wdrtas" 316 .identity = "wdrtas",
328 }; 317 };
329 318
330 switch (cmd) { 319 switch (cmd) {
@@ -357,9 +346,9 @@ wdrtas_ioctl(struct inode *inode, struct file *file,
357 wdrtas_timer_keepalive(); 346 wdrtas_timer_keepalive();
358 wdrtas_timer_start(); 347 wdrtas_timer_start();
359 } 348 }
349 /* not implemented. Done by H8
360 if (i & WDIOS_TEMPPANIC) { 350 if (i & WDIOS_TEMPPANIC) {
361 /* not implemented. Done by H8 */ 351 } */
362 }
363 return 0; 352 return 0;
364 353
365 case WDIOC_KEEPALIVE: 354 case WDIOC_KEEPALIVE:
@@ -399,8 +388,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file,
399 * 388 *
400 * function called when watchdog device is opened 389 * function called when watchdog device is opened
401 */ 390 */
402static int 391static int wdrtas_open(struct inode *inode, struct file *file)
403wdrtas_open(struct inode *inode, struct file *file)
404{ 392{
405 /* only open once */ 393 /* only open once */
406 if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { 394 if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {
@@ -423,8 +411,7 @@ wdrtas_open(struct inode *inode, struct file *file)
423 * 411 *
424 * close function. Always succeeds 412 * close function. Always succeeds
425 */ 413 */
426static int 414static int wdrtas_close(struct inode *inode, struct file *file)
427wdrtas_close(struct inode *inode, struct file *file)
428{ 415{
429 /* only stop watchdog, if this was announced using 'V' before */ 416 /* only stop watchdog, if this was announced using 'V' before */
430 if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) 417 if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)
@@ -453,8 +440,7 @@ wdrtas_close(struct inode *inode, struct file *file)
453 * wdrtas_temp_read gives the temperature to the users by copying this 440 * wdrtas_temp_read gives the temperature to the users by copying this
454 * value as one byte into the user space buffer. The unit is Fahrenheit... 441 * value as one byte into the user space buffer. The unit is Fahrenheit...
455 */ 442 */
456static ssize_t 443static ssize_t wdrtas_temp_read(struct file *file, char __user *buf,
457wdrtas_temp_read(struct file *file, char __user *buf,
458 size_t count, loff_t *ppos) 444 size_t count, loff_t *ppos)
459{ 445{
460 int temperature = 0; 446 int temperature = 0;
@@ -478,8 +464,7 @@ wdrtas_temp_read(struct file *file, char __user *buf,
478 * 464 *
479 * function called when temperature device is opened 465 * function called when temperature device is opened
480 */ 466 */
481static int 467static int wdrtas_temp_open(struct inode *inode, struct file *file)
482wdrtas_temp_open(struct inode *inode, struct file *file)
483{ 468{
484 return nonseekable_open(inode, file); 469 return nonseekable_open(inode, file);
485} 470}
@@ -493,8 +478,7 @@ wdrtas_temp_open(struct inode *inode, struct file *file)
493 * 478 *
494 * close function. Always succeeds 479 * close function. Always succeeds
495 */ 480 */
496static int 481static int wdrtas_temp_close(struct inode *inode, struct file *file)
497wdrtas_temp_close(struct inode *inode, struct file *file)
498{ 482{
499 return 0; 483 return 0;
500} 484}
@@ -509,10 +493,10 @@ wdrtas_temp_close(struct inode *inode, struct file *file)
509 * 493 *
510 * wdrtas_reboot stops the watchdog in case of a reboot 494 * wdrtas_reboot stops the watchdog in case of a reboot
511 */ 495 */
512static int 496static int wdrtas_reboot(struct notifier_block *this,
513wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) 497 unsigned long code, void *ptr)
514{ 498{
515 if ( (code==SYS_DOWN) || (code==SYS_HALT) ) 499 if (code == SYS_DOWN || code == SYS_HALT)
516 wdrtas_timer_stop(); 500 wdrtas_timer_stop();
517 501
518 return NOTIFY_DONE; 502 return NOTIFY_DONE;
@@ -524,7 +508,7 @@ static const struct file_operations wdrtas_fops = {
524 .owner = THIS_MODULE, 508 .owner = THIS_MODULE,
525 .llseek = no_llseek, 509 .llseek = no_llseek,
526 .write = wdrtas_write, 510 .write = wdrtas_write,
527 .ioctl = wdrtas_ioctl, 511 .unlocked_ioctl = wdrtas_ioctl,
528 .open = wdrtas_open, 512 .open = wdrtas_open,
529 .release = wdrtas_close, 513 .release = wdrtas_close,
530}; 514};
@@ -562,8 +546,7 @@ static struct notifier_block wdrtas_notifier = {
562 * this watchdog driver. It tolerates, if "get-sensor-state" and 546 * this watchdog driver. It tolerates, if "get-sensor-state" and
563 * "ibm,get-system-parameter" are not available. 547 * "ibm,get-system-parameter" are not available.
564 */ 548 */
565static int 549static int wdrtas_get_tokens(void)
566wdrtas_get_tokens(void)
567{ 550{
568 wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); 551 wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");
569 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { 552 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {
@@ -603,8 +586,7 @@ wdrtas_get_tokens(void)
603 * wdrtas_register_devs unregisters the watchdog and temperature watchdog 586 * wdrtas_register_devs unregisters the watchdog and temperature watchdog
604 * misc devs 587 * misc devs
605 */ 588 */
606static void 589static void wdrtas_unregister_devs(void)
607wdrtas_unregister_devs(void)
608{ 590{
609 misc_deregister(&wdrtas_miscdev); 591 misc_deregister(&wdrtas_miscdev);
610 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) 592 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)
@@ -619,8 +601,7 @@ wdrtas_unregister_devs(void)
619 * wdrtas_register_devs registers the watchdog and temperature watchdog 601 * wdrtas_register_devs registers the watchdog and temperature watchdog
620 * misc devs 602 * misc devs
621 */ 603 */
622static int 604static int wdrtas_register_devs(void)
623wdrtas_register_devs(void)
624{ 605{
625 int result; 606 int result;
626 607
@@ -651,8 +632,7 @@ wdrtas_register_devs(void)
651 * 632 *
652 * registers the file handlers and the reboot notifier 633 * registers the file handlers and the reboot notifier
653 */ 634 */
654static int __init 635static int __init wdrtas_init(void)
655wdrtas_init(void)
656{ 636{
657 if (wdrtas_get_tokens()) 637 if (wdrtas_get_tokens())
658 return -ENODEV; 638 return -ENODEV;
@@ -680,8 +660,7 @@ wdrtas_init(void)
680 * 660 *
681 * unregisters the file handlers and the reboot notifier 661 * unregisters the file handlers and the reboot notifier
682 */ 662 */
683static void __exit 663static void __exit wdrtas_exit(void)
684wdrtas_exit(void)
685{ 664{
686 if (!wdrtas_nowayout) 665 if (!wdrtas_nowayout)
687 wdrtas_timer_stop(); 666 wdrtas_timer_stop();
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index 53a6b18bcb9a..deeebb2b13ea 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -373,8 +373,6 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
373#endif /* CONFIG_WDT_501 */ 373#endif /* CONFIG_WDT_501 */
374 374
375 switch (cmd) { 375 switch (cmd) {
376 default:
377 return -ENOTTY;
378 case WDIOC_GETSUPPORT: 376 case WDIOC_GETSUPPORT:
379 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 377 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
380 case WDIOC_GETSTATUS: 378 case WDIOC_GETSTATUS:
@@ -394,6 +392,8 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
394 /* Fall */ 392 /* Fall */
395 case WDIOC_GETTIMEOUT: 393 case WDIOC_GETTIMEOUT:
396 return put_user(heartbeat, p); 394 return put_user(heartbeat, p);
395 default:
396 return -ENOTTY;
397 } 397 }
398} 398}
399 399
diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c
index e4cf661dc890..db362c34958b 100644
--- a/drivers/watchdog/wdt285.c
+++ b/drivers/watchdog/wdt285.c
@@ -26,10 +26,10 @@
26#include <linux/reboot.h> 26#include <linux/reboot.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/uaccess.h>
30#include <linux/irq.h>
31#include <mach/hardware.h>
29 32
30#include <asm/irq.h>
31#include <asm/uaccess.h>
32#include <asm/hardware.h>
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <asm/hardware/dec21285.h> 34#include <asm/hardware/dec21285.h>
35 35
@@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file)
115 return 0; 115 return 0;
116} 116}
117 117
118static ssize_t 118static ssize_t watchdog_write(struct file *file, const char *data,
119watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) 119 size_t len, loff_t *ppos)
120{ 120{
121 /* 121 /*
122 * Refresh the timer. 122 * Refresh the timer.
@@ -127,19 +127,18 @@ watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
127 return len; 127 return len;
128} 128}
129 129
130static struct watchdog_info ident = { 130static const struct watchdog_info ident = {
131 .options = WDIOF_SETTIMEOUT, 131 .options = WDIOF_SETTIMEOUT,
132 .identity = "Footbridge Watchdog", 132 .identity = "Footbridge Watchdog",
133}; 133};
134 134
135static int 135static long watchdog_ioctl(struct file *file, unsigned int cmd,
136watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 136 unsigned long arg)
137 unsigned long arg)
138{ 137{
139 unsigned int new_margin; 138 unsigned int new_margin;
140 int ret = -ENOTTY; 139 int ret = -ENOTTY;
141 140
142 switch(cmd) { 141 switch (cmd) {
143 case WDIOC_GETSUPPORT: 142 case WDIOC_GETSUPPORT:
144 ret = 0; 143 ret = 0;
145 if (copy_to_user((void *)arg, &ident, sizeof(ident))) 144 if (copy_to_user((void *)arg, &ident, sizeof(ident)))
@@ -148,7 +147,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
148 147
149 case WDIOC_GETSTATUS: 148 case WDIOC_GETSTATUS:
150 case WDIOC_GETBOOTSTATUS: 149 case WDIOC_GETBOOTSTATUS:
151 ret = put_user(0,(int *)arg); 150 ret = put_user(0, (int *)arg);
152 break; 151 break;
153 152
154 case WDIOC_KEEPALIVE: 153 case WDIOC_KEEPALIVE:
@@ -182,7 +181,7 @@ static const struct file_operations watchdog_fops = {
182 .owner = THIS_MODULE, 181 .owner = THIS_MODULE,
183 .llseek = no_llseek, 182 .llseek = no_llseek,
184 .write = watchdog_write, 183 .write = watchdog_write,
185 .ioctl = watchdog_ioctl, 184 .unlocked_ioctl = watchdog_ioctl,
186 .open = watchdog_open, 185 .open = watchdog_open,
187 .release = watchdog_release, 186 .release = watchdog_release,
188}; 187};
@@ -204,11 +203,13 @@ static int __init footbridge_watchdog_init(void)
204 if (retval < 0) 203 if (retval < 0)
205 return retval; 204 return retval;
206 205
207 printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", 206 printk(KERN_INFO
208 soft_margin); 207 "Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
208 soft_margin);
209 209
210 if (machine_is_cats()) 210 if (machine_is_cats())
211 printk("Warning: Watchdog reset may not work on this machine.\n"); 211 printk(KERN_WARNING
212 "Warning: Watchdog reset may not work on this machine.\n");
212 return 0; 213 return 0;
213} 214}
214 215
@@ -223,7 +224,7 @@ MODULE_LICENSE("GPL");
223MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 224MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
224 225
225module_param(soft_margin, int, 0); 226module_param(soft_margin, int, 0);
226MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds"); 227MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
227 228
228module_init(footbridge_watchdog_init); 229module_init(footbridge_watchdog_init);
229module_exit(footbridge_watchdog_exit); 230module_exit(footbridge_watchdog_exit);
diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c
index fb4b876c9fda..60e28d49ff52 100644
--- a/drivers/watchdog/wdt977.c
+++ b/drivers/watchdog/wdt977.c
@@ -19,7 +19,8 @@
19 * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in 19 * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in
20 * nwwatchdog_init. 20 * nwwatchdog_init.
21 * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks 21 * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks
22 * remove limitiation to be used on Netwinders only 22 * remove limitiation to be used on
23 * Netwinders only
23 */ 24 */
24 25
25#include <linux/module.h> 26#include <linux/module.h>
@@ -33,11 +34,11 @@
33#include <linux/watchdog.h> 34#include <linux/watchdog.h>
34#include <linux/notifier.h> 35#include <linux/notifier.h>
35#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/io.h>
38#include <linux/uaccess.h>
36 39
37#include <asm/io.h>
38#include <asm/system.h> 40#include <asm/system.h>
39#include <asm/mach-types.h> 41#include <asm/mach-types.h>
40#include <asm/uaccess.h>
41 42
42#define WATCHDOG_VERSION "0.04" 43#define WATCHDOG_VERSION "0.04"
43#define WATCHDOG_NAME "Wdt977" 44#define WATCHDOG_NAME "Wdt977"
@@ -45,7 +46,7 @@
45#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" 46#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
46 47
47#define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */ 48#define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */
48#define IO_DATA_PORT (IO_INDEX_PORT+1) 49#define IO_DATA_PORT (IO_INDEX_PORT + 1)
49 50
50#define UNLOCK_DATA 0x87 51#define UNLOCK_DATA 0x87
51#define LOCK_DATA 0xAA 52#define LOCK_DATA 0xAA
@@ -62,13 +63,16 @@ static char expect_close;
62static DEFINE_SPINLOCK(spinlock); 63static DEFINE_SPINLOCK(spinlock);
63 64
64module_param(timeout, int, 0); 65module_param(timeout, int, 0);
65MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); 66MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300), default="
67 __MODULE_STRING(DEFAULT_TIMEOUT) ")");
66module_param(testmode, int, 0); 68module_param(testmode, int, 0);
67MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0"); 69MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0");
68 70
69static int nowayout = WATCHDOG_NOWAYOUT; 71static int nowayout = WATCHDOG_NOWAYOUT;
70module_param(nowayout, int, 0); 72module_param(nowayout, int, 0);
71MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 73MODULE_PARM_DESC(nowayout,
74 "Watchdog cannot be stopped once started (default="
75 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
72 76
73/* 77/*
74 * Start the watchdog 78 * Start the watchdog
@@ -95,14 +99,16 @@ static int wdt977_start(void)
95 outb_p(0xF2, IO_INDEX_PORT); 99 outb_p(0xF2, IO_INDEX_PORT);
96 outb_p(timeoutM, IO_DATA_PORT); 100 outb_p(timeoutM, IO_DATA_PORT);
97 outb_p(0xF3, IO_INDEX_PORT); 101 outb_p(0xF3, IO_INDEX_PORT);
98 outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for kbd/mouse/LED */ 102 outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for
103 kbd/mouse/LED */
99 outb_p(0xF4, IO_INDEX_PORT); 104 outb_p(0xF4, IO_INDEX_PORT);
100 outb_p(0x00, IO_DATA_PORT); 105 outb_p(0x00, IO_DATA_PORT);
101 106
102 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ 107 /* At last select device Aux1 (dev=7) and set GP16 as a
103 /* in test mode watch the bit 1 on F4 to indicate "triggered" */ 108 * watchdog output. In test mode watch the bit 1 on F4 to
104 if (!testmode) 109 * indicate "triggered"
105 { 110 */
111 if (!testmode) {
106 outb_p(DEVICE_REGISTER, IO_INDEX_PORT); 112 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
107 outb_p(0x07, IO_DATA_PORT); 113 outb_p(0x07, IO_DATA_PORT);
108 outb_p(0xE6, IO_INDEX_PORT); 114 outb_p(0xE6, IO_INDEX_PORT);
@@ -147,7 +153,8 @@ static int wdt977_stop(void)
147 outb_p(0xF2, IO_INDEX_PORT); 153 outb_p(0xF2, IO_INDEX_PORT);
148 outb_p(0x00, IO_DATA_PORT); 154 outb_p(0x00, IO_DATA_PORT);
149 155
150 /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ 156 /* at last select device Aux1 (dev=7) and set
157 GP16 as a watchdog output */
151 outb_p(DEVICE_REGISTER, IO_INDEX_PORT); 158 outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
152 outb_p(0x07, IO_DATA_PORT); 159 outb_p(0x07, IO_DATA_PORT);
153 outb_p(0xE6, IO_INDEX_PORT); 160 outb_p(0xE6, IO_INDEX_PORT);
@@ -202,16 +209,18 @@ static int wdt977_set_timeout(int t)
202 tmrval = (t + 59) / 60; 209 tmrval = (t + 59) / 60;
203 210
204 if (machine_is_netwinder()) { 211 if (machine_is_netwinder()) {
205 /* we have a hw bug somewhere, so each 977 minute is actually only 30sec 212 /* we have a hw bug somewhere, so each 977 minute is actually
206 * this limits the max timeout to half of device max of 255 minutes... 213 * only 30sec. This limits the max timeout to half of device
214 * max of 255 minutes...
207 */ 215 */
208 tmrval += tmrval; 216 tmrval += tmrval;
209 } 217 }
210 218
211 if ((tmrval < 1) || (tmrval > 255)) 219 if (tmrval < 1 || tmrval > 255)
212 return -EINVAL; 220 return -EINVAL;
213 221
214 /* timeout is the timeout in seconds, timeoutM is the timeout in minutes) */ 222 /* timeout is the timeout in seconds, timeoutM is
223 the timeout in minutes) */
215 timeout = t; 224 timeout = t;
216 timeoutM = tmrval; 225 timeoutM = tmrval;
217 return 0; 226 return 0;
@@ -243,7 +252,7 @@ static int wdt977_get_status(int *status)
243 252
244 spin_unlock_irqrestore(&spinlock, flags); 253 spin_unlock_irqrestore(&spinlock, flags);
245 254
246 *status=0; 255 *status = 0;
247 if (new_status & 1) 256 if (new_status & 1)
248 *status |= WDIOF_CARDRESET; 257 *status |= WDIOF_CARDRESET;
249 258
@@ -258,7 +267,7 @@ static int wdt977_get_status(int *status)
258static int wdt977_open(struct inode *inode, struct file *file) 267static int wdt977_open(struct inode *inode, struct file *file)
259{ 268{
260 /* If the watchdog is alive we don't need to start it again */ 269 /* If the watchdog is alive we don't need to start it again */
261 if( test_and_set_bit(0,&timer_alive) ) 270 if (test_and_set_bit(0, &timer_alive))
262 return -EBUSY; 271 return -EBUSY;
263 272
264 if (nowayout) 273 if (nowayout)
@@ -274,13 +283,13 @@ static int wdt977_release(struct inode *inode, struct file *file)
274 * Shut off the timer. 283 * Shut off the timer.
275 * Lock it in if it's a module and we set nowayout 284 * Lock it in if it's a module and we set nowayout
276 */ 285 */
277 if (expect_close == 42) 286 if (expect_close == 42) {
278 {
279 wdt977_stop(); 287 wdt977_stop();
280 clear_bit(0,&timer_alive); 288 clear_bit(0, &timer_alive);
281 } else { 289 } else {
282 wdt977_keepalive(); 290 wdt977_keepalive();
283 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 291 printk(KERN_CRIT PFX
292 "Unexpected close, not stopping watchdog!\n");
284 } 293 }
285 expect_close = 0; 294 expect_close = 0;
286 return 0; 295 return 0;
@@ -301,17 +310,14 @@ static int wdt977_release(struct inode *inode, struct file *file)
301static ssize_t wdt977_write(struct file *file, const char __user *buf, 310static ssize_t wdt977_write(struct file *file, const char __user *buf,
302 size_t count, loff_t *ppos) 311 size_t count, loff_t *ppos)
303{ 312{
304 if (count) 313 if (count) {
305 { 314 if (!nowayout) {
306 if (!nowayout)
307 {
308 size_t i; 315 size_t i;
309 316
310 /* In case it was set long ago */ 317 /* In case it was set long ago */
311 expect_close = 0; 318 expect_close = 0;
312 319
313 for (i = 0; i != count; i++) 320 for (i = 0; i != count; i++) {
314 {
315 char c; 321 char c;
316 if (get_user(c, buf + i)) 322 if (get_user(c, buf + i))
317 return -EFAULT; 323 return -EFAULT;
@@ -326,6 +332,14 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf,
326 return count; 332 return count;
327} 333}
328 334
335static const struct watchdog_info ident = {
336 .options = WDIOF_SETTIMEOUT |
337 WDIOF_MAGICCLOSE |
338 WDIOF_KEEPALIVEPING,
339 .firmware_version = 1,
340 .identity = WATCHDOG_NAME,
341};
342
329/* 343/*
330 * wdt977_ioctl: 344 * wdt977_ioctl:
331 * @inode: inode of the device 345 * @inode: inode of the device
@@ -337,16 +351,8 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf,
337 * according to their available features. 351 * according to their available features.
338 */ 352 */
339 353
340static struct watchdog_info ident = { 354static long wdt977_ioctl(struct file *file, unsigned int cmd,
341 .options = WDIOF_SETTIMEOUT | 355 unsigned long arg)
342 WDIOF_MAGICCLOSE |
343 WDIOF_KEEPALIVEPING,
344 .firmware_version = 1,
345 .identity = WATCHDOG_NAME,
346};
347
348static int wdt977_ioctl(struct inode *inode, struct file *file,
349 unsigned int cmd, unsigned long arg)
350{ 356{
351 int status; 357 int status;
352 int new_options, retval = -EINVAL; 358 int new_options, retval = -EINVAL;
@@ -358,11 +364,7 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
358 364
359 uarg.i = (int __user *)arg; 365 uarg.i = (int __user *)arg;
360 366
361 switch(cmd) 367 switch (cmd) {
362 {
363 default:
364 return -ENOTTY;
365
366 case WDIOC_GETSUPPORT: 368 case WDIOC_GETSUPPORT:
367 return copy_to_user(uarg.ident, &ident, 369 return copy_to_user(uarg.ident, &ident,
368 sizeof(ident)) ? -EFAULT : 0; 370 sizeof(ident)) ? -EFAULT : 0;
@@ -374,12 +376,8 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
374 case WDIOC_GETBOOTSTATUS: 376 case WDIOC_GETBOOTSTATUS:
375 return put_user(0, uarg.i); 377 return put_user(0, uarg.i);
376 378
377 case WDIOC_KEEPALIVE:
378 wdt977_keepalive();
379 return 0;
380
381 case WDIOC_SETOPTIONS: 379 case WDIOC_SETOPTIONS:
382 if (get_user (new_options, uarg.i)) 380 if (get_user(new_options, uarg.i))
383 return -EFAULT; 381 return -EFAULT;
384 382
385 if (new_options & WDIOS_DISABLECARD) { 383 if (new_options & WDIOS_DISABLECARD) {
@@ -394,6 +392,10 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
394 392
395 return retval; 393 return retval;
396 394
395 case WDIOC_KEEPALIVE:
396 wdt977_keepalive();
397 return 0;
398
397 case WDIOC_SETTIMEOUT: 399 case WDIOC_SETTIMEOUT:
398 if (get_user(new_timeout, uarg.i)) 400 if (get_user(new_timeout, uarg.i))
399 return -EFAULT; 401 return -EFAULT;
@@ -407,29 +409,30 @@ static int wdt977_ioctl(struct inode *inode, struct file *file,
407 case WDIOC_GETTIMEOUT: 409 case WDIOC_GETTIMEOUT:
408 return put_user(timeout, uarg.i); 410 return put_user(timeout, uarg.i);
409 411
412 default:
413 return -ENOTTY;
414
410 } 415 }
411} 416}
412 417
413static int wdt977_notify_sys(struct notifier_block *this, unsigned long code, 418static int wdt977_notify_sys(struct notifier_block *this, unsigned long code,
414 void *unused) 419 void *unused)
415{ 420{
416 if(code==SYS_DOWN || code==SYS_HALT) 421 if (code == SYS_DOWN || code == SYS_HALT)
417 wdt977_stop(); 422 wdt977_stop();
418 return NOTIFY_DONE; 423 return NOTIFY_DONE;
419} 424}
420 425
421static const struct file_operations wdt977_fops= 426static const struct file_operations wdt977_fops = {
422{
423 .owner = THIS_MODULE, 427 .owner = THIS_MODULE,
424 .llseek = no_llseek, 428 .llseek = no_llseek,
425 .write = wdt977_write, 429 .write = wdt977_write,
426 .ioctl = wdt977_ioctl, 430 .unlocked_ioctl = wdt977_ioctl,
427 .open = wdt977_open, 431 .open = wdt977_open,
428 .release = wdt977_release, 432 .release = wdt977_release,
429}; 433};
430 434
431static struct miscdevice wdt977_miscdev= 435static struct miscdevice wdt977_miscdev = {
432{
433 .minor = WATCHDOG_MINOR, 436 .minor = WATCHDOG_MINOR,
434 .name = "watchdog", 437 .name = "watchdog",
435 .fops = &wdt977_fops, 438 .fops = &wdt977_fops,
@@ -443,51 +446,48 @@ static int __init wd977_init(void)
443{ 446{
444 int rc; 447 int rc;
445 448
446 //if (!machine_is_netwinder())
447 // return -ENODEV;
448
449 printk(KERN_INFO PFX DRIVER_VERSION); 449 printk(KERN_INFO PFX DRIVER_VERSION);
450 450
451 /* Check that the timeout value is within it's range ; if not reset to the default */ 451 /* Check that the timeout value is within its range;
452 if (wdt977_set_timeout(timeout)) 452 if not reset to the default */
453 { 453 if (wdt977_set_timeout(timeout)) {
454 wdt977_set_timeout(DEFAULT_TIMEOUT); 454 wdt977_set_timeout(DEFAULT_TIMEOUT);
455 printk(KERN_INFO PFX "timeout value must be 60<timeout<15300, using %d\n", 455 printk(KERN_INFO PFX
456 DEFAULT_TIMEOUT); 456 "timeout value must be 60 < timeout < 15300, using %d\n",
457 DEFAULT_TIMEOUT);
457 } 458 }
458 459
459 /* on Netwinder the IOports are already reserved by 460 /* on Netwinder the IOports are already reserved by
460 * arch/arm/mach-footbridge/netwinder-hw.c 461 * arch/arm/mach-footbridge/netwinder-hw.c
461 */ 462 */
462 if (!machine_is_netwinder()) 463 if (!machine_is_netwinder()) {
463 { 464 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) {
464 if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME)) 465 printk(KERN_ERR PFX
465 { 466 "I/O address 0x%04x already in use\n",
466 printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", 467 IO_INDEX_PORT);
467 IO_INDEX_PORT);
468 rc = -EIO; 468 rc = -EIO;
469 goto err_out; 469 goto err_out;
470 } 470 }
471 } 471 }
472 472
473 rc = register_reboot_notifier(&wdt977_notifier); 473 rc = register_reboot_notifier(&wdt977_notifier);
474 if (rc) 474 if (rc) {
475 { 475 printk(KERN_ERR PFX
476 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", 476 "cannot register reboot notifier (err=%d)\n", rc);
477 rc);
478 goto err_out_region; 477 goto err_out_region;
479 } 478 }
480 479
481 rc = misc_register(&wdt977_miscdev); 480 rc = misc_register(&wdt977_miscdev);
482 if (rc) 481 if (rc) {
483 { 482 printk(KERN_ERR PFX
484 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", 483 "cannot register miscdev on minor=%d (err=%d)\n",
485 wdt977_miscdev.minor, rc); 484 wdt977_miscdev.minor, rc);
486 goto err_out_reboot; 485 goto err_out_reboot;
487 } 486 }
488 487
489 printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n", 488 printk(KERN_INFO PFX
490 timeout, nowayout, testmode); 489 "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n",
490 timeout, nowayout, testmode);
491 491
492 return 0; 492 return 0;
493 493
@@ -495,7 +495,7 @@ err_out_reboot:
495 unregister_reboot_notifier(&wdt977_notifier); 495 unregister_reboot_notifier(&wdt977_notifier);
496err_out_region: 496err_out_region:
497 if (!machine_is_netwinder()) 497 if (!machine_is_netwinder())
498 release_region(IO_INDEX_PORT,2); 498 release_region(IO_INDEX_PORT, 2);
499err_out: 499err_out:
500 return rc; 500 return rc;
501} 501}
@@ -505,7 +505,7 @@ static void __exit wd977_exit(void)
505 wdt977_stop(); 505 wdt977_stop();
506 misc_deregister(&wdt977_miscdev); 506 misc_deregister(&wdt977_miscdev);
507 unregister_reboot_notifier(&wdt977_notifier); 507 unregister_reboot_notifier(&wdt977_notifier);
508 release_region(IO_INDEX_PORT,2); 508 release_region(IO_INDEX_PORT, 2);
509} 509}
510 510
511module_init(wd977_init); 511module_init(wd977_init);
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index 5d922fd6eafc..ed02bdb38c09 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -381,7 +381,7 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf,
381 381
382 for (i = 0; i != count; i++) { 382 for (i = 0; i != count; i++) {
383 char c; 383 char c;
384 if (get_user(c, buf+i)) 384 if (get_user(c, buf + i))
385 return -EFAULT; 385 return -EFAULT;
386 if (c == 'V') 386 if (c == 'V')
387 expect_close = 42; 387 expect_close = 42;
@@ -428,8 +428,6 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
428#endif /* CONFIG_WDT_501_PCI */ 428#endif /* CONFIG_WDT_501_PCI */
429 429
430 switch (cmd) { 430 switch (cmd) {
431 default:
432 return -ENOTTY;
433 case WDIOC_GETSUPPORT: 431 case WDIOC_GETSUPPORT:
434 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; 432 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
435 case WDIOC_GETSTATUS: 433 case WDIOC_GETSTATUS:
@@ -449,7 +447,9 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
449 /* Fall */ 447 /* Fall */
450 case WDIOC_GETTIMEOUT: 448 case WDIOC_GETTIMEOUT:
451 return put_user(heartbeat, p); 449 return put_user(heartbeat, p);
452 } 450 default:
451 return -ENOTTY;
452 }
453} 453}
454 454
455/** 455/**