From 81af7bb77945001eb93d5cea99044f4fe8d0917a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 27 May 2009 17:50:35 +0200 Subject: [PATCH] --- yaml --- r: 150890 b: refs/heads/master c: a17c859849402315613a0015ac8fbf101acf0cc1 h: refs/heads/master v: v3 --- [refs] | 2 +- .../feature-removal-schedule.txt | 7 - trunk/Documentation/isdn/INTERFACE.CAPI | 94 +- trunk/Documentation/networking/ieee802154.txt | 76 - trunk/Documentation/networking/ip-sysctl.txt | 7 - trunk/Documentation/networking/ipv6.txt | 37 - .../powerpc/dts-bindings/can/sja1000.txt | 53 - trunk/Documentation/rfkill.txt | 603 +++++- trunk/MAINTAINERS | 25 +- trunk/arch/alpha/include/asm/errno.h | 2 - trunk/arch/arm/mach-pxa/tosa-bt.c | 30 +- trunk/arch/arm/mach-pxa/tosa.c | 1 + trunk/arch/mips/include/asm/errno.h | 2 - trunk/arch/parisc/include/asm/errno.h | 1 - trunk/arch/powerpc/include/asm/qe.h | 2 - trunk/arch/sparc/include/asm/errno.h | 2 - trunk/drivers/Makefile | 1 - trunk/drivers/block/aoe/aoecmd.c | 7 + trunk/drivers/bluetooth/hci_vhci.c | 90 +- trunk/drivers/ieee802154/Kconfig | 22 - trunk/drivers/ieee802154/Makefile | 3 - trunk/drivers/ieee802154/fakehard.c | 270 --- trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c | 4 +- .../drivers/infiniband/ulp/ipoib/ipoib_main.c | 31 +- .../infiniband/ulp/ipoib/ipoib_multicast.c | 10 +- trunk/drivers/isdn/capi/capiutil.c | 67 +- trunk/drivers/isdn/capi/kcapi.c | 8 +- trunk/drivers/isdn/hardware/avm/b1.c | 2 +- trunk/drivers/isdn/hardware/avm/b1dma.c | 2 +- trunk/drivers/isdn/hardware/avm/c4.c | 4 +- trunk/drivers/isdn/hardware/avm/t1isa.c | 2 +- trunk/drivers/isdn/hardware/mISDN/hfcpci.c | 7 +- trunk/drivers/isdn/hisax/hfc_pci.c | 41 +- trunk/drivers/isdn/hisax/hisax.h | 2 +- trunk/drivers/isdn/hysdn/hycapi.c | 4 +- trunk/drivers/isdn/i4l/isdn_tty.c | 2 +- trunk/drivers/isdn/mISDN/dsp_pipeline.c | 11 +- trunk/drivers/isdn/mISDN/tei.c | 7 +- trunk/drivers/net/3c509.c | 4 - trunk/drivers/net/Kconfig | 13 +- trunk/drivers/net/Makefile | 3 +- trunk/drivers/net/acenic.c | 1 + trunk/drivers/net/appletalk/ipddp.c | 42 +- trunk/drivers/net/arm/ep93xx_eth.c | 4 +- trunk/drivers/net/arm/ixp4xx_eth.c | 4 +- trunk/drivers/net/atl1c/atl1c_ethtool.c | 2 +- trunk/drivers/net/atl1c/atl1c_main.c | 49 +- trunk/drivers/net/atl1e/atl1e_main.c | 7 +- trunk/drivers/net/atlx/atl1.c | 9 +- trunk/drivers/net/atlx/atlx.h | 6 + trunk/drivers/net/b44.c | 4 +- trunk/drivers/net/b44.h | 1 + trunk/drivers/net/benet/be_main.c | 131 +- trunk/drivers/net/bfin_mac.c | 264 +-- trunk/drivers/net/bnx2.c | 26 +- trunk/drivers/net/bnx2x_main.c | 1 + trunk/drivers/net/bonding/bond_main.c | 3 +- trunk/drivers/net/bonding/bond_sysfs.c | 1 - trunk/drivers/net/bonding/bonding.h | 3 +- trunk/drivers/net/can/Kconfig | 9 - trunk/drivers/net/can/dev.c | 2 +- trunk/drivers/net/can/sja1000/Makefile | 1 - trunk/drivers/net/can/sja1000/ems_pci.c | 39 +- trunk/drivers/net/can/sja1000/kvaser_pci.c | 21 +- trunk/drivers/net/can/sja1000/sja1000.c | 110 +- trunk/drivers/net/can/sja1000/sja1000.h | 9 +- .../net/can/sja1000/sja1000_of_platform.c | 235 -- .../net/can/sja1000/sja1000_platform.c | 19 +- trunk/drivers/net/chelsio/sge.c | 1 + trunk/drivers/net/cpmac.c | 8 +- trunk/drivers/net/cxgb3/Makefile | 2 +- trunk/drivers/net/cxgb3/adapter.h | 6 +- trunk/drivers/net/cxgb3/ael1002.c | 823 +------ trunk/drivers/net/cxgb3/aq100x.c | 355 --- trunk/drivers/net/cxgb3/common.h | 4 - trunk/drivers/net/cxgb3/cxgb3_main.c | 89 +- trunk/drivers/net/cxgb3/cxgb3_offload.c | 27 +- trunk/drivers/net/cxgb3/cxgb3_offload.h | 3 - trunk/drivers/net/cxgb3/sge.c | 29 +- trunk/drivers/net/cxgb3/t3_hw.c | 12 - trunk/drivers/net/cxgb3/version.h | 4 +- trunk/drivers/net/davinci_emac.c | 10 +- trunk/drivers/net/declance.c | 5 - trunk/drivers/net/dl2k.c | 8 +- trunk/drivers/net/e100.c | 199 +- trunk/drivers/net/e1000/e1000_main.c | 34 +- trunk/drivers/net/e1000e/82571.c | 99 +- trunk/drivers/net/e1000e/defines.h | 25 - trunk/drivers/net/e1000e/e1000.h | 61 - trunk/drivers/net/e1000e/es2lan.c | 3 - trunk/drivers/net/e1000e/ethtool.c | 46 +- trunk/drivers/net/e1000e/hw.h | 18 +- trunk/drivers/net/e1000e/ich8lan.c | 448 +--- trunk/drivers/net/e1000e/lib.c | 38 - trunk/drivers/net/e1000e/netdev.c | 261 +-- trunk/drivers/net/e1000e/param.c | 2 - trunk/drivers/net/e1000e/phy.c | 699 +----- trunk/drivers/net/enic/enic_main.c | 2 + trunk/drivers/net/forcedeth.c | 232 +- trunk/drivers/net/fsl_pq_mdio.c | 6 +- trunk/drivers/net/gianfar.h | 2 +- trunk/drivers/net/hamachi.c | 3 +- trunk/drivers/net/igb/igb_main.c | 6 +- trunk/drivers/net/igbvf/netdev.c | 6 +- trunk/drivers/net/ioc3-eth.c | 2 +- trunk/drivers/net/irda/irda-usb.c | 40 - trunk/drivers/net/ixgb/ixgb_main.c | 5 +- trunk/drivers/net/ixgbe/ixgbe.h | 122 +- trunk/drivers/net/ixgbe/ixgbe_82598.c | 115 +- trunk/drivers/net/ixgbe/ixgbe_82599.c | 1132 +--------- trunk/drivers/net/ixgbe/ixgbe_common.c | 272 ++- trunk/drivers/net/ixgbe/ixgbe_common.h | 8 +- trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c | 2 +- trunk/drivers/net/ixgbe/ixgbe_ethtool.c | 907 +------- trunk/drivers/net/ixgbe/ixgbe_fcoe.c | 6 +- trunk/drivers/net/ixgbe/ixgbe_fcoe.h | 1 - trunk/drivers/net/ixgbe/ixgbe_main.c | 686 ++---- trunk/drivers/net/ixgbe/ixgbe_phy.c | 1 - trunk/drivers/net/ixgbe/ixgbe_type.h | 168 +- trunk/drivers/net/jme.c | 1 + trunk/drivers/net/korina.c | 14 - trunk/drivers/net/ks8842.c | 732 ------- trunk/drivers/net/mac8390.c | 31 +- trunk/drivers/net/macvlan.c | 12 +- trunk/drivers/net/mdio.c | 17 - trunk/drivers/net/mlx4/Makefile | 2 +- trunk/drivers/net/mlx4/en_main.c | 68 +- trunk/drivers/net/mlx4/en_netdev.c | 175 +- .../net/mlx4/{en_ethtool.c => en_params.c} | 67 +- trunk/drivers/net/mlx4/en_rx.c | 78 +- trunk/drivers/net/mlx4/en_tx.c | 120 +- trunk/drivers/net/mlx4/eq.c | 4 +- trunk/drivers/net/mlx4/mlx4_en.h | 49 +- trunk/drivers/net/mlx4/mr.c | 7 +- trunk/drivers/net/mv643xx_eth.c | 11 +- trunk/drivers/net/myri10ge/myri10ge.c | 1 + trunk/drivers/net/netxen/netxen_nic_init.c | 9 +- trunk/drivers/net/netxen/netxen_nic_main.c | 1 + trunk/drivers/net/niu.c | 9 +- trunk/drivers/net/ns83820.c | 6 +- trunk/drivers/net/phy/marvell.c | 1 - trunk/drivers/net/pppol2tp.c | 11 +- trunk/drivers/net/qla3xxx.c | 1 + trunk/drivers/net/qlge/qlge.h | 31 +- trunk/drivers/net/qlge/qlge_ethtool.c | 6 +- trunk/drivers/net/qlge/qlge_main.c | 134 +- trunk/drivers/net/qlge/qlge_mpi.c | 58 +- trunk/drivers/net/r6040.c | 6 +- trunk/drivers/net/r8169.c | 106 +- trunk/drivers/net/s2io.c | 23 +- trunk/drivers/net/s2io.h | 9 + trunk/drivers/net/sfc/selftest.c | 1 - trunk/drivers/net/sfc/tenxpress.c | 11 +- trunk/drivers/net/sfc/tx.c | 7 + trunk/drivers/net/sis190.c | 59 +- trunk/drivers/net/skge.c | 2 + trunk/drivers/net/sky2.c | 1 + trunk/drivers/net/smsc911x.c | 2 +- trunk/drivers/net/sundance.c | 53 +- trunk/drivers/net/tehuti.c | 14 +- trunk/drivers/net/tg3.c | 18 +- trunk/drivers/net/tulip/Kconfig | 12 - trunk/drivers/net/tulip/de2104x.c | 13 +- trunk/drivers/net/tun.c | 19 +- trunk/drivers/net/ucc_geth.c | 79 +- trunk/drivers/net/ucc_geth.h | 28 +- trunk/drivers/net/usb/hso.c | 47 +- trunk/drivers/net/usb/rtl8150.c | 9 +- trunk/drivers/net/veth.c | 2 + trunk/drivers/net/via-rhine.c | 58 +- trunk/drivers/net/via-velocity.c | 22 +- trunk/drivers/net/via-velocity.h | 1 + trunk/drivers/net/virtio_net.c | 9 +- trunk/drivers/net/vxge/vxge-config.c | 12 +- trunk/drivers/net/vxge/vxge-main.c | 6 +- trunk/drivers/net/wan/ixp4xx_hss.c | 4 +- trunk/drivers/net/wimax/i2400m/control.c | 124 +- trunk/drivers/net/wimax/i2400m/driver.c | 45 +- trunk/drivers/net/wimax/i2400m/fw.c | 58 +- trunk/drivers/net/wimax/i2400m/i2400m-sdio.h | 9 - trunk/drivers/net/wimax/i2400m/i2400m.h | 48 - trunk/drivers/net/wimax/i2400m/netdev.c | 4 +- trunk/drivers/net/wimax/i2400m/op-rfkill.c | 4 +- trunk/drivers/net/wimax/i2400m/rx.c | 10 +- trunk/drivers/net/wimax/i2400m/sdio-fw.c | 109 +- trunk/drivers/net/wimax/i2400m/sdio-rx.c | 47 +- trunk/drivers/net/wimax/i2400m/sdio.c | 68 +- trunk/drivers/net/wimax/i2400m/tx.c | 75 +- trunk/drivers/net/wimax/i2400m/usb.c | 40 +- trunk/drivers/net/wireless/Kconfig | 5 +- trunk/drivers/net/wireless/at76c50x-usb.c | 12 +- .../drivers/net/wireless/ath/ar9170/ar9170.h | 44 +- trunk/drivers/net/wireless/ath/ar9170/hw.h | 8 +- trunk/drivers/net/wireless/ath/ar9170/led.c | 17 +- trunk/drivers/net/wireless/ath/ar9170/mac.c | 55 +- trunk/drivers/net/wireless/ath/ar9170/main.c | 774 +++---- trunk/drivers/net/wireless/ath/ar9170/phy.c | 6 +- trunk/drivers/net/wireless/ath/ar9170/usb.c | 191 +- trunk/drivers/net/wireless/ath/ar9170/usb.h | 9 +- trunk/drivers/net/wireless/ath/ath5k/Makefile | 1 - trunk/drivers/net/wireless/ath/ath5k/ath5k.h | 4 - trunk/drivers/net/wireless/ath/ath5k/base.c | 31 +- trunk/drivers/net/wireless/ath/ath5k/base.h | 12 - trunk/drivers/net/wireless/ath/ath5k/reset.c | 17 + trunk/drivers/net/wireless/ath/ath5k/rfkill.c | 121 -- trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 7 +- trunk/drivers/net/wireless/ath/ath9k/beacon.c | 9 - trunk/drivers/net/wireless/ath/ath9k/debug.c | 155 +- trunk/drivers/net/wireless/ath/ath9k/debug.h | 10 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 115 +- trunk/drivers/net/wireless/ath/ath9k/pci.c | 15 + trunk/drivers/net/wireless/ath/ath9k/xmit.c | 1 - trunk/drivers/net/wireless/ath/regd.c | 29 +- trunk/drivers/net/wireless/b43/Kconfig | 7 + trunk/drivers/net/wireless/b43/Makefile | 2 +- trunk/drivers/net/wireless/b43/b43.h | 17 +- trunk/drivers/net/wireless/b43/dma.c | 2 +- trunk/drivers/net/wireless/b43/leds.c | 9 +- trunk/drivers/net/wireless/b43/main.c | 87 +- trunk/drivers/net/wireless/b43/main.h | 1 + trunk/drivers/net/wireless/b43/phy_a.c | 4 +- trunk/drivers/net/wireless/b43/phy_common.c | 17 +- trunk/drivers/net/wireless/b43/phy_common.h | 6 +- trunk/drivers/net/wireless/b43/phy_g.c | 4 +- trunk/drivers/net/wireless/b43/phy_lp.c | 2 +- trunk/drivers/net/wireless/b43/phy_n.c | 2 +- trunk/drivers/net/wireless/b43/pio.c | 2 +- trunk/drivers/net/wireless/b43/rfkill.c | 170 +- trunk/drivers/net/wireless/b43/rfkill.h | 47 +- trunk/drivers/net/wireless/b43/xmit.c | 5 +- trunk/drivers/net/wireless/b43legacy/Kconfig | 8 + trunk/drivers/net/wireless/b43legacy/Makefile | 2 +- .../net/wireless/b43legacy/b43legacy.h | 3 + trunk/drivers/net/wireless/b43legacy/leds.c | 10 +- trunk/drivers/net/wireless/b43legacy/main.c | 17 +- trunk/drivers/net/wireless/b43legacy/rfkill.c | 172 +- trunk/drivers/net/wireless/b43legacy/rfkill.h | 54 +- trunk/drivers/net/wireless/iwlwifi/Kconfig | 5 + trunk/drivers/net/wireless/iwlwifi/Makefile | 1 + .../net/wireless/iwlwifi/iwl-3945-led.c | 4 + .../net/wireless/iwlwifi/iwl-3945-rs.c | 9 +- trunk/drivers/net/wireless/iwlwifi/iwl-3945.c | 73 +- trunk/drivers/net/wireless/iwlwifi/iwl-3945.h | 11 + trunk/drivers/net/wireless/iwlwifi/iwl-4965.c | 8 + trunk/drivers/net/wireless/iwlwifi/iwl-5000.c | 16 +- trunk/drivers/net/wireless/iwlwifi/iwl-6000.c | 1 + .../drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 22 +- trunk/drivers/net/wireless/iwlwifi/iwl-agn.c | 59 +- .../net/wireless/iwlwifi/iwl-commands.h | 14 +- trunk/drivers/net/wireless/iwlwifi/iwl-core.c | 152 +- trunk/drivers/net/wireless/iwlwifi/iwl-core.h | 28 +- .../net/wireless/iwlwifi/iwl-debugfs.c | 2 + trunk/drivers/net/wireless/iwlwifi/iwl-dev.h | 14 +- .../drivers/net/wireless/iwlwifi/iwl-eeprom.c | 12 +- trunk/drivers/net/wireless/iwlwifi/iwl-led.c | 4 + .../drivers/net/wireless/iwlwifi/iwl-rfkill.c | 144 ++ .../drivers/net/wireless/iwlwifi/iwl-rfkill.h | 48 + trunk/drivers/net/wireless/iwlwifi/iwl-sta.c | 56 +- trunk/drivers/net/wireless/iwlwifi/iwl-sta.h | 7 +- .../net/wireless/iwlwifi/iwl3945-base.c | 269 ++- .../drivers/net/wireless/iwmc3200wifi/Kconfig | 3 +- .../net/wireless/iwmc3200wifi/Makefile | 2 +- .../net/wireless/iwmc3200wifi/cfg80211.c | 2 +- trunk/drivers/net/wireless/iwmc3200wifi/fw.c | 2 +- trunk/drivers/net/wireless/iwmc3200wifi/iwm.h | 4 + .../net/wireless/iwmc3200wifi/netdev.c | 10 + .../net/wireless/iwmc3200wifi/rfkill.c | 88 + .../drivers/net/wireless/iwmc3200wifi/sdio.c | 2 +- trunk/drivers/net/wireless/libertas/11d.c | 26 +- trunk/drivers/net/wireless/libertas/11d.h | 29 +- trunk/drivers/net/wireless/libertas/assoc.c | 758 ++++--- trunk/drivers/net/wireless/libertas/assoc.h | 13 + trunk/drivers/net/wireless/libertas/cmd.c | 16 +- trunk/drivers/net/wireless/libertas/cmdresp.c | 17 +- trunk/drivers/net/wireless/libertas/debugfs.c | 8 +- trunk/drivers/net/wireless/libertas/dev.h | 10 +- trunk/drivers/net/wireless/libertas/hostcmd.h | 41 +- trunk/drivers/net/wireless/libertas/if_sdio.c | 76 +- trunk/drivers/net/wireless/libertas/if_spi.c | 126 +- trunk/drivers/net/wireless/libertas/main.c | 20 + trunk/drivers/net/wireless/libertas/scan.c | 63 +- trunk/drivers/net/wireless/libertas/types.h | 150 +- trunk/drivers/net/wireless/mac80211_hwsim.c | 27 +- trunk/drivers/net/wireless/p54/p54common.c | 46 +- trunk/drivers/net/wireless/p54/p54usb.c | 4 +- trunk/drivers/net/wireless/rndis_wlan.c | 292 +-- trunk/drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- trunk/drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- trunk/drivers/net/wireless/rt2x00/rt2500usb.c | 2 +- trunk/drivers/net/wireless/rt2x00/rt2800usb.c | 12 - trunk/drivers/net/wireless/rt2x00/rt2x00.h | 5 - .../net/wireless/rt2x00/rt2x00config.c | 3 - trunk/drivers/net/wireless/rt2x00/rt61pci.c | 2 +- trunk/drivers/net/wireless/rt2x00/rt73usb.c | 2 +- .../net/wireless/rtl818x/rtl8187_dev.c | 9 +- trunk/drivers/net/wireless/wavelan.c | 4 + trunk/drivers/net/wireless/wavelan_cs.c | 5 + trunk/drivers/net/yellowfin.c | 3 +- trunk/drivers/platform/x86/Kconfig | 14 +- trunk/drivers/platform/x86/acer-wmi.c | 51 +- trunk/drivers/platform/x86/dell-laptop.c | 101 +- trunk/drivers/platform/x86/eeepc-laptop.c | 99 +- trunk/drivers/platform/x86/hp-wmi.c | 99 +- trunk/drivers/platform/x86/sony-laptop.c | 189 +- trunk/drivers/platform/x86/thinkpad_acpi.c | 876 ++++---- trunk/drivers/platform/x86/toshiba_acpi.c | 159 +- trunk/drivers/s390/net/qeth_core_main.c | 4 +- trunk/drivers/s390/net/qeth_l2_main.c | 6 +- trunk/drivers/s390/net/qeth_l3_main.c | 9 +- trunk/drivers/scsi/fcoe/fcoe.c | 16 +- trunk/drivers/usb/gadget/f_phonet.c | 21 +- trunk/firmware/Makefile | 2 +- trunk/firmware/WHENCE | 2 +- trunk/firmware/cis/.gitignore | 1 - trunk/firmware/cxgb3/t3fw-7.1.0.bin.ihex | 1885 ++++++++++++++++ trunk/firmware/cxgb3/t3fw-7.4.0.bin.ihex | 1917 ----------------- trunk/include/asm-generic/errno.h | 2 - trunk/include/linux/Kbuild | 1 - trunk/include/linux/can/platform/sja1000.h | 3 - trunk/include/linux/ethtool.h | 8 +- trunk/include/linux/ieee80211.h | 1 - trunk/include/linux/if_arp.h | 2 - trunk/include/linux/if_ether.h | 1 - trunk/include/linux/in.h | 1 - trunk/include/linux/ipv6.h | 6 - trunk/include/linux/isdn/capilli.h | 2 +- trunk/include/linux/mISDNhw.h | 10 + trunk/include/linux/mdio.h | 9 - trunk/include/linux/netdevice.h | 48 +- .../linux/netfilter/nf_conntrack_tcp.h | 4 - .../linux/netfilter/nfnetlink_conntrack.h | 1 + trunk/include/linux/nl802154.h | 119 - trunk/include/linux/notifier.h | 1 - trunk/include/linux/pci_ids.h | 38 + trunk/include/linux/rfkill.h | 371 +--- trunk/include/linux/sctp.h | 20 +- trunk/include/linux/skbuff.h | 53 +- trunk/include/linux/socket.h | 4 +- trunk/include/linux/spi/libertas_spi.h | 3 + trunk/include/linux/wimax.h | 7 +- trunk/include/linux/wimax/i2400m.h | 2 +- trunk/include/net/bluetooth/bluetooth.h | 15 + trunk/include/net/bluetooth/hci_core.h | 2 - trunk/include/net/bluetooth/l2cap.h | 71 +- trunk/include/net/cfg80211.h | 51 - trunk/include/net/dst.h | 12 +- trunk/include/net/ieee802154/af_ieee802154.h | 60 - trunk/include/net/ieee802154/mac_def.h | 160 -- trunk/include/net/ieee802154/netdevice.h | 115 - trunk/include/net/ieee802154/nl802154.h | 41 - trunk/include/net/inet6_hashtables.h | 2 +- trunk/include/net/inet_hashtables.h | 2 +- trunk/include/net/inet_sock.h | 3 +- trunk/include/net/ip6_route.h | 2 +- trunk/include/net/mac80211.h | 29 +- trunk/include/net/netlink.h | 9 + trunk/include/net/pkt_sched.h | 7 +- trunk/include/net/route.h | 2 +- trunk/include/net/sctp/structs.h | 6 +- trunk/include/net/sctp/user.h | 2 - trunk/include/net/sock.h | 6 +- trunk/include/net/wimax.h | 8 +- trunk/include/net/xfrm.h | 4 +- trunk/net/8021q/vlan.c | 6 +- trunk/net/8021q/vlan_dev.c | 10 +- trunk/net/Kconfig | 1 - trunk/net/Makefile | 1 - trunk/net/appletalk/ddp.c | 31 +- trunk/net/atm/br2684.c | 28 +- trunk/net/atm/clip.c | 42 +- trunk/net/bluetooth/cmtp/capi.c | 2 +- trunk/net/bluetooth/hci_core.c | 41 +- trunk/net/bluetooth/hci_sysfs.c | 6 + trunk/net/bluetooth/l2cap.c | 117 +- trunk/net/bluetooth/rfcomm/core.c | 12 +- trunk/net/bridge/br_fdb.c | 2 +- trunk/net/bridge/br_netfilter.c | 33 +- trunk/net/can/af_can.c | 2 - trunk/net/core/datagram.c | 181 +- trunk/net/core/dev.c | 230 +- trunk/net/core/iovec.c | 4 +- trunk/net/core/neighbour.c | 57 +- trunk/net/core/pktgen.c | 6 +- trunk/net/core/skb_dma_map.c | 13 +- trunk/net/core/skbuff.c | 241 ++- trunk/net/core/sock.c | 135 +- trunk/net/core/user_dma.c | 46 +- trunk/net/dccp/ipv4.c | 10 +- trunk/net/dccp/ipv6.c | 8 +- trunk/net/dccp/output.c | 2 +- trunk/net/decnet/af_decnet.c | 25 +- trunk/net/decnet/dn_neigh.c | 8 +- trunk/net/decnet/dn_nsp_out.c | 14 +- trunk/net/decnet/dn_route.c | 25 +- trunk/net/dsa/slave.c | 10 +- trunk/net/econet/af_econet.c | 18 +- trunk/net/ieee802154/Kconfig | 12 - trunk/net/ieee802154/Makefile | 5 - trunk/net/ieee802154/af802154.h | 36 - trunk/net/ieee802154/af_ieee802154.c | 372 ---- trunk/net/ieee802154/dgram.c | 394 ---- trunk/net/ieee802154/netlink.c | 523 ----- trunk/net/ieee802154/nl_policy.c | 52 - trunk/net/ieee802154/raw.c | 254 --- trunk/net/ipv4/af_inet.c | 2 +- trunk/net/ipv4/arp.c | 6 +- trunk/net/ipv4/icmp.c | 20 +- trunk/net/ipv4/igmp.c | 8 +- trunk/net/ipv4/ip_forward.c | 6 +- trunk/net/ipv4/ip_fragment.c | 6 +- trunk/net/ipv4/ip_gre.c | 28 +- trunk/net/ipv4/ip_input.c | 8 +- trunk/net/ipv4/ip_options.c | 18 +- trunk/net/ipv4/ip_output.c | 37 +- trunk/net/ipv4/ip_sockglue.c | 86 +- trunk/net/ipv4/ipip.c | 16 +- trunk/net/ipv4/ipmr.c | 19 +- trunk/net/ipv4/netfilter.c | 28 +- trunk/net/ipv4/netfilter/ipt_MASQUERADE.c | 2 +- trunk/net/ipv4/netfilter/ipt_REJECT.c | 7 +- trunk/net/ipv4/netfilter/nf_nat_helper.c | 4 +- trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c | 5 +- trunk/net/ipv4/netfilter/nf_nat_standalone.c | 7 +- trunk/net/ipv4/raw.c | 2 +- trunk/net/ipv4/route.c | 43 +- trunk/net/ipv4/tcp.c | 17 +- trunk/net/ipv4/tcp_input.c | 98 +- trunk/net/ipv4/tcp_ipv4.c | 8 +- trunk/net/ipv4/tcp_output.c | 2 +- trunk/net/ipv4/tcp_vegas.c | 11 +- trunk/net/ipv4/udp.c | 4 +- trunk/net/ipv4/xfrm4_input.c | 2 +- trunk/net/ipv4/xfrm4_mode_tunnel.c | 4 +- trunk/net/ipv4/xfrm4_output.c | 6 +- trunk/net/ipv6/addrconf.c | 83 +- trunk/net/ipv6/af_inet6.c | 22 +- trunk/net/ipv6/exthdrs.c | 40 +- trunk/net/ipv6/inet6_connection_sock.c | 2 +- trunk/net/ipv6/ip6_input.c | 12 +- trunk/net/ipv6/ip6_output.c | 67 +- trunk/net/ipv6/ip6_tunnel.c | 26 +- trunk/net/ipv6/ip6mr.c | 13 +- trunk/net/ipv6/mcast.c | 17 +- trunk/net/ipv6/ndisc.c | 12 +- trunk/net/ipv6/netfilter.c | 16 +- trunk/net/ipv6/netfilter/ip6t_REJECT.c | 2 +- trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 4 +- trunk/net/ipv6/raw.c | 2 +- trunk/net/ipv6/reassembly.c | 26 +- trunk/net/ipv6/route.c | 12 +- trunk/net/ipv6/sit.c | 21 +- trunk/net/ipv6/tcp_ipv6.c | 8 +- trunk/net/ipv6/udp.c | 7 +- trunk/net/ipv6/xfrm6_mode_tunnel.c | 4 +- trunk/net/ipv6/xfrm6_output.c | 4 +- trunk/net/irda/irlap_frame.c | 18 +- trunk/net/llc/llc_conn.c | 4 + trunk/net/mac80211/Kconfig | 5 +- trunk/net/mac80211/agg-tx.c | 6 +- trunk/net/mac80211/cfg.c | 69 +- trunk/net/mac80211/driver-ops.h | 7 - trunk/net/mac80211/ieee80211_i.h | 5 - trunk/net/mac80211/iface.c | 4 +- trunk/net/mac80211/main.c | 81 +- trunk/net/mac80211/mlme.c | 57 +- trunk/net/mac80211/rc80211_minstrel.c | 2 +- trunk/net/mac80211/rx.c | 27 +- trunk/net/mac80211/sta_info.c | 9 - trunk/net/mac80211/tx.c | 21 +- trunk/net/mac80211/util.c | 56 +- trunk/net/mac80211/wext.c | 80 +- trunk/net/mac80211/wme.c | 2 +- trunk/net/netfilter/ipvs/ip_vs_xmit.c | 48 +- trunk/net/netfilter/nf_conntrack_netbios_ns.c | 2 +- trunk/net/netfilter/nf_conntrack_proto_dccp.c | 11 +- trunk/net/netfilter/nf_conntrack_proto_gre.c | 2 +- trunk/net/netfilter/nf_conntrack_proto_tcp.c | 18 - trunk/net/netfilter/nfnetlink_log.c | 6 - trunk/net/netfilter/nfnetlink_queue.c | 4 +- trunk/net/netfilter/xt_TCPMSS.c | 6 +- trunk/net/netfilter/xt_hashlimit.c | 2 +- trunk/net/netfilter/xt_policy.c | 2 +- trunk/net/netfilter/xt_realm.c | 2 +- trunk/net/packet/af_packet.c | 10 +- trunk/net/phonet/pep-gprs.c | 9 +- trunk/net/phonet/pep.c | 4 +- trunk/net/rfkill/Kconfig | 21 +- trunk/net/rfkill/Makefile | 5 +- trunk/net/rfkill/core.c | 1205 ----------- trunk/net/rfkill/input.c | 342 --- trunk/net/rfkill/rfkill-input.c | 390 ++++ trunk/net/rfkill/{rfkill.h => rfkill-input.h} | 10 +- trunk/net/rfkill/rfkill.c | 855 ++++++++ trunk/net/sched/cls_api.c | 23 +- trunk/net/sched/cls_cgroup.c | 22 +- trunk/net/sched/cls_flow.c | 8 +- trunk/net/sched/cls_route.c | 2 +- trunk/net/sched/em_meta.c | 8 +- trunk/net/sched/sch_hfsc.c | 8 +- trunk/net/sched/sch_sfq.c | 2 +- trunk/net/sched/sch_teql.c | 6 +- trunk/net/sctp/associola.c | 64 +- trunk/net/sctp/input.c | 4 +- trunk/net/sctp/output.c | 6 +- trunk/net/sctp/protocol.c | 10 +- trunk/net/sctp/sm_make_chunk.c | 16 +- trunk/net/sctp/sm_sideeffect.c | 8 +- trunk/net/sctp/sm_statefuns.c | 14 +- trunk/net/sctp/sm_statetable.c | 2 +- trunk/net/sctp/socket.c | 48 +- trunk/net/sctp/sysctl.c | 6 +- trunk/net/sctp/ulpevent.c | 7 +- trunk/net/sunrpc/auth_gss/auth_gss.c | 1 - trunk/net/sunrpc/xprtsock.c | 2 +- trunk/net/wimax/Kconfig | 15 +- trunk/net/wimax/Makefile | 1 - trunk/net/wimax/debug-levels.h | 1 - trunk/net/wimax/debugfs.c | 1 - trunk/net/wimax/op-msg.c | 17 +- trunk/net/wimax/op-rfkill.c | 124 +- trunk/net/wimax/op-state-get.c | 86 - trunk/net/wimax/stack.c | 5 +- trunk/net/wireless/Kconfig | 3 +- trunk/net/wireless/core.c | 108 +- trunk/net/wireless/core.h | 7 - trunk/net/wireless/nl80211.c | 57 +- trunk/net/wireless/reg.c | 15 +- trunk/net/wireless/scan.c | 3 +- trunk/net/wireless/util.c | 13 +- trunk/net/wireless/wext-compat.c | 83 - trunk/net/xfrm/xfrm_algo.c | 41 +- trunk/net/xfrm/xfrm_input.c | 3 +- trunk/net/xfrm/xfrm_output.c | 21 +- trunk/net/xfrm/xfrm_policy.c | 8 +- trunk/security/selinux/hooks.c | 2 +- trunk/security/selinux/xfrm.c | 2 +- 536 files changed, 11575 insertions(+), 21097 deletions(-) delete mode 100644 trunk/Documentation/networking/ieee802154.txt delete mode 100644 trunk/Documentation/powerpc/dts-bindings/can/sja1000.txt delete mode 100644 trunk/drivers/ieee802154/Kconfig delete mode 100644 trunk/drivers/ieee802154/Makefile delete mode 100644 trunk/drivers/ieee802154/fakehard.c delete mode 100644 trunk/drivers/net/can/sja1000/sja1000_of_platform.c delete mode 100644 trunk/drivers/net/cxgb3/aq100x.c delete mode 100644 trunk/drivers/net/ks8842.c rename trunk/drivers/net/mlx4/{en_ethtool.c => en_params.c} (86%) delete mode 100644 trunk/drivers/net/wireless/ath/ath5k/rfkill.c create mode 100644 trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c create mode 100644 trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h create mode 100644 trunk/drivers/net/wireless/iwmc3200wifi/rfkill.c delete mode 100644 trunk/firmware/cis/.gitignore create mode 100644 trunk/firmware/cxgb3/t3fw-7.1.0.bin.ihex delete mode 100644 trunk/firmware/cxgb3/t3fw-7.4.0.bin.ihex delete mode 100644 trunk/include/linux/nl802154.h delete mode 100644 trunk/include/net/ieee802154/af_ieee802154.h delete mode 100644 trunk/include/net/ieee802154/mac_def.h delete mode 100644 trunk/include/net/ieee802154/netdevice.h delete mode 100644 trunk/include/net/ieee802154/nl802154.h delete mode 100644 trunk/net/ieee802154/Kconfig delete mode 100644 trunk/net/ieee802154/Makefile delete mode 100644 trunk/net/ieee802154/af802154.h delete mode 100644 trunk/net/ieee802154/af_ieee802154.c delete mode 100644 trunk/net/ieee802154/dgram.c delete mode 100644 trunk/net/ieee802154/netlink.c delete mode 100644 trunk/net/ieee802154/nl_policy.c delete mode 100644 trunk/net/ieee802154/raw.c delete mode 100644 trunk/net/rfkill/core.c delete mode 100644 trunk/net/rfkill/input.c create mode 100644 trunk/net/rfkill/rfkill-input.c rename trunk/net/rfkill/{rfkill.h => rfkill-input.h} (60%) create mode 100644 trunk/net/rfkill/rfkill.c delete mode 100644 trunk/net/wimax/op-state-get.c diff --git a/[refs] b/[refs] index bb849613f260..5c2b1c470f03 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 17d0cdfa8f3c09a110061c67421d662b3e149d0a +refs/heads/master: a17c859849402315613a0015ac8fbf101acf0cc1 diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index edb2f0b07616..de491a3e2313 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -437,10 +437,3 @@ Why: Superseded by tdfxfb. I2C/DDC support used to live in a separate driver but this caused driver conflicts. Who: Jean Delvare Krzysztof Helt - ---------------------------- - -What: CONFIG_RFKILL_INPUT -When: 2.6.33 -Why: Should be implemented in userspace, policy daemon. -Who: Johannes Berg diff --git a/trunk/Documentation/isdn/INTERFACE.CAPI b/trunk/Documentation/isdn/INTERFACE.CAPI index 686e107923ec..786d619b36e5 100644 --- a/trunk/Documentation/isdn/INTERFACE.CAPI +++ b/trunk/Documentation/isdn/INTERFACE.CAPI @@ -45,7 +45,7 @@ From then on, Kernel CAPI may call the registered callback functions for the device. If the device becomes unusable for any reason (shutdown, disconnect ...), the -driver has to call capi_ctr_down(). This will prevent further calls to the +driver has to call capi_ctr_reseted(). This will prevent further calls to the callback functions by Kernel CAPI. @@ -114,36 +114,20 @@ char *driver_name int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata) (optional) pointer to a callback function for sending firmware and configuration data to the device - Return value: 0 on success, error code on error - Called in process context. void (*reset_ctr)(struct capi_ctr *ctrlr) - (optional) pointer to a callback function for performing a reset on - the device, releasing all registered applications - Called in process context. + pointer to a callback function for performing a reset on the device, + releasing all registered applications void (*register_appl)(struct capi_ctr *ctrlr, u16 applid, capi_register_params *rparam) void (*release_appl)(struct capi_ctr *ctrlr, u16 applid) pointers to callback functions for registration and deregistration of applications with the device - Calls to these functions are serialized by Kernel CAPI so that only - one call to any of them is active at any time. u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb) pointer to a callback function for sending a CAPI message to the device - Return value: CAPI error code - If the method returns 0 (CAPI_NOERROR) the driver has taken ownership - of the skb and the caller may no longer access it. If it returns a - non-zero (error) value then ownership of the skb returns to the caller - who may reuse or free it. - The return value should only be used to signal problems with respect - to accepting or queueing the message. Errors occurring during the - actual processing of the message should be signaled with an - appropriate reply message. - Calls to this function are not serialized by Kernel CAPI, ie. it must - be prepared to be re-entered. char *(*procinfo)(struct capi_ctr *ctrlr) pointer to a callback function returning the entry for the device in @@ -154,8 +138,6 @@ read_proc_t *ctr_read_proc system entry, /proc/capi/controllers/; will be called with a pointer to the device's capi_ctr structure as the last (data) argument -Note: Callback functions are never called in interrupt context. - - to be filled in before calling capi_ctr_ready(): u8 manu[CAPI_MANUFACTURER_LEN] @@ -171,45 +153,6 @@ u8 serial[CAPI_SERIAL_LEN] value to return for CAPI_GET_SERIAL -4.3 The _cmsg Structure - -(declared in ) - -The _cmsg structure stores the contents of a CAPI 2.0 message in an easily -accessible form. It contains members for all possible CAPI 2.0 parameters, of -which only those appearing in the message type currently being processed are -actually used. Unused members should be set to zero. - -Members are named after the CAPI 2.0 standard names of the parameters they -represent. See for the exact spelling. Member data -types are: - -u8 for CAPI parameters of type 'byte' - -u16 for CAPI parameters of type 'word' - -u32 for CAPI parameters of type 'dword' - -_cstruct for CAPI parameters of type 'struct' not containing any - variably-sized (struct) subparameters (eg. 'Called Party Number') - The member is a pointer to a buffer containing the parameter in - CAPI encoding (length + content). It may also be NULL, which will - be taken to represent an empty (zero length) parameter. - -_cmstruct for CAPI parameters of type 'struct' containing 'struct' - subparameters ('Additional Info' and 'B Protocol') - The representation is a single byte containing one of the values: - CAPI_DEFAULT: the parameter is empty - CAPI_COMPOSE: the values of the subparameters are stored - individually in the corresponding _cmsg structure members - -Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert -messages between their transport encoding described in the CAPI 2.0 standard -and their _cmsg structure representation. Note that capi_cmsg2message() does -not know or check the size of its destination buffer. The caller must make -sure it is big enough to accomodate the resulting CAPI message. - - 5. Lower Layer Interface Functions (declared in ) @@ -223,7 +166,7 @@ int detach_capi_ctr(struct capi_ctr *ctrlr) register/unregister a device (controller) with Kernel CAPI void capi_ctr_ready(struct capi_ctr *ctrlr) -void capi_ctr_down(struct capi_ctr *ctrlr) +void capi_ctr_reseted(struct capi_ctr *ctrlr) signal controller ready/not ready void capi_ctr_suspend_output(struct capi_ctr *ctrlr) @@ -268,32 +211,3 @@ CAPIMSG_CONTROL(m) CAPIMSG_SETCONTROL(m, contr) Controller/PLCI/NCCI (u32) CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16) - -Library functions for working with _cmsg structures -(from ): - -unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg) - Assembles a CAPI 2.0 message from the parameters in *cmsg, storing the - result in *msg. - -unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg) - Disassembles the CAPI 2.0 message in *msg, storing the parameters in - *cmsg. - -unsigned capi_cmsg_header(_cmsg *cmsg, u16 ApplId, u8 Command, u8 Subcommand, - u16 Messagenumber, u32 Controller) - Fills the header part and address field of the _cmsg structure *cmsg - with the given values, zeroing the remainder of the structure so only - parameters with non-default values need to be changed before sending - the message. - -void capi_cmsg_answer(_cmsg *cmsg) - Sets the low bit of the Subcommand field in *cmsg, thereby converting - _REQ to _CONF and _IND to _RESP. - -char *capi_cmd2str(u8 Command, u8 Subcommand) - Returns the CAPI 2.0 message name corresponding to the given command - and subcommand values, as a static ASCII string. The return value may - be NULL if the command/subcommand is not one of those defined in the - CAPI 2.0 standard. - diff --git a/trunk/Documentation/networking/ieee802154.txt b/trunk/Documentation/networking/ieee802154.txt deleted file mode 100644 index a0280ad2edc9..000000000000 --- a/trunk/Documentation/networking/ieee802154.txt +++ /dev/null @@ -1,76 +0,0 @@ - - Linux IEEE 802.15.4 implementation - - -Introduction -============ - -The Linux-ZigBee project goal is to provide complete implementation -of IEEE 802.15.4 / ZigBee / 6LoWPAN protocols. IEEE 802.15.4 is a stack -of protocols for organizing Low-Rate Wireless Personal Area Networks. - -Currently only IEEE 802.15.4 layer is implemented. We have choosen -to use plain Berkeley socket API, the generic Linux networking stack -to transfer IEEE 802.15.4 messages and a special protocol over genetlink -for configuration/management - - -Socket API -========== - -int sd = socket(PF_IEEE802154, SOCK_DGRAM, 0); -..... - -The address family, socket addresses etc. are defined in the -include/net/ieee802154/af_ieee802154.h header or in the special header -in our userspace package (see either linux-zigbee sourceforge download page -or git tree at git://linux-zigbee.git.sourceforge.net/gitroot/linux-zigbee). - -One can use SOCK_RAW for passing raw data towards device xmit function. YMMV. - - -MLME - MAC Level Management -============================ - -Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands. -See the include/net/ieee802154/nl802154.h header. Our userspace tools package -(see above) provides CLI configuration utility for radio interfaces and simple -coordinator for IEEE 802.15.4 networks as an example users of MLME protocol. - - -Kernel side -============= - -Like with WiFi, there are several types of devices implementing IEEE 802.15.4. -1) 'HardMAC'. The MAC layer is implemented in the device itself, the device - exports MLME and data API. -2) 'SoftMAC' or just radio. These types of devices are just radio transceivers - possibly with some kinds of acceleration like automatic CRC computation and - comparation, automagic ACK handling, address matching, etc. - -Those types of devices require different approach to be hooked into Linux kernel. - - -HardMAC -======= - -See the header include/net/ieee802154/netdevice.h. You have to implement Linux -net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family -code via plain sk_buffs. The control block of sk_buffs will contain additional -info as described in the struct ieee802154_mac_cb. - -To hook the MLME interface you have to populate the ml_priv field of your -net_device with a pointer to struct ieee802154_mlme_ops instance. All fields are -required. - -We provide an example of simple HardMAC driver at drivers/ieee802154/fakehard.c - - -SoftMAC -======= - -We are going to provide intermediate layer impelementing IEEE 802.15.4 MAC -in software. This is currently WIP. - -See header include/net/ieee802154/mac802154.h and several drivers in -drivers/ieee802154/ diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index 8be76235fe67..3ffd233c369c 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -1057,13 +1057,6 @@ disable_ipv6 - BOOLEAN address. Default: FALSE (enable IPv6 operation) - When this value is changed from 1 to 0 (IPv6 is being enabled), - it will dynamically create a link-local address on the given - interface and start Duplicate Address Detection, if necessary. - - When this value is changed from 0 to 1 (IPv6 is being disabled), - it will dynamically delete all address on the given interface. - accept_dad - INTEGER Whether to accept DAD (Duplicate Address Detection). 0: Disable DAD diff --git a/trunk/Documentation/networking/ipv6.txt b/trunk/Documentation/networking/ipv6.txt index 9fd7e21296c8..268e5c103dd8 100644 --- a/trunk/Documentation/networking/ipv6.txt +++ b/trunk/Documentation/networking/ipv6.txt @@ -33,40 +33,3 @@ disable A reboot is required to enable IPv6. -autoconf - - Specifies whether to enable IPv6 address autoconfiguration - on all interfaces. This might be used when one does not wish - for addresses to be automatically generated from prefixes - received in Router Advertisements. - - The possible values and their effects are: - - 0 - IPv6 address autoconfiguration is disabled on all interfaces. - - Only the IPv6 loopback address (::1) and link-local addresses - will be added to interfaces. - - 1 - IPv6 address autoconfiguration is enabled on all interfaces. - - This is the default value. - -disable_ipv6 - - Specifies whether to disable IPv6 on all interfaces. - This might be used when no IPv6 addresses are desired. - - The possible values and their effects are: - - 0 - IPv6 is enabled on all interfaces. - - This is the default value. - - 1 - IPv6 is disabled on all interfaces. - - No IPv6 addresses will be added to interfaces. - diff --git a/trunk/Documentation/powerpc/dts-bindings/can/sja1000.txt b/trunk/Documentation/powerpc/dts-bindings/can/sja1000.txt deleted file mode 100644 index d6d209ded937..000000000000 --- a/trunk/Documentation/powerpc/dts-bindings/can/sja1000.txt +++ /dev/null @@ -1,53 +0,0 @@ -Memory mapped SJA1000 CAN controller from NXP (formerly Philips) - -Required properties: - -- compatible : should be "nxp,sja1000". - -- reg : should specify the chip select, address offset and size required - to map the registers of the SJA1000. The size is usually 0x80. - -- interrupts: property with a value describing the interrupt source - (number and sensitivity) required for the SJA1000. - -Optional properties: - -- nxp,external-clock-frequency : Frequency of the external oscillator - clock in Hz. Note that the internal clock frequency used by the - SJA1000 is half of that value. If not specified, a default value - of 16000000 (16 MHz) is used. - -- nxp,tx-output-mode : operation mode of the TX output control logic: - <0x0> : bi-phase output mode - <0x1> : normal output mode (default) - <0x2> : test output mode - <0x3> : clock output mode - -- nxp,tx-output-config : TX output pin configuration: - <0x01> : TX0 invert - <0x02> : TX0 pull-down (default) - <0x04> : TX0 pull-up - <0x06> : TX0 push-pull - <0x08> : TX1 invert - <0x10> : TX1 pull-down - <0x20> : TX1 pull-up - <0x30> : TX1 push-pull - -- nxp,clock-out-frequency : clock frequency in Hz on the CLKOUT pin. - If not specified or if the specified value is 0, the CLKOUT pin - will be disabled. - -- nxp,no-comparator-bypass : Allows to disable the CAN input comperator. - -For futher information, please have a look to the SJA1000 data sheet. - -Examples: - -can@3,100 { - compatible = "nxp,sja1000"; - reg = <3 0x100 0x80>; - interrupts = <2 0>; - interrupt-parent = <&mpic>; - nxp,external-clock-frequency = <16000000>; -}; - diff --git a/trunk/Documentation/rfkill.txt b/trunk/Documentation/rfkill.txt index 1b74b5f30af4..40c3a3f10816 100644 --- a/trunk/Documentation/rfkill.txt +++ b/trunk/Documentation/rfkill.txt @@ -1,136 +1,571 @@ -rfkill - RF kill switch support -=============================== +rfkill - RF switch subsystem support +==================================== -1. Introduction -2. Implementation details -3. Kernel driver guidelines -4. Kernel API -5. Userspace support +1 Introduction +2 Implementation details +3 Kernel driver guidelines +3.1 wireless device drivers +3.2 platform/switch drivers +3.3 input device drivers +4 Kernel API +5 Userspace support -1. Introduction +1. Introduction: -The rfkill subsystem provides a generic interface to disabling any radio -transmitter in the system. When a transmitter is blocked, it shall not -radiate any power. +The rfkill switch subsystem exists to add a generic interface to circuitry that +can enable or disable the signal output of a wireless *transmitter* of any +type. By far, the most common use is to disable radio-frequency transmitters. -The subsystem also provides the ability to react on button presses and -disable all transmitters of a certain type (or all). This is intended for -situations where transmitters need to be turned off, for example on -aircraft. +Note that disabling the signal output means that the the transmitter is to be +made to not emit any energy when "blocked". rfkill is not about blocking data +transmissions, it is about blocking energy emission. +The rfkill subsystem offers support for keys and switches often found on +laptops to enable wireless devices like WiFi and Bluetooth, so that these keys +and switches actually perform an action in all wireless devices of a given type +attached to the system. +The buttons to enable and disable the wireless transmitters are important in +situations where the user is for example using his laptop on a location where +radio-frequency transmitters _must_ be disabled (e.g. airplanes). -2. Implementation details +Because of this requirement, userspace support for the keys should not be made +mandatory. Because userspace might want to perform some additional smarter +tasks when the key is pressed, rfkill provides userspace the possibility to +take over the task to handle the key events. + +=============================================================================== +2: Implementation details The rfkill subsystem is composed of various components: the rfkill class, the rfkill-input module (an input layer handler), and some specific input layer events. -The rfkill class is provided for kernel drivers to register their radio -transmitter with the kernel, provide methods for turning it on and off and, -optionally, letting the system know about hardware-disabled states that may -be implemented on the device. This code is enabled with the CONFIG_RFKILL -Kconfig option, which drivers can "select". +The rfkill class provides kernel drivers with an interface that allows them to +know when they should enable or disable a wireless network device transmitter. +This is enabled by the CONFIG_RFKILL Kconfig option. + +The rfkill class support makes sure userspace will be notified of all state +changes on rfkill devices through uevents. It provides a notification chain +for interested parties in the kernel to also get notified of rfkill state +changes in other drivers. It creates several sysfs entries which can be used +by userspace. See section "Userspace support". + +The rfkill-input module provides the kernel with the ability to implement a +basic response when the user presses a key or button (or toggles a switch) +related to rfkill functionality. It is an in-kernel implementation of default +policy of reacting to rfkill-related input events and neither mandatory nor +required for wireless drivers to operate. It is enabled by the +CONFIG_RFKILL_INPUT Kconfig option. + +rfkill-input is a rfkill-related events input layer handler. This handler will +listen to all rfkill key events and will change the rfkill state of the +wireless devices accordingly. With this option enabled userspace could either +do nothing or simply perform monitoring tasks. + +The rfkill-input module also provides EPO (emergency power-off) functionality +for all wireless transmitters. This function cannot be overridden, and it is +always active. rfkill EPO is related to *_RFKILL_ALL input layer events. + + +Important terms for the rfkill subsystem: + +In order to avoid confusion, we avoid the term "switch" in rfkill when it is +referring to an electronic control circuit that enables or disables a +transmitter. We reserve it for the physical device a human manipulates +(which is an input device, by the way): + +rfkill switch: + + A physical device a human manipulates. Its state can be perceived by + the kernel either directly (through a GPIO pin, ACPI GPE) or by its + effect on a rfkill line of a wireless device. + +rfkill controller: + + A hardware circuit that controls the state of a rfkill line, which a + kernel driver can interact with *to modify* that state (i.e. it has + either write-only or read/write access). + +rfkill line: + + An input channel (hardware or software) of a wireless device, which + causes a wireless transmitter to stop emitting energy (BLOCK) when it + is active. Point of view is extremely important here: rfkill lines are + always seen from the PoV of a wireless device (and its driver). + +soft rfkill line/software rfkill line: + + A rfkill line the wireless device driver can directly change the state + of. Related to rfkill_state RFKILL_STATE_SOFT_BLOCKED. + +hard rfkill line/hardware rfkill line: + + A rfkill line that works fully in hardware or firmware, and that cannot + be overridden by the kernel driver. The hardware device or the + firmware just exports its status to the driver, but it is read-only. + Related to rfkill_state RFKILL_STATE_HARD_BLOCKED. + +The enum rfkill_state describes the rfkill state of a transmitter: + +When a rfkill line or rfkill controller is in the RFKILL_STATE_UNBLOCKED state, +the wireless transmitter (radio TX circuit for example) is *enabled*. When the +it is in the RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the +wireless transmitter is to be *blocked* from operating. + +RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change +that state. RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio() +will not be able to change the state and will return with a suitable error if +attempts are made to set the state to RFKILL_STATE_UNBLOCKED. + +RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is +locked in the BLOCKED state by a hardwire rfkill line (typically an input pin +that, when active, forces the transmitter to be disabled) which the driver +CANNOT override. + +Full rfkill functionality requires two different subsystems to cooperate: the +input layer and the rfkill class. The input layer issues *commands* to the +entire system requesting that devices registered to the rfkill class change +state. The way this interaction happens is not complex, but it is not obvious +either: + +Kernel Input layer: + + * Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and + other such events when the user presses certain keys, buttons, or + toggles certain physical switches. + + THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE + KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT. It is + used to issue *commands* for the system to change behaviour, and these + commands may or may not be carried out by some kernel driver or + userspace application. It follows that doing user feedback based only + on input events is broken, as there is no guarantee that an input event + will be acted upon. + + Most wireless communication device drivers implementing rfkill + functionality MUST NOT generate these events, and have no reason to + register themselves with the input layer. Doing otherwise is a common + misconception. There is an API to propagate rfkill status change + information, and it is NOT the input layer. + +rfkill class: + + * Calls a hook in a driver to effectively change the wireless + transmitter state; + * Keeps track of the wireless transmitter state (with help from + the driver); + * Generates userspace notifications (uevents) and a call to a + notification chain (kernel) when there is a wireless transmitter + state change; + * Connects a wireless communications driver with the common rfkill + control system, which, for example, allows actions such as + "switch all bluetooth devices offline" to be carried out by + userspace or by rfkill-input. + + THE RFKILL CLASS NEVER ISSUES INPUT EVENTS. THE RFKILL CLASS DOES + NOT LISTEN TO INPUT EVENTS. NO DRIVER USING THE RFKILL CLASS SHALL + EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS. Doing otherwise is + a layering violation. + + Most wireless data communication drivers in the kernel have just to + implement the rfkill class API to work properly. Interfacing to the + input layer is not often required (and is very often a *bug*) on + wireless drivers. + + Platform drivers often have to attach to the input layer to *issue* + (but never to listen to) rfkill events for rfkill switches, and also to + the rfkill class to export a control interface for the platform rfkill + controllers to the rfkill subsystem. This does NOT mean the rfkill + switch is attached to a rfkill class (doing so is almost always wrong). + It just means the same kernel module is the driver for different + devices (rfkill switches and rfkill controllers). + + +Userspace input handlers (uevents) or kernel input handlers (rfkill-input): + + * Implements the policy of what should happen when one of the input + layer events related to rfkill operation is received. + * Uses the sysfs interface (userspace) or private rfkill API calls + to tell the devices registered with the rfkill class to change + their state (i.e. translates the input layer event into real + action). + + * rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0 + (power off all transmitters) in a special way: it ignores any + overrides and local state cache and forces all transmitters to the + RFKILL_STATE_SOFT_BLOCKED state (including those which are already + supposed to be BLOCKED). + * rfkill EPO will remain active until rfkill-input receives an + EV_SW SW_RFKILL_ALL 1 event. While the EPO is active, transmitters + are locked in the blocked state (rfkill will refuse to unblock them). + * rfkill-input implements different policies that the user can + select for handling EV_SW SW_RFKILL_ALL 1. It will unlock rfkill, + and either do nothing (leave transmitters blocked, but now unlocked), + restore the transmitters to their state before the EPO, or unblock + them all. + +Userspace uevent handler or kernel platform-specific drivers hooked to the +rfkill notifier chain: + + * Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents, + in order to know when a device that is registered with the rfkill + class changes state; + * Issues feedback notifications to the user; + * In the rare platforms where this is required, synthesizes an input + event to command all *OTHER* rfkill devices to also change their + statues when a specific rfkill device changes state. + + +=============================================================================== +3: Kernel driver guidelines + +Remember: point-of-view is everything for a driver that connects to the rfkill +subsystem. All the details below must be measured/perceived from the point of +view of the specific driver being modified. + +The first thing one needs to know is whether his driver should be talking to +the rfkill class or to the input layer. In rare cases (platform drivers), it +could happen that you need to do both, as platform drivers often handle a +variety of devices in the same driver. + +Do not mistake input devices for rfkill controllers. The only type of "rfkill +switch" device that is to be registered with the rfkill class are those +directly controlling the circuits that cause a wireless transmitter to stop +working (or the software equivalent of them), i.e. what we call a rfkill +controller. Every other kind of "rfkill switch" is just an input device and +MUST NOT be registered with the rfkill class. + +A driver should register a device with the rfkill class when ALL of the +following conditions are met (they define a rfkill controller): + +1. The device is/controls a data communications wireless transmitter; + +2. The kernel can interact with the hardware/firmware to CHANGE the wireless + transmitter state (block/unblock TX operation); + +3. The transmitter can be made to not emit any energy when "blocked": + rfkill is not about blocking data transmissions, it is about blocking + energy emission; + +A driver should register a device with the input subsystem to issue +rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX, +SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met: + +1. It is directly related to some physical device the user interacts with, to + command the O.S./firmware/hardware to enable/disable a data communications + wireless transmitter. + + Examples of the physical device are: buttons, keys and switches the user + will press/touch/slide/switch to enable or disable the wireless + communication device. + +2. It is NOT slaved to another device, i.e. there is no other device that + issues rfkill-related input events in preference to this one. + + Please refer to the corner cases and examples section for more details. + +When in doubt, do not issue input events. For drivers that should generate +input events in some platforms, but not in others (e.g. b43), the best solution +is to NEVER generate input events in the first place. That work should be +deferred to a platform-specific kernel module (which will know when to generate +events through the rfkill notifier chain) or to userspace. This avoids the +usual maintenance problems with DMI whitelisting. + + +Corner cases and examples: +==================================== + +1. If the device is an input device that, because of hardware or firmware, +causes wireless transmitters to be blocked regardless of the kernel's will, it +is still just an input device, and NOT to be registered with the rfkill class. + +2. If the wireless transmitter switch control is read-only, it is an input +device and not to be registered with the rfkill class (and maybe not to be made +an input layer event source either, see below). + +3. If there is some other device driver *closer* to the actual hardware the +user interacted with (the button/switch/key) to issue an input event, THAT is +the device driver that should be issuing input events. + +E.g: + [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input] + (platform driver) (wireless card driver) + +The user is closer to the RFKILL slide switch plaform driver, so the driver +which must issue input events is the platform driver looking at the GPIO +hardware, and NEVER the wireless card driver (which is just a slave). It is +very likely that there are other leaves than just the WLAN card rf-kill input +(e.g. a bluetooth card, etc)... + +On the other hand, some embedded devices do this: + + [RFKILL slider switch] -- [WLAN card rf-kill input] + (wireless card driver) + +In this situation, the wireless card driver *could* register itself as an input +device and issue rf-kill related input events... but in order to AVOID the need +for DMI whitelisting, the wireless card driver does NOT do it. Userspace (HAL) +or a platform driver (that exists only on these embedded devices) will do the +dirty job of issuing the input events. + + +COMMON MISTAKES in kernel drivers, related to rfkill: +==================================== + +1. NEVER confuse input device keys and buttons with input device switches. + + 1a. Switches are always set or reset. They report the current state + (on position or off position). + + 1b. Keys and buttons are either in the pressed or not-pressed state, and + that's it. A "button" that latches down when you press it, and + unlatches when you press it again is in fact a switch as far as input + devices go. + +Add the SW_* events you need for switches, do NOT try to emulate a button using +KEY_* events just because there is no such SW_* event yet. Do NOT try to use, +for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead. + +2. Input device switches (sources of EV_SW events) DO store their current state +(so you *must* initialize it by issuing a gratuitous input layer event on +driver start-up and also when resuming from sleep), and that state CAN be +queried from userspace through IOCTLs. There is no sysfs interface for this, +but that doesn't mean you should break things trying to hook it to the rfkill +class to get a sysfs interface :-) + +3. Do not issue *_RFKILL_ALL events by default, unless you are sure it is the +correct event for your switch/button. These events are emergency power-off +events when they are trying to turn the transmitters off. An example of an +input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill +switch in a laptop which is NOT a hotkey, but a real sliding/rocker switch. +An example of an input device which SHOULD NOT generate *_RFKILL_ALL events by +default, is any sort of hot key that is type-specific (e.g. the one for WLAN). + + +3.1 Guidelines for wireless device drivers +------------------------------------------ + +(in this text, rfkill->foo means the foo field of struct rfkill). + +1. Each independent transmitter in a wireless device (usually there is only one +transmitter per device) should have a SINGLE rfkill class attached to it. + +2. If the device does not have any sort of hardware assistance to allow the +driver to rfkill the device, the driver should emulate it by taking all actions +required to silence the transmitter. + +3. If it is impossible to silence the transmitter (i.e. it still emits energy, +even if it is just in brief pulses, when there is no data to transmit and there +is no hardware support to turn it off) do NOT lie to the users. Do not attach +it to a rfkill class. The rfkill subsystem does not deal with data +transmission, it deals with energy emission. If the transmitter is emitting +energy, it is not blocked in rfkill terms. + +4. It doesn't matter if the device has multiple rfkill input lines affecting +the same transmitter, their combined state is to be exported as a single state +per transmitter (see rule 1). + +This rule exists because users of the rfkill subsystem expect to get (and set, +when possible) the overall transmitter rfkill state, not of a particular rfkill +line. + +5. The wireless device driver MUST NOT leave the transmitter enabled during +suspend and hibernation unless: -The rfkill class code also notifies userspace of state changes, this is -achieved via uevents. It also provides some sysfs files for userspace to -check the status of radio transmitters. See the "Userspace support" section -below. + 5.1. The transmitter has to be enabled for some sort of functionality + like wake-on-wireless-packet or autonomous packed forwarding in a mesh + network, and that functionality is enabled for this suspend/hibernation + cycle. +AND -The rfkill-input code implements a basic response to rfkill buttons -- it -implements turning on/off all devices of a certain class (or all). + 5.2. The device was not on a user-requested BLOCKED state before + the suspend (i.e. the driver must NOT unblock a device, not even + to support wake-on-wireless-packet or remain in the mesh). -When the device is hard-blocked (either by a call to rfkill_set_hw_state() -or from query_hw_block) set_block() will be invoked but drivers can well -ignore the method call since they can use the return value of the function -rfkill_set_hw_state() to sync the software state instead of keeping track -of calls to set_block(). +In other words, there is absolutely no allowed scenario where a driver can +automatically take action to unblock a rfkill controller (obviously, this deals +with scenarios where soft-blocking or both soft and hard blocking is happening. +Scenarios where hardware rfkill lines are the only ones blocking the +transmitter are outside of this rule, since the wireless device driver does not +control its input hardware rfkill lines in the first place). +6. During resume, rfkill will try to restore its previous state. -The entire functionality is spread over more than one subsystem: +7. After a rfkill class is suspended, it will *not* call rfkill->toggle_radio +until it is resumed. - * The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and - SW_RFKILL_ALL -- when the user presses a button. Drivers for radio - transmitters generally do not register to the input layer, unless the - device really provides an input device (i.e. a button that has no - effect other than generating a button press event) - * The rfkill-input code hooks up to these events and switches the soft-block - of the various radio transmitters, depending on the button type. +Example of a WLAN wireless driver connected to the rfkill subsystem: +-------------------------------------------------------------------- - * The rfkill drivers turn off/on their transmitters as requested. +A certain WLAN card has one input pin that causes it to block the transmitter +and makes the status of that input pin available (only for reading!) to the +kernel driver. This is a hard rfkill input line (it cannot be overridden by +the kernel driver). - * The rfkill class will generate userspace notifications (uevents) to tell - userspace what the current state is. +The card also has one PCI register that, if manipulated by the driver, causes +it to block the transmitter. This is a soft rfkill input line. +It has also a thermal protection circuitry that shuts down its transmitter if +the card overheats, and makes the status of that protection available (only for +reading!) to the kernel driver. This is also a hard rfkill input line. +If either one of these rfkill lines are active, the transmitter is blocked by +the hardware and forced offline. -3. Kernel driver guidelines +The driver should allocate and attach to its struct device *ONE* instance of +the rfkill class (there is only one transmitter). +It can implement the get_state() hook, and return RFKILL_STATE_HARD_BLOCKED if +either one of its two hard rfkill input lines are active. If the two hard +rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft +rfkill input line is active. Only if none of the rfkill input lines are +active, will it return RFKILL_STATE_UNBLOCKED. -Drivers for radio transmitters normally implement only the rfkill class. -These drivers may not unblock the transmitter based on own decisions, they -should act on information provided by the rfkill class only. +Since the device has a hardware rfkill line, it IS subject to state changes +external to rfkill. Therefore, the driver must make sure that it calls +rfkill_force_state() to keep the status always up-to-date, and it must do a +rfkill_force_state() on resume from sleep. -Platform drivers might implement input devices if the rfkill button is just -that, a button. If that button influences the hardware then you need to -implement an rfkill class instead. This also applies if the platform provides -a way to turn on/off the transmitter(s). +Every time the driver gets a notification from the card that one of its rfkill +lines changed state (polling might be needed on badly designed cards that don't +generate interrupts for such events), it recomputes the rfkill state as per +above, and calls rfkill_force_state() to update it. -During suspend/hibernation, transmitters should only be left enabled when -wake-on wlan or similar functionality requires it and the device wasn't -blocked before suspend/hibernate. Note that it may be necessary to update -the rfkill subsystem's idea of what the current state is at resume time if -the state may have changed over suspend. +The driver should implement the toggle_radio() hook, that: +1. Returns an error if one of the hardware rfkill lines are active, and the +caller asked for RFKILL_STATE_UNBLOCKED. +2. Activates the soft rfkill line if the caller asked for state +RFKILL_STATE_SOFT_BLOCKED. It should do this even if one of the hard rfkill +lines are active, effectively double-blocking the transmitter. -4. Kernel API +3. Deactivates the soft rfkill line if none of the hardware rfkill lines are +active and the caller asked for RFKILL_STATE_UNBLOCKED. + +=============================================================================== +4: Kernel API To build a driver with rfkill subsystem support, the driver should depend on -(or select) the Kconfig symbol RFKILL. +(or select) the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT. The hardware the driver talks to may be write-only (where the current state of the hardware is unknown), or read-write (where the hardware can be queried about its current state). -Calling rfkill_set_hw_state() when a state change happens is required from -rfkill drivers that control devices that can be hard-blocked unless they also -assign the poll_hw_block() callback (then the rfkill core will poll the -device). Don't do this unless you cannot get the event in any other way. +The rfkill class will call the get_state hook of a device every time it needs +to know the *real* current state of the hardware. This can happen often, but +it does not do any polling, so it is not enough on hardware that is subject +to state changes outside of the rfkill subsystem. +Therefore, calling rfkill_force_state() when a state change happens is +mandatory when the device has a hardware rfkill line, or when something else +like the firmware could cause its state to be changed without going through the +rfkill class. +Some hardware provides events when its status changes. In these cases, it is +best for the driver to not provide a get_state hook, and instead register the +rfkill class *already* with the correct status, and keep it updated using +rfkill_force_state() when it gets an event from the hardware. -5. Userspace support +rfkill_force_state() must be used on the device resume handlers to update the +rfkill status, should there be any chance of the device status changing during +the sleep. -The following sysfs entries exist for every rfkill device: +There is no provision for a statically-allocated rfkill struct. You must +use rfkill_allocate() to allocate one. - name: Name assigned by driver to this key (interface or driver name). - type: Name of the key type ("wlan", "bluetooth", etc). - state: Current state of the transmitter - 0: RFKILL_STATE_SOFT_BLOCKED - transmitter is turned off by software - 1: RFKILL_STATE_UNBLOCKED - transmitter is (potentially) active - 2: RFKILL_STATE_HARD_BLOCKED - transmitter is forced off by something outside of - the driver's control. - claim: 0: Kernel handles events (currently always reads that value) +You should: + - rfkill_allocate() + - modify rfkill fields (flags, name) + - modify state to the current hardware state (THIS IS THE ONLY TIME + YOU CAN ACCESS state DIRECTLY) + - rfkill_register() + +The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through +a suitable return of get_state() or through rfkill_force_state(). + +When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch +it to a different state is through a suitable return of get_state() or through +rfkill_force_state(). + +If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED +when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should +not return an error. Instead, it should try to double-block the transmitter, +so that its state will change from RFKILL_STATE_HARD_BLOCKED to +RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease. -rfkill devices also issue uevents (with an action of "change"), with the -following environment variables set: +Please refer to the source for more documentation. + +=============================================================================== +5: Userspace support + +rfkill devices issue uevents (with an action of "change"), with the following +environment variables set: RFKILL_NAME RFKILL_STATE RFKILL_TYPE -The contents of these variables corresponds to the "name", "state" and -"type" sysfs files explained above. +The ABI for these variables is defined by the sysfs attributes. It is best +to take a quick look at the source to make sure of the possible values. + +It is expected that HAL will trap those, and bridge them to DBUS, etc. These +events CAN and SHOULD be used to give feedback to the user about the rfkill +status of the system. -An alternative userspace interface exists as a misc device /dev/rfkill, -which allows userspace to obtain and set the state of rfkill devices and -sets of devices. It also notifies userspace about device addition and -removal. The API is a simple read/write API that is defined in -linux/rfkill.h. +Input devices may issue events that are related to rfkill. These are the +various KEY_* events and SW_* events supported by rfkill-input.c. + +Userspace may not change the state of an rfkill switch in response to an +input event, it should refrain from changing states entirely. + +Userspace cannot assume it is the only source of control for rfkill switches. +Their state can change due to firmware actions, direct user actions, and the +rfkill-input EPO override for *_RFKILL_ALL. + +When rfkill-input is not active, userspace must initiate a rfkill status +change by writing to the "state" attribute in order for anything to happen. + +Take particular care to implement EV_SW SW_RFKILL_ALL properly. When that +switch is set to OFF, *every* rfkill device *MUST* be immediately put into the +RFKILL_STATE_SOFT_BLOCKED state, no questions asked. + +The following sysfs entries will be created: + + name: Name assigned by driver to this key (interface or driver name). + type: Name of the key type ("wlan", "bluetooth", etc). + state: Current state of the transmitter + 0: RFKILL_STATE_SOFT_BLOCKED + transmitter is forced off, but one can override it + by a write to the state attribute; + 1: RFKILL_STATE_UNBLOCKED + transmiter is NOT forced off, and may operate if + all other conditions for such operation are met + (such as interface is up and configured, etc); + 2: RFKILL_STATE_HARD_BLOCKED + transmitter is forced off by something outside of + the driver's control. One cannot set a device to + this state through writes to the state attribute; + claim: 1: Userspace handles events, 0: Kernel handles events + +Both the "state" and "claim" entries are also writable. For the "state" entry +this means that when 1 or 0 is written, the device rfkill state (if not yet in +the requested state), will be will be toggled accordingly. + +For the "claim" entry writing 1 to it means that the kernel no longer handles +key events even though RFKILL_INPUT input was enabled. When "claim" has been +set to 0, userspace should make sure that it listens for the input events or +check the sysfs "state" entry regularly to correctly perform the required tasks +when the rkfill key is pressed. + +A note about input devices and EV_SW events: + +In order to know the current state of an input device switch (like +SW_RFKILL_ALL), you will need to use an IOCTL. That information is not +available through sysfs in a generic way at this time, and it is not available +through the rfkill class AT ALL. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a6df68fad9ba..77f277e1b4b9 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1545,13 +1545,6 @@ W: http://www.fi.muni.cz/~kas/cosa/ S: Maintained F: drivers/net/wan/cosa* -CPMAC ETHERNET DRIVER -P: Florian Fainelli -M: florian@openwrt.org -L: netdev@vger.kernel.org -S: Maintained -F: drivers/net/cpmac.c - CPU FREQUENCY DRIVERS P: Dave Jones M: davej@redhat.com @@ -2819,18 +2812,6 @@ L: linux1394-devel@lists.sourceforge.net S: Maintained F: drivers/ieee1394/raw1394* -IEEE 802.15.4 SUBSYSTEM -P: Dmitry Eremin-Solenikov -M: dbaryshkov@gmail.com -P: Sergey Lapin -M: slapin@ossfans.org -L: linux-zigbee-devel@lists.sourceforge.net -W: http://apps.sourceforge.net/trac/linux-zigbee -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lumag/lowpan.git -S: Maintained -F: net/ieee802154/ -F: drivers/ieee801254/ - INTEGRITY MEASUREMENT ARCHITECTURE (IMA) P: Mimi Zohar M: zohar@us.ibm.com @@ -4765,9 +4746,9 @@ S: Supported F: fs/reiserfs/ RFKILL -P: Johannes Berg -M: johannes@sipsolutions.net -L: linux-wireless@vger.kernel.org +P: Ivo van Doorn +M: IvDoorn@gmail.com +L: netdev@vger.kernel.org S: Maintained F Documentation/rfkill.txt F: net/rfkill/ diff --git a/trunk/arch/alpha/include/asm/errno.h b/trunk/arch/alpha/include/asm/errno.h index 98099bda9370..69e2655249d2 100644 --- a/trunk/arch/alpha/include/asm/errno.h +++ b/trunk/arch/alpha/include/asm/errno.h @@ -120,6 +120,4 @@ #define EOWNERDEAD 136 /* Owner died */ #define ENOTRECOVERABLE 137 /* State not recoverable */ -#define ERFKILL 138 /* Operation not possible due to RF-kill */ - #endif diff --git a/trunk/arch/arm/mach-pxa/tosa-bt.c b/trunk/arch/arm/mach-pxa/tosa-bt.c index c31e601eb49c..bde42aa29374 100644 --- a/trunk/arch/arm/mach-pxa/tosa-bt.c +++ b/trunk/arch/arm/mach-pxa/tosa-bt.c @@ -35,25 +35,21 @@ static void tosa_bt_off(struct tosa_bt_data *data) gpio_set_value(data->gpio_reset, 0); } -static int tosa_bt_set_block(void *data, bool blocked) +static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) { - pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on"); + pr_info("BT_RADIO going: %s\n", + state == RFKILL_STATE_UNBLOCKED ? "on" : "off"); - if (!blocked) { + if (state == RFKILL_STATE_UNBLOCKED) { pr_info("TOSA_BT: going ON\n"); tosa_bt_on(data); } else { pr_info("TOSA_BT: going OFF\n"); tosa_bt_off(data); } - return 0; } -static const struct rfkill_ops tosa_bt_rfkill_ops = { - .set_block = tosa_bt_set_block, -}; - static int tosa_bt_probe(struct platform_device *dev) { int rc; @@ -74,14 +70,18 @@ static int tosa_bt_probe(struct platform_device *dev) if (rc) goto err_pwr_dir; - rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH, - &tosa_bt_rfkill_ops, data); + rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); if (!rfk) { rc = -ENOMEM; goto err_rfk_alloc; } - rfkill_set_led_trigger_name(rfk, "tosa-bt"); + rfk->name = "tosa-bt"; + rfk->toggle_radio = tosa_bt_toggle_radio; + rfk->data = data; +#ifdef CONFIG_RFKILL_LEDS + rfk->led_trigger.name = "tosa-bt"; +#endif rc = rfkill_register(rfk); if (rc) @@ -92,7 +92,9 @@ static int tosa_bt_probe(struct platform_device *dev) return 0; err_rfkill: - rfkill_destroy(rfk); + if (rfk) + rfkill_free(rfk); + rfk = NULL; err_rfk_alloc: tosa_bt_off(data); err_pwr_dir: @@ -111,10 +113,8 @@ static int __devexit tosa_bt_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); - if (rfk) { + if (rfk) rfkill_unregister(rfk); - rfkill_destroy(rfk); - } rfk = NULL; tosa_bt_off(data); diff --git a/trunk/arch/arm/mach-pxa/tosa.c b/trunk/arch/arm/mach-pxa/tosa.c index 58ce807fe440..afac5b6d3d78 100644 --- a/trunk/arch/arm/mach-pxa/tosa.c +++ b/trunk/arch/arm/mach-pxa/tosa.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/mips/include/asm/errno.h b/trunk/arch/mips/include/asm/errno.h index a0efc73819e4..3c0d840e4577 100644 --- a/trunk/arch/mips/include/asm/errno.h +++ b/trunk/arch/mips/include/asm/errno.h @@ -119,8 +119,6 @@ #define EOWNERDEAD 165 /* Owner died */ #define ENOTRECOVERABLE 166 /* State not recoverable */ -#define ERFKILL 167 /* Operation not possible due to RF-kill */ - #define EDQUOT 1133 /* Quota exceeded */ #ifdef __KERNEL__ diff --git a/trunk/arch/parisc/include/asm/errno.h b/trunk/arch/parisc/include/asm/errno.h index 9992abdd782d..e2f3ddc796be 100644 --- a/trunk/arch/parisc/include/asm/errno.h +++ b/trunk/arch/parisc/include/asm/errno.h @@ -120,6 +120,5 @@ #define EOWNERDEAD 254 /* Owner died */ #define ENOTRECOVERABLE 255 /* State not recoverable */ -#define ERFKILL 256 /* Operation not possible due to RF-kill */ #endif diff --git a/trunk/arch/powerpc/include/asm/qe.h b/trunk/arch/powerpc/include/asm/qe.h index 4459d20dc76a..2701753d9937 100644 --- a/trunk/arch/powerpc/include/asm/qe.h +++ b/trunk/arch/powerpc/include/asm/qe.h @@ -668,8 +668,6 @@ struct ucc_slow_pram { #define UCC_GETH_UPSMR_RMM 0x00001000 #define UCC_GETH_UPSMR_CAM 0x00000400 #define UCC_GETH_UPSMR_BRO 0x00000200 -#define UCC_GETH_UPSMR_SMM 0x00000080 -#define UCC_GETH_UPSMR_SGMM 0x00000020 /* UCC Transmit On Demand Register (UTODR) */ #define UCC_SLOW_TOD 0x8000 diff --git a/trunk/arch/sparc/include/asm/errno.h b/trunk/arch/sparc/include/asm/errno.h index 4e2bc490d714..a9ef172977de 100644 --- a/trunk/arch/sparc/include/asm/errno.h +++ b/trunk/arch/sparc/include/asm/errno.h @@ -110,6 +110,4 @@ #define EOWNERDEAD 132 /* Owner died */ #define ENOTRECOVERABLE 133 /* State not recoverable */ -#define ERFKILL 134 /* Operation not possible due to RF-kill */ - #endif diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index 9e7d4e56c85b..1266ead6ace0 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -107,4 +107,3 @@ obj-$(CONFIG_SSB) += ssb/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ -obj-y += ieee802154/ diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 965ece2c7e4d..31693bc24444 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -34,6 +34,13 @@ new_skb(ulong len) skb_reset_mac_header(skb); skb_reset_network_header(skb); skb->protocol = __constant_htons(ETH_P_AOE); + skb->priority = 0; + skb->next = skb->prev = NULL; + + /* tell the network layer not to perform IP checksums + * or to get the NIC to do it + */ + skb->ip_summed = CHECKSUM_NONE; } return skb; } diff --git a/trunk/drivers/bluetooth/hci_vhci.c b/trunk/drivers/bluetooth/hci_vhci.c index 1df9dda2e377..0bbefba6469c 100644 --- a/trunk/drivers/bluetooth/hci_vhci.c +++ b/trunk/drivers/bluetooth/hci_vhci.c @@ -40,7 +40,7 @@ #include #include -#define VERSION "1.3" +#define VERSION "1.2" static int minor = MISC_DYNAMIC_MINOR; @@ -51,8 +51,14 @@ struct vhci_data { wait_queue_head_t read_wait; struct sk_buff_head readq; + + struct fasync_struct *fasync; }; +#define VHCI_FASYNC 0x0010 + +static struct miscdevice vhci_miscdev; + static int vhci_open_dev(struct hci_dev *hdev) { set_bit(HCI_RUNNING, &hdev->flags); @@ -99,6 +105,9 @@ static int vhci_send_frame(struct sk_buff *skb) memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); skb_queue_tail(&data->readq, skb); + if (data->flags & VHCI_FASYNC) + kill_fasync(&data->fasync, SIGIO, POLL_IN); + wake_up_interruptible(&data->read_wait); return 0; @@ -170,31 +179,41 @@ static inline ssize_t vhci_put_user(struct vhci_data *data, static ssize_t vhci_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { + DECLARE_WAITQUEUE(wait, current); struct vhci_data *data = file->private_data; struct sk_buff *skb; ssize_t ret = 0; + add_wait_queue(&data->read_wait, &wait); while (count) { + set_current_state(TASK_INTERRUPTIBLE); + skb = skb_dequeue(&data->readq); - if (skb) { - ret = vhci_put_user(data, skb, buf, count); - if (ret < 0) - skb_queue_head(&data->readq, skb); - else - kfree_skb(skb); - break; + if (!skb) { + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + break; + } + + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + schedule(); + continue; } - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } + if (access_ok(VERIFY_WRITE, buf, count)) + ret = vhci_put_user(data, skb, buf, count); + else + ret = -EFAULT; - ret = wait_event_interruptible(data->read_wait, - !skb_queue_empty(&data->readq)); - if (ret < 0) - break; + kfree_skb(skb); + break; } + set_current_state(TASK_RUNNING); + remove_wait_queue(&data->read_wait, &wait); return ret; } @@ -204,6 +223,9 @@ static ssize_t vhci_write(struct file *file, { struct vhci_data *data = file->private_data; + if (!access_ok(VERIFY_READ, buf, count)) + return -EFAULT; + return vhci_get_user(data, buf, count); } @@ -237,9 +259,11 @@ static int vhci_open(struct inode *inode, struct file *file) skb_queue_head_init(&data->readq); init_waitqueue_head(&data->read_wait); + lock_kernel(); hdev = hci_alloc_dev(); if (!hdev) { kfree(data); + unlock_kernel(); return -ENOMEM; } @@ -260,10 +284,12 @@ static int vhci_open(struct inode *inode, struct file *file) BT_ERR("Can't register HCI device"); kfree(data); hci_free_dev(hdev); + unlock_kernel(); return -EBUSY; } file->private_data = data; + unlock_kernel(); return nonseekable_open(inode, file); } @@ -284,25 +310,48 @@ static int vhci_release(struct inode *inode, struct file *file) return 0; } +static int vhci_fasync(int fd, struct file *file, int on) +{ + struct vhci_data *data = file->private_data; + int err = 0; + + lock_kernel(); + err = fasync_helper(fd, file, on, &data->fasync); + if (err < 0) + goto out; + + if (on) + data->flags |= VHCI_FASYNC; + else + data->flags &= ~VHCI_FASYNC; + +out: + unlock_kernel(); + return err; +} + static const struct file_operations vhci_fops = { + .owner = THIS_MODULE, .read = vhci_read, .write = vhci_write, .poll = vhci_poll, .ioctl = vhci_ioctl, .open = vhci_open, .release = vhci_release, + .fasync = vhci_fasync, }; static struct miscdevice vhci_miscdev= { - .name = "vhci", - .fops = &vhci_fops, - .minor = MISC_DYNAMIC_MINOR, + .name = "vhci", + .fops = &vhci_fops, }; static int __init vhci_init(void) { BT_INFO("Virtual HCI driver ver %s", VERSION); + vhci_miscdev.minor = minor; + if (misc_register(&vhci_miscdev) < 0) { BT_ERR("Can't register misc device with minor %d", minor); return -EIO; @@ -320,6 +369,9 @@ static void __exit vhci_exit(void) module_init(vhci_init); module_exit(vhci_exit); +module_param(minor, int, 0444); +MODULE_PARM_DESC(minor, "Miscellaneous minor device number"); + MODULE_AUTHOR("Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); MODULE_VERSION(VERSION); diff --git a/trunk/drivers/ieee802154/Kconfig b/trunk/drivers/ieee802154/Kconfig deleted file mode 100644 index 25740bd54975..000000000000 --- a/trunk/drivers/ieee802154/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -menuconfig IEEE802154_DRIVERS - bool "IEEE 802.15.4 drivers" - depends on NETDEVICES && IEEE802154 - default y - ---help--- - Say Y here to get to see options for IEEE 802.15.4 Low-Rate - Wireless Personal Area Network device drivers. This option alone - does not add any kernel code. - - If you say N, all options in this submenu will be skipped and - disabled. - -config IEEE802154_FAKEHARD - tristate "Fake LR-WPAN driver with several interconnected devices" - depends on IEEE802154_DRIVERS - ---help--- - Say Y here to enable the fake driver that serves as an example - of HardMAC device driver. - - This driver can also be built as a module. To do so say M here. - The module will be called 'fakehard'. - diff --git a/trunk/drivers/ieee802154/Makefile b/trunk/drivers/ieee802154/Makefile deleted file mode 100644 index e0e8e1a184ff..000000000000 --- a/trunk/drivers/ieee802154/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o - -EXTRA_CFLAGS += -DDEBUG -DCONFIG_FFD diff --git a/trunk/drivers/ieee802154/fakehard.c b/trunk/drivers/ieee802154/fakehard.c deleted file mode 100644 index 0384144c0b34..000000000000 --- a/trunk/drivers/ieee802154/fakehard.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Sample driver for HardMAC IEEE 802.15.4 devices - * - * Copyright (C) 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Dmitry Eremin-Solenikov - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static u16 fake_get_pan_id(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0xeba1; -} - -static u16 fake_get_short_addr(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0x1; -} - -static u8 fake_get_dsn(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0x00; /* DSN are implemented in HW, so return just 0 */ -} - -static u8 fake_get_bsn(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0x00; /* BSN are implemented in HW, so return just 0 */ -} - -static int fake_assoc_req(struct net_device *dev, - struct ieee802154_addr *addr, u8 channel, u8 cap) -{ - /* We simply emulate it here */ - return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev), - IEEE802154_SUCCESS); -} - -static int fake_assoc_resp(struct net_device *dev, - struct ieee802154_addr *addr, u16 short_addr, u8 status) -{ - return 0; -} - -static int fake_disassoc_req(struct net_device *dev, - struct ieee802154_addr *addr, u8 reason) -{ - return ieee802154_nl_disassoc_confirm(dev, IEEE802154_SUCCESS); -} - -static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, - u8 channel, - u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, - u8 coord_realign) -{ - return 0; -} - -static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, - u8 duration) -{ - u8 edl[27] = {}; - return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, - channels, - type == IEEE802154_MAC_SCAN_ED ? edl : NULL); -} - -static struct ieee802154_mlme_ops fake_mlme = { - .assoc_req = fake_assoc_req, - .assoc_resp = fake_assoc_resp, - .disassoc_req = fake_disassoc_req, - .start_req = fake_start_req, - .scan_req = fake_scan_req, - - .get_pan_id = fake_get_pan_id, - .get_short_addr = fake_get_short_addr, - .get_dsn = fake_get_dsn, - .get_bsn = fake_get_bsn, -}; - -static int ieee802154_fake_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; -} - -static int ieee802154_fake_close(struct net_device *dev) -{ - netif_stop_queue(dev); - return 0; -} - -static int ieee802154_fake_xmit(struct sk_buff *skb, struct net_device *dev) -{ - skb->iif = dev->ifindex; - skb->dev = dev; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - dev->trans_start = jiffies; - - /* FIXME: do hardware work here ... */ - - return 0; -} - - -static int ieee802154_fake_ioctl(struct net_device *dev, struct ifreq *ifr, - int cmd) -{ - struct sockaddr_ieee802154 *sa = - (struct sockaddr_ieee802154 *)&ifr->ifr_addr; - u16 pan_id, short_addr; - - switch (cmd) { - case SIOCGIFADDR: - /* FIXME: fixed here, get from device IRL */ - pan_id = fake_get_pan_id(dev); - short_addr = fake_get_short_addr(dev); - if (pan_id == IEEE802154_PANID_BROADCAST || - short_addr == IEEE802154_ADDR_BROADCAST) - return -EADDRNOTAVAIL; - - sa->family = AF_IEEE802154; - sa->addr.addr_type = IEEE802154_ADDR_SHORT; - sa->addr.pan_id = pan_id; - sa->addr.short_addr = short_addr; - return 0; - } - return -ENOIOCTLCMD; -} - -static int ieee802154_fake_mac_addr(struct net_device *dev, void *p) -{ - return -EBUSY; /* HW address is built into the device */ -} - -static const struct net_device_ops fake_ops = { - .ndo_open = ieee802154_fake_open, - .ndo_stop = ieee802154_fake_close, - .ndo_start_xmit = ieee802154_fake_xmit, - .ndo_do_ioctl = ieee802154_fake_ioctl, - .ndo_set_mac_address = ieee802154_fake_mac_addr, -}; - - -static void ieee802154_fake_setup(struct net_device *dev) -{ - dev->addr_len = IEEE802154_ADDR_LEN; - memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); - dev->features = NETIF_F_NO_CSUM; - dev->needed_tailroom = 2; /* FCS */ - dev->mtu = 127; - dev->tx_queue_len = 10; - dev->type = ARPHRD_IEEE802154; - dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; -} - - -static int __devinit ieee802154fake_probe(struct platform_device *pdev) -{ - struct net_device *dev = - alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup); - int err; - - if (!dev) - return -ENOMEM; - - memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef", - dev->addr_len); - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - - dev->netdev_ops = &fake_ops; - dev->ml_priv = &fake_mlme; - - /* - * If the name is a format string the caller wants us to do a - * name allocation. - */ - if (strchr(dev->name, '%')) { - err = dev_alloc_name(dev, dev->name); - if (err < 0) - goto out; - } - - SET_NETDEV_DEV(dev, &pdev->dev); - - platform_set_drvdata(pdev, dev); - - err = register_netdev(dev); - if (err < 0) - goto out; - - - dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); - return 0; - -out: - unregister_netdev(dev); - return err; -} - -static int __devexit ieee802154fake_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - unregister_netdev(dev); - free_netdev(dev); - return 0; -} - -static struct platform_device *ieee802154fake_dev; - -static struct platform_driver ieee802154fake_driver = { - .probe = ieee802154fake_probe, - .remove = __devexit_p(ieee802154fake_remove), - .driver = { - .name = "ieee802154hardmac", - .owner = THIS_MODULE, - }, -}; - -static __init int fake_init(void) -{ - ieee802154fake_dev = platform_device_register_simple( - "ieee802154hardmac", -1, NULL, 0); - return platform_driver_register(&ieee802154fake_driver); -} - -static __exit void fake_exit(void) -{ - platform_driver_unregister(&ieee802154fake_driver); - platform_device_unregister(ieee802154fake_dev); -} - -module_init(fake_init); -module_exit(fake_exit); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 181b1f32325f..4248c3139364 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -1394,8 +1394,8 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb, struct ipoib_dev_priv *priv = netdev_priv(dev); int e = skb_queue_empty(&priv->cm.skb_queue); - if (skb_dst(skb)) - skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + if (skb->dst) + skb->dst->ops->update_pmtu(skb->dst, mtu); skb_queue_tail(&priv->cm.skb_queue, skb); if (e) diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index e319d91f60a6..ab2c192c76bc 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -561,7 +561,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) struct ipoib_neigh *neigh; unsigned long flags; - neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev); + neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev); if (!neigh) { ++dev->stats.tx_dropped; dev_kfree_skb_any(skb); @@ -570,9 +570,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&priv->lock, flags); - path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4); + path = __path_find(dev, skb->dst->neighbour->ha + 4); if (!path) { - path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4); + path = path_rec_create(dev, skb->dst->neighbour->ha + 4); if (!path) goto err_path; @@ -605,7 +605,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev) goto err_drop; } } else - ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha)); + ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha)); } else { neigh->ah = NULL; @@ -635,15 +635,15 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev) struct ipoib_dev_priv *priv = netdev_priv(skb->dev); /* Look up path record for unicasts */ - if (skb_dst(skb)->neighbour->ha[4] != 0xff) { + if (skb->dst->neighbour->ha[4] != 0xff) { neigh_add_path(skb, dev); return; } /* Add in the P_Key for multicasts */ - skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff; - skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff; - ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb); + skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff; + skb->dst->neighbour->ha[9] = priv->pkey & 0xff; + ipoib_mcast_send(dev, skb->dst->neighbour->ha + 4, skb); } static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, @@ -708,16 +708,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) struct ipoib_neigh *neigh; unsigned long flags; - if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) { - if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) { + if (likely(skb->dst && skb->dst->neighbour)) { + if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) { ipoib_path_lookup(skb, dev); return NETDEV_TX_OK; } - neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour); + neigh = *to_ipoib_neigh(skb->dst->neighbour); if (unlikely((memcmp(&neigh->dgid.raw, - skb_dst(skb)->neighbour->ha + 4, + skb->dst->neighbour->ha + 4, sizeof(union ib_gid))) || (neigh->dev != dev))) { spin_lock_irqsave(&priv->lock, flags); @@ -743,7 +743,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } } else if (neigh->ah) { - ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha)); + ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha)); return NETDEV_TX_OK; } @@ -772,7 +772,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) && (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) { ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n", - skb_dst(skb) ? "neigh" : "dst", + skb->dst ? "neigh" : "dst", be16_to_cpup((__be16 *) skb->data), IPOIB_QPN(phdr->hwaddr), phdr->hwaddr + 4); @@ -817,7 +817,7 @@ static int ipoib_hard_header(struct sk_buff *skb, * destination address onto the front of the skb so we can * figure out where to send the packet later. */ - if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) { + if ((!skb->dst || !skb->dst->neighbour) && daddr) { struct ipoib_pseudoheader *phdr = (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); @@ -1053,7 +1053,6 @@ static void ipoib_setup(struct net_device *dev) dev->tx_queue_len = ipoib_sendq_size * 2; dev->features = (NETIF_F_VLAN_CHALLENGED | NETIF_F_HIGHDMA); - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index a0e97532e714..425e31112ed7 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -261,7 +261,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, skb->dev = dev; - if (!skb_dst(skb) || !skb_dst(skb)->neighbour) { + if (!skb->dst || !skb->dst->neighbour) { /* put pseudoheader back on for next time */ skb_push(skb, sizeof (struct ipoib_pseudoheader)); } @@ -707,10 +707,10 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) out: if (mcast && mcast->ah) { - if (skb_dst(skb) && - skb_dst(skb)->neighbour && - !*to_ipoib_neigh(skb_dst(skb)->neighbour)) { - struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, + if (skb->dst && + skb->dst->neighbour && + !*to_ipoib_neigh(skb->dst->neighbour)) { + struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev); if (neigh) { diff --git a/trunk/drivers/isdn/capi/capiutil.c b/trunk/drivers/isdn/capi/capiutil.c index 16f2e465e5f9..29419a8d31dc 100644 --- a/trunk/drivers/isdn/capi/capiutil.c +++ b/trunk/drivers/isdn/capi/capiutil.c @@ -490,14 +490,7 @@ static void pars_2_message(_cmsg * cmsg) } } -/** - * capi_cmsg2message() - assemble CAPI 2.0 message from _cmsg structure - * @cmsg: _cmsg structure - * @msg: buffer for assembled message - * - * Return value: 0 for success - */ - +/*-------------------------------------------------------*/ unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg) { cmsg->m = msg; @@ -560,14 +553,7 @@ static void message_2_pars(_cmsg * cmsg) } } -/** - * capi_message2cmsg() - disassemble CAPI 2.0 message into _cmsg structure - * @cmsg: _cmsg structure - * @msg: buffer for assembled message - * - * Return value: 0 for success - */ - +/*-------------------------------------------------------*/ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) { memset(cmsg, 0, sizeof(_cmsg)); @@ -587,18 +573,7 @@ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) return 0; } -/** - * capi_cmsg_header() - initialize header part of _cmsg structure - * @cmsg: _cmsg structure - * @_ApplId: ApplID field value - * @_Command: Command field value - * @_Subcommand: Subcommand field value - * @_Messagenumber: Message Number field value - * @_Controller: Controller/PLCI/NCCI field value - * - * Return value: 0 for success - */ - +/*-------------------------------------------------------*/ unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId, u8 _Command, u8 _Subcommand, u16 _Messagenumber, u32 _Controller) @@ -666,14 +641,6 @@ static char *mnames[] = [0x4e] = "MANUFACTURER_RESP" }; -/** - * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name - * @cmd: command number - * @subcmd: subcommand number - * - * Return value: static string, NULL if command/subcommand unknown - */ - char *capi_cmd2str(u8 cmd, u8 subcmd) { return mnames[command_2_index(cmd, subcmd)]; @@ -912,11 +879,6 @@ static _cdebbuf *cdebbuf_alloc(void) return cdb; } -/** - * cdebbuf_free() - free CAPI debug buffer - * @cdb: buffer to free - */ - void cdebbuf_free(_cdebbuf *cdb) { if (likely(cdb == g_debbuf)) { @@ -929,16 +891,6 @@ void cdebbuf_free(_cdebbuf *cdb) } -/** - * capi_message2str() - format CAPI 2.0 message for printing - * @msg: CAPI 2.0 message - * - * Allocates a CAPI debug buffer and fills it with a printable representation - * of the CAPI 2.0 message in @msg. - * Return value: allocated debug buffer, NULL on error - * The returned buffer should be freed by a call to cdebbuf_free() after use. - */ - _cdebbuf *capi_message2str(u8 * msg) { _cdebbuf *cdb; @@ -974,23 +926,10 @@ _cdebbuf *capi_message2str(u8 * msg) return cdb; } -/** - * capi_cmsg2str() - format _cmsg structure for printing - * @cmsg: _cmsg structure - * - * Allocates a CAPI debug buffer and fills it with a printable representation - * of the CAPI 2.0 message stored in @cmsg by a previous call to - * capi_cmsg2message() or capi_message2cmsg(). - * Return value: allocated debug buffer, NULL on error - * The returned buffer should be freed by a call to cdebbuf_free() after use. - */ - _cdebbuf *capi_cmsg2str(_cmsg * cmsg) { _cdebbuf *cdb; - if (!cmsg->m) - return NULL; /* no message */ cdb = cdebbuf_alloc(); if (!cdb) return NULL; diff --git a/trunk/drivers/isdn/capi/kcapi.c b/trunk/drivers/isdn/capi/kcapi.c index 57d26360f64e..f33170368cd1 100644 --- a/trunk/drivers/isdn/capi/kcapi.c +++ b/trunk/drivers/isdn/capi/kcapi.c @@ -377,14 +377,14 @@ void capi_ctr_ready(struct capi_ctr * card) EXPORT_SYMBOL(capi_ctr_ready); /** - * capi_ctr_down() - signal CAPI controller not ready + * capi_ctr_reseted() - signal CAPI controller reset * @card: controller descriptor structure. * * Called by hardware driver to signal that the controller is down and * unavailable for use. */ -void capi_ctr_down(struct capi_ctr * card) +void capi_ctr_reseted(struct capi_ctr * card) { u16 appl; @@ -413,7 +413,7 @@ void capi_ctr_down(struct capi_ctr * card) notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); } -EXPORT_SYMBOL(capi_ctr_down); +EXPORT_SYMBOL(capi_ctr_reseted); /** * capi_ctr_suspend_output() - suspend controller @@ -517,7 +517,7 @@ EXPORT_SYMBOL(attach_capi_ctr); int detach_capi_ctr(struct capi_ctr *card) { if (card->cardstate != CARD_DETECTED) - capi_ctr_down(card); + capi_ctr_reseted(card); ncards--; diff --git a/trunk/drivers/isdn/hardware/avm/b1.c b/trunk/drivers/isdn/hardware/avm/b1.c index a7c0083e78a7..abf05ec31760 100644 --- a/trunk/drivers/isdn/hardware/avm/b1.c +++ b/trunk/drivers/isdn/hardware/avm/b1.c @@ -330,7 +330,7 @@ void b1_reset_ctr(struct capi_ctr *ctrl) spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } void b1_register_appl(struct capi_ctr *ctrl, diff --git a/trunk/drivers/isdn/hardware/avm/b1dma.c b/trunk/drivers/isdn/hardware/avm/b1dma.c index 0e84aaae43fd..da34b98e3de7 100644 --- a/trunk/drivers/isdn/hardware/avm/b1dma.c +++ b/trunk/drivers/isdn/hardware/avm/b1dma.c @@ -759,7 +759,7 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl) memset(cinfo->version, 0, sizeof(cinfo->version)); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } /* ------------------------------------------------------------- */ diff --git a/trunk/drivers/isdn/hardware/avm/c4.c b/trunk/drivers/isdn/hardware/avm/c4.c index 6833301a45fc..9df1d3f66c87 100644 --- a/trunk/drivers/isdn/hardware/avm/c4.c +++ b/trunk/drivers/isdn/hardware/avm/c4.c @@ -681,7 +681,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(&cinfo->capi_ctrl); + capi_ctr_reseted(&cinfo->capi_ctrl); } card->nlogcontr = 0; return IRQ_HANDLED; @@ -909,7 +909,7 @@ static void c4_reset_ctr(struct capi_ctr *ctrl) for (i=0; i < card->nr_controllers; i++) { cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); - capi_ctr_down(&cinfo->capi_ctrl); + capi_ctr_reseted(&cinfo->capi_ctrl); } card->nlogcontr = 0; } diff --git a/trunk/drivers/isdn/hardware/avm/t1isa.c b/trunk/drivers/isdn/hardware/avm/t1isa.c index 1c53fd49adb6..e7724493738c 100644 --- a/trunk/drivers/isdn/hardware/avm/t1isa.c +++ b/trunk/drivers/isdn/hardware/avm/t1isa.c @@ -339,7 +339,7 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl) spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } static void t1isa_remove(struct pci_dev *pdev) diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c b/trunk/drivers/isdn/hardware/mISDN/hfcpci.c index 228ffbed1286..776afc8c9270 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/trunk/drivers/isdn/hardware/mISDN/hfcpci.c @@ -1806,9 +1806,10 @@ init_card(struct hfc_pci *hc) printk(KERN_WARNING "HFC PCI: IRQ(%d) getting no interrupts " "during init %d\n", hc->irq, 4 - cnt); - if (cnt == 1) - break; - else { + if (cnt == 1) { + spin_unlock_irqrestore(&hc->lock, flags); + return -EIO; + } else { reset_hfcpci(hc); cnt--; } diff --git a/trunk/drivers/isdn/hisax/hfc_pci.c b/trunk/drivers/isdn/hisax/hfc_pci.c index 3d337d924c23..f1265667b062 100644 --- a/trunk/drivers/isdn/hisax/hfc_pci.c +++ b/trunk/drivers/isdn/hisax/hfc_pci.c @@ -82,9 +82,8 @@ release_io_hfcpci(struct IsdnCardState *cs) Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */ del_timer(&cs->hw.hfcpci.timer); - pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, - cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); - cs->hw.hfcpci.fifos = NULL; + kfree(cs->hw.hfcpci.share_start); + cs->hw.hfcpci.share_start = NULL; iounmap((void *)cs->hw.hfcpci.pci_io); } @@ -1664,19 +1663,8 @@ setup_hfcpci(struct IsdnCard *card) dev_hfcpci); i++; if (tmp_hfcpci) { - dma_addr_t dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL; if (pci_enable_device(tmp_hfcpci)) continue; - if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) { - printk(KERN_WARNING - "HiSax hfc_pci: No suitable DMA available.\n"); - continue; - } - if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) { - printk(KERN_WARNING - "HiSax hfc_pci: No suitable consistent DMA available.\n"); - continue; - } pci_set_master(tmp_hfcpci); if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK))) continue; @@ -1705,29 +1693,22 @@ setup_hfcpci(struct IsdnCard *card) printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); return (0); } - /* Allocate memory for FIFOS */ - cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev, - 0x8000, &cs->hw.hfcpci.dma); - if (!cs->hw.hfcpci.fifos) { - printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n"); - return 0; - } - if (cs->hw.hfcpci.dma & 0x7fff) { - printk(KERN_WARNING - "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n", - (u_long)cs->hw.hfcpci.dma); - pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, - cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); + /* Because the HFC-PCI needs a 32K physical alignment, we */ + /* need to allocate the double mem and align the address */ + if (!(cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) { + printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n"); return 0; } - pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma); + cs->hw.hfcpci.fifos = (void *) + (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000; + pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos)); cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256); printk(KERN_INFO - "HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n", + "HFC-PCI: defined at mem %p fifo %p(%#x) IRQ %d HZ %d\n", cs->hw.hfcpci.pci_io, cs->hw.hfcpci.fifos, - (u_long)cs->hw.hfcpci.dma, + (u_int) virt_to_bus(cs->hw.hfcpci.fifos), cs->irq, HZ); spin_lock_irqsave(&cs->lock, flags); diff --git a/trunk/drivers/isdn/hisax/hisax.h b/trunk/drivers/isdn/hisax/hisax.h index 0685c1946969..f8527046f197 100644 --- a/trunk/drivers/isdn/hisax/hisax.h +++ b/trunk/drivers/isdn/hisax/hisax.h @@ -703,7 +703,7 @@ struct hfcPCI_hw { int nt_timer; struct pci_dev *dev; unsigned char *pci_io; /* start of PCI IO memory */ - dma_addr_t dma; /* dma handle for Fifos */ + void *share_start; /* shared memory for Fifos start */ void *fifos; /* FIFO memory */ int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */ struct timer_list timer; diff --git a/trunk/drivers/isdn/hysdn/hycapi.c b/trunk/drivers/isdn/hysdn/hycapi.c index 4ffaa14b9fc4..53f6ad1235db 100644 --- a/trunk/drivers/isdn/hysdn/hycapi.c +++ b/trunk/drivers/isdn/hysdn/hycapi.c @@ -67,7 +67,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl) printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n"); #endif capilib_release(&cinfo->ncci_head); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } /****************************** @@ -347,7 +347,7 @@ int hycapi_capi_stop(hysdn_card *card) if(cinfo) { ctrl = &cinfo->capi_ctrl; /* ctrl->suspend_output(ctrl); */ - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } return 0; } diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index b4d4522e5071..1a2222cbb805 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/drivers/isdn/i4l/isdn_tty.c @@ -1592,7 +1592,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp) int retval, line; line = tty->index; - if (line < 0 || line >= ISDN_MAX_CHANNELS) + if (line < 0 || line > ISDN_MAX_CHANNELS) return -ENODEV; info = &dev->mdm.info[line]; if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) diff --git a/trunk/drivers/isdn/mISDN/dsp_pipeline.c b/trunk/drivers/isdn/mISDN/dsp_pipeline.c index e9941678edfa..ac61f198eb32 100644 --- a/trunk/drivers/isdn/mISDN/dsp_pipeline.c +++ b/trunk/drivers/isdn/mISDN/dsp_pipeline.c @@ -55,19 +55,20 @@ static ssize_t attr_show_args(struct device *dev, struct device_attribute *attr, char *buf) { struct mISDN_dsp_element *elem = dev_get_drvdata(dev); - int i; - char *p = buf; + ssize_t len = 0; + int i = 0; *buf = 0; - for (i = 0; i < elem->num_args; i++) - p += sprintf(p, "Name: %s\n%s%s%sDescription: %s\n\n", + for (; i < elem->num_args; ++i) + len = sprintf(buf, "%sName: %s\n%s%s%sDescription: %s\n" + "\n", buf, elem->args[i].name, elem->args[i].def ? "Default: " : "", elem->args[i].def ? elem->args[i].def : "", elem->args[i].def ? "\n" : "", elem->args[i].desc); - return p - buf; + return len; } static struct device_attribute element_attributes[] = { diff --git a/trunk/drivers/isdn/mISDN/tei.c b/trunk/drivers/isdn/mISDN/tei.c index e04bad6c5baf..bfcdd97df95d 100644 --- a/trunk/drivers/isdn/mISDN/tei.c +++ b/trunk/drivers/isdn/mISDN/tei.c @@ -862,7 +862,8 @@ static int ph_data_ind(struct manager *mgr, struct sk_buff *skb) { int ret = -EINVAL; - struct layer2 *l2, *nl2; + struct layer2 *l2; + u_long flags; u_char mt; if (skb->len < 8) { @@ -907,9 +908,11 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb) new_tei_req(mgr, &skb->data[4]); goto done; } - list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) { + read_lock_irqsave(&mgr->lock, flags); + list_for_each_entry(l2, &mgr->layer2, list) { tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4); } + read_unlock_irqrestore(&mgr->lock, flags); done: return ret; } diff --git a/trunk/drivers/net/3c509.c b/trunk/drivers/net/3c509.c index d2137efbd455..8d9aa49de145 100644 --- a/trunk/drivers/net/3c509.c +++ b/trunk/drivers/net/3c509.c @@ -480,13 +480,9 @@ static int pnp_registered; #ifdef CONFIG_EISA static struct eisa_device_id el3_eisa_ids[] = { - { "TCM5090" }, - { "TCM5091" }, { "TCM5092" }, { "TCM5093" }, - { "TCM5094" }, { "TCM5095" }, - { "TCM5098" }, { "" } }; MODULE_DEVICE_TABLE(eisa, el3_eisa_ids); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 3f739cfd92fa..43a5254df98d 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1001,7 +1001,7 @@ config SMC911X config SMSC911X tristate "SMSC LAN911x/LAN921x families embedded ethernet support" - depends on ARM || SUPERH || BLACKFIN + depends on ARM || SUPERH select CRC32 select MII select PHYLIB @@ -1723,11 +1723,6 @@ config TLAN Please email feedback to . -config KS8842 - tristate "Micrel KSZ8842" - help - This platform driver is for Micrel KSZ8842 chip. - config VIA_RHINE tristate "VIA Rhine support" depends on NET_PCI && PCI @@ -1864,8 +1859,8 @@ config 68360_ENET the Motorola 68360 processor. config FEC - bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" - depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35 + bool "FEC ethernet controller (of ColdFire CPUs)" + depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 help Say Y here if you want to use the built-in 10/100 Fast ethernet controller on some Motorola ColdFire and Freescale i.MX processors. @@ -2725,8 +2720,6 @@ source "drivers/net/wan/Kconfig" source "drivers/atm/Kconfig" -source "drivers/ieee802154/Kconfig" - source "drivers/s390/net/Kconfig" config XEN_NETDEV_FRONTEND diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 1c378dd5933e..f07a1e956417 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -86,7 +86,6 @@ obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKY2) += sky2.o obj-$(CONFIG_SKFP) += skfp/ -obj-$(CONFIG_KS8842) += ks8842.o obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o @@ -106,7 +105,7 @@ obj-$(CONFIG_HAMACHI) += hamachi.o obj-$(CONFIG_NET) += Space.o loopback.o obj-$(CONFIG_SEEQ8005) += seeq8005.o obj-$(CONFIG_NET_SB1000) += sb1000.o -obj-$(CONFIG_MAC8390) += mac8390.o +obj-$(CONFIG_MAC8390) += mac8390.o 8390.o obj-$(CONFIG_APNE) += apne.o 8390.o obj-$(CONFIG_PCMCIA_PCNET) += 8390.o obj-$(CONFIG_HP100) += hp100.o diff --git a/trunk/drivers/net/acenic.c b/trunk/drivers/net/acenic.c index 08419ee10290..57bc71527850 100644 --- a/trunk/drivers/net/acenic.c +++ b/trunk/drivers/net/acenic.c @@ -2573,6 +2573,7 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_wake_queue(dev); } + dev->trans_start = jiffies; return NETDEV_TX_OK; overflow: diff --git a/trunk/drivers/net/appletalk/ipddp.c b/trunk/drivers/net/appletalk/ipddp.c index 78cea5e80b1d..f939e92fcf8a 100644 --- a/trunk/drivers/net/appletalk/ipddp.c +++ b/trunk/drivers/net/appletalk/ipddp.c @@ -39,7 +39,6 @@ static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson \n"; static struct ipddp_route *ipddp_route_list; -static DEFINE_SPINLOCK(ipddp_route_lock); #ifdef CONFIG_IPDDP_ENCAP static int ipddp_mode = IPDDP_ENCAP; @@ -51,7 +50,7 @@ static int ipddp_mode = IPDDP_DECAP; static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev); static int ipddp_create(struct ipddp_route *new_rt); static int ipddp_delete(struct ipddp_route *rt); -static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt); +static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt); static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static const struct net_device_ops ipddp_netdev_ops = { @@ -115,13 +114,11 @@ static struct net_device * __init ipddp_init(void) */ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) { - __be32 paddr = skb_rtable(skb)->rt_gateway; + __be32 paddr = ((struct rtable*)skb->dst)->rt_gateway; struct ddpehdr *ddp; struct ipddp_route *rt; struct atalk_addr *our_addr; - spin_lock(&ipddp_route_lock); - /* * Find appropriate route to use, based only on IP number. */ @@ -130,10 +127,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) if(rt->ip == paddr) break; } - if(rt == NULL) { - spin_unlock(&ipddp_route_lock); + if(rt == NULL) return 0; - } our_addr = atalk_find_dev_addr(rt->dev); @@ -179,8 +174,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0) dev_kfree_skb(skb); - spin_unlock(&ipddp_route_lock); - return 0; } @@ -203,9 +196,7 @@ static int ipddp_create(struct ipddp_route *new_rt) return -ENETUNREACH; } - spin_lock_bh(&ipddp_route_lock); - if (__ipddp_find_route(rt)) { - spin_unlock_bh(&ipddp_route_lock); + if (ipddp_find_route(rt)) { kfree(rt); return -EEXIST; } @@ -213,8 +204,6 @@ static int ipddp_create(struct ipddp_route *new_rt) rt->next = ipddp_route_list; ipddp_route_list = rt; - spin_unlock_bh(&ipddp_route_lock); - return 0; } @@ -227,7 +216,6 @@ static int ipddp_delete(struct ipddp_route *rt) struct ipddp_route **r = &ipddp_route_list; struct ipddp_route *tmp; - spin_lock_bh(&ipddp_route_lock); while((tmp = *r) != NULL) { if(tmp->ip == rt->ip @@ -235,21 +223,19 @@ static int ipddp_delete(struct ipddp_route *rt) && tmp->at.s_node == rt->at.s_node) { *r = tmp->next; - spin_unlock_bh(&ipddp_route_lock); kfree(tmp); return 0; } r = &tmp->next; } - spin_unlock_bh(&ipddp_route_lock); return (-ENOENT); } /* * Find a routing entry, we only return a FULL match */ -static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) +static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt) { struct ipddp_route *f; @@ -267,7 +253,7 @@ static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ipddp_route __user *rt = ifr->ifr_data; - struct ipddp_route rcp, rcp2, *rp; + struct ipddp_route rcp; if(!capable(CAP_NET_ADMIN)) return -EPERM; @@ -281,19 +267,9 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return (ipddp_create(&rcp)); case SIOCFINDIPDDPRT: - spin_lock_bh(&ipddp_route_lock); - rp = __ipddp_find_route(&rcp); - if (rp) - memcpy(&rcp2, rp, sizeof(rcp2)); - spin_unlock_bh(&ipddp_route_lock); - - if (rp) { - if (copy_to_user(rt, &rcp2, - sizeof(struct ipddp_route))) - return -EFAULT; - return 0; - } else - return -ENOENT; + if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route))) + return -EFAULT; + return 0; case SIOCDELIPDDPRT: return (ipddp_delete(&rcp)); diff --git a/trunk/drivers/net/arm/ep93xx_eth.c b/trunk/drivers/net/arm/ep93xx_eth.c index fbf4645417d4..b72b3d639f6e 100644 --- a/trunk/drivers/net/arm/ep93xx_eth.c +++ b/trunk/drivers/net/arm/ep93xx_eth.c @@ -253,7 +253,7 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) skb = dev_alloc_skb(length + 2); if (likely(skb != NULL)) { skb_reserve(skb, 2); - dma_sync_single_for_cpu(NULL, ep->descs->rdesc[entry].buf_addr, + dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr, length, DMA_FROM_DEVICE); skb_copy_to_linear_data(skb, ep->rx_buf[entry], length); skb_put(skb, length); @@ -331,7 +331,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) ep->descs->tdesc[entry].tdesc1 = TDESC1_EOF | (entry << 16) | (skb->len & 0xfff); skb_copy_and_csum_dev(skb, ep->tx_buf[entry]); - dma_sync_single_for_cpu(NULL, ep->descs->tdesc[entry].buf_addr, + dma_sync_single(NULL, ep->descs->tdesc[entry].buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb(skb); diff --git a/trunk/drivers/net/arm/ixp4xx_eth.c b/trunk/drivers/net/arm/ixp4xx_eth.c index 1fcf8388b1c8..322c49b908dc 100644 --- a/trunk/drivers/net/arm/ixp4xx_eth.c +++ b/trunk/drivers/net/arm/ixp4xx_eth.c @@ -561,8 +561,8 @@ static int eth_poll(struct napi_struct *napi, int budget) dma_unmap_single(&dev->dev, desc->data - NET_IP_ALIGN, RX_BUFF_SIZE, DMA_FROM_DEVICE); #else - dma_sync_single_for_cpu(&dev->dev, desc->data - NET_IP_ALIGN, - RX_BUFF_SIZE, DMA_FROM_DEVICE); + dma_sync_single(&dev->dev, desc->data - NET_IP_ALIGN, + RX_BUFF_SIZE, DMA_FROM_DEVICE); memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n], ALIGN(NET_IP_ALIGN + desc->pkt_len, 4) / 4); #endif diff --git a/trunk/drivers/net/atl1c/atl1c_ethtool.c b/trunk/drivers/net/atl1c/atl1c_ethtool.c index e4afbd628c23..45c5b7332cd3 100644 --- a/trunk/drivers/net/atl1c/atl1c_ethtool.c +++ b/trunk/drivers/net/atl1c/atl1c_ethtool.c @@ -271,7 +271,7 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) struct atl1c_adapter *adapter = netdev_priv(netdev); if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | - WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) + WAKE_MCAST | WAKE_BCAST | WAKE_MCAST)) return -EOPNOTSUPP; /* these settings will always override what we currently have */ adapter->wol = 0; diff --git a/trunk/drivers/net/atl1c/atl1c_main.c b/trunk/drivers/net/atl1c/atl1c_main.c index cd547a205fb9..fc1092b835d2 100644 --- a/trunk/drivers/net/atl1c/atl1c_main.c +++ b/trunk/drivers/net/atl1c/atl1c_main.c @@ -163,24 +163,6 @@ static inline void atl1c_irq_reset(struct atl1c_adapter *adapter) atl1c_irq_enable(adapter); } -/* - * atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads - * of the idle status register until the device is actually idle - */ -static u32 atl1c_wait_until_idle(struct atl1c_hw *hw) -{ - int timeout; - u32 data; - - for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { - AT_READ_REG(hw, REG_IDLE_STATUS, &data); - if ((data & IDLE_STATUS_MASK) == 0) - return 0; - msleep(1); - } - return data; -} - /* * atl1c_phy_config - Timer Call-back * @data: pointer to netdev cast into an unsigned long @@ -1124,6 +1106,7 @@ static void atl1c_configure_dma(struct atl1c_adapter *adapter) static int atl1c_stop_mac(struct atl1c_hw *hw) { u32 data; + int timeout; AT_READ_REG(hw, REG_RXQ_CTRL, &data); data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN | @@ -1134,13 +1117,25 @@ static int atl1c_stop_mac(struct atl1c_hw *hw) data &= ~TXQ_CTRL_EN; AT_WRITE_REG(hw, REG_TWSI_CTRL, data); - atl1c_wait_until_idle(hw); + for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { + AT_READ_REG(hw, REG_IDLE_STATUS, &data); + if ((data & (IDLE_STATUS_RXQ_NO_IDLE | + IDLE_STATUS_TXQ_NO_IDLE)) == 0) + break; + msleep(1); + } AT_READ_REG(hw, REG_MAC_CTRL, &data); data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN); AT_WRITE_REG(hw, REG_MAC_CTRL, data); - return (int)atl1c_wait_until_idle(hw); + for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { + AT_READ_REG(hw, REG_IDLE_STATUS, &data); + if ((data & IDLE_STATUS_MASK) == 0) + return 0; + msleep(1); + } + return data; } static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw) @@ -1183,6 +1178,8 @@ static int atl1c_reset_mac(struct atl1c_hw *hw) { struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; struct pci_dev *pdev = adapter->pdev; + u32 idle_status_data = 0; + int timeout = 0; int ret; AT_WRITE_REG(hw, REG_IMR, 0); @@ -1201,10 +1198,15 @@ static int atl1c_reset_mac(struct atl1c_hw *hw) AT_WRITE_FLUSH(hw); msleep(10); /* Wait at least 10ms for All module to be Idle */ - - if (atl1c_wait_until_idle(hw)) { + for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) { + AT_READ_REG(hw, REG_IDLE_STATUS, &idle_status_data); + if ((idle_status_data & IDLE_STATUS_MASK) == 0) + break; + msleep(1); + } + if (timeout >= AT_HW_MAX_IDLE_DELAY) { dev_err(&pdev->dev, - "MAC state machine can't be idle since" + "MAC state machine cann't be idle since" " disabled for 10ms second\n"); return -1; } @@ -2111,6 +2113,7 @@ static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev) atl1c_tx_map(adapter, skb, tpd, type); atl1c_tx_queue(adapter, skb, tpd, type); + netdev->trans_start = jiffies; spin_unlock_irqrestore(&adapter->tx_lock, flags); return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/atl1e/atl1e_main.c b/trunk/drivers/net/atl1e/atl1e_main.c index 9fc6d6d9060e..c271b7537fab 100644 --- a/trunk/drivers/net/atl1e/atl1e_main.c +++ b/trunk/drivers/net/atl1e/atl1e_main.c @@ -37,7 +37,6 @@ char atl1e_driver_version[] = DRV_VERSION; */ static struct pci_device_id atl1e_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)}, - {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)}, /* required last entry */ { 0 } }; @@ -1602,7 +1601,7 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb) } if (skb_is_gso(skb)) { - if (skb->protocol == htons(ETH_P_IP) || + if (skb->protocol == ntohs(ETH_P_IP) || (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) { proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); @@ -1878,7 +1877,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev) TPD_VLAN_SHIFT; } - if (skb->protocol == htons(ETH_P_8021Q)) + if (skb->protocol == ntohs(ETH_P_8021Q)) tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT; if (skb_network_offset(skb) != ETH_HLEN) @@ -1894,7 +1893,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev) atl1e_tx_map(adapter, skb, tpd); atl1e_tx_queue(adapter, tpd_req, tpd); - netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ + netdev->trans_start = jiffies; spin_unlock_irqrestore(&adapter->tx_lock, flags); return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/atlx/atl1.c b/trunk/drivers/net/atlx/atl1.c index 94d7325caf4f..13f0bdc32449 100644 --- a/trunk/drivers/net/atlx/atl1.c +++ b/trunk/drivers/net/atlx/atl1.c @@ -82,12 +82,6 @@ #include "atl1.h" -#define ATLX_DRIVER_VERSION "2.1.3" -MODULE_AUTHOR("Xiong Huang , \ - Chris Snook , Jay Cliburn "); -MODULE_LICENSE("GPL"); -MODULE_VERSION(ATLX_DRIVER_VERSION); - /* Temporary hack for merging atl1 and atl2 */ #include "atlx.c" @@ -2382,7 +2376,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) mss = skb_shinfo(skb)->gso_size; if (mss) { - if (skb->protocol == htons(ETH_P_IP)) { + if (skb->protocol == ntohs(ETH_P_IP)) { proto_hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); if (unlikely(proto_hdr_len > len)) { @@ -2437,6 +2431,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) atl1_tx_queue(adapter, count, ptpd); atl1_update_mailbox(adapter); mmiowb(); + netdev->trans_start = jiffies; return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/atlx/atlx.h b/trunk/drivers/net/atlx/atlx.h index 14054b75aa62..297a03da6b7f 100644 --- a/trunk/drivers/net/atlx/atlx.h +++ b/trunk/drivers/net/atlx/atlx.h @@ -29,6 +29,12 @@ #include #include +#define ATLX_DRIVER_VERSION "2.1.3" +MODULE_AUTHOR("Xiong Huang , \ + Chris Snook , Jay Cliburn "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(ATLX_DRIVER_VERSION); + #define ATLX_ERR_PHY 2 #define ATLX_ERR_PHY_SPEED 7 #define ATLX_ERR_PHY_RES 8 diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index 36d4d377ec2f..b70b81ec34c3 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -782,7 +782,7 @@ static int b44_rx(struct b44 *bp, int budget) drop_it: b44_recycle_rx(bp, cons, bp->rx_prod); drop_it_no_recycle: - bp->dev->stats.rx_dropped++; + bp->stats.rx_dropped++; goto next_pkt; } @@ -1647,7 +1647,7 @@ static int b44_close(struct net_device *dev) static struct net_device_stats *b44_get_stats(struct net_device *dev) { struct b44 *bp = netdev_priv(dev); - struct net_device_stats *nstat = &dev->stats; + struct net_device_stats *nstat = &bp->stats; struct b44_hw_stats *hwstat = &bp->hw_stats; /* Convert HW stats into netdevice stats. */ diff --git a/trunk/drivers/net/b44.h b/trunk/drivers/net/b44.h index 0443f6801f60..e678498de6db 100644 --- a/trunk/drivers/net/b44.h +++ b/trunk/drivers/net/b44.h @@ -384,6 +384,7 @@ struct b44 { struct timer_list timer; + struct net_device_stats stats; struct b44_hw_stats hw_stats; struct ssb_device *sdev; diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 66bb56874d9b..ae2f6b58ba25 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -168,7 +168,6 @@ static void netdev_stats_update(struct be_adapter *adapter) struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; struct net_device_stats *dev_stats = &adapter->stats.net_stats; - struct be_erx_stats *erx_stats = &hw_stats->erx; dev_stats->rx_packets = port_stats->rx_total_frames; dev_stats->tx_packets = port_stats->tx_unicastframes + @@ -182,33 +181,29 @@ static void netdev_stats_update(struct be_adapter *adapter) dev_stats->rx_errors = port_stats->rx_crc_errors + port_stats->rx_alignment_symbol_errors + port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + - port_stats->rx_frame_too_long + - port_stats->rx_dropped_too_small + - port_stats->rx_dropped_too_short + - port_stats->rx_dropped_header_too_small + - port_stats->rx_dropped_tcp_length + - port_stats->rx_dropped_runt + - port_stats->rx_tcp_checksum_errs + - port_stats->rx_ip_checksum_errs + - port_stats->rx_udp_checksum_errs; - - /* no space in linux buffers: best possible approximation */ - dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0]; + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; + + /* packet transmit problems */ + dev_stats->tx_errors = 0; + + /* no space in linux buffers */ + dev_stats->rx_dropped = 0; + + /* no space available in linux */ + dev_stats->tx_dropped = 0; + + dev_stats->multicast = port_stats->tx_multicastframes; + dev_stats->collisions = 0; /* detailed rx errors */ dev_stats->rx_length_errors = port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + - port_stats->rx_frame_too_long; - + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; /* receive ring buffer overflow */ dev_stats->rx_over_errors = 0; - dev_stats->rx_crc_errors = port_stats->rx_crc_errors; /* frame alignment errors */ dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; - /* receiver fifo overrun */ /* drops_no_pbuf is no per i/f, it's per BE card */ dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + @@ -216,16 +211,6 @@ static void netdev_stats_update(struct be_adapter *adapter) rxf_stats->rx_drops_no_pbuf; /* receiver missed packetd */ dev_stats->rx_missed_errors = 0; - - /* packet transmit problems */ - dev_stats->tx_errors = 0; - - /* no space available in linux */ - dev_stats->tx_dropped = 0; - - dev_stats->multicast = port_stats->tx_multicastframes; - dev_stats->collisions = 0; - /* detailed tx_errors */ dev_stats->tx_aborted_errors = 0; dev_stats->tx_carrier_errors = 0; @@ -352,10 +337,13 @@ static void be_tx_stats_update(struct be_adapter *adapter, /* Determine number of WRB entries needed to xmit data in an skb */ static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) { - int cnt = (skb->len > skb->data_len); - - cnt += skb_shinfo(skb)->nr_frags; - + int cnt = 0; + while (skb) { + if (skb->len > skb->data_len) + cnt++; + cnt += skb_shinfo(skb)->nr_frags; + skb = skb_shinfo(skb)->frag_list; + } /* to account for hdr wrb */ cnt++; if (cnt & 1) { @@ -421,28 +409,31 @@ static int make_tx_wrbs(struct be_adapter *adapter, hdr = queue_head_node(txq); queue_head_inc(txq); - if (skb->len > skb->data_len) { - int len = skb->len - skb->data_len; - busaddr = pci_map_single(pdev, skb->data, len, - PCI_DMA_TODEVICE); - wrb = queue_head_node(txq); - wrb_fill(wrb, busaddr, len); - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - queue_head_inc(txq); - copied += len; - } + while (skb) { + if (skb->len > skb->data_len) { + int len = skb->len - skb->data_len; + busaddr = pci_map_single(pdev, skb->data, len, + PCI_DMA_TODEVICE); + wrb = queue_head_node(txq); + wrb_fill(wrb, busaddr, len); + be_dws_cpu_to_le(wrb, sizeof(*wrb)); + queue_head_inc(txq); + copied += len; + } - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - struct skb_frag_struct *frag = - &skb_shinfo(skb)->frags[i]; - busaddr = pci_map_page(pdev, frag->page, - frag->page_offset, - frag->size, PCI_DMA_TODEVICE); - wrb = queue_head_node(txq); - wrb_fill(wrb, busaddr, frag->size); - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - queue_head_inc(txq); - copied += frag->size; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + struct skb_frag_struct *frag = + &skb_shinfo(skb)->frags[i]; + busaddr = pci_map_page(pdev, frag->page, + frag->page_offset, + frag->size, PCI_DMA_TODEVICE); + wrb = queue_head_node(txq); + wrb_fill(wrb, busaddr, frag->size); + be_dws_cpu_to_le(wrb, sizeof(*wrb)); + queue_head_inc(txq); + copied += frag->size; + } + skb = skb_shinfo(skb)->frag_list; } if (dummy_wrb) { @@ -487,6 +478,8 @@ static int be_xmit(struct sk_buff *skb, struct net_device *netdev) be_txq_notify(&adapter->ctrl, txq->id, wrb_cnt); + netdev->trans_start = jiffies; + be_tx_stats_update(adapter, wrb_cnt, copied, stopped); return NETDEV_TX_OK; } @@ -743,7 +736,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, if (pktsize <= rx_frag_size) { BUG_ON(num_rcvd != 1); - goto done; + return; } /* More frags present for this completion */ @@ -765,7 +758,6 @@ static void skb_fill_rx_data(struct be_adapter *adapter, memset(page_info, 0, sizeof(*page_info)); } -done: be_rx_stats_update(adapter, pktsize, num_rcvd); return; } @@ -876,19 +868,12 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); + rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; + queue_tail_inc(&adapter->rx_obj.cq); return rxcp; } -/* To reset the valid bit, we need to reset the whole word as - * when walking the queue the valid entries are little-endian - * and invalid entries are host endian - */ -static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp) -{ - rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; -} - static inline struct page *be_alloc_pages(u32 size) { gfp_t alloc_flags = GFP_ATOMIC; @@ -1020,7 +1005,6 @@ static void be_rx_q_clean(struct be_adapter *adapter) /* First cleanup pending rx completions */ while ((rxcp = be_rx_compl_get(adapter)) != NULL) { be_rx_compl_discard(adapter, rxcp); - be_rx_compl_reset(rxcp); be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1); } @@ -1056,13 +1040,8 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) struct be_queue_info *q; q = &adapter->tx_obj.q; - if (q->created) { + if (q->created) be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ); - - /* No more tx completions can be rcvd now; clean up if there - * are any pending completions or pending tx requests */ - be_tx_q_clean(adapter); - } be_queue_free(adapter, q); q = &adapter->tx_obj.cq; @@ -1070,6 +1049,10 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); be_queue_free(adapter, q); + /* No more tx completions can be rcvd now; clean up if there are + * any pending completions or pending tx requests */ + be_tx_q_clean(adapter); + q = &adapter->tx_eq.q; if (q->created) be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); @@ -1303,8 +1286,6 @@ int be_poll_rx(struct napi_struct *napi, int budget) be_rx_compl_process_lro(adapter, rxcp); else be_rx_compl_process(adapter, rxcp); - - be_rx_compl_reset(rxcp); } lro_flush_all(&adapter->rx_obj.lro_mgr); @@ -1560,7 +1541,7 @@ static int be_close(struct net_device *netdev) struct be_eq_obj *tx_eq = &adapter->tx_eq; int vec; - cancel_delayed_work_sync(&adapter->work); + cancel_delayed_work(&adapter->work); netif_stop_queue(netdev); netif_carrier_off(netdev); diff --git a/trunk/drivers/net/bfin_mac.c b/trunk/drivers/net/bfin_mac.c index c15fc281f79f..9f971ed6b58d 100644 --- a/trunk/drivers/net/bfin_mac.c +++ b/trunk/drivers/net/bfin_mac.c @@ -194,13 +194,13 @@ static int desc_list_init(void) struct dma_descriptor *b = &(r->desc_b); /* allocate a new skb for next time receive */ - new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN); + new_skb = dev_alloc_skb(PKT_BUF_SZ + 2); if (!new_skb) { printk(KERN_NOTICE DRV_NAME ": init: low on mem - packet dropped\n"); goto init_error; } - skb_reserve(new_skb, NET_IP_ALIGN); + skb_reserve(new_skb, 2); r->skb = new_skb; /* @@ -566,9 +566,9 @@ static void adjust_tx_list(void) */ if (current_tx_ptr->next->next == tx_list_head) { while (tx_list_head->status.status_word == 0) { - udelay(10); + mdelay(1); if (tx_list_head->status.status_word != 0 - || !(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)) { + || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) { goto adjust_head; } if (timeout_cnt-- < 0) { @@ -606,41 +606,93 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { u16 *data; - u32 data_align = (unsigned long)(skb->data) & 0x3; + current_tx_ptr->skb = skb; - if (data_align == 0x2) { - /* move skb->data to current_tx_ptr payload */ - data = (u16 *)(skb->data) - 1; - *data = (u16)(skb->len); - current_tx_ptr->desc_a.start_addr = (u32)data; - /* this is important! */ - blackfin_dcache_flush_range((u32)data, - (u32)((u8 *)data + skb->len + 4)); + if (ANOMALY_05000285) { + /* + * TXDWA feature is not avaible to older revision < 0.3 silicon + * of BF537 + * + * Only if data buffer is ODD WORD alignment, we do not + * need to memcpy + */ + u32 data_align = (u32)(skb->data) & 0x3; + if (data_align == 0x2) { + /* move skb->data to current_tx_ptr payload */ + data = (u16 *)(skb->data) - 1; + *data = (u16)(skb->len); + current_tx_ptr->desc_a.start_addr = (u32)data; + /* this is important! */ + blackfin_dcache_flush_range((u32)data, + (u32)((u8 *)data + skb->len + 4)); + } else { + *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); + memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, + skb->len); + current_tx_ptr->desc_a.start_addr = + (u32)current_tx_ptr->packet; + if (current_tx_ptr->status.status_word != 0) + current_tx_ptr->status.status_word = 0; + blackfin_dcache_flush_range( + (u32)current_tx_ptr->packet, + (u32)(current_tx_ptr->packet + skb->len + 2)); + } } else { - *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); - memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, - skb->len); - current_tx_ptr->desc_a.start_addr = - (u32)current_tx_ptr->packet; - if (current_tx_ptr->status.status_word != 0) - current_tx_ptr->status.status_word = 0; - blackfin_dcache_flush_range( - (u32)current_tx_ptr->packet, - (u32)(current_tx_ptr->packet + skb->len + 2)); + /* + * TXDWA feature is avaible to revision < 0.3 silicon of + * BF537 and always avaible to BF52x + */ + u32 data_align = (u32)(skb->data) & 0x3; + if (data_align == 0x0) { + u16 sysctl = bfin_read_EMAC_SYSCTL(); + sysctl |= TXDWA; + bfin_write_EMAC_SYSCTL(sysctl); + + /* move skb->data to current_tx_ptr payload */ + data = (u16 *)(skb->data) - 2; + *data = (u16)(skb->len); + current_tx_ptr->desc_a.start_addr = (u32)data; + /* this is important! */ + blackfin_dcache_flush_range( + (u32)data, + (u32)((u8 *)data + skb->len + 4)); + } else if (data_align == 0x2) { + u16 sysctl = bfin_read_EMAC_SYSCTL(); + sysctl &= ~TXDWA; + bfin_write_EMAC_SYSCTL(sysctl); + + /* move skb->data to current_tx_ptr payload */ + data = (u16 *)(skb->data) - 1; + *data = (u16)(skb->len); + current_tx_ptr->desc_a.start_addr = (u32)data; + /* this is important! */ + blackfin_dcache_flush_range( + (u32)data, + (u32)((u8 *)data + skb->len + 4)); + } else { + u16 sysctl = bfin_read_EMAC_SYSCTL(); + sysctl &= ~TXDWA; + bfin_write_EMAC_SYSCTL(sysctl); + + *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); + memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, + skb->len); + current_tx_ptr->desc_a.start_addr = + (u32)current_tx_ptr->packet; + if (current_tx_ptr->status.status_word != 0) + current_tx_ptr->status.status_word = 0; + blackfin_dcache_flush_range( + (u32)current_tx_ptr->packet, + (u32)(current_tx_ptr->packet + skb->len + 2)); + } } - /* make sure the internal data buffers in the core are drained - * so that the DMA descriptors are completely written when the - * DMA engine goes to fetch them below - */ - SSYNC(); - /* enable this packet's dma */ current_tx_ptr->desc_a.config |= DMAEN; /* tx dma is running, just return */ - if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN) + if (bfin_read_DMA2_IRQ_STATUS() & 0x08) goto out; /* tx dma is not running */ @@ -666,7 +718,7 @@ static void bfin_mac_rx(struct net_device *dev) /* allocate a new skb for next time receive */ skb = current_rx_ptr->skb; - new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN); + new_skb = dev_alloc_skb(PKT_BUF_SZ + 2); if (!new_skb) { printk(KERN_NOTICE DRV_NAME ": rx: low on mem - packet dropped\n"); @@ -674,7 +726,7 @@ static void bfin_mac_rx(struct net_device *dev) goto out; } /* reserve 2 bytes for RXDWA padding */ - skb_reserve(new_skb, NET_IP_ALIGN); + skb_reserve(new_skb, 2); current_rx_ptr->skb = new_skb; current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2; @@ -927,7 +979,22 @@ static int bfin_mac_open(struct net_device *dev) return 0; } +static const struct net_device_ops bfin_mac_netdev_ops = { + .ndo_open = bfin_mac_open, + .ndo_stop = bfin_mac_close, + .ndo_start_xmit = bfin_mac_hard_start_xmit, + .ndo_set_mac_address = bfin_mac_set_mac_address, + .ndo_tx_timeout = bfin_mac_timeout, + .ndo_set_multicast_list = bfin_mac_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = bfin_mac_poll, +#endif +}; + /* + * * this makes the board clean up everything that it can * and not talk to the outside world. Caused by * an 'ifconfig ethX down' @@ -952,26 +1019,11 @@ static int bfin_mac_close(struct net_device *dev) return 0; } -static const struct net_device_ops bfin_mac_netdev_ops = { - .ndo_open = bfin_mac_open, - .ndo_stop = bfin_mac_close, - .ndo_start_xmit = bfin_mac_hard_start_xmit, - .ndo_set_mac_address = bfin_mac_set_mac_address, - .ndo_tx_timeout = bfin_mac_timeout, - .ndo_set_multicast_list = bfin_mac_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = bfin_mac_poll, -#endif -}; - static int __devinit bfin_mac_probe(struct platform_device *pdev) { struct net_device *ndev; struct bfin_mac_local *lp; - struct platform_device *pd; - int rc; + int rc, i; ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); if (!ndev) { @@ -996,6 +1048,13 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) goto out_err_probe_mac; } + /* set the GPIO pins to Ethernet mode */ + rc = peripheral_request_list(pin_req, DRV_NAME); + if (rc) { + dev_err(&pdev->dev, "Requesting peripherals failed!\n"); + rc = -EFAULT; + goto out_err_setup_pin_mux; + } /* * Is it valid? (Did bootloader initialize it?) @@ -1011,14 +1070,26 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) setup_mac_addr(ndev->dev_addr); - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n"); - rc = -ENODEV; - goto out_err_probe_mac; - } - pd = pdev->dev.platform_data; - lp->mii_bus = platform_get_drvdata(pd); + /* MDIO bus initial */ + lp->mii_bus = mdiobus_alloc(); + if (lp->mii_bus == NULL) + goto out_err_mdiobus_alloc; + lp->mii_bus->priv = ndev; + lp->mii_bus->read = bfin_mdiobus_read; + lp->mii_bus->write = bfin_mdiobus_write; + lp->mii_bus->reset = bfin_mdiobus_reset; + lp->mii_bus->name = "bfin_mac_mdio"; + snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "0"); + lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); + for (i = 0; i < PHY_MAX_ADDR; ++i) + lp->mii_bus->irq[i] = PHY_POLL; + + rc = mdiobus_register(lp->mii_bus); + if (rc) { + dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); + goto out_err_mdiobus_register; + } rc = mii_probe(ndev); if (rc) { @@ -1037,7 +1108,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) /* now, enable interrupts */ /* register irq handler */ rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt, - IRQF_DISABLED, "EMAC_RX", ndev); + IRQF_DISABLED | IRQF_SHARED, "EMAC_RX", ndev); if (rc) { dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n"); rc = -EBUSY; @@ -1060,8 +1131,11 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) out_err_request_irq: out_err_mii_probe: mdiobus_unregister(lp->mii_bus); +out_err_mdiobus_register: mdiobus_free(lp->mii_bus); +out_err_mdiobus_alloc: peripheral_free_list(pin_req); +out_err_setup_pin_mux: out_err_probe_mac: platform_set_drvdata(pdev, NULL); free_netdev(ndev); @@ -1076,7 +1150,8 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); - lp->mii_bus->priv = NULL; + mdiobus_unregister(lp->mii_bus); + mdiobus_free(lp->mii_bus); unregister_netdev(ndev); @@ -1114,74 +1189,6 @@ static int bfin_mac_resume(struct platform_device *pdev) #define bfin_mac_resume NULL #endif /* CONFIG_PM */ -static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) -{ - struct mii_bus *miibus; - int rc, i; - - /* - * We are setting up a network card, - * so set the GPIO pins to Ethernet mode - */ - rc = peripheral_request_list(pin_req, DRV_NAME); - if (rc) { - dev_err(&pdev->dev, "Requesting peripherals failed!\n"); - return rc; - } - - rc = -ENOMEM; - miibus = mdiobus_alloc(); - if (miibus == NULL) - goto out_err_alloc; - miibus->read = bfin_mdiobus_read; - miibus->write = bfin_mdiobus_write; - miibus->reset = bfin_mdiobus_reset; - - miibus->parent = &pdev->dev; - miibus->name = "bfin_mii_bus"; - snprintf(miibus->id, MII_BUS_ID_SIZE, "0"); - miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); - if (miibus->irq == NULL) - goto out_err_alloc; - for (i = 0; i < PHY_MAX_ADDR; ++i) - miibus->irq[i] = PHY_POLL; - - rc = mdiobus_register(miibus); - if (rc) { - dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); - goto out_err_mdiobus_register; - } - - platform_set_drvdata(pdev, miibus); - return 0; - -out_err_mdiobus_register: - mdiobus_free(miibus); -out_err_alloc: - peripheral_free_list(pin_req); - - return rc; -} - -static int __devexit bfin_mii_bus_remove(struct platform_device *pdev) -{ - struct mii_bus *miibus = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); - mdiobus_unregister(miibus); - mdiobus_free(miibus); - peripheral_free_list(pin_req); - return 0; -} - -static struct platform_driver bfin_mii_bus_driver = { - .probe = bfin_mii_bus_probe, - .remove = __devexit_p(bfin_mii_bus_remove), - .driver = { - .name = "bfin_mii_bus", - .owner = THIS_MODULE, - }, -}; - static struct platform_driver bfin_mac_driver = { .probe = bfin_mac_probe, .remove = __devexit_p(bfin_mac_remove), @@ -1195,11 +1202,7 @@ static struct platform_driver bfin_mac_driver = { static int __init bfin_mac_init(void) { - int ret; - ret = platform_driver_register(&bfin_mii_bus_driver); - if (!ret) - return platform_driver_register(&bfin_mac_driver); - return -ENODEV; + return platform_driver_register(&bfin_mac_driver); } module_init(bfin_mac_init); @@ -1207,7 +1210,6 @@ module_init(bfin_mac_init); static void __exit bfin_mac_cleanup(void) { platform_driver_unregister(&bfin_mac_driver); - platform_driver_unregister(&bfin_mii_bus_driver); } module_exit(bfin_mac_cleanup); diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index f99e17e0a319..c37acc1d10ac 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -48,7 +48,6 @@ #include #include #include -#include #include "bnx2.h" #include "bnx2_fw.h" @@ -546,7 +545,8 @@ bnx2_free_rx_mem(struct bnx2 *bp) rxr->rx_desc_mapping[j]); rxr->rx_desc_ring[j] = NULL; } - vfree(rxr->rx_buf_ring); + if (rxr->rx_buf_ring) + vfree(rxr->rx_buf_ring); rxr->rx_buf_ring = NULL; for (j = 0; j < bp->rx_max_pg_ring; j++) { @@ -556,7 +556,8 @@ bnx2_free_rx_mem(struct bnx2 *bp) rxr->rx_pg_desc_mapping[j]); rxr->rx_pg_desc_ring[j] = NULL; } - vfree(rxr->rx_pg_ring); + if (rxr->rx_pg_ring) + vfree(rxr->rx_pg_ring); rxr->rx_pg_ring = NULL; } } @@ -3309,7 +3310,7 @@ bnx2_set_rx_mode(struct net_device *dev) { struct bnx2 *bp = netdev_priv(dev); u32 rx_mode, sort_mode; - struct netdev_hw_addr *ha; + struct dev_addr_list *uc_ptr; int i; if (!netif_running(dev)) @@ -3368,19 +3369,21 @@ bnx2_set_rx_mode(struct net_device *dev) sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; } + uc_ptr = NULL; if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) { rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | BNX2_RPM_SORT_USER0_PROM_VLAN; } else if (!(dev->flags & IFF_PROMISC)) { + uc_ptr = dev->uc_list; + /* Add all entries into to the match filter list */ - i = 0; - list_for_each_entry(ha, &dev->uc_list, list) { - bnx2_set_mac_addr(bp, ha->addr, + for (i = 0; i < dev->uc_count; i++) { + bnx2_set_mac_addr(bp, uc_ptr->da_addr, i + BNX2_START_UNICAST_ADDRESS_INDEX); sort_mode |= (1 << (i + BNX2_START_UNICAST_ADDRESS_INDEX)); - i++; + uc_ptr = uc_ptr->next; } } @@ -5485,7 +5488,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) dev_kfree_skb(skb); return -EIO; } - map = skb_shinfo(skb)->dma_head; + map = skb_shinfo(skb)->dma_maps[0]; REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); @@ -6165,7 +6168,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) } sp = skb_shinfo(skb); - mapping = sp->dma_head; + mapping = sp->dma_maps[0]; tx_buf = &txr->tx_buf_ring[ring_prod]; tx_buf->skb = skb; @@ -6189,7 +6192,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) txbd = &txr->tx_desc_ring[ring_prod]; len = frag->size; - mapping = sp->dma_maps[i]; + mapping = sp->dma_maps[i + 1]; txbd->tx_bd_haddr_hi = (u64) mapping >> 32; txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff; @@ -6208,6 +6211,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) mmiowb(); txr->tx_prod = prod; + dev->trans_start = jiffies; if (unlikely(bnx2_tx_avail(bp, txr) <= MAX_SKB_FRAGS)) { netif_tx_stop_queue(txq); diff --git a/trunk/drivers/net/bnx2x_main.c b/trunk/drivers/net/bnx2x_main.c index fbf1352e9c1c..e01539c33b8a 100644 --- a/trunk/drivers/net/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x_main.c @@ -10617,6 +10617,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) mmiowb(); fp->tx_bd_prod += nbd; + dev->trans_start = jiffies; if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { /* We want bnx2x_tx_int to "see" the updated tx_bd_prod diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 2f4329e91a4c..92a9d69c5650 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -2405,7 +2405,8 @@ static void bond_miimon_commit(struct bonding *bond) bond_3ad_handle_link_change(slave, BOND_LINK_DOWN); - if (bond_is_lb(bond)) + if (bond->params.mode == BOND_MODE_TLB || + bond->params.mode == BOND_MODE_ALB) bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN); diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index 5fb861a08664..3a1b7b04eb79 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -1541,7 +1541,6 @@ int bond_create_sysfs(void) printk(KERN_ERR "network device named %s already exists in sysfs", class_attr_bonding_masters.attr.name); - ret = 0; } return ret; diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index 41ceca12c68f..ca849d2adf98 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -286,7 +286,8 @@ static inline unsigned long slave_last_rx(struct bonding *bond, static inline void bond_set_slave_inactive_flags(struct slave *slave) { struct bonding *bond = netdev_priv(slave->dev->master); - if (!bond_is_lb(bond)) + if (bond->params.mode != BOND_MODE_TLB && + bond->params.mode != BOND_MODE_ALB) slave->state = BOND_STATE_BACKUP; slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; if (slave_do_arp_validate(bond, slave)) diff --git a/trunk/drivers/net/can/Kconfig b/trunk/drivers/net/can/Kconfig index d5e18812bf49..cfd6c5a285fa 100644 --- a/trunk/drivers/net/can/Kconfig +++ b/trunk/drivers/net/can/Kconfig @@ -51,15 +51,6 @@ config CAN_SJA1000_PLATFORM boards from Phytec (http://www.phytec.de) like the PCM027, PCM038. -config CAN_SJA1000_OF_PLATFORM - depends on CAN_SJA1000 && PPC_OF - tristate "Generic OF Platform Bus based SJA1000 driver" - ---help--- - This driver adds support for the SJA1000 chips connected to - the OpenFirmware "platform bus" found on embedded systems with - OpenFirmware bindings, e.g. if you have a PowerPC based system - you may want to enable this option. - config CAN_EMS_PCI tristate "EMS CPC-PCI and CPC-PCIe Card" depends on PCI && CAN_SJA1000 diff --git a/trunk/drivers/net/can/dev.c b/trunk/drivers/net/can/dev.c index 574daddc21bf..52b0e7d8901d 100644 --- a/trunk/drivers/net/can/dev.c +++ b/trunk/drivers/net/can/dev.c @@ -477,7 +477,7 @@ int open_candev(struct net_device *dev) return 0; } -EXPORT_SYMBOL_GPL(open_candev); +EXPORT_SYMBOL(open_candev); /* * Common close function for cleanup before the device gets closed. diff --git a/trunk/drivers/net/can/sja1000/Makefile b/trunk/drivers/net/can/sja1000/Makefile index 9d0c08da273c..d6c631f9e665 100644 --- a/trunk/drivers/net/can/sja1000/Makefile +++ b/trunk/drivers/net/can/sja1000/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_CAN_SJA1000) += sja1000.o obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o -obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o diff --git a/trunk/drivers/net/can/sja1000/ems_pci.c b/trunk/drivers/net/can/sja1000/ems_pci.c index 121b64101d72..3cd2ff9165e3 100644 --- a/trunk/drivers/net/can/sja1000/ems_pci.c +++ b/trunk/drivers/net/can/sja1000/ems_pci.c @@ -99,21 +99,25 @@ MODULE_DEVICE_TABLE(pci, ems_pci_tbl); */ static u8 ems_pci_readb(struct ems_pci_card *card, unsigned int port) { - return readb(card->base_addr + (port * EMS_PCI_PORT_BYTES)); + return readb((void __iomem *)card->base_addr + + (port * EMS_PCI_PORT_BYTES)); } -static u8 ems_pci_read_reg(const struct sja1000_priv *priv, int port) +static u8 ems_pci_read_reg(const struct net_device *dev, int port) { - return readb(priv->reg_base + (port * EMS_PCI_PORT_BYTES)); + return readb((void __iomem *)dev->base_addr + + (port * EMS_PCI_PORT_BYTES)); } -static void ems_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val) +static void ems_pci_write_reg(const struct net_device *dev, int port, u8 val) { - writeb(val, priv->reg_base + (port * EMS_PCI_PORT_BYTES)); + writeb(val, (void __iomem *)dev->base_addr + + (port * EMS_PCI_PORT_BYTES)); } -static void ems_pci_post_irq(const struct sja1000_priv *priv) +static void ems_pci_post_irq(const struct net_device *dev) { + struct sja1000_priv *priv = netdev_priv(dev); struct ems_pci_card *card = (struct ems_pci_card *)priv->priv; /* reset int flag of pita */ @@ -125,17 +129,17 @@ static void ems_pci_post_irq(const struct sja1000_priv *priv) * Check if a CAN controller is present at the specified location * by trying to set 'em into the PeliCAN mode */ -static inline int ems_pci_check_chan(const struct sja1000_priv *priv) +static inline int ems_pci_check_chan(struct net_device *dev) { unsigned char res; /* Make sure SJA1000 is in reset mode */ - ems_pci_write_reg(priv, REG_MOD, 1); + ems_pci_write_reg(dev, REG_MOD, 1); - ems_pci_write_reg(priv, REG_CDR, CDR_PELICAN); + ems_pci_write_reg(dev, REG_CDR, CDR_PELICAN); /* read reset-values */ - res = ems_pci_read_reg(priv, REG_CDR); + res = ems_pci_read_reg(dev, REG_CDR); if (res == CDR_PELICAN) return 1; @@ -214,12 +218,14 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev, card->conf_addr = pci_iomap(pdev, 0, EMS_PCI_MEM_SIZE); if (card->conf_addr == NULL) { err = -ENOMEM; + goto failure_cleanup; } card->base_addr = pci_iomap(pdev, 1, EMS_PCI_MEM_SIZE); if (card->base_addr == NULL) { err = -ENOMEM; + goto failure_cleanup; } @@ -233,6 +239,7 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev, ems_pci_readb(card, 3) != 0xCB || ems_pci_readb(card, 4) != 0x11) { dev_err(&pdev->dev, "Not EMS Dr. Thomas Wuensche interface\n"); + err = -ENODEV; goto failure_cleanup; } @@ -253,11 +260,12 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev, priv->irq_flags = IRQF_SHARED; dev->irq = pdev->irq; - priv->reg_base = card->base_addr + EMS_PCI_CAN_BASE_OFFSET - + (i * EMS_PCI_CAN_CTRL_SIZE); + dev->base_addr = (unsigned long)(card->base_addr + + EMS_PCI_CAN_BASE_OFFSET + + (i * EMS_PCI_CAN_CTRL_SIZE)); /* Check if channel is present */ - if (ems_pci_check_chan(priv)) { + if (ems_pci_check_chan(dev)) { priv->read_reg = ems_pci_read_reg; priv->write_reg = ems_pci_write_reg; priv->post_irq = ems_pci_post_irq; @@ -281,8 +289,9 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev, card->channels++; - dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d\n", - i + 1, priv->reg_base, dev->irq); + dev_info(&pdev->dev, "Channel #%d at %#lX, irq %d\n", + i + 1, dev->base_addr, + dev->irq); } else { free_sja1000dev(dev); } diff --git a/trunk/drivers/net/can/sja1000/kvaser_pci.c b/trunk/drivers/net/can/sja1000/kvaser_pci.c index 7dd7769b9713..00830b358c4f 100644 --- a/trunk/drivers/net/can/sja1000/kvaser_pci.c +++ b/trunk/drivers/net/can/sja1000/kvaser_pci.c @@ -117,15 +117,14 @@ static struct pci_device_id kvaser_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, kvaser_pci_tbl); -static u8 kvaser_pci_read_reg(const struct sja1000_priv *priv, int port) +static u8 kvaser_pci_read_reg(const struct net_device *dev, int port) { - return ioread8(priv->reg_base + port); + return ioread8((void __iomem *)(dev->base_addr + port)); } -static void kvaser_pci_write_reg(const struct sja1000_priv *priv, - int port, u8 val) +static void kvaser_pci_write_reg(const struct net_device *dev, int port, u8 val) { - iowrite8(val, priv->reg_base + port); + iowrite8(val, (void __iomem *)(dev->base_addr + port)); } static void kvaser_pci_disable_irq(struct net_device *dev) @@ -200,7 +199,7 @@ static void kvaser_pci_del_chan(struct net_device *dev) } unregister_sja1000dev(dev); - pci_iounmap(board->pci_dev, priv->reg_base); + pci_iounmap(board->pci_dev, (void __iomem *)dev->base_addr); pci_iounmap(board->pci_dev, board->conf_addr); pci_iounmap(board->pci_dev, board->res_addr); @@ -211,7 +210,7 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, struct net_device **master_dev, void __iomem *conf_addr, void __iomem *res_addr, - void __iomem *base_addr) + unsigned long base_addr) { struct net_device *dev; struct sja1000_priv *priv; @@ -253,7 +252,7 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, board->xilinx_ver = master_board->xilinx_ver; } - priv->reg_base = base_addr + channel * KVASER_PCI_PORT_BYTES; + dev->base_addr = base_addr + channel * KVASER_PCI_PORT_BYTES; priv->read_reg = kvaser_pci_read_reg; priv->write_reg = kvaser_pci_write_reg; @@ -268,8 +267,8 @@ static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel, init_step = 4; - dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n", - priv->reg_base, board->conf_addr, dev->irq); + dev_info(&pdev->dev, "base_addr=%#lx conf_addr=%p irq=%d\n", + dev->base_addr, board->conf_addr, dev->irq); SET_NETDEV_DEV(dev, &pdev->dev); @@ -344,7 +343,7 @@ static int __devinit kvaser_pci_init_one(struct pci_dev *pdev, for (i = 0; i < no_channels; i++) { err = kvaser_pci_add_chan(pdev, i, &master_dev, conf_addr, res_addr, - base_addr); + (unsigned long)base_addr); if (err) goto failure_cleanup; } diff --git a/trunk/drivers/net/can/sja1000/sja1000.c b/trunk/drivers/net/can/sja1000/sja1000.c index 571f133a8fec..05b38dde648e 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.c +++ b/trunk/drivers/net/can/sja1000/sja1000.c @@ -89,7 +89,7 @@ static int sja1000_probe_chip(struct net_device *dev) { struct sja1000_priv *priv = netdev_priv(dev); - if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) { + if (dev->base_addr && (priv->read_reg(dev, 0) == 0xFF)) { printk(KERN_INFO "%s: probing @0x%lX failed\n", DRV_NAME, dev->base_addr); return 0; @@ -100,11 +100,11 @@ static int sja1000_probe_chip(struct net_device *dev) static void set_reset_mode(struct net_device *dev) { struct sja1000_priv *priv = netdev_priv(dev); - unsigned char status = priv->read_reg(priv, REG_MOD); + unsigned char status = priv->read_reg(dev, REG_MOD); int i; /* disable interrupts */ - priv->write_reg(priv, REG_IER, IRQ_OFF); + priv->write_reg(dev, REG_IER, IRQ_OFF); for (i = 0; i < 100; i++) { /* check reset bit */ @@ -113,9 +113,9 @@ static void set_reset_mode(struct net_device *dev) return; } - priv->write_reg(priv, REG_MOD, MOD_RM); /* reset chip */ + priv->write_reg(dev, REG_MOD, MOD_RM); /* reset chip */ udelay(10); - status = priv->read_reg(priv, REG_MOD); + status = priv->read_reg(dev, REG_MOD); } dev_err(dev->dev.parent, "setting SJA1000 into reset mode failed!\n"); @@ -124,7 +124,7 @@ static void set_reset_mode(struct net_device *dev) static void set_normal_mode(struct net_device *dev) { struct sja1000_priv *priv = netdev_priv(dev); - unsigned char status = priv->read_reg(priv, REG_MOD); + unsigned char status = priv->read_reg(dev, REG_MOD); int i; for (i = 0; i < 100; i++) { @@ -132,14 +132,14 @@ static void set_normal_mode(struct net_device *dev) if ((status & MOD_RM) == 0) { priv->can.state = CAN_STATE_ERROR_ACTIVE; /* enable all interrupts */ - priv->write_reg(priv, REG_IER, IRQ_ALL); + priv->write_reg(dev, REG_IER, IRQ_ALL); return; } /* set chip to normal mode */ - priv->write_reg(priv, REG_MOD, 0x00); + priv->write_reg(dev, REG_MOD, 0x00); udelay(10); - status = priv->read_reg(priv, REG_MOD); + status = priv->read_reg(dev, REG_MOD); } dev_err(dev->dev.parent, "setting SJA1000 into normal mode failed!\n"); @@ -154,9 +154,9 @@ static void sja1000_start(struct net_device *dev) set_reset_mode(dev); /* Clear error counters and error code capture */ - priv->write_reg(priv, REG_TXERR, 0x0); - priv->write_reg(priv, REG_RXERR, 0x0); - priv->read_reg(priv, REG_ECC); + priv->write_reg(dev, REG_TXERR, 0x0); + priv->write_reg(dev, REG_RXERR, 0x0); + priv->read_reg(dev, REG_ECC); /* leave reset mode */ set_normal_mode(dev); @@ -198,8 +198,8 @@ static int sja1000_set_bittiming(struct net_device *dev) dev_info(dev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); - priv->write_reg(priv, REG_BTR0, btr0); - priv->write_reg(priv, REG_BTR1, btr1); + priv->write_reg(dev, REG_BTR0, btr0); + priv->write_reg(dev, REG_BTR1, btr1); return 0; } @@ -217,20 +217,20 @@ static void chipset_init(struct net_device *dev) struct sja1000_priv *priv = netdev_priv(dev); /* set clock divider and output control register */ - priv->write_reg(priv, REG_CDR, priv->cdr | CDR_PELICAN); + priv->write_reg(dev, REG_CDR, priv->cdr | CDR_PELICAN); /* set acceptance filter (accept all) */ - priv->write_reg(priv, REG_ACCC0, 0x00); - priv->write_reg(priv, REG_ACCC1, 0x00); - priv->write_reg(priv, REG_ACCC2, 0x00); - priv->write_reg(priv, REG_ACCC3, 0x00); + priv->write_reg(dev, REG_ACCC0, 0x00); + priv->write_reg(dev, REG_ACCC1, 0x00); + priv->write_reg(dev, REG_ACCC2, 0x00); + priv->write_reg(dev, REG_ACCC3, 0x00); - priv->write_reg(priv, REG_ACCM0, 0xFF); - priv->write_reg(priv, REG_ACCM1, 0xFF); - priv->write_reg(priv, REG_ACCM2, 0xFF); - priv->write_reg(priv, REG_ACCM3, 0xFF); + priv->write_reg(dev, REG_ACCM0, 0xFF); + priv->write_reg(dev, REG_ACCM1, 0xFF); + priv->write_reg(dev, REG_ACCM2, 0xFF); + priv->write_reg(dev, REG_ACCM3, 0xFF); - priv->write_reg(priv, REG_OCR, priv->ocr | OCR_MODE_NORMAL); + priv->write_reg(dev, REG_OCR, priv->ocr | OCR_MODE_NORMAL); } /* @@ -261,27 +261,27 @@ static int sja1000_start_xmit(struct sk_buff *skb, struct net_device *dev) if (id & CAN_EFF_FLAG) { fi |= FI_FF; dreg = EFF_BUF; - priv->write_reg(priv, REG_FI, fi); - priv->write_reg(priv, REG_ID1, (id & 0x1fe00000) >> (5 + 16)); - priv->write_reg(priv, REG_ID2, (id & 0x001fe000) >> (5 + 8)); - priv->write_reg(priv, REG_ID3, (id & 0x00001fe0) >> 5); - priv->write_reg(priv, REG_ID4, (id & 0x0000001f) << 3); + priv->write_reg(dev, REG_FI, fi); + priv->write_reg(dev, REG_ID1, (id & 0x1fe00000) >> (5 + 16)); + priv->write_reg(dev, REG_ID2, (id & 0x001fe000) >> (5 + 8)); + priv->write_reg(dev, REG_ID3, (id & 0x00001fe0) >> 5); + priv->write_reg(dev, REG_ID4, (id & 0x0000001f) << 3); } else { dreg = SFF_BUF; - priv->write_reg(priv, REG_FI, fi); - priv->write_reg(priv, REG_ID1, (id & 0x000007f8) >> 3); - priv->write_reg(priv, REG_ID2, (id & 0x00000007) << 5); + priv->write_reg(dev, REG_FI, fi); + priv->write_reg(dev, REG_ID1, (id & 0x000007f8) >> 3); + priv->write_reg(dev, REG_ID2, (id & 0x00000007) << 5); } for (i = 0; i < dlc; i++) - priv->write_reg(priv, dreg++, cf->data[i]); + priv->write_reg(dev, dreg++, cf->data[i]); stats->tx_bytes += dlc; dev->trans_start = jiffies; can_put_echo_skb(skb, dev, 0); - priv->write_reg(priv, REG_CMR, CMD_TR); + priv->write_reg(dev, REG_CMR, CMD_TR); return 0; } @@ -304,22 +304,22 @@ static void sja1000_rx(struct net_device *dev) skb->dev = dev; skb->protocol = htons(ETH_P_CAN); - fi = priv->read_reg(priv, REG_FI); + fi = priv->read_reg(dev, REG_FI); dlc = fi & 0x0F; if (fi & FI_FF) { /* extended frame format (EFF) */ dreg = EFF_BUF; - id = (priv->read_reg(priv, REG_ID1) << (5 + 16)) - | (priv->read_reg(priv, REG_ID2) << (5 + 8)) - | (priv->read_reg(priv, REG_ID3) << 5) - | (priv->read_reg(priv, REG_ID4) >> 3); + id = (priv->read_reg(dev, REG_ID1) << (5 + 16)) + | (priv->read_reg(dev, REG_ID2) << (5 + 8)) + | (priv->read_reg(dev, REG_ID3) << 5) + | (priv->read_reg(dev, REG_ID4) >> 3); id |= CAN_EFF_FLAG; } else { /* standard frame format (SFF) */ dreg = SFF_BUF; - id = (priv->read_reg(priv, REG_ID1) << 3) - | (priv->read_reg(priv, REG_ID2) >> 5); + id = (priv->read_reg(dev, REG_ID1) << 3) + | (priv->read_reg(dev, REG_ID2) >> 5); } if (fi & FI_RTR) @@ -330,13 +330,13 @@ static void sja1000_rx(struct net_device *dev) cf->can_id = id; cf->can_dlc = dlc; for (i = 0; i < dlc; i++) - cf->data[i] = priv->read_reg(priv, dreg++); + cf->data[i] = priv->read_reg(dev, dreg++); while (i < 8) cf->data[i++] = 0; /* release receive buffer */ - priv->write_reg(priv, REG_CMR, CMD_RRB); + priv->write_reg(dev, REG_CMR, CMD_RRB); netif_rx(skb); @@ -371,7 +371,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; stats->rx_errors++; - priv->write_reg(priv, REG_CMR, CMD_CDO); /* clear bit */ + priv->write_reg(dev, REG_CMR, CMD_CDO); /* clear bit */ } if (isrc & IRQ_EI) { @@ -392,7 +392,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) priv->can.can_stats.bus_error++; stats->rx_errors++; - ecc = priv->read_reg(priv, REG_ECC); + ecc = priv->read_reg(dev, REG_ECC); cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; @@ -426,7 +426,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (isrc & IRQ_ALI) { /* arbitration lost interrupt */ dev_dbg(dev->dev.parent, "arbitration lost interrupt\n"); - alc = priv->read_reg(priv, REG_ALC); + alc = priv->read_reg(dev, REG_ALC); priv->can.can_stats.arbitration_lost++; stats->rx_errors++; cf->can_id |= CAN_ERR_LOSTARB; @@ -435,8 +435,8 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING || state == CAN_STATE_ERROR_PASSIVE)) { - uint8_t rxerr = priv->read_reg(priv, REG_RXERR); - uint8_t txerr = priv->read_reg(priv, REG_TXERR); + uint8_t rxerr = priv->read_reg(dev, REG_RXERR); + uint8_t txerr = priv->read_reg(dev, REG_TXERR); cf->can_id |= CAN_ERR_CRTL; if (state == CAN_STATE_ERROR_WARNING) { priv->can.can_stats.error_warning++; @@ -471,15 +471,15 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) int n = 0; /* Shared interrupts and IRQ off? */ - if (priv->read_reg(priv, REG_IER) == IRQ_OFF) + if (priv->read_reg(dev, REG_IER) == IRQ_OFF) return IRQ_NONE; if (priv->pre_irq) - priv->pre_irq(priv); + priv->pre_irq(dev); - while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { + while ((isrc = priv->read_reg(dev, REG_IR)) && (n < SJA1000_MAX_IRQ)) { n++; - status = priv->read_reg(priv, REG_SR); + status = priv->read_reg(dev, REG_SR); if (isrc & IRQ_WUI) dev_warn(dev->dev.parent, "wakeup interrupt\n"); @@ -494,7 +494,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) /* receive interrupt */ while (status & SR_RBS) { sja1000_rx(dev); - status = priv->read_reg(priv, REG_SR); + status = priv->read_reg(dev, REG_SR); } } if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) { @@ -505,7 +505,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) } if (priv->post_irq) - priv->post_irq(priv); + priv->post_irq(dev); if (n >= SJA1000_MAX_IRQ) dev_dbg(dev->dev.parent, "%d messages handled in ISR", n); @@ -532,8 +532,8 @@ static int sja1000_open(struct net_device *dev) err = request_irq(dev->irq, &sja1000_interrupt, priv->irq_flags, dev->name, (void *)dev); if (err) { - close_candev(dev); return -EAGAIN; + close_candev(dev); } } diff --git a/trunk/drivers/net/can/sja1000/sja1000.h b/trunk/drivers/net/can/sja1000/sja1000.h index 302d2c763ad7..ccd302887964 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.h +++ b/trunk/drivers/net/can/sja1000/sja1000.h @@ -155,15 +155,14 @@ struct sja1000_priv { struct sk_buff *echo_skb; /* the lower-layer is responsible for appropriate locking */ - u8 (*read_reg) (const struct sja1000_priv *priv, int reg); - void (*write_reg) (const struct sja1000_priv *priv, int reg, u8 val); - void (*pre_irq) (const struct sja1000_priv *priv); - void (*post_irq) (const struct sja1000_priv *priv); + u8 (*read_reg) (const struct net_device *dev, int reg); + void (*write_reg) (const struct net_device *dev, int reg, u8 val); + void (*pre_irq) (const struct net_device *dev); + void (*post_irq) (const struct net_device *dev); void *priv; /* for board-specific data */ struct net_device *dev; - void __iomem *reg_base; /* ioremap'ed address to registers */ unsigned long irq_flags; /* for request_irq() */ u16 flags; /* custom mode flags */ diff --git a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c deleted file mode 100644 index 3373560405ba..000000000000 --- a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus - * - * Copyright (C) 2008-2009 Wolfgang Grandegger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the version 2 of the GNU General Public License - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* This is a generic driver for SJA1000 chips on the OpenFirmware platform - * bus found on embedded PowerPC systems. You need a SJA1000 CAN node - * definition in your flattened device tree source (DTS) file similar to: - * - * can@3,100 { - * compatible = "nxp,sja1000"; - * reg = <3 0x100 0x80>; - * interrupts = <2 0>; - * interrupt-parent = <&mpic>; - * nxp,external-clock-frequency = <16000000>; - * }; - * - * See "Documentation/powerpc/dts-bindings/can/sja1000.txt" for further - * information. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "sja1000.h" - -#define DRV_NAME "sja1000_of_platform" - -MODULE_AUTHOR("Wolfgang Grandegger "); -MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus"); -MODULE_LICENSE("GPL v2"); - -#define SJA1000_OFP_CAN_CLOCK (16000000 / 2) - -#define SJA1000_OFP_OCR OCR_TX0_PULLDOWN -#define SJA1000_OFP_CDR (CDR_CBP | CDR_CLK_OFF) - -static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg) -{ - return in_8(priv->reg_base + reg); -} - -static void sja1000_ofp_write_reg(const struct sja1000_priv *priv, - int reg, u8 val) -{ - out_8(priv->reg_base + reg, val); -} - -static int __devexit sja1000_ofp_remove(struct of_device *ofdev) -{ - struct net_device *dev = dev_get_drvdata(&ofdev->dev); - struct sja1000_priv *priv = netdev_priv(dev); - struct device_node *np = ofdev->node; - struct resource res; - - dev_set_drvdata(&ofdev->dev, NULL); - - unregister_sja1000dev(dev); - free_sja1000dev(dev); - iounmap(priv->reg_base); - irq_dispose_mapping(dev->irq); - - of_address_to_resource(np, 0, &res); - release_mem_region(res.start, resource_size(&res)); - - return 0; -} - -static int __devinit sja1000_ofp_probe(struct of_device *ofdev, - const struct of_device_id *id) -{ - struct device_node *np = ofdev->node; - struct net_device *dev; - struct sja1000_priv *priv; - struct resource res; - const u32 *prop; - int err, irq, res_size, prop_size; - void __iomem *base; - - err = of_address_to_resource(np, 0, &res); - if (err) { - dev_err(&ofdev->dev, "invalid address\n"); - return err; - } - - res_size = resource_size(&res); - - if (!request_mem_region(res.start, res_size, DRV_NAME)) { - dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); - return -EBUSY; - } - - base = ioremap_nocache(res.start, res_size); - if (!base) { - dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); - err = -ENOMEM; - goto exit_release_mem; - } - - irq = irq_of_parse_and_map(np, 0); - if (irq == NO_IRQ) { - dev_err(&ofdev->dev, "no irq found\n"); - err = -ENODEV; - goto exit_unmap_mem; - } - - dev = alloc_sja1000dev(0); - if (!dev) { - err = -ENOMEM; - goto exit_dispose_irq; - } - - priv = netdev_priv(dev); - - priv->read_reg = sja1000_ofp_read_reg; - priv->write_reg = sja1000_ofp_write_reg; - - prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); - if (prop && (prop_size == sizeof(u32))) - priv->can.clock.freq = *prop / 2; - else - priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ - - prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); - if (prop && (prop_size == sizeof(u32))) - priv->ocr |= *prop & OCR_MODE_MASK; - else - priv->ocr |= OCR_MODE_NORMAL; /* default */ - - prop = of_get_property(np, "nxp,tx-output-config", &prop_size); - if (prop && (prop_size == sizeof(u32))) - priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; - else - priv->ocr |= OCR_TX0_PULLDOWN; /* default */ - - prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); - if (prop && (prop_size == sizeof(u32)) && *prop) { - u32 divider = priv->can.clock.freq * 2 / *prop; - - if (divider > 1) - priv->cdr |= divider / 2 - 1; - else - priv->cdr |= CDR_CLKOUT_MASK; - } else { - priv->cdr |= CDR_CLK_OFF; /* default */ - } - - prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); - if (!prop) - priv->cdr |= CDR_CBP; /* default */ - - priv->irq_flags = IRQF_SHARED; - priv->reg_base = base; - - dev->irq = irq; - - dev_info(&ofdev->dev, - "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n", - priv->reg_base, dev->irq, priv->can.clock.freq, - priv->ocr, priv->cdr); - - dev_set_drvdata(&ofdev->dev, dev); - SET_NETDEV_DEV(dev, &ofdev->dev); - - err = register_sja1000dev(dev); - if (err) { - dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", - DRV_NAME, err); - goto exit_free_sja1000; - } - - return 0; - -exit_free_sja1000: - free_sja1000dev(dev); -exit_dispose_irq: - irq_dispose_mapping(irq); -exit_unmap_mem: - iounmap(base); -exit_release_mem: - release_mem_region(res.start, res_size); - - return err; -} - -static struct of_device_id __devinitdata sja1000_ofp_table[] = { - {.compatible = "nxp,sja1000"}, - {}, -}; - -static struct of_platform_driver sja1000_ofp_driver = { - .owner = THIS_MODULE, - .name = DRV_NAME, - .probe = sja1000_ofp_probe, - .remove = __devexit_p(sja1000_ofp_remove), - .match_table = sja1000_ofp_table, -}; - -static int __init sja1000_ofp_init(void) -{ - return of_register_platform_driver(&sja1000_ofp_driver); -} -module_init(sja1000_ofp_init); - -static void __exit sja1000_ofp_exit(void) -{ - return of_unregister_platform_driver(&sja1000_ofp_driver); -}; -module_exit(sja1000_ofp_exit); diff --git a/trunk/drivers/net/can/sja1000/sja1000_platform.c b/trunk/drivers/net/can/sja1000/sja1000_platform.c index 628374c2a05f..8017229d6fd6 100644 --- a/trunk/drivers/net/can/sja1000/sja1000_platform.c +++ b/trunk/drivers/net/can/sja1000/sja1000_platform.c @@ -37,14 +37,14 @@ MODULE_AUTHOR("Sascha Hauer "); MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus"); MODULE_LICENSE("GPL v2"); -static u8 sp_read_reg(const struct sja1000_priv *priv, int reg) +static u8 sp_read_reg(const struct net_device *dev, int reg) { - return ioread8(priv->reg_base + reg); + return ioread8((void __iomem *)(dev->base_addr + reg)); } -static void sp_write_reg(const struct sja1000_priv *priv, int reg, u8 val) +static void sp_write_reg(const struct net_device *dev, int reg, u8 val) { - iowrite8(val, priv->reg_base + reg); + iowrite8(val, (void __iomem *)(dev->base_addr + reg)); } static int sp_probe(struct platform_device *pdev) @@ -89,9 +89,9 @@ static int sp_probe(struct platform_device *pdev) } priv = netdev_priv(dev); + dev->base_addr = (unsigned long)addr; dev->irq = res_irq->start; priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; - priv->reg_base = addr; priv->read_reg = sp_read_reg; priv->write_reg = sp_write_reg; priv->can.clock.freq = pdata->clock; @@ -108,8 +108,8 @@ static int sp_probe(struct platform_device *pdev) goto exit_free; } - dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n", - DRV_NAME, priv->reg_base, dev->irq); + dev_info(&pdev->dev, "%s device registered (base_addr=%#lx, irq=%d)\n", + DRV_NAME, dev->base_addr, dev->irq); return 0; exit_free: @@ -125,14 +125,13 @@ static int sp_probe(struct platform_device *pdev) static int sp_remove(struct platform_device *pdev) { struct net_device *dev = dev_get_drvdata(&pdev->dev); - struct sja1000_priv *priv = netdev_priv(dev); struct resource *res; unregister_sja1000dev(dev); dev_set_drvdata(&pdev->dev, NULL); - if (priv->reg_base) - iounmap(priv->reg_base); + if (dev->base_addr) + iounmap((void __iomem *)dev->base_addr); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); diff --git a/trunk/drivers/net/chelsio/sge.c b/trunk/drivers/net/chelsio/sge.c index 3711d64e45ef..5e97a1a71d88 100644 --- a/trunk/drivers/net/chelsio/sge.c +++ b/trunk/drivers/net/chelsio/sge.c @@ -1879,6 +1879,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) cpl->vlan_valid = 0; send: + dev->trans_start = jiffies; ret = t1_sge_tx(skb, adapter, 0, dev); /* If transmit busy, and we reallocated skb's due to headroom limit, diff --git a/trunk/drivers/net/cpmac.c b/trunk/drivers/net/cpmac.c index 58afafbd3b9c..cfb4198b6776 100644 --- a/trunk/drivers/net/cpmac.c +++ b/trunk/drivers/net/cpmac.c @@ -615,13 +615,13 @@ static void cpmac_end_xmit(struct net_device *dev, int queue) dev_kfree_skb_irq(desc->skb); desc->skb = NULL; - if (__netif_subqueue_stopped(dev, queue)) + if (netif_subqueue_stopped(dev, queue)) netif_wake_subqueue(dev, queue); } else { if (netif_msg_tx_err(priv) && net_ratelimit()) printk(KERN_WARNING "%s: end_xmit: spurious interrupt\n", dev->name); - if (__netif_subqueue_stopped(dev, queue)) + if (netif_subqueue_stopped(dev, queue)) netif_wake_subqueue(dev, queue); } } @@ -731,6 +731,7 @@ static void cpmac_clear_tx(struct net_device *dev) static void cpmac_hw_error(struct work_struct *work) { + int i; struct cpmac_priv *priv = container_of(work, struct cpmac_priv, reset_work); @@ -817,6 +818,7 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id) static void cpmac_tx_timeout(struct net_device *dev) { + int i; struct cpmac_priv *priv = netdev_priv(dev); spin_lock(&priv->lock); @@ -1108,7 +1110,7 @@ static int external_switch; static int __devinit cpmac_probe(struct platform_device *pdev) { - int rc, phy_id; + int rc, phy_id, i; char *mdio_bus_id = "0"; struct resource *mem; struct cpmac_priv *priv; diff --git a/trunk/drivers/net/cxgb3/Makefile b/trunk/drivers/net/cxgb3/Makefile index 29aff78c7820..343467985321 100644 --- a/trunk/drivers/net/cxgb3/Makefile +++ b/trunk/drivers/net/cxgb3/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_CHELSIO_T3) += cxgb3.o cxgb3-objs := cxgb3_main.o ael1002.o vsc8211.o t3_hw.o mc5.o \ - xgmac.o sge.o l2t.o cxgb3_offload.o aq100x.o + xgmac.o sge.o l2t.o cxgb3_offload.o diff --git a/trunk/drivers/net/cxgb3/adapter.h b/trunk/drivers/net/cxgb3/adapter.h index 1694fad38720..322434ac42fc 100644 --- a/trunk/drivers/net/cxgb3/adapter.h +++ b/trunk/drivers/net/cxgb3/adapter.h @@ -85,8 +85,8 @@ struct fl_pg_chunk { struct page *page; void *va; unsigned int offset; - unsigned long *p_cnt; - dma_addr_t mapping; + u64 *p_cnt; + DECLARE_PCI_UNMAP_ADDR(mapping); }; struct rx_desc; @@ -253,8 +253,6 @@ struct adapter { struct mutex mdio_lock; spinlock_t stats_lock; spinlock_t work_lock; - - struct sk_buff *nofail_skb; }; static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr) diff --git a/trunk/drivers/net/cxgb3/ael1002.c b/trunk/drivers/net/cxgb3/ael1002.c index 9fe008ec9ba5..df1f58576689 100644 --- a/trunk/drivers/net/cxgb3/ael1002.c +++ b/trunk/drivers/net/cxgb3/ael1002.c @@ -44,33 +44,12 @@ enum { AEL_I2C_STAT = 0xc30c, AEL2005_GPIO_CTRL = 0xc214, AEL2005_GPIO_STAT = 0xc215, - - AEL2020_GPIO_INTR = 0xc103, /* Latch High (LH) */ - AEL2020_GPIO_CTRL = 0xc108, /* Store Clear (SC) */ - AEL2020_GPIO_STAT = 0xc10c, /* Read Only (RO) */ - AEL2020_GPIO_CFG = 0xc110, /* Read Write (RW) */ - - AEL2020_GPIO_SDA = 0, /* IN: i2c serial data */ - AEL2020_GPIO_MODDET = 1, /* IN: Module Detect */ - AEL2020_GPIO_0 = 3, /* IN: unassigned */ - AEL2020_GPIO_1 = 2, /* OUT: unassigned */ - AEL2020_GPIO_LSTAT = AEL2020_GPIO_1, /* wired to link status LED */ }; enum { edc_none, edc_sr, edc_twinax }; /* PHY module I2C device address */ -enum { - MODULE_DEV_ADDR = 0xa0, - SFF_DEV_ADDR = 0xa2, -}; - -/* PHY transceiver type */ -enum { - phy_transtype_unknown = 0, - phy_transtype_sfp = 3, - phy_transtype_xfp = 6, -}; +#define MODULE_DEV_ADDR 0xa0 #define AEL2005_MODDET_IRQ 4 @@ -107,37 +86,6 @@ static void ael100x_txon(struct cphy *phy) msleep(30); } -/* - * Read an 8-bit word from a device attached to the PHY's i2c bus. - */ -static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) -{ - int i, err; - unsigned int stat, data; - - err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, - (dev_addr << 8) | (1 << 8) | word_addr); - if (err) - return err; - - for (i = 0; i < 200; i++) { - msleep(1); - err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); - if (err) - return err; - if ((stat & 3) == 1) { - err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA, - &data); - if (err) - return err; - return data >> 8; - } - } - CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %#x.%#x timed out\n", - phy->mdio.prtad, dev_addr, word_addr); - return -ETIMEDOUT; -} - static int ael1002_power_down(struct cphy *phy, int enable) { int err; @@ -251,51 +199,6 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, return 0; } -/* - * Decode our module type. - */ -static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) -{ - int v; - - if (delay_ms) - msleep(delay_ms); - - /* see SFF-8472 for below */ - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); - if (v < 0) - return v; - - if (v == 0x10) - return phy_modtype_sr; - if (v == 0x20) - return phy_modtype_lr; - if (v == 0x40) - return phy_modtype_lrm; - - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); - if (v < 0) - return v; - if (v != 4) - goto unknown; - - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); - if (v < 0) - return v; - - if (v & 0x80) { - v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); - if (v < 0) - return v; - return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; - } -unknown: - return phy_modtype_unknown; -} - -/* - * Code to support the Aeluros/NetLogic 2005 10Gb PHY. - */ static int ael2005_setup_sr_edc(struct cphy *phy) { static struct reg_val regs[] = { @@ -990,7 +893,35 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) return err; } -static int ael2005_get_module_type(struct cphy *phy, int delay_ms) +static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) +{ + int i, err; + unsigned int stat, data; + + err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, + (dev_addr << 8) | (1 << 8) | word_addr); + if (err) + return err; + + for (i = 0; i < 5; i++) { + msleep(1); + err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); + if (err) + return err; + if ((stat & 3) == 1) { + err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA, + &data); + if (err) + return err; + return data >> 8; + } + } + CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", + phy->mdio.prtad, word_addr); + return -ETIMEDOUT; +} + +static int get_module_type(struct cphy *phy, int delay_ms) { int v; unsigned int stat; @@ -1002,7 +933,39 @@ static int ael2005_get_module_type(struct cphy *phy, int delay_ms) if (stat & (1 << 8)) /* module absent */ return phy_modtype_none; - return ael2xxx_get_module_type(phy, delay_ms); + if (delay_ms) + msleep(delay_ms); + + /* see SFF-8472 for below */ + v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3); + if (v < 0) + return v; + + if (v == 0x10) + return phy_modtype_sr; + if (v == 0x20) + return phy_modtype_lr; + if (v == 0x40) + return phy_modtype_lrm; + + v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6); + if (v < 0) + return v; + if (v != 4) + goto unknown; + + v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10); + if (v < 0) + return v; + + if (v & 0x80) { + v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); + if (v < 0) + return v; + return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; + } +unknown: + return phy_modtype_unknown; } static int ael2005_intr_enable(struct cphy *phy) @@ -1061,7 +1024,7 @@ static int ael2005_reset(struct cphy *phy, int wait) msleep(50); - err = ael2005_get_module_type(phy, 0); + err = get_module_type(phy, 0); if (err < 0) return err; phy->modtype = err; @@ -1099,7 +1062,7 @@ static int ael2005_intr_handler(struct cphy *phy) return ret; /* modules have max 300 ms init time after hot plug */ - ret = ael2005_get_module_type(phy, 300); + ret = get_module_type(phy, 300); if (ret < 0) return ret; @@ -1149,662 +1112,6 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, 1 << 5); } -/* - * Setup EDC and other parameters for operation with an optical module. - */ -static int ael2020_setup_sr_edc(struct cphy *phy) -{ - static struct reg_val regs[] = { - /* set CDR offset to 10 */ - { MDIO_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a }, - - /* adjust 10G RX bias current */ - { MDIO_MMD_PMAPMD, 0xcb1b, 0xffff, 0x0200 }, - { MDIO_MMD_PMAPMD, 0xcb1c, 0xffff, 0x00f0 }, - { MDIO_MMD_PMAPMD, 0xcc06, 0xffff, 0x00e0 }, - - /* end */ - { 0, 0, 0, 0 } - }; - int err; - - err = set_phy_regs(phy, regs); - msleep(50); - if (err) - return err; - - phy->priv = edc_sr; - return 0; -} - -/* - * Setup EDC and other parameters for operation with an TWINAX module. - */ -static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) -{ - /* set uC to 40MHz */ - static struct reg_val uCclock40MHz[] = { - { MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 }, - { MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 }, - { 0, 0, 0, 0 } - }; - - /* activate uC clock */ - static struct reg_val uCclockActivate[] = { - { MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 }, - { 0, 0, 0, 0 } - }; - - /* set PC to start of SRAM and activate uC */ - static struct reg_val uCactivate[] = { - { MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 }, - { MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 }, - { 0, 0, 0, 0 } - }; - - /* TWINAX EDC firmware */ - static u16 twinax_edc[] = { - 0xd800, 0x4009, - 0xd801, 0x2fff, - 0xd802, 0x300f, - 0xd803, 0x40aa, - 0xd804, 0x401c, - 0xd805, 0x401e, - 0xd806, 0x2ff4, - 0xd807, 0x3dc4, - 0xd808, 0x2035, - 0xd809, 0x3035, - 0xd80a, 0x6524, - 0xd80b, 0x2cb2, - 0xd80c, 0x3012, - 0xd80d, 0x1002, - 0xd80e, 0x26e2, - 0xd80f, 0x3022, - 0xd810, 0x1002, - 0xd811, 0x27d2, - 0xd812, 0x3022, - 0xd813, 0x1002, - 0xd814, 0x2822, - 0xd815, 0x3012, - 0xd816, 0x1002, - 0xd817, 0x2492, - 0xd818, 0x3022, - 0xd819, 0x1002, - 0xd81a, 0x2772, - 0xd81b, 0x3012, - 0xd81c, 0x1002, - 0xd81d, 0x23d2, - 0xd81e, 0x3022, - 0xd81f, 0x1002, - 0xd820, 0x22cd, - 0xd821, 0x301d, - 0xd822, 0x27f2, - 0xd823, 0x3022, - 0xd824, 0x1002, - 0xd825, 0x5553, - 0xd826, 0x0307, - 0xd827, 0x2522, - 0xd828, 0x3022, - 0xd829, 0x1002, - 0xd82a, 0x2142, - 0xd82b, 0x3012, - 0xd82c, 0x1002, - 0xd82d, 0x4016, - 0xd82e, 0x5e63, - 0xd82f, 0x0344, - 0xd830, 0x2142, - 0xd831, 0x3012, - 0xd832, 0x1002, - 0xd833, 0x400e, - 0xd834, 0x2522, - 0xd835, 0x3022, - 0xd836, 0x1002, - 0xd837, 0x2b52, - 0xd838, 0x3012, - 0xd839, 0x1002, - 0xd83a, 0x2742, - 0xd83b, 0x3022, - 0xd83c, 0x1002, - 0xd83d, 0x25e2, - 0xd83e, 0x3022, - 0xd83f, 0x1002, - 0xd840, 0x2fa4, - 0xd841, 0x3dc4, - 0xd842, 0x6624, - 0xd843, 0x414b, - 0xd844, 0x56b3, - 0xd845, 0x03c6, - 0xd846, 0x866b, - 0xd847, 0x400c, - 0xd848, 0x2712, - 0xd849, 0x3012, - 0xd84a, 0x1002, - 0xd84b, 0x2c4b, - 0xd84c, 0x309b, - 0xd84d, 0x56b3, - 0xd84e, 0x03c3, - 0xd84f, 0x866b, - 0xd850, 0x400c, - 0xd851, 0x2272, - 0xd852, 0x3022, - 0xd853, 0x1002, - 0xd854, 0x2742, - 0xd855, 0x3022, - 0xd856, 0x1002, - 0xd857, 0x25e2, - 0xd858, 0x3022, - 0xd859, 0x1002, - 0xd85a, 0x2fb4, - 0xd85b, 0x3dc4, - 0xd85c, 0x6624, - 0xd85d, 0x56b3, - 0xd85e, 0x03c3, - 0xd85f, 0x866b, - 0xd860, 0x401c, - 0xd861, 0x2c45, - 0xd862, 0x3095, - 0xd863, 0x5b53, - 0xd864, 0x2372, - 0xd865, 0x3012, - 0xd866, 0x13c2, - 0xd867, 0x5cc3, - 0xd868, 0x2712, - 0xd869, 0x3012, - 0xd86a, 0x1312, - 0xd86b, 0x2b52, - 0xd86c, 0x3012, - 0xd86d, 0x1002, - 0xd86e, 0x2742, - 0xd86f, 0x3022, - 0xd870, 0x1002, - 0xd871, 0x2582, - 0xd872, 0x3022, - 0xd873, 0x1002, - 0xd874, 0x2142, - 0xd875, 0x3012, - 0xd876, 0x1002, - 0xd877, 0x628f, - 0xd878, 0x2985, - 0xd879, 0x33a5, - 0xd87a, 0x25e2, - 0xd87b, 0x3022, - 0xd87c, 0x1002, - 0xd87d, 0x5653, - 0xd87e, 0x03d2, - 0xd87f, 0x401e, - 0xd880, 0x6f72, - 0xd881, 0x1002, - 0xd882, 0x628f, - 0xd883, 0x2304, - 0xd884, 0x3c84, - 0xd885, 0x6436, - 0xd886, 0xdff4, - 0xd887, 0x6436, - 0xd888, 0x2ff5, - 0xd889, 0x3005, - 0xd88a, 0x8656, - 0xd88b, 0xdfba, - 0xd88c, 0x56a3, - 0xd88d, 0xd05a, - 0xd88e, 0x2972, - 0xd88f, 0x3012, - 0xd890, 0x1392, - 0xd891, 0xd05a, - 0xd892, 0x56a3, - 0xd893, 0xdfba, - 0xd894, 0x0383, - 0xd895, 0x6f72, - 0xd896, 0x1002, - 0xd897, 0x2b45, - 0xd898, 0x3005, - 0xd899, 0x4178, - 0xd89a, 0x5653, - 0xd89b, 0x0384, - 0xd89c, 0x2a62, - 0xd89d, 0x3012, - 0xd89e, 0x1002, - 0xd89f, 0x2f05, - 0xd8a0, 0x3005, - 0xd8a1, 0x41c8, - 0xd8a2, 0x5653, - 0xd8a3, 0x0382, - 0xd8a4, 0x0002, - 0xd8a5, 0x4218, - 0xd8a6, 0x2474, - 0xd8a7, 0x3c84, - 0xd8a8, 0x6437, - 0xd8a9, 0xdff4, - 0xd8aa, 0x6437, - 0xd8ab, 0x2ff5, - 0xd8ac, 0x3c05, - 0xd8ad, 0x8757, - 0xd8ae, 0xb888, - 0xd8af, 0x9787, - 0xd8b0, 0xdff4, - 0xd8b1, 0x6724, - 0xd8b2, 0x866a, - 0xd8b3, 0x6f72, - 0xd8b4, 0x1002, - 0xd8b5, 0x2641, - 0xd8b6, 0x3021, - 0xd8b7, 0x1001, - 0xd8b8, 0xc620, - 0xd8b9, 0x0000, - 0xd8ba, 0xc621, - 0xd8bb, 0x0000, - 0xd8bc, 0xc622, - 0xd8bd, 0x00ce, - 0xd8be, 0xc623, - 0xd8bf, 0x007f, - 0xd8c0, 0xc624, - 0xd8c1, 0x0032, - 0xd8c2, 0xc625, - 0xd8c3, 0x0000, - 0xd8c4, 0xc627, - 0xd8c5, 0x0000, - 0xd8c6, 0xc628, - 0xd8c7, 0x0000, - 0xd8c8, 0xc62c, - 0xd8c9, 0x0000, - 0xd8ca, 0x0000, - 0xd8cb, 0x2641, - 0xd8cc, 0x3021, - 0xd8cd, 0x1001, - 0xd8ce, 0xc502, - 0xd8cf, 0x53ac, - 0xd8d0, 0xc503, - 0xd8d1, 0x2cd3, - 0xd8d2, 0xc600, - 0xd8d3, 0x2a6e, - 0xd8d4, 0xc601, - 0xd8d5, 0x2a2c, - 0xd8d6, 0xc605, - 0xd8d7, 0x5557, - 0xd8d8, 0xc60c, - 0xd8d9, 0x5400, - 0xd8da, 0xc710, - 0xd8db, 0x0700, - 0xd8dc, 0xc711, - 0xd8dd, 0x0f06, - 0xd8de, 0xc718, - 0xd8df, 0x0700, - 0xd8e0, 0xc719, - 0xd8e1, 0x0f06, - 0xd8e2, 0xc720, - 0xd8e3, 0x4700, - 0xd8e4, 0xc721, - 0xd8e5, 0x0f06, - 0xd8e6, 0xc728, - 0xd8e7, 0x0700, - 0xd8e8, 0xc729, - 0xd8e9, 0x1207, - 0xd8ea, 0xc801, - 0xd8eb, 0x7f50, - 0xd8ec, 0xc802, - 0xd8ed, 0x7760, - 0xd8ee, 0xc803, - 0xd8ef, 0x7fce, - 0xd8f0, 0xc804, - 0xd8f1, 0x520e, - 0xd8f2, 0xc805, - 0xd8f3, 0x5c11, - 0xd8f4, 0xc806, - 0xd8f5, 0x3c51, - 0xd8f6, 0xc807, - 0xd8f7, 0x4061, - 0xd8f8, 0xc808, - 0xd8f9, 0x49c1, - 0xd8fa, 0xc809, - 0xd8fb, 0x3840, - 0xd8fc, 0xc80a, - 0xd8fd, 0x0000, - 0xd8fe, 0xc821, - 0xd8ff, 0x0002, - 0xd900, 0xc822, - 0xd901, 0x0046, - 0xd902, 0xc844, - 0xd903, 0x182f, - 0xd904, 0xc013, - 0xd905, 0xf341, - 0xd906, 0xc084, - 0xd907, 0x0030, - 0xd908, 0xc904, - 0xd909, 0x1401, - 0xd90a, 0xcb0c, - 0xd90b, 0x0004, - 0xd90c, 0xcb0e, - 0xd90d, 0xa00a, - 0xd90e, 0xcb0f, - 0xd90f, 0xc0c0, - 0xd910, 0xcb10, - 0xd911, 0xc0c0, - 0xd912, 0xcb11, - 0xd913, 0x00a0, - 0xd914, 0xcb12, - 0xd915, 0x0007, - 0xd916, 0xc241, - 0xd917, 0xa000, - 0xd918, 0xc243, - 0xd919, 0x7fe0, - 0xd91a, 0xc604, - 0xd91b, 0x000e, - 0xd91c, 0xc609, - 0xd91d, 0x00f5, - 0xd91e, 0xc611, - 0xd91f, 0x000e, - 0xd920, 0xc660, - 0xd921, 0x9600, - 0xd922, 0xc687, - 0xd923, 0x0004, - 0xd924, 0xc60a, - 0xd925, 0x04f5, - 0xd926, 0x0000, - 0xd927, 0x2641, - 0xd928, 0x3021, - 0xd929, 0x1001, - 0xd92a, 0xc620, - 0xd92b, 0x14e5, - 0xd92c, 0xc621, - 0xd92d, 0xc53d, - 0xd92e, 0xc622, - 0xd92f, 0x3cbe, - 0xd930, 0xc623, - 0xd931, 0x4452, - 0xd932, 0xc624, - 0xd933, 0xc5c5, - 0xd934, 0xc625, - 0xd935, 0xe01e, - 0xd936, 0xc627, - 0xd937, 0x0000, - 0xd938, 0xc628, - 0xd939, 0x0000, - 0xd93a, 0xc62c, - 0xd93b, 0x0000, - 0xd93c, 0x0000, - 0xd93d, 0x2b84, - 0xd93e, 0x3c74, - 0xd93f, 0x6435, - 0xd940, 0xdff4, - 0xd941, 0x6435, - 0xd942, 0x2806, - 0xd943, 0x3006, - 0xd944, 0x8565, - 0xd945, 0x2b24, - 0xd946, 0x3c24, - 0xd947, 0x6436, - 0xd948, 0x1002, - 0xd949, 0x2b24, - 0xd94a, 0x3c24, - 0xd94b, 0x6436, - 0xd94c, 0x4045, - 0xd94d, 0x8656, - 0xd94e, 0x5663, - 0xd94f, 0x0302, - 0xd950, 0x401e, - 0xd951, 0x1002, - 0xd952, 0x2807, - 0xd953, 0x31a7, - 0xd954, 0x20c4, - 0xd955, 0x3c24, - 0xd956, 0x6724, - 0xd957, 0x1002, - 0xd958, 0x2807, - 0xd959, 0x3187, - 0xd95a, 0x20c4, - 0xd95b, 0x3c24, - 0xd95c, 0x6724, - 0xd95d, 0x1002, - 0xd95e, 0x24f4, - 0xd95f, 0x3c64, - 0xd960, 0x6436, - 0xd961, 0xdff4, - 0xd962, 0x6436, - 0xd963, 0x1002, - 0xd964, 0x2006, - 0xd965, 0x3d76, - 0xd966, 0xc161, - 0xd967, 0x6134, - 0xd968, 0x6135, - 0xd969, 0x5443, - 0xd96a, 0x0303, - 0xd96b, 0x6524, - 0xd96c, 0x00fb, - 0xd96d, 0x1002, - 0xd96e, 0x20d4, - 0xd96f, 0x3c24, - 0xd970, 0x2025, - 0xd971, 0x3005, - 0xd972, 0x6524, - 0xd973, 0x1002, - 0xd974, 0xd019, - 0xd975, 0x2104, - 0xd976, 0x3c24, - 0xd977, 0x2105, - 0xd978, 0x3805, - 0xd979, 0x6524, - 0xd97a, 0xdff4, - 0xd97b, 0x4005, - 0xd97c, 0x6524, - 0xd97d, 0x2e8d, - 0xd97e, 0x303d, - 0xd97f, 0x2408, - 0xd980, 0x35d8, - 0xd981, 0x5dd3, - 0xd982, 0x0307, - 0xd983, 0x8887, - 0xd984, 0x63a7, - 0xd985, 0x8887, - 0xd986, 0x63a7, - 0xd987, 0xdffd, - 0xd988, 0x00f9, - 0xd989, 0x1002, - 0xd98a, 0x0000, - }; - int i, err; - - /* set uC clock and activate it */ - err = set_phy_regs(phy, uCclock40MHz); - msleep(500); - if (err) - return err; - err = set_phy_regs(phy, uCclockActivate); - msleep(500); - if (err) - return err; - - /* write TWINAX EDC firmware into PHY */ - for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) - err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], - twinax_edc[i + 1]); - /* activate uC */ - err = set_phy_regs(phy, uCactivate); - if (!err) - phy->priv = edc_twinax; - return err; -} - -/* - * Return Module Type. - */ -static int ael2020_get_module_type(struct cphy *phy, int delay_ms) -{ - int v; - unsigned int stat; - - v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_STAT, &stat); - if (v) - return v; - - if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) { - /* module absent */ - return phy_modtype_none; - } - - return ael2xxx_get_module_type(phy, delay_ms); -} - -/* - * Enable PHY interrupts. We enable "Module Detection" interrupts (on any - * state transition) and then generic Link Alarm Status Interrupt (LASI). - */ -static int ael2020_intr_enable(struct cphy *phy) -{ - int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, - 0x2 << (AEL2020_GPIO_MODDET*4)); - return err ? err : t3_phy_lasi_intr_enable(phy); -} - -/* - * Disable PHY interrupts. The mirror of the above ... - */ -static int ael2020_intr_disable(struct cphy *phy) -{ - int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, - 0x1 << (AEL2020_GPIO_MODDET*4)); - return err ? err : t3_phy_lasi_intr_disable(phy); -} - -/* - * Clear PHY interrupt state. - */ -static int ael2020_intr_clear(struct cphy *phy) -{ - /* - * The GPIO Interrupt register on the AEL2020 is a "Latching High" - * (LH) register which is cleared to the current state when it's read. - * Thus, we simply read the register and discard the result. - */ - unsigned int stat; - int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat); - return err ? err : t3_phy_lasi_intr_clear(phy); -} - -/* - * Reset the PHY and put it into a canonical operating state. - */ -static int ael2020_reset(struct cphy *phy, int wait) -{ - static struct reg_val regs0[] = { - /* Erratum #2: CDRLOL asserted, causing PMA link down status */ - { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 }, - - /* force XAUI to send LF when RX_LOS is asserted */ - { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 }, - - /* RX_LOS pin is active high */ - { MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, - 0x0020, 0x0020 }, - - /* output Module's Loss Of Signal (LOS) to LED */ - { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, - 0xffff, 0x0004 }, - { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, - 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) }, - - /* end */ - { 0, 0, 0, 0 } - }; - int err; - unsigned int lasi_ctrl; - - /* grab current interrupt state */ - err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, - &lasi_ctrl); - if (err) - return err; - - err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 125); - if (err) - return err; - msleep(100); - - /* basic initialization for all module types */ - phy->priv = edc_none; - err = set_phy_regs(phy, regs0); - if (err) - return err; - - /* determine module type and perform appropriate initialization */ - err = ael2020_get_module_type(phy, 0); - if (err < 0) - return err; - phy->modtype = (u8)err; - if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) - err = ael2020_setup_twinax_edc(phy, err); - else - err = ael2020_setup_sr_edc(phy); - if (err) - return err; - - /* reset wipes out interrupts, reenable them if they were on */ - if (lasi_ctrl & 1) - err = ael2005_intr_enable(phy); - return err; -} - -/* - * Handle a PHY interrupt. - */ -static int ael2020_intr_handler(struct cphy *phy) -{ - unsigned int stat; - int ret, edc_needed, cause = 0; - - ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat); - if (ret) - return ret; - - if (stat & (0x1 << AEL2020_GPIO_MODDET)) { - /* modules have max 300 ms init time after hot plug */ - ret = ael2020_get_module_type(phy, 300); - if (ret < 0) - return ret; - - phy->modtype = (u8)ret; - if (ret == phy_modtype_none) - edc_needed = phy->priv; /* on unplug retain EDC */ - else if (ret == phy_modtype_twinax || - ret == phy_modtype_twinax_long) - edc_needed = edc_twinax; - else - edc_needed = edc_sr; - - if (edc_needed != phy->priv) { - ret = ael2020_reset(phy, 0); - return ret ? ret : cphy_cause_module_change; - } - cause = cphy_cause_module_change; - } - - ret = t3_phy_lasi_intr_handler(phy); - if (ret < 0) - return ret; - - ret |= cause; - return ret ? ret : cphy_cause_link_change; -} - -static struct cphy_ops ael2020_ops = { - .reset = ael2020_reset, - .intr_enable = ael2020_intr_enable, - .intr_disable = ael2020_intr_disable, - .intr_clear = ael2020_intr_clear, - .intr_handler = ael2020_intr_handler, - .get_link_status = get_link_status_r, - .power_down = ael1002_power_down, - .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, -}; - -int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, - const struct mdio_ops *mdio_ops) -{ - cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops, - SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | - SUPPORTED_IRQ, "10GBASE-R"); - msleep(125); - return 0; -} - /* * Get link status for a 10GBASE-X device. */ diff --git a/trunk/drivers/net/cxgb3/aq100x.c b/trunk/drivers/net/cxgb3/aq100x.c deleted file mode 100644 index b1fd5bf836e4..000000000000 --- a/trunk/drivers/net/cxgb3/aq100x.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "common.h" -#include "regs.h" - -enum { - /* MDIO_DEV_PMA_PMD registers */ - AQ_LINK_STAT = 0xe800, - AQ_IMASK_PMA = 0xf000, - - /* MDIO_DEV_XGXS registers */ - AQ_XAUI_RX_CFG = 0xc400, - AQ_XAUI_TX_CFG = 0xe400, - - /* MDIO_DEV_ANEG registers */ - AQ_1G_CTRL = 0xc400, - AQ_ANEG_STAT = 0xc800, - - /* MDIO_DEV_VEND1 registers */ - AQ_FW_VERSION = 0x0020, - AQ_IFLAG_GLOBAL = 0xfc00, - AQ_IMASK_GLOBAL = 0xff00, -}; - -enum { - IMASK_PMA = 1 << 2, - IMASK_GLOBAL = 1 << 15, - ADV_1G_FULL = 1 << 15, - ADV_1G_HALF = 1 << 14, - ADV_10G_FULL = 1 << 12, - AQ_RESET = (1 << 14) | (1 << 15), - AQ_LOWPOWER = 1 << 12, -}; - -static int aq100x_reset(struct cphy *phy, int wait) -{ - /* - * Ignore the caller specified wait time; always wait for the reset to - * complete. Can take up to 3s. - */ - int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000); - - if (err) - CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n", - phy->mdio.prtad, err); - - return err; -} - -static int aq100x_intr_enable(struct cphy *phy) -{ - int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA); - if (err) - return err; - - err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL); - return err; -} - -static int aq100x_intr_disable(struct cphy *phy) -{ - return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0); -} - -static int aq100x_intr_clear(struct cphy *phy) -{ - unsigned int v; - - t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v); - t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v); - - return 0; -} - -static int aq100x_intr_handler(struct cphy *phy) -{ - int err; - unsigned int cause, v; - - err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause); - if (err) - return err; - - /* Read (and reset) the latching version of the status */ - t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v); - - return cphy_cause_link_change; -} - -static int aq100x_power_down(struct cphy *phy, int off) -{ - return mdio_set_flag(&phy->mdio, phy->mdio.prtad, - MDIO_MMD_PMAPMD, MDIO_CTRL1, - MDIO_CTRL1_LPOWER, off); -} - -static int aq100x_autoneg_enable(struct cphy *phy) -{ - int err; - - err = aq100x_power_down(phy, 0); - if (!err) - err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, - MDIO_MMD_AN, MDIO_CTRL1, - BMCR_ANENABLE | BMCR_ANRESTART, 1); - - return err; -} - -static int aq100x_autoneg_restart(struct cphy *phy) -{ - int err; - - err = aq100x_power_down(phy, 0); - if (!err) - err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, - MDIO_MMD_AN, MDIO_CTRL1, - BMCR_ANENABLE | BMCR_ANRESTART, 1); - - return err; -} - -static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map) -{ - unsigned int adv; - int err; - - /* 10G advertisement */ - adv = 0; - if (advertise_map & ADVERTISED_10000baseT_Full) - adv |= ADV_10G_FULL; - err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, - ADV_10G_FULL, adv); - if (err) - return err; - - /* 1G advertisement */ - adv = 0; - if (advertise_map & ADVERTISED_1000baseT_Full) - adv |= ADV_1G_FULL; - if (advertise_map & ADVERTISED_1000baseT_Half) - adv |= ADV_1G_HALF; - err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL, - ADV_1G_FULL | ADV_1G_HALF, adv); - if (err) - return err; - - /* 100M, pause advertisement */ - adv = 0; - if (advertise_map & ADVERTISED_100baseT_Half) - adv |= ADVERTISE_100HALF; - if (advertise_map & ADVERTISED_100baseT_Full) - adv |= ADVERTISE_100FULL; - if (advertise_map & ADVERTISED_Pause) - adv |= ADVERTISE_PAUSE_CAP; - if (advertise_map & ADVERTISED_Asym_Pause) - adv |= ADVERTISE_PAUSE_ASYM; - err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE, - 0xfe0, adv); - - return err; -} - -static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable) -{ - return mdio_set_flag(&phy->mdio, phy->mdio.prtad, - MDIO_MMD_PMAPMD, MDIO_CTRL1, - BMCR_LOOPBACK, enable); -} - -static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex) -{ - /* no can do */ - return -1; -} - -static int aq100x_get_link_status(struct cphy *phy, int *link_ok, - int *speed, int *duplex, int *fc) -{ - int err; - unsigned int v; - - if (link_ok) { - err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v); - if (err) - return err; - - *link_ok = v & 1; - if (!*link_ok) - return 0; - } - - err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v); - if (err) - return err; - - if (speed) { - switch (v & 0x6) { - case 0x6: - *speed = SPEED_10000; - break; - case 0x4: - *speed = SPEED_1000; - break; - case 0x2: - *speed = SPEED_100; - break; - case 0x0: - *speed = SPEED_10; - break; - } - } - - if (duplex) - *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF; - - return 0; -} - -static struct cphy_ops aq100x_ops = { - .reset = aq100x_reset, - .intr_enable = aq100x_intr_enable, - .intr_disable = aq100x_intr_disable, - .intr_clear = aq100x_intr_clear, - .intr_handler = aq100x_intr_handler, - .autoneg_enable = aq100x_autoneg_enable, - .autoneg_restart = aq100x_autoneg_restart, - .advertise = aq100x_advertise, - .set_loopback = aq100x_set_loopback, - .set_speed_duplex = aq100x_set_speed_duplex, - .get_link_status = aq100x_get_link_status, - .power_down = aq100x_power_down, - .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, -}; - -int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, - const struct mdio_ops *mdio_ops) -{ - unsigned int v, v2, gpio, wait; - int err; - - cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops, - SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | - SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T"); - - /* - * The PHY has been out of reset ever since the system powered up. So - * we do a hard reset over here. - */ - gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; - t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); - msleep(1); - t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); - - /* - * Give it enough time to load the firmware and get ready for mdio. - */ - msleep(1000); - wait = 500; /* in 10ms increments */ - do { - err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); - if (err || v == 0xffff) { - - /* Allow prep_adapter to succeed when ffff is read */ - - CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", - phy_addr, err, v); - goto done; - } - - v &= AQ_RESET; - if (v) - msleep(10); - } while (v && --wait); - if (v) { - CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", - phy_addr, v); - - goto done; /* let prep_adapter succeed */ - } - - /* Datasheet says 3s max but this has been observed */ - wait = (500 - wait) * 10 + 1000; - if (wait > 3000) - CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait); - - /* Firmware version check. */ - t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v); - if (v != 30) { - CH_WARN(adapter, "PHY%d: unsupported firmware %d\n", - phy_addr, v); - return 0; /* allow t3_prep_adapter to succeed */ - } - - /* - * The PHY should start in really-low-power mode. Prepare it for normal - * operations. - */ - err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); - if (err) - return err; - if (v & AQ_LOWPOWER) { - err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1, - AQ_LOWPOWER, 0); - if (err) - return err; - msleep(10); - } else - CH_WARN(adapter, "PHY%d does not start in low power mode.\n", - phy_addr); - - /* - * Verify XAUI settings, but let prep succeed no matter what. - */ - v = v2 = 0; - t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v); - t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2); - if (v != 0x1b || v2 != 0x1b) - CH_WARN(adapter, - "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n", - phy_addr, v, v2); - -done: - return err; -} diff --git a/trunk/drivers/net/cxgb3/common.h b/trunk/drivers/net/cxgb3/common.h index d21b705501a9..79a113b99e2f 100644 --- a/trunk/drivers/net/cxgb3/common.h +++ b/trunk/drivers/net/cxgb3/common.h @@ -802,12 +802,8 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops); int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops); int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops); int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops); -int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, - int phy_addr, const struct mdio_ops *mdio_ops); #endif /* __CHELSIO_COMMON_H */ diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 538dda4422dc..0b87fee023f5 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -91,8 +91,6 @@ static const struct pci_device_id cxgb3_pci_tbl[] = { CH_DEVICE(0x31, 3), /* T3B20 */ CH_DEVICE(0x32, 1), /* T3B02 */ CH_DEVICE(0x35, 6), /* T3C20-derived T3C10 */ - CH_DEVICE(0x36, 3), /* S320E-CR */ - CH_DEVICE(0x37, 7), /* N320E-G2 */ {0,} }; @@ -433,78 +431,40 @@ static int init_tp_parity(struct adapter *adap) for (i = 0; i < 16; i++) { struct cpl_smt_write_req *req; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i)); req->iff = i; t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - await_mgmt_replies(adap, cnt, i + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!adap->nofail_skb) - goto alloc_skb_fail; - } } for (i = 0; i < 2048; i++) { struct cpl_l2t_write_req *req; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i)); req->params = htonl(V_L2T_W_IDX(i)); t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - await_mgmt_replies(adap, cnt, 16 + i + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!adap->nofail_skb) - goto alloc_skb_fail; - } } for (i = 0; i < 2048; i++) { struct cpl_rte_write_req *req; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i)); req->l2t_idx = htonl(V_L2T_W_IDX(i)); t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!adap->nofail_skb) - goto alloc_skb_fail; - } } - skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL); greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq)); memset(greq, 0, sizeof(*greq)); greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); @@ -513,17 +473,8 @@ static int init_tp_parity(struct adapter *adap) t3_mgmt_tx(adap, skb); i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); - if (skb == adap->nofail_skb) { - i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - } - t3_tp_set_offload_mode(adap, 0); return i; - -alloc_skb_fail: - t3_tp_set_offload_mode(adap, 0); - return -ENOMEM; } /** @@ -918,12 +869,7 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, struct mngt_pktsched_wr *req; int ret; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - return -ENOMEM; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; @@ -933,12 +879,6 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, req->max = hi; req->binding = port; ret = t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field), - GFP_KERNEL); - if (!adap->nofail_skb) - ret = -ENOMEM; - } return ret; } @@ -2511,16 +2451,14 @@ static void check_link_status(struct adapter *adapter) for_each_port(adapter, i) { struct net_device *dev = adapter->port[i]; struct port_info *p = netdev_priv(dev); - int link_fault; spin_lock_irq(&adapter->work_lock); - link_fault = p->link_fault; - spin_unlock_irq(&adapter->work_lock); - - if (link_fault) { + if (p->link_fault) { t3_link_fault(adapter, i); + spin_unlock_irq(&adapter->work_lock); continue; } + spin_unlock_irq(&adapter->work_lock); if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) { t3_xgm_intr_disable(adapter, i); @@ -3078,14 +3016,6 @@ static int __devinit init_one(struct pci_dev *pdev, goto out_disable_device; } - adapter->nofail_skb = - alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL); - if (!adapter->nofail_skb) { - dev_err(&pdev->dev, "cannot allocate nofail buffer\n"); - err = -ENOMEM; - goto out_free_adapter; - } - adapter->regs = ioremap_nocache(mmio_start, mmio_len); if (!adapter->regs) { dev_err(&pdev->dev, "cannot map device registers\n"); @@ -3129,6 +3059,7 @@ static int __devinit init_one(struct pci_dev *pdev, netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; + netdev->features |= NETIF_F_LLTX; netdev->features |= NETIF_F_GRO; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -3242,8 +3173,6 @@ static void __devexit remove_one(struct pci_dev *pdev) free_netdev(adapter->port[i]); iounmap(adapter->regs); - if (adapter->nofail_skb) - kfree_skb(adapter->nofail_skb); kfree(adapter); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c index f9f54b57b28c..620d80be6aac 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.c @@ -566,31 +566,13 @@ static void t3_process_tid_release_list(struct work_struct *work) spin_unlock_bh(&td->tid_release_lock); skb = alloc_skb(sizeof(struct cpl_tid_release), - GFP_KERNEL); - if (!skb) - skb = td->nofail_skb; - if (!skb) { - spin_lock_bh(&td->tid_release_lock); - p->ctx = (void *)td->tid_release_list; - td->tid_release_list = (struct t3c_tid_entry *)p; - break; - } + GFP_KERNEL | __GFP_NOFAIL); mk_tid_release(skb, p - td->tid_maps.tid_tab); cxgb3_ofld_send(tdev, skb); p->ctx = NULL; - if (skb == td->nofail_skb) - td->nofail_skb = - alloc_skb(sizeof(struct cpl_tid_release), - GFP_KERNEL); spin_lock_bh(&td->tid_release_lock); } - td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1; spin_unlock_bh(&td->tid_release_lock); - - if (!td->nofail_skb) - td->nofail_skb = - alloc_skb(sizeof(struct cpl_tid_release), - GFP_KERNEL); } /* use ctx as a next pointer in the tid release list */ @@ -603,7 +585,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid) p->ctx = (void *)td->tid_release_list; p->client = NULL; td->tid_release_list = p; - if (!p->ctx || td->release_list_incomplete) + if (!p->ctx) schedule_work(&td->tid_release_task); spin_unlock_bh(&td->tid_release_lock); } @@ -1292,9 +1274,6 @@ int cxgb3_offload_activate(struct adapter *adapter) if (list_empty(&adapter_list)) register_netevent_notifier(&nb); - t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL); - t->release_list_incomplete = 0; - add_adapter(adapter); return 0; @@ -1319,8 +1298,6 @@ void cxgb3_offload_deactivate(struct adapter *adapter) T3C_DATA(tdev) = NULL; t3_free_l2t(L2DATA(tdev)); L2DATA(tdev) = NULL; - if (t->nofail_skb) - kfree_skb(t->nofail_skb); kfree(t); } diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.h b/trunk/drivers/net/cxgb3/cxgb3_offload.h index 55945f422aec..a8e8e5fcdf84 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.h +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.h @@ -191,9 +191,6 @@ struct t3c_data { struct t3c_tid_entry *tid_release_list; spinlock_t tid_release_lock; struct work_struct tid_release_task; - - struct sk_buff *nofail_skb; - unsigned int release_list_incomplete; }; /* diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c index 29c79eb43beb..73d569e758ec 100644 --- a/trunk/drivers/net/cxgb3/sge.c +++ b/trunk/drivers/net/cxgb3/sge.c @@ -355,7 +355,7 @@ static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q, (*d->pg_chunk.p_cnt)--; if (!*d->pg_chunk.p_cnt) pci_unmap_page(pdev, - d->pg_chunk.mapping, + pci_unmap_addr(&d->pg_chunk, mapping), q->alloc_size, PCI_DMA_FROMDEVICE); put_page(d->pg_chunk.page); @@ -454,7 +454,7 @@ static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q, q->pg_chunk.offset = 0; mapping = pci_map_page(adapter->pdev, q->pg_chunk.page, 0, q->alloc_size, PCI_DMA_FROMDEVICE); - q->pg_chunk.mapping = mapping; + pci_unmap_addr_set(&q->pg_chunk, mapping, mapping); } sd->pg_chunk = q->pg_chunk; @@ -511,7 +511,8 @@ static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp) nomem: q->alloc_failed++; break; } - mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset; + mapping = pci_unmap_addr(&sd->pg_chunk, mapping) + + sd->pg_chunk.offset; pci_unmap_addr_set(sd, dma_addr, mapping); add_one_rx_chunk(mapping, d, q->gen); @@ -881,7 +882,7 @@ static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl, (*sd->pg_chunk.p_cnt)--; if (!*sd->pg_chunk.p_cnt) pci_unmap_page(adap->pdev, - sd->pg_chunk.mapping, + pci_unmap_addr(&sd->pg_chunk, mapping), fl->alloc_size, PCI_DMA_FROMDEVICE); if (!skb) { @@ -1240,6 +1241,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) q = &qs->txq[TXQ_ETH]; txq = netdev_get_tx_queue(dev, qidx); + spin_lock(&q->lock); reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK); credits = q->size - q->in_use; @@ -1250,6 +1252,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) dev_err(&adap->pdev->dev, "%s: Tx ring %u full while queue awake!\n", dev->name, q->cntxt_id & 7); + spin_unlock(&q->lock); return NETDEV_TX_BUSY; } @@ -1283,6 +1286,9 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) if (vlan_tx_tag_present(skb) && pi->vlan_grp) qs->port_stats[SGE_PSTAT_VLANINS]++; + dev->trans_start = jiffies; + spin_unlock(&q->lock); + /* * We do not use Tx completion interrupts to free DMAd Tx packets. * This is good for performamce but means that we rely on new Tx @@ -2090,7 +2096,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, (*sd->pg_chunk.p_cnt)--; if (!*sd->pg_chunk.p_cnt) pci_unmap_page(adap->pdev, - sd->pg_chunk.mapping, + pci_unmap_addr(&sd->pg_chunk, mapping), fl->alloc_size, PCI_DMA_FROMDEVICE); @@ -2852,12 +2858,11 @@ static void sge_timer_tx(unsigned long data) unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0}; unsigned long next_period; - if (__netif_tx_trylock(qs->tx_q)) { - tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH], - TX_RECLAIM_TIMER_CHUNK); - __netif_tx_unlock(qs->tx_q); + if (spin_trylock(&qs->txq[TXQ_ETH].lock)) { + tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH], + TX_RECLAIM_TIMER_CHUNK); + spin_unlock(&qs->txq[TXQ_ETH].lock); } - if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) { tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD], TX_RECLAIM_TIMER_CHUNK); @@ -2865,8 +2870,8 @@ static void sge_timer_tx(unsigned long data) } next_period = TX_RECLAIM_PERIOD >> - (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) / - TX_RECLAIM_TIMER_CHUNK); + (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) / + TX_RECLAIM_TIMER_CHUNK); mod_timer(&qs->tx_reclaim_timer, jiffies + next_period); } diff --git a/trunk/drivers/net/cxgb3/t3_hw.c b/trunk/drivers/net/cxgb3/t3_hw.c index 870d44992c70..fc7db8a9ba89 100644 --- a/trunk/drivers/net/cxgb3/t3_hw.c +++ b/trunk/drivers/net/cxgb3/t3_hw.c @@ -526,11 +526,6 @@ static const struct adapter_info t3_adap_info[] = { F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, &mi1_mdio_ext_ops, "Chelsio T310" }, - {1, 0, 0, - F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | - F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL, - { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, - &mi1_mdio_ext_ops, "Chelsio N320E-G2" }, }; /* @@ -557,8 +552,6 @@ static const struct port_type_info port_types[] = { { t3_qt2045_phy_prep }, { t3_ael1006_phy_prep }, { NULL }, - { t3_aq100x_phy_prep }, - { t3_ael2020_phy_prep }, }; #define VPD_ENTRY(name, len) \ @@ -1288,11 +1281,6 @@ void t3_link_fault(struct adapter *adapter, int port_id) A_XGM_INT_STATUS + mac->offset); link_fault &= F_LINKFAULTCHANGE; - link_ok = lc->link_ok; - speed = lc->speed; - duplex = lc->duplex; - fc = lc->fc; - phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); if (link_fault) { diff --git a/trunk/drivers/net/cxgb3/version.h b/trunk/drivers/net/cxgb3/version.h index 9d0bd9dd9ab1..7bf963ec5548 100644 --- a/trunk/drivers/net/cxgb3/version.h +++ b/trunk/drivers/net/cxgb3/version.h @@ -35,10 +35,10 @@ #define DRV_DESC "Chelsio T3 Network Driver" #define DRV_NAME "cxgb3" /* Driver version */ -#define DRV_VERSION "1.1.3-ko" +#define DRV_VERSION "1.1.2-ko" /* Firmware version */ #define FW_VERSION_MAJOR 7 -#define FW_VERSION_MINOR 4 +#define FW_VERSION_MINOR 1 #define FW_VERSION_MICRO 0 #endif /* __CHELSIO_VERSION_H */ diff --git a/trunk/drivers/net/davinci_emac.c b/trunk/drivers/net/davinci_emac.c index 0e9b9f9632c1..cf689a056b38 100644 --- a/trunk/drivers/net/davinci_emac.c +++ b/trunk/drivers/net/davinci_emac.c @@ -1819,6 +1819,7 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr) struct emac_rxch *rxch = priv->rxch[EMAC_DEF_RX_CH]; struct device *emac_dev = &priv->ndev->dev; struct sockaddr *sa = addr; + DECLARE_MAC_BUF(mac); /* Store mac addr in priv and rx channel and set it in EMAC hw */ memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len); @@ -1827,8 +1828,8 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr) emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr); if (netif_msg_drv(priv)) - dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n", - priv->mac_addr); + dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %s\n", + print_mac(mac, priv->mac_addr)); return 0; } @@ -2682,10 +2683,11 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) ndev->irq = res->start; if (!is_valid_ether_addr(priv->mac_addr)) { + DECLARE_MAC_BUF(buf); /* Use random MAC if none passed */ random_ether_addr(priv->mac_addr); - printk(KERN_WARNING "%s: using random MAC addr: %pM\n", - __func__, priv->mac_addr); + printk(KERN_WARNING "%s: using random MAC addr: %s\n", + __func__, print_mac(buf, priv->mac_addr)); } ndev->netdev_ops = &emac_netdev_ops; diff --git a/trunk/drivers/net/declance.c b/trunk/drivers/net/declance.c index 2b22e580c4de..b62405a69180 100644 --- a/trunk/drivers/net/declance.c +++ b/trunk/drivers/net/declance.c @@ -895,7 +895,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; volatile u16 *ib = (volatile u16 *)dev->mem_start; - unsigned long flags; int entry, len; len = skb->len; @@ -908,8 +907,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_bytes += len; - spin_lock_irqsave(&lp->lock, flags); - entry = lp->tx_new; *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; @@ -928,8 +925,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Kick the lance: transmit now */ writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD); - spin_unlock_irqrestore(&lp->lock, flags); - dev->trans_start = jiffies; dev_kfree_skb(skb); diff --git a/trunk/drivers/net/dl2k.c b/trunk/drivers/net/dl2k.c index 895d72143ee0..4a1b554654eb 100644 --- a/trunk/drivers/net/dl2k.c +++ b/trunk/drivers/net/dl2k.c @@ -539,7 +539,7 @@ rio_tx_timeout (struct net_device *dev) dev->name, readl (ioaddr + TxStatus)); rio_free_tx(dev, 0); dev->if_port = 0; - dev->trans_start = jiffies; /* prevent tx timeout */ + dev->trans_start = jiffies; } /* allocate and initialize Tx and Rx descriptors */ @@ -610,7 +610,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) if (np->link_status == 0) { /* Link Down */ dev_kfree_skb(skb); - return NETDEV_TX_OK; + return 0; } ioaddr = dev->base_addr; entry = np->cur_tx % TX_RING_SIZE; @@ -665,7 +665,9 @@ start_xmit (struct sk_buff *skb, struct net_device *dev) writel (0, dev->base_addr + TFDListPtr1); } - return NETDEV_TX_OK; + /* NETDEV WATCHDOG timer */ + dev->trans_start = jiffies; + return 0; } static irqreturn_t diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 119dc5300f9d..0f9ee1348552 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -143,8 +143,6 @@ * FIXES: * 2005/12/02 - Michael O'Donnell * - Stratus87247: protect MDI control register manipulations - * 2009/06/01 - Andreas Mohr - * - add clean lowlevel I/O emulation for cards with MII-lacking PHYs */ #include @@ -374,7 +372,6 @@ enum eeprom_op { enum eeprom_offsets { eeprom_cnfg_mdix = 0x03, - eeprom_phy_iface = 0x06, eeprom_id = 0x0A, eeprom_config_asf = 0x0D, eeprom_smbus_addr = 0x90, @@ -384,18 +381,6 @@ enum eeprom_cnfg_mdix { eeprom_mdix_enabled = 0x0080, }; -enum eeprom_phy_iface { - NoSuchPhy = 0, - I82553AB, - I82553C, - I82503, - DP83840, - S80C240, - S80C24, - I82555, - DP83840A = 10, -}; - enum eeprom_id { eeprom_id_wol = 0x0020, }; @@ -560,7 +545,6 @@ struct nic { u32 msg_enable ____cacheline_aligned; struct net_device *netdev; struct pci_dev *pdev; - u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data); struct rx *rxs ____cacheline_aligned; struct rx *rx_to_use; @@ -915,21 +899,7 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, return err; } -static int mdio_read(struct net_device *netdev, int addr, int reg) -{ - struct nic *nic = netdev_priv(netdev); - return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0); -} - -static void mdio_write(struct net_device *netdev, int addr, int reg, int data) -{ - struct nic *nic = netdev_priv(netdev); - - nic->mdio_ctrl(nic, addr, mdi_write, reg, data); -} - -/* the standard mdio_ctrl() function for usual MII-compliant hardware */ -static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) +static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) { u32 data_out = 0; unsigned int i; @@ -968,83 +938,30 @@ static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) return (u16)data_out; } -/* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */ -static u16 mdio_ctrl_phy_82552_v(struct nic *nic, - u32 addr, - u32 dir, - u32 reg, - u16 data) -{ - if ((reg == MII_BMCR) && (dir == mdi_write)) { - if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) { - u16 advert = mdio_read(nic->netdev, nic->mii.phy_id, - MII_ADVERTISE); - - /* - * Workaround Si issue where sometimes the part will not - * autoneg to 100Mbps even when advertised. - */ - if (advert & ADVERTISE_100FULL) - data |= BMCR_SPEED100 | BMCR_FULLDPLX; - else if (advert & ADVERTISE_100HALF) - data |= BMCR_SPEED100; - } - } - return mdio_ctrl_hw(nic, addr, dir, reg, data); +static int mdio_read(struct net_device *netdev, int addr, int reg) +{ + return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0); } -/* Fully software-emulated mdio_ctrl() function for cards without - * MII-compliant PHYs. - * For now, this is mainly geared towards 80c24 support; in case of further - * requirements for other types (i82503, ...?) either extend this mechanism - * or split it, whichever is cleaner. - */ -static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic, - u32 addr, - u32 dir, - u32 reg, - u16 data) -{ - /* might need to allocate a netdev_priv'ed register array eventually - * to be able to record state changes, but for now - * some fully hardcoded register handling ought to be ok I guess. */ - - if (dir == mdi_read) { - switch (reg) { - case MII_BMCR: - /* Auto-negotiation, right? */ - return BMCR_ANENABLE | - BMCR_FULLDPLX; - case MII_BMSR: - return BMSR_LSTATUS /* for mii_link_ok() */ | - BMSR_ANEGCAPABLE | - BMSR_10FULL; - case MII_ADVERTISE: - /* 80c24 is a "combo card" PHY, right? */ - return ADVERTISE_10HALF | - ADVERTISE_10FULL; - default: - DPRINTK(HW, DEBUG, - "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n", - dir == mdi_read ? "READ" : "WRITE", addr, reg, data); - return 0xFFFF; - } - } else { - switch (reg) { - default: - DPRINTK(HW, DEBUG, - "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n", - dir == mdi_read ? "READ" : "WRITE", addr, reg, data); - return 0xFFFF; - } - } -} -static inline int e100_phy_supports_mii(struct nic *nic) +static void mdio_write(struct net_device *netdev, int addr, int reg, int data) { - /* for now, just check it by comparing whether we - are using MII software emulation. - */ - return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated); + struct nic *nic = netdev_priv(netdev); + + if ((nic->phy == phy_82552_v) && (reg == MII_BMCR) && + (data & (BMCR_ANRESTART | BMCR_ANENABLE))) { + u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE); + + /* + * Workaround Si issue where sometimes the part will not + * autoneg to 100Mbps even when advertised. + */ + if (advert & ADVERTISE_100FULL) + data |= BMCR_SPEED100 | BMCR_FULLDPLX; + else if (advert & ADVERTISE_100HALF) + data |= BMCR_SPEED100; + } + + mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data); } static void e100_get_defaults(struct nic *nic) @@ -1096,8 +1013,7 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) config->standard_stat_counter = 0x1; /* 1=standard, 0=extended */ config->rx_discard_short_frames = 0x1; /* 1=discard, 0=pass */ config->tx_underrun_retry = 0x3; /* # of underrun retries */ - if (e100_phy_supports_mii(nic)) - config->mii_mode = 1; /* 1=MII mode, 0=i82503 mode */ + config->mii_mode = 0x1; /* 1=MII mode, 0=503 mode */ config->pad10 = 0x6; config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */ config->preamble_length = 0x2; /* 0=1, 1=3, 2=7, 3=15 bytes */ @@ -1354,42 +1270,6 @@ static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb) offsetof(struct mem, dump_buf)); } -static int e100_phy_check_without_mii(struct nic *nic) -{ - u8 phy_type; - int without_mii; - - phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f; - - switch (phy_type) { - case NoSuchPhy: /* Non-MII PHY; UNTESTED! */ - case I82503: /* Non-MII PHY; UNTESTED! */ - case S80C24: /* Non-MII PHY; tested and working */ - /* paragraph from the FreeBSD driver, "FXP_PHY_80C24": - * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter - * doesn't have a programming interface of any sort. The - * media is sensed automatically based on how the link partner - * is configured. This is, in essence, manual configuration. - */ - DPRINTK(PROBE, INFO, - "found MII-less i82503 or 80c24 or other PHY\n"); - - nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated; - nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */ - - /* these might be needed for certain MII-less cards... - * nic->flags |= ich; - * nic->flags |= ich_10h_workaround; */ - - without_mii = 1; - break; - default: - without_mii = 0; - break; - } - return without_mii; -} - #define NCONFIG_AUTO_SWITCH 0x0080 #define MII_NSC_CONG MII_RESV1 #define NSC_CONG_ENABLE 0x0100 @@ -1410,21 +1290,9 @@ static int e100_phy_init(struct nic *nic) if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) break; } - if (addr == 32) { - /* uhoh, no PHY detected: check whether we seem to be some - * weird, rare variant which is *known* to not have any MII. - * But do this AFTER MII checking only, since this does - * lookup of EEPROM values which may easily be unreliable. */ - if (e100_phy_check_without_mii(nic)) - return 0; /* simply return and hope for the best */ - else { - /* for unknown cases log a fatal error */ - DPRINTK(HW, ERR, - "Failed to locate any known PHY, aborting.\n"); - return -EAGAIN; - } - } else - DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); + DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); + if (addr == 32) + return -EAGAIN; /* Isolate all the PHY ids */ for (addr = 0; addr < 32; addr++) @@ -1452,9 +1320,6 @@ static int e100_phy_init(struct nic *nic) if (nic->phy == phy_82552_v) { u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE); - /* assign special tweaked mdio_ctrl() function */ - nic->mdio_ctrl = mdio_ctrl_phy_82552_v; - /* Workaround Si not advertising flow-control during autoneg */ advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert); @@ -2720,7 +2585,6 @@ static int __devinit e100_probe(struct pci_dev *pdev, nic->netdev = netdev; nic->pdev = pdev; nic->msg_enable = (1 << debug) - 1; - nic->mdio_ctrl = mdio_ctrl_hw; pci_set_drvdata(pdev, netdev); if ((err = pci_enable_device(pdev))) { @@ -2958,13 +2822,12 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - netif_device_detach(netdev); + /* Similar to calling e100_down(), but avoids adapter I/O. */ + e100_close(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - - if (netif_running(netdev)) - e100_down(nic); + /* Detach; put netif into a state similar to hotplug unplug. */ + napi_enable(&nic->napi); + netif_device_detach(netdev); pci_disable_device(pdev); /* Request a slot reset. */ diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 8d36743c8140..9a32d0c73cb3 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -2330,8 +2330,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - struct netdev_hw_addr *ha; - bool use_uc = false; + struct dev_addr_list *uc_ptr; struct dev_addr_list *mc_ptr; u32 rctl; u32 hash_value; @@ -2370,11 +2369,12 @@ static void e1000_set_rx_mode(struct net_device *netdev) rctl |= E1000_RCTL_VFE; } + uc_ptr = NULL; if (netdev->uc_count > rar_entries - 1) { rctl |= E1000_RCTL_UPE; } else if (!(netdev->flags & IFF_PROMISC)) { rctl &= ~E1000_RCTL_UPE; - use_uc = true; + uc_ptr = netdev->uc_list; } ew32(RCTL, rctl); @@ -2392,20 +2392,13 @@ static void e1000_set_rx_mode(struct net_device *netdev) * if there are not 14 addresses, go ahead and clear the filters * -- with 82571 controllers only 0-13 entries are filled here */ - i = 1; - if (use_uc) - list_for_each_entry(ha, &netdev->uc_list, list) { - if (i == rar_entries) - break; - e1000_rar_set(hw, ha->addr, i++); - } - - WARN_ON(i == rar_entries); - mc_ptr = netdev->mc_list; - for (; i < rar_entries; i++) { - if (mc_ptr) { + for (i = 1; i < rar_entries; i++) { + if (uc_ptr) { + e1000_rar_set(hw, uc_ptr->da_addr, i); + uc_ptr = uc_ptr->next; + } else if (mc_ptr) { e1000_rar_set(hw, mc_ptr->da_addr, i); mc_ptr = mc_ptr->next; } else { @@ -2415,6 +2408,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) E1000_WRITE_FLUSH(); } } + WARN_ON(uc_ptr != NULL); /* load any remaining addresses into the hash table */ @@ -2998,7 +2992,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, size -= 4; buffer_info->length = size; - buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + buffer_info->dma = map[0] + offset; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; @@ -3039,7 +3033,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, size -= 4; buffer_info->length = size; - buffer_info->dma = map[f] + offset; + buffer_info->dma = map[f + 1] + offset; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; @@ -3371,6 +3365,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (count) { e1000_tx_queue(adapter, tx_ring, tx_flags, count); + netdev->trans_start = jiffies; /* Make sure there is space in the ring for the next send. */ e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2); @@ -4035,9 +4030,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, PCI_DMA_FROMDEVICE); length = le16_to_cpu(rx_desc->length); - /* !EOP means multiple descriptors were used to store a single - * packet, also make sure the frame isn't just CRC only */ - if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) { + + if (unlikely(!(status & E1000_RXD_STAT_EOP))) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" " buffers\n", netdev->name); diff --git a/trunk/drivers/net/e1000e/82571.c b/trunk/drivers/net/e1000e/82571.c index b53b40ba88a8..6c01a2072c87 100644 --- a/trunk/drivers/net/e1000e/82571.c +++ b/trunk/drivers/net/e1000e/82571.c @@ -71,7 +71,6 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw); static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); static s32 e1000_led_on_82574(struct e1000_hw *hw); -static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); /** * e1000_init_phy_params_82571 - Init PHY func ptrs. @@ -213,9 +212,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; struct e1000_mac_operations *func = &mac->ops; - u32 swsm = 0; - u32 swsm2 = 0; - bool force_clear_smbi = false; /* Set media type */ switch (adapter->pdev->device) { @@ -280,50 +276,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) break; } - /* - * Ensure that the inter-port SWSM.SMBI lock bit is clear before - * first NVM or PHY acess. This should be done for single-port - * devices, and for one port only on dual-port devices so that - * for those devices we can still use the SMBI lock to synchronize - * inter-port accesses to the PHY & NVM. - */ - switch (hw->mac.type) { - case e1000_82571: - case e1000_82572: - swsm2 = er32(SWSM2); - - if (!(swsm2 & E1000_SWSM2_LOCK)) { - /* Only do this for the first interface on this card */ - ew32(SWSM2, - swsm2 | E1000_SWSM2_LOCK); - force_clear_smbi = true; - } else - force_clear_smbi = false; - break; - default: - force_clear_smbi = true; - break; - } - - if (force_clear_smbi) { - /* Make sure SWSM.SMBI is clear */ - swsm = er32(SWSM); - if (swsm & E1000_SWSM_SMBI) { - /* This bit should not be set on a first interface, and - * indicates that the bootagent or EFI code has - * improperly left this bit enabled - */ - hw_dbg(hw, "Please update your 82571 Bootagent\n"); - } - ew32(SWSM, swsm & ~E1000_SWSM_SMBI); - } - - /* - * Initialze device specific counter of SMBI acquisition - * timeouts. - */ - hw->dev_spec.e82571.smb_counter = 0; - return 0; } @@ -389,10 +341,8 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1, &eeprom_data) < 0) break; - if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) { - adapter->flags |= FLAG_HAS_JUMBO_FRAMES; - adapter->max_hw_frame_size = DEFAULT_JUMBO; - } + if (eeprom_data & NVM_WORD1A_ASPM_MASK) + adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES; } break; default: @@ -461,37 +411,11 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; - s32 sw_timeout = hw->nvm.word_size + 1; - s32 fw_timeout = hw->nvm.word_size + 1; + s32 timeout = hw->nvm.word_size + 1; s32 i = 0; - /* - * If we have timedout 3 times on trying to acquire - * the inter-port SMBI semaphore, there is old code - * operating on the other port, and it is not - * releasing SMBI. Modify the number of times that - * we try for the semaphore to interwork with this - * older code. - */ - if (hw->dev_spec.e82571.smb_counter > 2) - sw_timeout = 1; - - /* Get the SW semaphore */ - while (i < sw_timeout) { - swsm = er32(SWSM); - if (!(swsm & E1000_SWSM_SMBI)) - break; - - udelay(50); - i++; - } - - if (i == sw_timeout) { - hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n"); - hw->dev_spec.e82571.smb_counter++; - } /* Get the FW semaphore. */ - for (i = 0; i < fw_timeout; i++) { + for (i = 0; i < timeout; i++) { swsm = er32(SWSM); ew32(SWSM, swsm | E1000_SWSM_SWESMBI); @@ -502,9 +426,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) udelay(50); } - if (i == fw_timeout) { + if (i == timeout) { /* Release semaphores */ - e1000_put_hw_semaphore_82571(hw); + e1000e_put_hw_semaphore(hw); hw_dbg(hw, "Driver can't access the NVM\n"); return -E1000_ERR_NVM; } @@ -523,7 +447,9 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) u32 swsm; swsm = er32(SWSM); - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + + swsm &= ~E1000_SWSM_SWESMBI; + ew32(SWSM, swsm); } @@ -1659,7 +1585,6 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) static struct e1000_mac_operations e82571_mac_ops = { /* .check_mng_mode: mac type dependent */ /* .check_for_link: media type dependent */ - .id_led_init = e1000e_id_led_init, .cleanup_led = e1000e_cleanup_led_generic, .clear_hw_cntrs = e1000_clear_hw_cntrs_82571, .get_bus_info = e1000e_get_bus_info_pcie, @@ -1671,7 +1596,6 @@ static struct e1000_mac_operations e82571_mac_ops = { .init_hw = e1000_init_hw_82571, .setup_link = e1000_setup_link_82571, /* .setup_physical_interface: media type dependent */ - .setup_led = e1000e_setup_led_generic, }; static struct e1000_phy_operations e82_phy_ops_igp = { @@ -1748,7 +1672,6 @@ struct e1000_info e1000_82571_info = { | FLAG_TARC_SPEED_MODE_BIT /* errata */ | FLAG_APME_CHECK_PORT_B, .pba = 38, - .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_igp, @@ -1765,7 +1688,6 @@ struct e1000_info e1000_82572_info = { | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_TARC_SPEED_MODE_BIT, /* errata */ .pba = 38, - .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_igp, @@ -1784,7 +1706,6 @@ struct e1000_info e1000_82573_info = { | FLAG_HAS_ERT | FLAG_HAS_SWSM_ON_LOAD, .pba = 20, - .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_m88, @@ -1803,7 +1724,6 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, .pba = 20, - .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_bm, @@ -1820,7 +1740,6 @@ struct e1000_info e1000_82583_info = { | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, .pba = 20, - .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, .phy_ops = &e82_phy_ops_bm, diff --git a/trunk/drivers/net/e1000e/defines.h b/trunk/drivers/net/e1000e/defines.h index 8890c97e1120..243aa499fe90 100644 --- a/trunk/drivers/net/e1000e/defines.h +++ b/trunk/drivers/net/e1000e/defines.h @@ -56,7 +56,6 @@ /* Wake Up Control */ #define E1000_WUC_APME 0x00000001 /* APM Enable */ #define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ -#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */ /* Wake Up Filter Control */ #define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ @@ -66,13 +65,6 @@ #define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ -/* Wake Up Status */ -#define E1000_WUS_LNKC E1000_WUFC_LNKC -#define E1000_WUS_MAG E1000_WUFC_MAG -#define E1000_WUS_EX E1000_WUFC_EX -#define E1000_WUS_MC E1000_WUFC_MC -#define E1000_WUS_BC E1000_WUFC_BC - /* Extended Device Control */ #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ @@ -85,7 +77,6 @@ #define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ #define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ -#define E1000_CTRL_EXT_PHYPDEN 0x00100000 /* Receive Descriptor bit definitions */ #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ @@ -149,7 +140,6 @@ #define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */ #define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min threshold size */ #define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ -#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ #define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ #define E1000_RCTL_SZ_2048 0x00000000 /* Rx buffer size 2048 */ @@ -163,7 +153,6 @@ #define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ #define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ #define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ -#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ #define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ #define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ @@ -266,16 +255,11 @@ #define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX /* LED Control */ -#define E1000_PHY_LED0_MODE_MASK 0x00000007 -#define E1000_PHY_LED0_IVRT 0x00000008 -#define E1000_PHY_LED0_MASK 0x0000001F - #define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F #define E1000_LEDCTL_LED0_MODE_SHIFT 0 #define E1000_LEDCTL_LED0_IVRT 0x00000040 #define E1000_LEDCTL_LED0_BLINK 0x00000080 -#define E1000_LEDCTL_MODE_LINK_UP 0x2 #define E1000_LEDCTL_MODE_LED_ON 0xE #define E1000_LEDCTL_MODE_LED_OFF 0xF @@ -376,8 +360,6 @@ #define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ #define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ -#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */ - /* Interrupt Cause Read */ #define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ #define E1000_ICR_LSC 0x00000004 /* Link Status Change */ @@ -487,8 +469,6 @@ #define AUTO_READ_DONE_TIMEOUT 10 /* Flow Control */ -#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */ -#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ #define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ /* Transmit Configuration Word */ @@ -694,8 +674,6 @@ #define IFE_C_E_PHY_ID 0x02A80310 #define BME1000_E_PHY_ID 0x01410CB0 #define BME1000_E_PHY_ID_R2 0x01410CB1 -#define I82577_E_PHY_ID 0x01540050 -#define I82578_E_PHY_ID 0x004DD040 /* M88E1000 Specific Registers */ #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ @@ -749,9 +727,6 @@ #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 -#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020 -#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C - /* BME1000 PHY Specific Control Register */ #define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */ diff --git a/trunk/drivers/net/e1000e/e1000.h b/trunk/drivers/net/e1000e/e1000.h index d6e491bc58c9..f37360aa12a8 100644 --- a/trunk/drivers/net/e1000e/e1000.h +++ b/trunk/drivers/net/e1000e/e1000.h @@ -96,51 +96,6 @@ struct e1000_info; /* Number of packet split data buffers (not including the header buffer) */ #define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1) -#define DEFAULT_JUMBO 9234 - -/* BM/HV Specific Registers */ -#define BM_PORT_CTRL_PAGE 769 - -#define PHY_UPPER_SHIFT 21 -#define BM_PHY_REG(page, reg) \ - (((reg) & MAX_PHY_REG_ADDRESS) |\ - (((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\ - (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT))) - -/* PHY Wakeup Registers and defines */ -#define BM_RCTL PHY_REG(BM_WUC_PAGE, 0) -#define BM_WUC PHY_REG(BM_WUC_PAGE, 1) -#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2) -#define BM_WUS PHY_REG(BM_WUC_PAGE, 3) -#define BM_RAR_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2))) -#define BM_RAR_M(_i) (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2))) -#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2))) -#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2))) -#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1))) - -#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */ -#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */ -#define BM_RCTL_MO_SHIFT 3 /* Multicast Offset Shift */ -#define BM_RCTL_MO_MASK (3 << 3) /* Multicast Offset Mask */ -#define BM_RCTL_BAM 0x0020 /* Broadcast Accept Mode */ -#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */ -#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */ - -#define HV_SCC_UPPER PHY_REG(778, 16) /* Single Collision Count */ -#define HV_SCC_LOWER PHY_REG(778, 17) -#define HV_ECOL_UPPER PHY_REG(778, 18) /* Excessive Collision Count */ -#define HV_ECOL_LOWER PHY_REG(778, 19) -#define HV_MCC_UPPER PHY_REG(778, 20) /* Multiple Collision Count */ -#define HV_MCC_LOWER PHY_REG(778, 21) -#define HV_LATECOL_UPPER PHY_REG(778, 23) /* Late Collision Count */ -#define HV_LATECOL_LOWER PHY_REG(778, 24) -#define HV_COLC_UPPER PHY_REG(778, 25) /* Collision Count */ -#define HV_COLC_LOWER PHY_REG(778, 26) -#define HV_DC_UPPER PHY_REG(778, 27) /* Defer Count */ -#define HV_DC_LOWER PHY_REG(778, 28) -#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ -#define HV_TNCRS_LOWER PHY_REG(778, 30) - enum e1000_boards { board_82571, board_82572, @@ -151,7 +106,6 @@ enum e1000_boards { board_ich8lan, board_ich9lan, board_ich10lan, - board_pchlan, }; struct e1000_queue_stats { @@ -339,7 +293,6 @@ struct e1000_adapter { u32 eeprom_wol; u32 wol; u32 pba; - u32 max_hw_frame_size; bool fc_autoneg; @@ -349,7 +302,6 @@ struct e1000_adapter { unsigned int flags2; struct work_struct downshift_task; struct work_struct update_phy_task; - struct work_struct led_blink_task; }; struct e1000_info { @@ -357,7 +309,6 @@ struct e1000_info { unsigned int flags; unsigned int flags2; u32 pba; - u32 max_hw_frame_size; s32 (*get_variants)(struct e1000_adapter *); struct e1000_mac_operations *mac_ops; struct e1000_phy_operations *phy_ops; @@ -400,7 +351,6 @@ struct e1000_info { /* CRC Stripping defines */ #define FLAG2_CRC_STRIPPING (1 << 0) -#define FLAG2_HAS_PHY_WAKEUP (1 << 1) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) @@ -454,7 +404,6 @@ extern struct e1000_info e1000_82583_info; extern struct e1000_info e1000_ich8_info; extern struct e1000_info e1000_ich9_info; extern struct e1000_info e1000_ich10_info; -extern struct e1000_info e1000_pch_info; extern struct e1000_info e1000_es2_info; extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num); @@ -476,7 +425,6 @@ extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw); extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw); extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw); extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw); -extern s32 e1000e_setup_led_generic(struct e1000_hw *hw); extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw); extern s32 e1000e_led_on_generic(struct e1000_hw *hw); extern s32 e1000e_led_off_generic(struct e1000_hw *hw); @@ -545,15 +493,6 @@ extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000e_check_downshift(struct e1000_hw *hw); -extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data); -extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); -extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow); -extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); -extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); -extern s32 e1000_check_polarity_82577(struct e1000_hw *hw); -extern s32 e1000_get_phy_info_82577(struct e1000_hw *hw); -extern s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw); -extern s32 e1000_get_cable_length_82577(struct e1000_hw *hw); static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw) { diff --git a/trunk/drivers/net/e1000e/es2lan.c b/trunk/drivers/net/e1000e/es2lan.c index ae5d73689353..8964838c686b 100644 --- a/trunk/drivers/net/e1000e/es2lan.c +++ b/trunk/drivers/net/e1000e/es2lan.c @@ -1366,7 +1366,6 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) } static struct e1000_mac_operations es2_mac_ops = { - .id_led_init = e1000e_id_led_init, .check_mng_mode = e1000e_check_mng_mode_generic, /* check_for_link dependent on media type */ .cleanup_led = e1000e_cleanup_led_generic, @@ -1380,7 +1379,6 @@ static struct e1000_mac_operations es2_mac_ops = { .init_hw = e1000_init_hw_80003es2lan, .setup_link = e1000e_setup_link, /* setup_physical_interface dependent on media type */ - .setup_led = e1000e_setup_led_generic, }; static struct e1000_phy_operations es2_phy_ops = { @@ -1424,7 +1422,6 @@ struct e1000_info e1000_es2_info = { | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, .pba = 38, - .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_80003es2lan, .mac_ops = &es2_mac_ops, .phy_ops = &es2_phy_ops, diff --git a/trunk/drivers/net/e1000e/ethtool.c b/trunk/drivers/net/e1000e/ethtool.c index 1bf4d2a5d34f..4d25ede88369 100644 --- a/trunk/drivers/net/e1000e/ethtool.c +++ b/trunk/drivers/net/e1000e/ethtool.c @@ -167,15 +167,6 @@ static int e1000_get_settings(struct net_device *netdev, ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; - - /* MDI-X => 2; MDI =>1; Invalid =>0 */ - if ((hw->phy.media_type == e1000_media_type_copper) && - !hw->mac.get_link_status) - ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : - ETH_TP_MDI; - else - ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; - return 0; } @@ -785,7 +776,6 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) u32 after; u32 i; u32 toggle; - u32 mask; /* * The status register is Read Only, so a write should fail. @@ -798,9 +788,17 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) case e1000_80003es2lan: toggle = 0x7FFFF3FF; break; - default: + case e1000_82573: + case e1000_82574: + case e1000_82583: + case e1000_ich8lan: + case e1000_ich9lan: + case e1000_ich10lan: toggle = 0x7FFFF033; break; + default: + toggle = 0xFFFFF833; + break; } before = er32(STATUS); @@ -846,18 +844,11 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF); REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF); REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF); - mask = 0x8003FFFF; - switch (mac->type) { - case e1000_ich10lan: - case e1000_pchlan: - mask |= (1 << 18); - break; - default: - break; - } for (i = 0; i < mac->rar_entry_count; i++) REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1), - mask, 0xFFFFFFFF); + ((mac->type == e1000_ich10lan) ? + 0x8007FFFF : 0x8003FFFF), + 0xFFFFFFFF); for (i = 0; i < mac->mta_reg_count; i++) REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF); @@ -1795,22 +1786,15 @@ static int e1000_set_wol(struct net_device *netdev, /* bit defines for adapter->led_status */ #define E1000_LED_ON 0 -static void e1000e_led_blink_task(struct work_struct *work) +static void e1000_led_blink_callback(unsigned long data) { - struct e1000_adapter *adapter = container_of(work, - struct e1000_adapter, led_blink_task); + struct e1000_adapter *adapter = (struct e1000_adapter *) data; if (test_and_change_bit(E1000_LED_ON, &adapter->led_status)) adapter->hw.mac.ops.led_off(&adapter->hw); else adapter->hw.mac.ops.led_on(&adapter->hw); -} - -static void e1000_led_blink_callback(unsigned long data) -{ - struct e1000_adapter *adapter = (struct e1000_adapter *) data; - schedule_work(&adapter->led_blink_task); mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL); } @@ -1823,9 +1807,7 @@ static int e1000_phys_id(struct net_device *netdev, u32 data) data = INT_MAX; if ((hw->phy.type == e1000_phy_ife) || - (hw->mac.type == e1000_pchlan) || (hw->mac.type == e1000_82574)) { - INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); if (!adapter->blink_timer.function) { init_timer(&adapter->blink_timer); adapter->blink_timer.function = diff --git a/trunk/drivers/net/e1000e/hw.h b/trunk/drivers/net/e1000e/hw.h index 163c1c0cfee7..6cdb703be951 100644 --- a/trunk/drivers/net/e1000e/hw.h +++ b/trunk/drivers/net/e1000e/hw.h @@ -193,11 +193,7 @@ enum e1e_registers { E1000_RXCSUM = 0x05000, /* Rx Checksum Control - RW */ E1000_RFCTL = 0x05008, /* Receive Filter Control */ E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */ - E1000_RAL_BASE = 0x05400, /* Receive Address Low - RW */ -#define E1000_RAL(_n) (E1000_RAL_BASE + ((_n) * 8)) -#define E1000_RA (E1000_RAL(0)) - E1000_RAH_BASE = 0x05404, /* Receive Address High - RW */ -#define E1000_RAH(_n) (E1000_RAH_BASE + ((_n) * 8)) + E1000_RA = 0x05400, /* Receive Address - RW Array */ E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */ E1000_WUC = 0x05800, /* Wakeup Control - RW */ E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */ @@ -214,7 +210,6 @@ enum e1e_registers { E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ E1000_SWSM = 0x05B50, /* SW Semaphore */ E1000_FWSM = 0x05B54, /* FW Semaphore */ - E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */ E1000_HICR = 0x08F00, /* Host Interface Control */ }; @@ -373,10 +368,6 @@ enum e1e_registers { #define E1000_DEV_ID_ICH10_R_BM_V 0x10CE #define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE #define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF -#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA -#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB -#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF -#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0 #define E1000_REVISION_4 4 @@ -392,7 +383,6 @@ enum e1000_mac_type { e1000_ich8lan, e1000_ich9lan, e1000_ich10lan, - e1000_pchlan, }; enum e1000_media_type { @@ -427,8 +417,6 @@ enum e1000_phy_type { e1000_phy_igp_3, e1000_phy_ife, e1000_phy_bm, - e1000_phy_82578, - e1000_phy_82577, }; enum e1000_bus_width { @@ -732,7 +720,6 @@ struct e1000_host_mng_command_info { /* Function pointers and static data for the MAC. */ struct e1000_mac_operations { - s32 (*id_led_init)(struct e1000_hw *); bool (*check_mng_mode)(struct e1000_hw *); s32 (*check_for_link)(struct e1000_hw *); s32 (*cleanup_led)(struct e1000_hw *); @@ -746,13 +733,11 @@ struct e1000_mac_operations { s32 (*init_hw)(struct e1000_hw *); s32 (*setup_link)(struct e1000_hw *); s32 (*setup_physical_interface)(struct e1000_hw *); - s32 (*setup_led)(struct e1000_hw *); }; /* Function pointers for the PHY. */ struct e1000_phy_operations { s32 (*acquire_phy)(struct e1000_hw *); - s32 (*check_polarity)(struct e1000_hw *); s32 (*check_reset_block)(struct e1000_hw *); s32 (*commit_phy)(struct e1000_hw *); s32 (*force_speed_duplex)(struct e1000_hw *); @@ -884,7 +869,6 @@ struct e1000_fc_info { struct e1000_dev_spec_82571 { bool laa_is_present; bool alt_mac_addr_is_present; - u32 smb_counter; }; struct e1000_shadow_ram { diff --git a/trunk/drivers/net/e1000e/ich8lan.c b/trunk/drivers/net/e1000e/ich8lan.c index 9e23f50fb9cd..6d1aab6316ba 100644 --- a/trunk/drivers/net/e1000e/ich8lan.c +++ b/trunk/drivers/net/e1000e/ich8lan.c @@ -48,10 +48,6 @@ * 82567LF-3 Gigabit Network Connection * 82567LM-3 Gigabit Network Connection * 82567LM-4 Gigabit Network Connection - * 82577LM Gigabit Network Connection - * 82577LC Gigabit Network Connection - * 82578DM Gigabit Network Connection - * 82578DC Gigabit Network Connection */ #include @@ -120,8 +116,6 @@ #define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 #define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 -#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */ - /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { @@ -192,14 +186,6 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); -static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); -static s32 e1000_led_on_ich8lan(struct e1000_hw *hw); -static s32 e1000_led_off_ich8lan(struct e1000_hw *hw); -static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw); -static s32 e1000_setup_led_pchlan(struct e1000_hw *hw); -static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw); -static s32 e1000_led_on_pchlan(struct e1000_hw *hw); -static s32 e1000_led_off_pchlan(struct e1000_hw *hw); static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) { @@ -226,41 +212,6 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) #define ew16flash(reg,val) __ew16flash(hw, (reg), (val)) #define ew32flash(reg,val) __ew32flash(hw, (reg), (val)) -/** - * e1000_init_phy_params_pchlan - Initialize PHY function pointers - * @hw: pointer to the HW structure - * - * Initialize family-specific PHY parameters and function pointers. - **/ -static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = 0; - - phy->addr = 1; - phy->reset_delay_us = 100; - - phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan; - phy->ops.read_phy_reg = e1000_read_phy_reg_hv; - phy->ops.write_phy_reg = e1000_write_phy_reg_hv; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - - phy->id = e1000_phy_unknown; - e1000e_get_phy_id(hw); - phy->type = e1000e_get_phy_type_from_id(phy->id); - - if (phy->type == e1000_phy_82577) { - phy->ops.check_polarity = e1000_check_polarity_82577; - phy->ops.force_speed_duplex = - e1000_phy_force_speed_duplex_82577; - phy->ops.get_cable_length = e1000_get_cable_length_82577; - phy->ops.get_phy_info = e1000_get_phy_info_82577; - phy->ops.commit_phy = e1000e_phy_sw_reset; - } - - return ret_val; -} - /** * e1000_init_phy_params_ich8lan - Initialize PHY function pointers * @hw: pointer to the HW structure @@ -322,8 +273,6 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) break; } - phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan; - return 0; } @@ -409,36 +358,6 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = 1; - /* LED operations */ - switch (mac->type) { - case e1000_ich8lan: - case e1000_ich9lan: - case e1000_ich10lan: - /* ID LED init */ - mac->ops.id_led_init = e1000e_id_led_init; - /* setup LED */ - mac->ops.setup_led = e1000e_setup_led_generic; - /* cleanup LED */ - mac->ops.cleanup_led = e1000_cleanup_led_ich8lan; - /* turn on/off LED */ - mac->ops.led_on = e1000_led_on_ich8lan; - mac->ops.led_off = e1000_led_off_ich8lan; - break; - case e1000_pchlan: - /* ID LED init */ - mac->ops.id_led_init = e1000_id_led_init_pchlan; - /* setup LED */ - mac->ops.setup_led = e1000_setup_led_pchlan; - /* cleanup LED */ - mac->ops.cleanup_led = e1000_cleanup_led_pchlan; - /* turn on/off LED */ - mac->ops.led_on = e1000_led_on_pchlan; - mac->ops.led_off = e1000_led_off_pchlan; - break; - default: - break; - } - /* Enable PCS Lock-loss workaround for ICH8 */ if (mac->type == e1000_ich8lan) e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 1); @@ -459,18 +378,10 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) if (rc) return rc; - if (hw->mac.type == e1000_pchlan) - rc = e1000_init_phy_params_pchlan(hw); - else - rc = e1000_init_phy_params_ich8lan(hw); + rc = e1000_init_phy_params_ich8lan(hw); if (rc) return rc; - if (adapter->hw.phy.type == e1000_phy_ife) { - adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES; - adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN; - } - if ((adapter->hw.mac.type == e1000_ich8lan) && (adapter->hw.phy.type == e1000_phy_igp_3)) adapter->flags |= FLAG_LSC_GIG_SPEED_DROP; @@ -499,15 +410,12 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) while (timeout) { extcnf_ctrl = er32(EXTCNF_CTRL); + extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; + ew32(EXTCNF_CTRL, extcnf_ctrl); - if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) { - extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; - ew32(EXTCNF_CTRL, extcnf_ctrl); - - extcnf_ctrl = er32(EXTCNF_CTRL); - if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) - break; - } + extcnf_ctrl = er32(EXTCNF_CTRL); + if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) + break; mdelay(1); timeout--; } @@ -646,53 +554,6 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) return 0; } -/** - * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be - * done after every PHY reset. - **/ -static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) -{ - s32 ret_val = 0; - - if (hw->mac.type != e1000_pchlan) - return ret_val; - - if (((hw->phy.type == e1000_phy_82577) && - ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || - ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { - /* Disable generation of early preamble */ - ret_val = e1e_wphy(hw, PHY_REG(769, 25), 0x4431); - if (ret_val) - return ret_val; - - /* Preamble tuning for SSC */ - ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204); - if (ret_val) - return ret_val; - } - - if (hw->phy.type == e1000_phy_82578) { - /* - * Return registers to default by doing a soft reset then - * writing 0x3140 to the control register. - */ - if (hw->phy.revision < 2) { - e1000e_phy_sw_reset(hw); - ret_val = e1e_wphy(hw, PHY_CONTROL, 0x3140); - } - } - - /* Select page 0 */ - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - hw->phy.addr = 1; - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); - hw->phy.ops.release_phy(hw); - - return ret_val; -} - /** * e1000_phy_hw_reset_ich8lan - Performs a PHY reset * @hw: pointer to the HW structure @@ -714,12 +575,6 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) if (ret_val) return ret_val; - if (hw->mac.type == e1000_pchlan) { - ret_val = e1000_hv_phy_workarounds_ich8lan(hw); - if (ret_val) - return ret_val; - } - /* * Initialize the PHY from the NVM on ICH platforms. This * is needed due to an issue where the NVM configuration is @@ -846,7 +701,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) phy->polarity_correction = (!(data & IFE_PSC_AUTO_POLARITY_DISABLE)); if (phy->polarity_correction) { - ret_val = phy->ops.check_polarity(hw); + ret_val = e1000_check_polarity_ife_ich8lan(hw); if (ret_val) return ret_val; } else { @@ -886,8 +741,6 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) break; case e1000_phy_igp_3: case e1000_phy_bm: - case e1000_phy_82578: - case e1000_phy_82577: return e1000e_get_phy_info_igp(hw); break; default: @@ -1998,79 +1851,6 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) return 0; } -/** - * e1000_id_led_init_pchlan - store LED configurations - * @hw: pointer to the HW structure - * - * PCH does not control LEDs via the LEDCTL register, rather it uses - * the PHY LED configuration register. - * - * PCH also does not have an "always on" or "always off" mode which - * complicates the ID feature. Instead of using the "on" mode to indicate - * in ledctl_mode2 the LEDs to use for ID (see e1000e_id_led_init()), - * use "link_up" mode. The LEDs will still ID on request if there is no - * link based on logic in e1000_led_[on|off]_pchlan(). - **/ -static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - const u32 ledctl_on = E1000_LEDCTL_MODE_LINK_UP; - const u32 ledctl_off = E1000_LEDCTL_MODE_LINK_UP | E1000_PHY_LED0_IVRT; - u16 data, i, temp, shift; - - /* Get default ID LED modes */ - ret_val = hw->nvm.ops.valid_led_default(hw, &data); - if (ret_val) - goto out; - - mac->ledctl_default = er32(LEDCTL); - mac->ledctl_mode1 = mac->ledctl_default; - mac->ledctl_mode2 = mac->ledctl_default; - - for (i = 0; i < 4; i++) { - temp = (data >> (i << 2)) & E1000_LEDCTL_LED0_MODE_MASK; - shift = (i * 5); - switch (temp) { - case ID_LED_ON1_DEF2: - case ID_LED_ON1_ON2: - case ID_LED_ON1_OFF2: - mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift); - mac->ledctl_mode1 |= (ledctl_on << shift); - break; - case ID_LED_OFF1_DEF2: - case ID_LED_OFF1_ON2: - case ID_LED_OFF1_OFF2: - mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift); - mac->ledctl_mode1 |= (ledctl_off << shift); - break; - default: - /* Do nothing */ - break; - } - switch (temp) { - case ID_LED_DEF1_ON2: - case ID_LED_ON1_ON2: - case ID_LED_OFF1_ON2: - mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift); - mac->ledctl_mode2 |= (ledctl_on << shift); - break; - case ID_LED_DEF1_OFF2: - case ID_LED_ON1_OFF2: - case ID_LED_OFF1_OFF2: - mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift); - mac->ledctl_mode2 |= (ledctl_off << shift); - break; - default: - /* Do nothing */ - break; - } - } - -out: - return ret_val; -} - /** * e1000_get_bus_info_ich8lan - Get/Set the bus type and width * @hw: pointer to the HW structure @@ -2180,9 +1960,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) kab |= E1000_KABGTXD_BGSQLBIAS; ew32(KABGTXD, kab); - if (hw->mac.type == e1000_pchlan) - ret_val = e1000_hv_phy_workarounds_ich8lan(hw); - return ret_val; } @@ -2208,7 +1985,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) e1000_initialize_hw_bits_ich8lan(hw); /* Initialize identification LED */ - ret_val = mac->ops.id_led_init(hw); + ret_val = e1000e_id_led_init(hw); if (ret_val) { hw_dbg(hw, "Error initializing identification LED\n"); return ret_val; @@ -2253,16 +2030,6 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) ctrl_ext |= E1000_CTRL_EXT_RO_DIS; ew32(CTRL_EXT, ctrl_ext); - /* - * The 82578 Rx buffer will stall if wakeup is enabled in host and - * the ME. Reading the BM_WUC register will clear the host wakeup bit. - * Reset the phy after disabling host wakeup to reset the Rx buffer. - */ - if (hw->phy.type == e1000_phy_82578) { - e1e_rphy(hw, BM_WUC, &i); - e1000e_phy_hw_reset_generic(hw); - } - /* * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link @@ -2287,9 +2054,6 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) /* Extended Device Control */ reg = er32(CTRL_EXT); reg |= (1 << 22); - /* Enable PHY low-power state when MAC is at D3 w/o WoL */ - if (hw->mac.type >= e1000_pchlan) - reg |= E1000_CTRL_EXT_PHYPDEN; ew32(CTRL_EXT, reg); /* Transmit Descriptor Control 0 */ @@ -2348,13 +2112,8 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) * the default flow control setting, so we explicitly * set it to full. */ - if (hw->fc.requested_mode == e1000_fc_default) { - /* Workaround h/w hang when Tx flow control enabled */ - if (hw->mac.type == e1000_pchlan) - hw->fc.requested_mode = e1000_fc_rx_pause; - else - hw->fc.requested_mode = e1000_fc_full; - } + if (hw->fc.requested_mode == e1000_fc_default) + hw->fc.requested_mode = e1000_fc_full; /* * Save off the requested flow control mode for use later. Depending @@ -2371,14 +2130,6 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) return ret_val; ew32(FCTTV, hw->fc.pause_time); - if ((hw->phy.type == e1000_phy_82578) || - (hw->phy.type == e1000_phy_82577)) { - ret_val = hw->phy.ops.write_phy_reg(hw, - PHY_REG(BM_PORT_CTRL_PAGE, 27), - hw->fc.pause_time); - if (ret_val) - return ret_val; - } return e1000e_set_fc_watermarks(hw); } @@ -2418,26 +2169,18 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) if (ret_val) return ret_val; - switch (hw->phy.type) { - case e1000_phy_igp_3: + if (hw->phy.type == e1000_phy_igp_3) { ret_val = e1000e_copper_link_setup_igp(hw); if (ret_val) return ret_val; - break; - case e1000_phy_bm: - case e1000_phy_82578: + } else if (hw->phy.type == e1000_phy_bm) { ret_val = e1000e_copper_link_setup_m88(hw); if (ret_val) return ret_val; - break; - case e1000_phy_82577: - ret_val = e1000_copper_link_setup_82577(hw); - if (ret_val) - return ret_val; - break; - case e1000_phy_ife: - ret_val = hw->phy.ops.read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, - ®_data); + } + + if (hw->phy.type == e1000_phy_ife) { + ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data); if (ret_val) return ret_val; @@ -2455,13 +2198,9 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) reg_data |= IFE_PMC_AUTO_MDIX; break; } - ret_val = hw->phy.ops.write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, - reg_data); + ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data); if (ret_val) return ret_val; - break; - default: - break; } return e1000e_setup_copper_link(hw); } @@ -2678,26 +2417,18 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation * to a lower speed. * - * Should only be called for applicable parts. + * Should only be called for ICH9 and ICH10 devices. **/ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) { u32 phy_ctrl; - switch (hw->mac.type) { - case e1000_ich9lan: - case e1000_ich10lan: - case e1000_pchlan: + if ((hw->mac.type == e1000_ich10lan) || + (hw->mac.type == e1000_ich9lan)) { phy_ctrl = er32(PHY_CTRL); phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; ew32(PHY_CTRL, phy_ctrl); - - /* Workaround SWFLAG unexpectedly set during S0->Sx */ - if (hw->mac.type == e1000_pchlan) - udelay(500); - default: - break; } return; @@ -2750,92 +2481,6 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) return 0; } -/** - * e1000_setup_led_pchlan - Configures SW controllable LED - * @hw: pointer to the HW structure - * - * This prepares the SW controllable LED for use. - **/ -static s32 e1000_setup_led_pchlan(struct e1000_hw *hw) -{ - return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, - (u16)hw->mac.ledctl_mode1); -} - -/** - * e1000_cleanup_led_pchlan - Restore the default LED operation - * @hw: pointer to the HW structure - * - * Return the LED back to the default configuration. - **/ -static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw) -{ - return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, - (u16)hw->mac.ledctl_default); -} - -/** - * e1000_led_on_pchlan - Turn LEDs on - * @hw: pointer to the HW structure - * - * Turn on the LEDs. - **/ -static s32 e1000_led_on_pchlan(struct e1000_hw *hw) -{ - u16 data = (u16)hw->mac.ledctl_mode2; - u32 i, led; - - /* - * If no link, then turn LED on by setting the invert bit - * for each LED that's mode is "link_up" in ledctl_mode2. - */ - if (!(er32(STATUS) & E1000_STATUS_LU)) { - for (i = 0; i < 3; i++) { - led = (data >> (i * 5)) & E1000_PHY_LED0_MASK; - if ((led & E1000_PHY_LED0_MODE_MASK) != - E1000_LEDCTL_MODE_LINK_UP) - continue; - if (led & E1000_PHY_LED0_IVRT) - data &= ~(E1000_PHY_LED0_IVRT << (i * 5)); - else - data |= (E1000_PHY_LED0_IVRT << (i * 5)); - } - } - - return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data); -} - -/** - * e1000_led_off_pchlan - Turn LEDs off - * @hw: pointer to the HW structure - * - * Turn off the LEDs. - **/ -static s32 e1000_led_off_pchlan(struct e1000_hw *hw) -{ - u16 data = (u16)hw->mac.ledctl_mode1; - u32 i, led; - - /* - * If no link, then turn LED off by clearing the invert bit - * for each LED that's mode is "link_up" in ledctl_mode1. - */ - if (!(er32(STATUS) & E1000_STATUS_LU)) { - for (i = 0; i < 3; i++) { - led = (data >> (i * 5)) & E1000_PHY_LED0_MASK; - if ((led & E1000_PHY_LED0_MODE_MASK) != - E1000_LEDCTL_MODE_LINK_UP) - continue; - if (led & E1000_PHY_LED0_IVRT) - data &= ~(E1000_PHY_LED0_IVRT << (i * 5)); - else - data |= (E1000_PHY_LED0_IVRT << (i * 5)); - } - } - - return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data); -} - /** * e1000_get_cfg_done_ich8lan - Read config done bit * @hw: pointer to the HW structure @@ -2843,7 +2488,7 @@ static s32 e1000_led_off_pchlan(struct e1000_hw *hw) * Read the management control register for the config done bit for * completion status. NOTE: silicon which is EEPROM-less will fail trying * to read the config done bit, so an error is *ONLY* logged and returns - * 0. If we were to return with error, EEPROM-less silicon + * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon * would not be able to be reset or change link. **/ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) @@ -2853,8 +2498,7 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) e1000e_get_cfg_done(hw); /* If EEPROM is not marked present, init the IGP 3 PHY manually */ - if ((hw->mac.type != e1000_ich10lan) && - (hw->mac.type != e1000_pchlan)) { + if (hw->mac.type != e1000_ich10lan) { if (((er32(EECD) & E1000_EECD_PRES) == 0) && (hw->phy.type == e1000_phy_igp_3)) { e1000e_phy_init_script_igp3(hw); @@ -2880,7 +2524,6 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) { u32 temp; - u16 phy_data; e1000e_clear_hw_cntrs_base(hw); @@ -2898,42 +2541,22 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) temp = er32(IAC); temp = er32(ICRXOC); - /* Clear PHY statistics registers */ - if ((hw->phy.type == e1000_phy_82578) || - (hw->phy.type == e1000_phy_82577)) { - hw->phy.ops.read_phy_reg(hw, HV_SCC_UPPER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_SCC_LOWER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_ECOL_UPPER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_ECOL_LOWER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_MCC_UPPER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_MCC_LOWER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_LATECOL_UPPER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_LATECOL_LOWER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_COLC_UPPER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_COLC_LOWER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_DC_UPPER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_DC_LOWER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_TNCRS_UPPER, &phy_data); - hw->phy.ops.read_phy_reg(hw, HV_TNCRS_LOWER, &phy_data); - } } static struct e1000_mac_operations ich8_mac_ops = { - .id_led_init = e1000e_id_led_init, .check_mng_mode = e1000_check_mng_mode_ich8lan, .check_for_link = e1000e_check_for_copper_link, - /* cleanup_led dependent on mac type */ + .cleanup_led = e1000_cleanup_led_ich8lan, .clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan, .get_bus_info = e1000_get_bus_info_ich8lan, .get_link_up_info = e1000_get_link_up_info_ich8lan, - /* led_on dependent on mac type */ - /* led_off dependent on mac type */ + .led_on = e1000_led_on_ich8lan, + .led_off = e1000_led_off_ich8lan, .update_mc_addr_list = e1000e_update_mc_addr_list_generic, .reset_hw = e1000_reset_hw_ich8lan, .init_hw = e1000_init_hw_ich8lan, .setup_link = e1000_setup_link_ich8lan, .setup_physical_interface= e1000_setup_copper_link_ich8lan, - /* id_led_init dependent on mac type */ }; static struct e1000_phy_operations ich8_phy_ops = { @@ -2972,7 +2595,6 @@ struct e1000_info e1000_ich8_info = { | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, .pba = 8, - .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, .phy_ops = &ich8_phy_ops, @@ -2991,7 +2613,6 @@ struct e1000_info e1000_ich9_info = { | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, .pba = 10, - .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, .phy_ops = &ich8_phy_ops, @@ -3010,25 +2631,6 @@ struct e1000_info e1000_ich10_info = { | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, .pba = 10, - .max_hw_frame_size = DEFAULT_JUMBO, - .get_variants = e1000_get_variants_ich8lan, - .mac_ops = &ich8_mac_ops, - .phy_ops = &ich8_phy_ops, - .nvm_ops = &ich8_nvm_ops, -}; - -struct e1000_info e1000_pch_info = { - .mac = e1000_pchlan, - .flags = FLAG_IS_ICH - | FLAG_HAS_WOL - | FLAG_RX_CSUM_ENABLED - | FLAG_HAS_CTRLEXT_ON_LOAD - | FLAG_HAS_AMT - | FLAG_HAS_FLASH - | FLAG_HAS_JUMBO_FRAMES - | FLAG_APME_IN_WUC, - .pba = 26, - .max_hw_frame_size = 4096, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, .phy_ops = &ich8_phy_ops, diff --git a/trunk/drivers/net/e1000e/lib.c b/trunk/drivers/net/e1000e/lib.c index be6d9e990374..18a4f5902f3b 100644 --- a/trunk/drivers/net/e1000e/lib.c +++ b/trunk/drivers/net/e1000e/lib.c @@ -378,12 +378,6 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw) mac->get_link_status = 0; - if (hw->phy.type == e1000_phy_82578) { - ret_val = e1000_link_stall_workaround_hv(hw); - if (ret_val) - return ret_val; - } - /* * Check if there was DownShift, must be checked * immediately after link-up @@ -1411,38 +1405,6 @@ s32 e1000e_id_led_init(struct e1000_hw *hw) return 0; } -/** - * e1000e_setup_led_generic - Configures SW controllable LED - * @hw: pointer to the HW structure - * - * This prepares the SW controllable LED for use and saves the current state - * of the LED so it can be later restored. - **/ -s32 e1000e_setup_led_generic(struct e1000_hw *hw) -{ - u32 ledctl; - - if (hw->mac.ops.setup_led != e1000e_setup_led_generic) { - return -E1000_ERR_CONFIG; - } - - if (hw->phy.media_type == e1000_media_type_fiber) { - ledctl = er32(LEDCTL); - hw->mac.ledctl_default = ledctl; - /* Turn off LED0 */ - ledctl &= ~(E1000_LEDCTL_LED0_IVRT | - E1000_LEDCTL_LED0_BLINK | - E1000_LEDCTL_LED0_MODE_MASK); - ledctl |= (E1000_LEDCTL_MODE_LED_OFF << - E1000_LEDCTL_LED0_MODE_SHIFT); - ew32(LEDCTL, ledctl); - } else if (hw->phy.media_type == e1000_media_type_copper) { - ew32(LEDCTL, hw->mac.ledctl_mode1); - } - - return 0; -} - /** * e1000e_cleanup_led_generic - Set LED config to default operation * @hw: pointer to the HW structure diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 677f60490f67..ccaaee0951cf 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -48,7 +48,7 @@ #include "e1000.h" -#define DRV_VERSION "1.0.2-k2" +#define DRV_VERSION "0.3.3.4-k4" char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -62,7 +62,6 @@ static const struct e1000_info *e1000_info_tbl[] = { [board_ich8lan] = &e1000_ich8_info, [board_ich9lan] = &e1000_ich9_info, [board_ich10lan] = &e1000_ich10_info, - [board_pchlan] = &e1000_pch_info, }; #ifdef DEBUG @@ -2256,6 +2255,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) ew32(TARC(1), tarc); } + e1000e_config_collision_dist(hw); + /* Setup Transmit Descriptor Settings for eop descriptor */ adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; @@ -2268,8 +2269,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) ew32(TCTL, tctl); - e1000e_config_collision_dist(hw); - adapter->tx_queue_len = adapter->netdev->tx_queue_len; } @@ -2309,23 +2308,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) if (adapter->flags2 & FLAG2_CRC_STRIPPING) rctl |= E1000_RCTL_SECRC; - /* Workaround Si errata on 82577 PHY - configure IPG for jumbos */ - if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) { - u16 phy_data; - - e1e_rphy(hw, PHY_REG(770, 26), &phy_data); - phy_data &= 0xfff8; - phy_data |= (1 << 2); - e1e_wphy(hw, PHY_REG(770, 26), phy_data); - - e1e_rphy(hw, 22, &phy_data); - phy_data &= 0x0fff; - phy_data |= (1 << 14); - e1e_wphy(hw, 0x10, 0x2823); - e1e_wphy(hw, 0x11, 0x0003); - e1e_wphy(hw, 22, phy_data); - } - /* Setup buffer sizes */ rctl &= ~E1000_RCTL_SZ_4096; rctl |= E1000_RCTL_BSEX; @@ -2769,25 +2751,23 @@ void e1000e_reset(struct e1000_adapter *adapter) /* * flow control settings * - * The high water mark must be low enough to fit two full frame + * The high water mark must be low enough to fit one full frame * (or the size used for early receive) above it in the Rx FIFO. * Set it to the lower of: * - 90% of the Rx FIFO size, and * - the full Rx FIFO size minus the early receive size (for parts * with ERT support assuming ERT set to E1000_ERT_2048), or - * - the full Rx FIFO size minus two full frames + * - the full Rx FIFO size minus one full frame */ - if ((adapter->flags & FLAG_HAS_ERT) && - (adapter->netdev->mtu > ETH_DATA_LEN)) + if (adapter->flags & FLAG_HAS_ERT) hwm = min(((pba << 10) * 9 / 10), ((pba << 10) - (E1000_ERT_2048 << 3))); else hwm = min(((pba << 10) * 9 / 10), - ((pba << 10) - (2 * adapter->max_frame_size))); + ((pba << 10) - adapter->max_frame_size)); - fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ - fc->low_water = (fc->high_water - (2 * adapter->max_frame_size)); - fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */ + fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */ + fc->low_water = fc->high_water - 8; if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) fc->pause_time = 0xFFFF; @@ -2807,8 +2787,6 @@ void e1000e_reset(struct e1000_adapter *adapter) e1000_get_hw_control(adapter); ew32(WUC, 0); - if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) - e1e_wphy(&adapter->hw, BM_WUC, 0); if (mac->ops.init_hw(hw)) e_err("Hardware Error\n"); @@ -2821,8 +2799,7 @@ void e1000e_reset(struct e1000_adapter *adapter) e1000e_reset_adaptive(hw); e1000_get_phy_info(hw); - if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && - !(adapter->flags & FLAG_SMART_POWER_DOWN)) { + if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) { u16 phy_data = 0; /* * speed up time to link by disabling smart power down, ignore @@ -3289,7 +3266,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; struct pci_dev *pdev = adapter->pdev; - u16 phy_data; /* * Prevent stats update while adapter is being reset, or if the pci @@ -3309,34 +3285,11 @@ void e1000e_update_stats(struct e1000_adapter *adapter) adapter->stats.roc += er32(ROC); adapter->stats.mpc += er32(MPC); - if ((hw->phy.type == e1000_phy_82578) || - (hw->phy.type == e1000_phy_82577)) { - e1e_rphy(hw, HV_SCC_UPPER, &phy_data); - e1e_rphy(hw, HV_SCC_LOWER, &phy_data); - adapter->stats.scc += phy_data; - - e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); - adapter->stats.ecol += phy_data; - - e1e_rphy(hw, HV_MCC_UPPER, &phy_data); - e1e_rphy(hw, HV_MCC_LOWER, &phy_data); - adapter->stats.mcc += phy_data; - - e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); - adapter->stats.latecol += phy_data; - - e1e_rphy(hw, HV_DC_UPPER, &phy_data); - e1e_rphy(hw, HV_DC_LOWER, &phy_data); - adapter->stats.dc += phy_data; - } else { - adapter->stats.scc += er32(SCC); - adapter->stats.ecol += er32(ECOL); - adapter->stats.mcc += er32(MCC); - adapter->stats.latecol += er32(LATECOL); - adapter->stats.dc += er32(DC); - } + adapter->stats.scc += er32(SCC); + adapter->stats.ecol += er32(ECOL); + adapter->stats.mcc += er32(MCC); + adapter->stats.latecol += er32(LATECOL); + adapter->stats.dc += er32(DC); adapter->stats.xonrxc += er32(XONRXC); adapter->stats.xontxc += er32(XONTXC); adapter->stats.xoffrxc += er32(XOFFRXC); @@ -3354,28 +3307,13 @@ void e1000e_update_stats(struct e1000_adapter *adapter) hw->mac.tx_packet_delta = er32(TPT); adapter->stats.tpt += hw->mac.tx_packet_delta; - if ((hw->phy.type == e1000_phy_82578) || - (hw->phy.type == e1000_phy_82577)) { - e1e_rphy(hw, HV_COLC_UPPER, &phy_data); - e1e_rphy(hw, HV_COLC_LOWER, &phy_data); - hw->mac.collision_delta = phy_data; - } else { - hw->mac.collision_delta = er32(COLC); - } + hw->mac.collision_delta = er32(COLC); adapter->stats.colc += hw->mac.collision_delta; adapter->stats.algnerrc += er32(ALGNERRC); adapter->stats.rxerrc += er32(RXERRC); - if ((hw->phy.type == e1000_phy_82578) || - (hw->phy.type == e1000_phy_82577)) { - e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); - e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); - adapter->stats.tncrs += phy_data; - } else { - if ((hw->mac.type != e1000_82574) && - (hw->mac.type != e1000_82583)) - adapter->stats.tncrs += er32(TNCRS); - } + if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583)) + adapter->stats.tncrs += er32(TNCRS); adapter->stats.cexterr += er32(CEXTERR); adapter->stats.tsctc += er32(TSCTC); adapter->stats.tsctfc += er32(TSCTFC); @@ -3916,7 +3854,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, buffer_info->length = size; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + buffer_info->dma = map[0] + offset; count++; len -= size; @@ -3947,7 +3885,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, buffer_info->length = size; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = map[f] + offset; + buffer_info->dma = map[f + 1] + offset; len -= size; offset += size; @@ -4211,6 +4149,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); if (count) { e1000_tx_queue(adapter, tx_flags, count); + netdev->trans_start = jiffies; /* Make sure there is space in the ring for the next send. */ e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2); @@ -4271,17 +4210,27 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) struct e1000_adapter *adapter = netdev_priv(netdev); int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; - /* Jumbo frame support */ - if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && - !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { - e_err("Jumbo Frames not supported.\n"); + if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) || + (max_frame > MAX_JUMBO_FRAME_SIZE)) { + e_err("Invalid MTU setting\n"); return -EINVAL; } - /* Supported frame sizes */ - if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) || - (max_frame > adapter->max_hw_frame_size)) { - e_err("Unsupported MTU setting\n"); + /* Jumbo frame size limits */ + if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { + if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; + } + if (adapter->hw.phy.type == e1000_phy_ife) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; + } + } + +#define MAX_STD_JUMBO_FRAME_SIZE 9234 + if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { + e_err("MTU > 9216 not supported.\n"); return -EINVAL; } @@ -4401,81 +4350,6 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) } } -static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc) -{ - struct e1000_hw *hw = &adapter->hw; - u32 i, mac_reg; - u16 phy_reg; - int retval = 0; - - /* copy MAC RARs to PHY RARs */ - for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) { - mac_reg = er32(RAL(i)); - e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF)); - e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF)); - mac_reg = er32(RAH(i)); - e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF)); - e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF)); - } - - /* copy MAC MTA to PHY MTA */ - for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) { - mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i); - e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF)); - e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF)); - } - - /* configure PHY Rx Control register */ - e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg); - mac_reg = er32(RCTL); - if (mac_reg & E1000_RCTL_UPE) - phy_reg |= BM_RCTL_UPE; - if (mac_reg & E1000_RCTL_MPE) - phy_reg |= BM_RCTL_MPE; - phy_reg &= ~(BM_RCTL_MO_MASK); - if (mac_reg & E1000_RCTL_MO_3) - phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT) - << BM_RCTL_MO_SHIFT); - if (mac_reg & E1000_RCTL_BAM) - phy_reg |= BM_RCTL_BAM; - if (mac_reg & E1000_RCTL_PMCF) - phy_reg |= BM_RCTL_PMCF; - mac_reg = er32(CTRL); - if (mac_reg & E1000_CTRL_RFCE) - phy_reg |= BM_RCTL_RFCE; - e1e_wphy(&adapter->hw, BM_RCTL, phy_reg); - - /* enable PHY wakeup in MAC register */ - ew32(WUFC, wufc); - ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN); - - /* configure and enable PHY wakeup in PHY registers */ - e1e_wphy(&adapter->hw, BM_WUFC, wufc); - e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN); - - /* activate PHY wakeup */ - retval = hw->phy.ops.acquire_phy(hw); - if (retval) { - e_err("Could not acquire PHY\n"); - return retval; - } - e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); - retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); - if (retval) { - e_err("Could not read PHY page 769\n"); - goto out; - } - phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT; - retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); - if (retval) - e_err("Could not set PHY Host Wakeup bit\n"); -out: - hw->phy.ops.release_phy(hw); - - return retval; -} - static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) { struct net_device *netdev = pci_get_drvdata(pdev); @@ -4518,9 +4392,8 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) #define E1000_CTRL_ADVD3WUC 0x00100000 /* phy power management enable */ #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 - ctrl |= E1000_CTRL_ADVD3WUC; - if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)) - ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT; + ctrl |= E1000_CTRL_ADVD3WUC | + E1000_CTRL_EN_PHY_PWR_MGMT; ew32(CTRL, ctrl); if (adapter->hw.phy.media_type == e1000_media_type_fiber || @@ -4538,17 +4411,8 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) /* Allow time for pending master requests to run */ e1000e_disable_pcie_master(&adapter->hw); - if ((adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) && - !(hw->mac.ops.check_mng_mode(hw))) { - /* enable wakeup by the PHY */ - retval = e1000_init_phy_wakeup(adapter, wufc); - if (retval) - return retval; - } else { - /* enable wakeup by the MAC */ - ew32(WUFC, wufc); - ew32(WUC, E1000_WUC_PME_EN); - } + ew32(WUC, E1000_WUC_PME_EN); + ew32(WUFC, wufc); } else { ew32(WUC, 0); ew32(WUFC, 0); @@ -4691,37 +4555,8 @@ static int e1000_resume(struct pci_dev *pdev) } e1000e_power_up_phy(adapter); - - /* report the system wakeup cause from S3/S4 */ - if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) { - u16 phy_data; - - e1e_rphy(&adapter->hw, BM_WUS, &phy_data); - if (phy_data) { - e_info("PHY Wakeup cause - %s\n", - phy_data & E1000_WUS_EX ? "Unicast Packet" : - phy_data & E1000_WUS_MC ? "Multicast Packet" : - phy_data & E1000_WUS_BC ? "Broadcast Packet" : - phy_data & E1000_WUS_MAG ? "Magic Packet" : - phy_data & E1000_WUS_LNKC ? "Link Status " - " Change" : "other"); - } - e1e_wphy(&adapter->hw, BM_WUS, ~0); - } else { - u32 wus = er32(WUS); - if (wus) { - e_info("MAC Wakeup cause - %s\n", - wus & E1000_WUS_EX ? "Unicast Packet" : - wus & E1000_WUS_MC ? "Multicast Packet" : - wus & E1000_WUS_BC ? "Broadcast Packet" : - wus & E1000_WUS_MAG ? "Magic Packet" : - wus & E1000_WUS_LNKC ? "Link Status Change" : - "other"); - } - ew32(WUS, ~0); - } - e1000e_reset(adapter); + ew32(WUS, ~0); e1000_init_manageability(adapter); @@ -5011,7 +4846,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->flags2 = ei->flags2; adapter->hw.adapter = adapter; adapter->hw.mac.type = ei->mac; - adapter->max_hw_frame_size = ei->max_hw_frame_size; adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; mmio_start = pci_resource_start(pdev, 0); @@ -5167,8 +5001,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, /* APME bit in EEPROM is mapped to WUC.APME */ eeprom_data = er32(WUC); eeprom_apme_mask = E1000_WUC_APME; - if (eeprom_data & E1000_WUC_PHY_WAKE) - adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP; } else if (adapter->flags & FLAG_APME_IN_CTRL3) { if (adapter->flags & FLAG_APME_CHECK_PORT_B && (adapter->hw.bus.func == 1)) @@ -5370,11 +5202,6 @@ static struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan }, - { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); diff --git a/trunk/drivers/net/e1000e/param.c b/trunk/drivers/net/e1000e/param.c index 1342e0b1815c..e909f96698e8 100644 --- a/trunk/drivers/net/e1000e/param.c +++ b/trunk/drivers/net/e1000e/param.c @@ -427,8 +427,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) e1000_validate_option(&crc_stripping, &opt, adapter); if (crc_stripping == OPTION_ENABLED) adapter->flags2 |= FLAG2_CRC_STRIPPING; - } else { - adapter->flags2 |= FLAG2_CRC_STRIPPING; } } { /* Kumeran Lock Loss Workaround */ diff --git a/trunk/drivers/net/e1000e/phy.c b/trunk/drivers/net/e1000e/phy.c index e23459cf3d0e..dc4a9cba6a73 100644 --- a/trunk/drivers/net/e1000e/phy.c +++ b/trunk/drivers/net/e1000e/phy.c @@ -37,9 +37,6 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw); static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data, bool read); -static u32 e1000_get_phy_addr_for_hv_page(u32 page); -static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, - u16 *data, bool read); /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = @@ -57,55 +54,6 @@ static const u16 e1000_igp_2_cable_length_table[] = #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_igp_2_cable_length_table) -#define BM_PHY_REG_PAGE(offset) \ - ((u16)(((offset) >> PHY_PAGE_SHIFT) & 0xFFFF)) -#define BM_PHY_REG_NUM(offset) \ - ((u16)(((offset) & MAX_PHY_REG_ADDRESS) |\ - (((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\ - ~MAX_PHY_REG_ADDRESS))) - -#define HV_INTC_FC_PAGE_START 768 -#define I82578_ADDR_REG 29 -#define I82577_ADDR_REG 16 -#define I82577_CFG_REG 22 -#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) -#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ -#define I82577_CTRL_REG 23 -#define I82577_CTRL_DOWNSHIFT_MASK (7 << 10) - -/* 82577 specific PHY registers */ -#define I82577_PHY_CTRL_2 18 -#define I82577_PHY_STATUS_2 26 -#define I82577_PHY_DIAG_STATUS 31 - -/* I82577 PHY Status 2 */ -#define I82577_PHY_STATUS2_REV_POLARITY 0x0400 -#define I82577_PHY_STATUS2_MDIX 0x0800 -#define I82577_PHY_STATUS2_SPEED_MASK 0x0300 -#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200 - -/* I82577 PHY Control 2 */ -#define I82577_PHY_CTRL2_AUTO_MDIX 0x0400 -#define I82577_PHY_CTRL2_FORCE_MDI_MDIX 0x0200 - -/* I82577 PHY Diagnostics Status */ -#define I82577_DSTATUS_CABLE_LENGTH 0x03FC -#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2 - -/* BM PHY Copper Specific Control 1 */ -#define BM_CS_CTRL1 16 - -/* BM PHY Copper Specific Status */ -#define BM_CS_STATUS 17 -#define BM_CS_STATUS_LINK_UP 0x0400 -#define BM_CS_STATUS_RESOLVED 0x0800 -#define BM_CS_STATUS_SPEED_MASK 0xC000 -#define BM_CS_STATUS_SPEED_1000 0x8000 - -#define HV_MUX_DATA_CTRL PHY_REG(776, 16) -#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400 -#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004 - /** * e1000e_check_reset_block_generic - Check if PHY reset is blocked * @hw: pointer to the HW structure @@ -134,48 +82,23 @@ s32 e1000e_check_reset_block_generic(struct e1000_hw *hw) s32 e1000e_get_phy_id(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = 0; + s32 ret_val; u16 phy_id; - u16 retry_count = 0; - if (!(phy->ops.read_phy_reg)) - goto out; - - while (retry_count < 2) { - ret_val = e1e_rphy(hw, PHY_ID1, &phy_id); - if (ret_val) - goto out; - - phy->id = (u32)(phy_id << 16); - udelay(20); - ret_val = e1e_rphy(hw, PHY_ID2, &phy_id); - if (ret_val) - goto out; - - phy->id |= (u32)(phy_id & PHY_REVISION_MASK); - phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); - - if (phy->id != 0 && phy->id != PHY_REVISION_MASK) - goto out; + ret_val = e1e_rphy(hw, PHY_ID1, &phy_id); + if (ret_val) + return ret_val; - /* - * If the PHY ID is still unknown, we may have an 82577i - * without link. We will try again after setting Slow - * MDIC mode. No harm in trying again in this case since - * the PHY ID is unknown at this point anyway - */ - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; + phy->id = (u32)(phy_id << 16); + udelay(20); + ret_val = e1e_rphy(hw, PHY_ID2, &phy_id); + if (ret_val) + return ret_val; - retry_count++; - } -out: - /* Revert to MDIO fast mode, if applicable */ - if (retry_count) - ret_val = e1000_set_mdio_slow_mode_hv(hw, false); + phy->id |= (u32)(phy_id & PHY_REVISION_MASK); + phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); - return ret_val; + return 0; } /** @@ -486,43 +409,6 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) return ret_val; } -/** - * e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link - * @hw: pointer to the HW structure - * - * Sets up Carrier-sense on Transmit and downshift values. - **/ -s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 phy_data; - - /* Enable CRS on TX. This must be set for half-duplex operation. */ - ret_val = phy->ops.read_phy_reg(hw, I82577_CFG_REG, &phy_data); - if (ret_val) - goto out; - - phy_data |= I82577_CFG_ASSERT_CRS_ON_TX; - - /* Enable downshift */ - phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; - - ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data); - if (ret_val) - goto out; - - /* Set number of link attempts before downshift */ - ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data); - if (ret_val) - goto out; - phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK; - ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data); - -out: - return ret_val; -} - /** * e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link * @hw: pointer to the HW structure @@ -541,8 +427,8 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) if (ret_val) return ret_val; - /* For BM PHY this bit is downshift enable */ - if (phy->type != e1000_phy_bm) + /* For newer PHYs this bit is downshift enable */ + if (phy->type == e1000_phy_m88) phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; /* @@ -634,27 +520,10 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) /* Commit the changes. */ ret_val = e1000e_commit_phy(hw); - if (ret_val) { + if (ret_val) hw_dbg(hw, "Error committing the PHY changes\n"); - return ret_val; - } - - if (phy->type == e1000_phy_82578) { - ret_val = phy->ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - &phy_data); - if (ret_val) - return ret_val; - - /* 82578 PHY - set the downshift count to 1x. */ - phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE; - phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK; - ret_val = phy->ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - phy_data); - if (ret_val) - return ret_val; - } - return 0; + return ret_val; } /** @@ -1382,8 +1251,6 @@ s32 e1000e_check_downshift(struct e1000_hw *hw) switch (phy->type) { case e1000_phy_m88: case e1000_phy_gg82563: - case e1000_phy_82578: - case e1000_phy_82577: offset = M88E1000_PHY_SPEC_STATUS; mask = M88E1000_PSSR_DOWNSHIFT; break; @@ -2019,12 +1886,6 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id) case BME1000_E_PHY_ID_R2: phy_type = e1000_phy_bm; break; - case I82578_E_PHY_ID: - phy_type = e1000_phy_82578; - break; - case I82577_E_PHY_ID: - phy_type = e1000_phy_82577; - break; default: phy_type = e1000_phy_unknown; break; @@ -2320,16 +2181,11 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data, bool read) { s32 ret_val; - u16 reg = BM_PHY_REG_NUM(offset); + u16 reg = ((u16)offset) & PHY_REG_MASK; u16 phy_reg = 0; u8 phy_acquired = 1; - /* Gig must be disabled for MDIO accesses to page 800 */ - if ((hw->mac.type == e1000_pchlan) && - (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE))) - hw_dbg(hw, "Attempting to access page 800 while gig enabled\n"); - ret_val = hw->phy.ops.acquire_phy(hw); if (ret_val) { phy_acquired = 0; @@ -2433,524 +2289,3 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) return 0; } - -s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) -{ - s32 ret_val = 0; - u16 data = 0; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - return ret_val; - - /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ - hw->phy.addr = 1; - ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release_phy(hw); - return ret_val; - } - ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, - (0x2180 | (slow << 10))); - - /* dummy read when reverting to fast mode - throw away result */ - if (!slow) - e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); - - hw->phy.ops.release_phy(hw); - - return ret_val; -} - -/** - * e1000_read_phy_reg_hv - Read HV PHY register - * @hw: pointer to the HW structure - * @offset: register offset to be read - * @data: pointer to the read data - * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired - * semaphore before exiting. - **/ -s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data) -{ - s32 ret_val; - u16 page = BM_PHY_REG_PAGE(offset); - u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = false; - - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(er32(STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - - in_slow_mode = true; - } - - /* Page 800 works differently than the rest so it has its own func */ - if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, - data, true); - goto out; - } - - if (page > 0 && page < HV_INTC_FC_PAGE_START) { - ret_val = e1000_access_phy_debug_regs_hv(hw, offset, - data, true); - goto out; - } - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); - - if (page == HV_INTC_FC_PAGE_START) - page = 0; - - if (reg > MAX_PHY_MULTI_PAGE_REG) { - if ((hw->phy.type != e1000_phy_82578) || - ((reg != I82578_ADDR_REG) && - (reg != I82578_ADDR_REG + 1))) { - u32 phy_addr = hw->phy.addr; - - hw->phy.addr = 1; - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release_phy(hw); - goto out; - } - hw->phy.addr = phy_addr; - } - } - - ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, - data); - hw->phy.ops.release_phy(hw); - -out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val = e1000_set_mdio_slow_mode_hv(hw, false); - - return ret_val; -} - -/** - * e1000_write_phy_reg_hv - Write HV PHY register - * @hw: pointer to the HW structure - * @offset: register offset to write to - * @data: data to write at register offset - * - * Acquires semaphore, if necessary, then writes the data to PHY register - * at the offset. Release any acquired semaphores before exiting. - **/ -s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data) -{ - s32 ret_val; - u16 page = BM_PHY_REG_PAGE(offset); - u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = false; - - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(er32(STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - - in_slow_mode = true; - } - - /* Page 800 works differently than the rest so it has its own func */ - if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, - &data, false); - goto out; - } - - if (page > 0 && page < HV_INTC_FC_PAGE_START) { - ret_val = e1000_access_phy_debug_regs_hv(hw, offset, - &data, false); - goto out; - } - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - - hw->phy.addr = e1000_get_phy_addr_for_hv_page(page); - - if (page == HV_INTC_FC_PAGE_START) - page = 0; - - /* - * Workaround MDIO accesses being disabled after entering IEEE Power - * Down (whenever bit 11 of the PHY Control register is set) - */ - if ((hw->phy.type == e1000_phy_82578) && - (hw->phy.revision >= 1) && - (hw->phy.addr == 2) && - ((MAX_PHY_REG_ADDRESS & reg) == 0) && - (data & (1 << 11))) { - u16 data2 = 0x7EFF; - hw->phy.ops.release_phy(hw); - ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3, - &data2, false); - if (ret_val) - goto out; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) - goto out; - } - - if (reg > MAX_PHY_MULTI_PAGE_REG) { - if ((hw->phy.type != e1000_phy_82578) || - ((reg != I82578_ADDR_REG) && - (reg != I82578_ADDR_REG + 1))) { - u32 phy_addr = hw->phy.addr; - - hw->phy.addr = 1; - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000e_write_phy_reg_mdic(hw, - IGP01E1000_PHY_PAGE_SELECT, - (page << IGP_PAGE_SHIFT)); - if (ret_val) { - hw->phy.ops.release_phy(hw); - goto out; - } - hw->phy.addr = phy_addr; - } - } - - ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, - data); - hw->phy.ops.release_phy(hw); - -out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val = e1000_set_mdio_slow_mode_hv(hw, false); - - return ret_val; -} - -/** - * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page - * @page: page to be accessed - **/ -static u32 e1000_get_phy_addr_for_hv_page(u32 page) -{ - u32 phy_addr = 2; - - if (page >= HV_INTC_FC_PAGE_START) - phy_addr = 1; - - return phy_addr; -} - -/** - * e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers - * @hw: pointer to the HW structure - * @offset: register offset to be read or written - * @data: pointer to the data to be read or written - * @read: determines if operation is read or written - * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retreived information in data. Release any acquired - * semaphores before exiting. Note that the procedure to read these regs - * uses the address port and data port to read/write. - **/ -static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, - u16 *data, bool read) -{ - s32 ret_val; - u32 addr_reg = 0; - u32 data_reg = 0; - u8 phy_acquired = 1; - - /* This takes care of the difference with desktop vs mobile phy */ - addr_reg = (hw->phy.type == e1000_phy_82578) ? - I82578_ADDR_REG : I82577_ADDR_REG; - data_reg = addr_reg + 1; - - ret_val = hw->phy.ops.acquire_phy(hw); - if (ret_val) { - hw_dbg(hw, "Could not acquire PHY\n"); - phy_acquired = 0; - goto out; - } - - /* All operations in this function are phy address 2 */ - hw->phy.addr = 2; - - /* masking with 0x3F to remove the page from offset */ - ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F); - if (ret_val) { - hw_dbg(hw, "Could not write PHY the HV address register\n"); - goto out; - } - - /* Read or write the data value next */ - if (read) - ret_val = e1000e_read_phy_reg_mdic(hw, data_reg, data); - else - ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data); - - if (ret_val) { - hw_dbg(hw, "Could not read data value from HV data register\n"); - goto out; - } - -out: - if (phy_acquired == 1) - hw->phy.ops.release_phy(hw); - return ret_val; -} - -/** - * e1000_link_stall_workaround_hv - Si workaround - * @hw: pointer to the HW structure - * - * This function works around a Si bug where the link partner can get - * a link up indication before the PHY does. If small packets are sent - * by the link partner they can be placed in the packet buffer without - * being properly accounted for by the PHY and will stall preventing - * further packets from being received. The workaround is to clear the - * packet buffer after the PHY detects link up. - **/ -s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) -{ - s32 ret_val = 0; - u16 data; - - if (hw->phy.type != e1000_phy_82578) - goto out; - - /* check if link is up and at 1Gbps */ - ret_val = hw->phy.ops.read_phy_reg(hw, BM_CS_STATUS, &data); - if (ret_val) - goto out; - - data &= BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_MASK; - - if (data != (BM_CS_STATUS_LINK_UP | - BM_CS_STATUS_RESOLVED | - BM_CS_STATUS_SPEED_1000)) - goto out; - - mdelay(200); - - /* flush the packets in the fifo buffer */ - ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL, - HV_MUX_DATA_CTRL_GEN_TO_MAC | - HV_MUX_DATA_CTRL_FORCE_SPEED); - if (ret_val) - goto out; - - ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL, - HV_MUX_DATA_CTRL_GEN_TO_MAC); - -out: - return ret_val; -} - -/** - * e1000_check_polarity_82577 - Checks the polarity. - * @hw: pointer to the HW structure - * - * Success returns 0, Failure returns -E1000_ERR_PHY (-2) - * - * Polarity is determined based on the PHY specific status register. - **/ -s32 e1000_check_polarity_82577(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 data; - - ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data); - - if (!ret_val) - phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY) - ? e1000_rev_polarity_reversed - : e1000_rev_polarity_normal; - - return ret_val; -} - -/** - * e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY - * @hw: pointer to the HW structure - * - * Calls the PHY setup function to force speed and duplex. Clears the - * auto-crossover to force MDI manually. Waits for link and returns - * successful if link up is successful, else -E1000_ERR_PHY (-2). - **/ -s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 phy_data; - bool link; - - ret_val = phy->ops.read_phy_reg(hw, PHY_CONTROL, &phy_data); - if (ret_val) - goto out; - - e1000e_phy_force_speed_duplex_setup(hw, &phy_data); - - ret_val = phy->ops.write_phy_reg(hw, PHY_CONTROL, phy_data); - if (ret_val) - goto out; - - /* - * Clear Auto-Crossover to force MDI manually. 82577 requires MDI - * forced whenever speed and duplex are forced. - */ - ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_CTRL_2, &phy_data); - if (ret_val) - goto out; - - phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX; - phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX; - - ret_val = phy->ops.write_phy_reg(hw, I82577_PHY_CTRL_2, phy_data); - if (ret_val) - goto out; - - hw_dbg(hw, "I82577_PHY_CTRL_2: %X\n", phy_data); - - udelay(1); - - if (phy->autoneg_wait_to_complete) { - hw_dbg(hw, "Waiting for forced speed/duplex link on 82577 phy\n"); - - ret_val = e1000e_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); - if (ret_val) - goto out; - - if (!link) - hw_dbg(hw, "Link taking longer than expected.\n"); - - /* Try once more */ - ret_val = e1000e_phy_has_link_generic(hw, - PHY_FORCE_LIMIT, - 100000, - &link); - if (ret_val) - goto out; - } - -out: - return ret_val; -} - -/** - * e1000_get_phy_info_82577 - Retrieve I82577 PHY information - * @hw: pointer to the HW structure - * - * Read PHY status to determine if link is up. If link is up, then - * set/determine 10base-T extended distance and polarity correction. Read - * PHY port status to determine MDI/MDIx and speed. Based on the speed, - * determine on the cable length, local and remote receiver. - **/ -s32 e1000_get_phy_info_82577(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 data; - bool link; - - ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); - if (ret_val) - goto out; - - if (!link) { - hw_dbg(hw, "Phy info is only valid if link is up\n"); - ret_val = -E1000_ERR_CONFIG; - goto out; - } - - phy->polarity_correction = true; - - ret_val = e1000_check_polarity_82577(hw); - if (ret_val) - goto out; - - ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data); - if (ret_val) - goto out; - - phy->is_mdix = (data & I82577_PHY_STATUS2_MDIX) ? true : false; - - if ((data & I82577_PHY_STATUS2_SPEED_MASK) == - I82577_PHY_STATUS2_SPEED_1000MBPS) { - ret_val = hw->phy.ops.get_cable_length(hw); - if (ret_val) - goto out; - - ret_val = phy->ops.read_phy_reg(hw, PHY_1000T_STATUS, &data); - if (ret_val) - goto out; - - phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; - - phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS) - ? e1000_1000t_rx_status_ok - : e1000_1000t_rx_status_not_ok; - } else { - phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; - phy->local_rx = e1000_1000t_rx_status_undefined; - phy->remote_rx = e1000_1000t_rx_status_undefined; - } - -out: - return ret_val; -} - -/** - * e1000_get_cable_length_82577 - Determine cable length for 82577 PHY - * @hw: pointer to the HW structure - * - * Reads the diagnostic status register and verifies result is valid before - * placing it in the phy_cable_length field. - **/ -s32 e1000_get_cable_length_82577(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 phy_data, length; - - ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data); - if (ret_val) - goto out; - - length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >> - I82577_DSTATUS_CABLE_LENGTH_SHIFT; - - if (length == E1000_CABLE_LENGTH_UNDEFINED) - ret_val = E1000_ERR_PHY; - - phy->cable_length = length; - -out: - return ret_val; -} diff --git a/trunk/drivers/net/enic/enic_main.c b/trunk/drivers/net/enic/enic_main.c index 8005b602f776..9080f07da8fe 100644 --- a/trunk/drivers/net/enic/enic_main.c +++ b/trunk/drivers/net/enic/enic_main.c @@ -661,6 +661,8 @@ static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + 1) netif_stop_queue(netdev); + netdev->trans_start = jiffies; + spin_unlock_irqrestore(&enic->wq_lock[0], flags); return NETDEV_TX_OK; diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index b60a3041b64c..d0b1d9f17a5d 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -77,31 +77,27 @@ * Hardware access: */ -#define DEV_NEED_TIMERIRQ 0x0000001 /* set the timer irq flag in the irq mask */ -#define DEV_NEED_LINKTIMER 0x0000002 /* poll link settings. Relies on the timer irq */ -#define DEV_HAS_LARGEDESC 0x0000004 /* device supports jumbo frames and needs packet format 2 */ -#define DEV_HAS_HIGH_DMA 0x0000008 /* device supports 64bit dma */ -#define DEV_HAS_CHECKSUM 0x0000010 /* device supports tx and rx checksum offloads */ -#define DEV_HAS_VLAN 0x0000020 /* device supports vlan tagging and striping */ -#define DEV_HAS_MSI 0x0000040 /* device supports MSI */ -#define DEV_HAS_MSI_X 0x0000080 /* device supports MSI-X */ -#define DEV_HAS_POWER_CNTRL 0x0000100 /* device supports power savings */ -#define DEV_HAS_STATISTICS_V1 0x0000200 /* device supports hw statistics version 1 */ -#define DEV_HAS_STATISTICS_V2 0x0000600 /* device supports hw statistics version 2 */ -#define DEV_HAS_STATISTICS_V3 0x0000e00 /* device supports hw statistics version 3 */ -#define DEV_HAS_TEST_EXTENDED 0x0001000 /* device supports extended diagnostic test */ -#define DEV_HAS_MGMT_UNIT 0x0002000 /* device supports management unit */ -#define DEV_HAS_CORRECT_MACADDR 0x0004000 /* device supports correct mac address order */ -#define DEV_HAS_COLLISION_FIX 0x0008000 /* device supports tx collision fix */ -#define DEV_HAS_PAUSEFRAME_TX_V1 0x0010000 /* device supports tx pause frames version 1 */ -#define DEV_HAS_PAUSEFRAME_TX_V2 0x0020000 /* device supports tx pause frames version 2 */ -#define DEV_HAS_PAUSEFRAME_TX_V3 0x0040000 /* device supports tx pause frames version 3 */ -#define DEV_NEED_TX_LIMIT 0x0080000 /* device needs to limit tx */ -#define DEV_NEED_TX_LIMIT2 0x0180000 /* device needs to limit tx, expect for some revs */ -#define DEV_HAS_GEAR_MODE 0x0200000 /* device supports gear mode */ -#define DEV_NEED_PHY_INIT_FIX 0x0400000 /* device needs specific phy workaround */ -#define DEV_NEED_LOW_POWER_FIX 0x0800000 /* device needs special power up workaround */ -#define DEV_NEED_MSI_FIX 0x1000000 /* device needs msi workaround */ +#define DEV_NEED_TIMERIRQ 0x000001 /* set the timer irq flag in the irq mask */ +#define DEV_NEED_LINKTIMER 0x000002 /* poll link settings. Relies on the timer irq */ +#define DEV_HAS_LARGEDESC 0x000004 /* device supports jumbo frames and needs packet format 2 */ +#define DEV_HAS_HIGH_DMA 0x000008 /* device supports 64bit dma */ +#define DEV_HAS_CHECKSUM 0x000010 /* device supports tx and rx checksum offloads */ +#define DEV_HAS_VLAN 0x000020 /* device supports vlan tagging and striping */ +#define DEV_HAS_MSI 0x000040 /* device supports MSI */ +#define DEV_HAS_MSI_X 0x000080 /* device supports MSI-X */ +#define DEV_HAS_POWER_CNTRL 0x000100 /* device supports power savings */ +#define DEV_HAS_STATISTICS_V1 0x000200 /* device supports hw statistics version 1 */ +#define DEV_HAS_STATISTICS_V2 0x000600 /* device supports hw statistics version 2 */ +#define DEV_HAS_STATISTICS_V3 0x000e00 /* device supports hw statistics version 3 */ +#define DEV_HAS_TEST_EXTENDED 0x001000 /* device supports extended diagnostic test */ +#define DEV_HAS_MGMT_UNIT 0x002000 /* device supports management unit */ +#define DEV_HAS_CORRECT_MACADDR 0x004000 /* device supports correct mac address order */ +#define DEV_HAS_COLLISION_FIX 0x008000 /* device supports tx collision fix */ +#define DEV_HAS_PAUSEFRAME_TX_V1 0x010000 /* device supports tx pause frames version 1 */ +#define DEV_HAS_PAUSEFRAME_TX_V2 0x020000 /* device supports tx pause frames version 2 */ +#define DEV_HAS_PAUSEFRAME_TX_V3 0x040000 /* device supports tx pause frames version 3 */ +#define DEV_NEED_TX_LIMIT 0x080000 /* device needs to limit tx */ +#define DEV_HAS_GEAR_MODE 0x100000 /* device supports gear mode */ enum { NvRegIrqStatus = 0x000, @@ -902,12 +898,6 @@ enum { }; static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED; -/* - * Power down phy when interface is down (persists through reboot; - * older Linux and other OSes may not power it up again) - */ -static int phy_power_down = 0; - static inline struct fe_priv *get_nvpriv(struct net_device *dev) { return netdev_priv(dev); @@ -1275,7 +1265,14 @@ static int phy_init(struct net_device *dev) } } if (np->phy_model == PHY_MODEL_REALTEK_8201) { - if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { + if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) { phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); phy_reserved |= PHY_REALTEK_INIT7; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { @@ -1466,7 +1463,14 @@ static int phy_init(struct net_device *dev) } } if (np->phy_model == PHY_MODEL_REALTEK_8201) { - if (np->driver_data & DEV_NEED_PHY_INIT_FIX) { + if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 || + np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) { phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); phy_reserved |= PHY_REALTEK_INIT7; if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { @@ -1499,10 +1503,7 @@ static int phy_init(struct net_device *dev) /* restart auto negotiation, power down phy */ mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); - mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); - if (phy_power_down) { - mii_control |= BMCR_PDOWN; - } + mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE | BMCR_PDOWN); if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { return PHY_ERROR; } @@ -5533,7 +5534,7 @@ static int nv_close(struct net_device *dev) nv_drain_rxtx(dev); - if (np->wolenabled || !phy_power_down) { + if (np->wolenabled) { nv_txrx_gate(dev, false); writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); nv_start_rx(dev); @@ -5834,7 +5835,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* take phy and nic out of low power mode */ powerstate = readl(base + NvRegPowerState2); powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; - if ((id->driver_data & DEV_NEED_LOW_POWER_FIX) && + if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) && pci_dev->revision >= 0xA3) powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; writel(powerstate, base + NvRegPowerState2); @@ -5890,7 +5892,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i /* Limit the number of tx's outstanding for hw bug */ if (id->driver_data & DEV_NEED_TX_LIMIT) { np->tx_limit = 1; - if ((id->driver_data & DEV_NEED_TX_LIMIT2) && + if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_32 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_33 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_34 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_35 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_36 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_37 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_38 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_39) && pci_dev->revision >= 0xA2) np->tx_limit = 0; } @@ -6140,8 +6149,7 @@ static int nv_resume(struct pci_dev *pdev) for (i = 0;i <= np->register_size/sizeof(u32); i++) writel(np->saved_config_space[i], base+i*sizeof(u32)); - if (np->driver_data & DEV_NEED_MSI_FIX) - pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE); + pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE); /* restore phy state, including autoneg */ phy_init(dev); @@ -6190,164 +6198,160 @@ static void nv_shutdown(struct pci_dev *pdev) static struct pci_device_id pci_tbl[] = { { /* nForce Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x01C3), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce2 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0066), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_2), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce3 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x00D6), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_3), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce3 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0086), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM, }, { /* nForce3 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x008C), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM, }, { /* nForce3 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x00E6), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM, }, { /* nForce3 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x00DF), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7), .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM, }, { /* CK804 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0056), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8), .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* CK804 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0057), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9), .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP04 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0037), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10), .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP04 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0038), + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11), .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP51 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0268), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1|DEV_NEED_LOW_POWER_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1, }, { /* MCP51 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0269), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1|DEV_NEED_LOW_POWER_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1, }, { /* MCP55 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0372), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT, }, { /* MCP55 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0373), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT, }, { /* MCP61 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x03E5), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x03E6), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x03EE), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x03EF), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0450), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP65 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0451), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP65 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0452), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP65 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0453), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x054C), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x054D), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x054E), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP67 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x054F), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x07DC), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x07DD), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x07DE), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP73 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x07DF), - .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31), + .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE, }, { /* MCP77 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0760), - .driver_data = 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_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32), + .driver_data = 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, }, { /* MCP77 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0761), - .driver_data = 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_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33), + .driver_data = 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, }, { /* MCP77 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0762), - .driver_data = 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_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34), + .driver_data = 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, }, { /* MCP77 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0763), - .driver_data = 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_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35), + .driver_data = 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, }, { /* MCP79 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0AB0), - .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36), + .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0AB1), - .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37), + .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0AB2), - .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38), + .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, { /* MCP79 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0AB3), - .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX, - }, - { /* MCP89 Ethernet Controller */ - PCI_DEVICE(0x10DE, 0x0D7D), - .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX, + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39), + .driver_data = 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_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE, }, {0,}, }; @@ -6386,8 +6390,6 @@ module_param(dma_64bit, int, 0); MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0."); module_param(phy_cross, int, 0); MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0."); -module_param(phy_power_down, int, 0); -MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0)."); MODULE_AUTHOR("Manfred Spraul "); MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); diff --git a/trunk/drivers/net/fsl_pq_mdio.c b/trunk/drivers/net/fsl_pq_mdio.c index 3af581303ca2..d12e0e0336f4 100644 --- a/trunk/drivers/net/fsl_pq_mdio.c +++ b/trunk/drivers/net/fsl_pq_mdio.c @@ -301,17 +301,13 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, of_device_is_compatible(np, "ucc_geth_phy")) { #ifdef CONFIG_UCC_GETH u32 id; - static u32 mii_mng_master; tbipa = ®s->utbipar; if ((err = get_ucc_id_for_range(addr, addr + size, &id))) goto err_free_irqs; - if (!mii_mng_master) { - mii_mng_master = id; - ucc_set_qe_mux_mii_mng(id - 1); - } + ucc_set_qe_mux_mii_mng(id - 1); #else err = -ENODEV; goto err_free_irqs; diff --git a/trunk/drivers/net/gianfar.h b/trunk/drivers/net/gianfar.h index 2cd94338b5d3..91317bc11154 100644 --- a/trunk/drivers/net/gianfar.h +++ b/trunk/drivers/net/gianfar.h @@ -259,7 +259,7 @@ extern const char gfar_driver_version[]; (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \ IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \ | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \ - | IEVENT_MAG | IEVENT_BABR) + | IEVENT_MAG) #define IMASK_INIT_CLEAR 0x00000000 #define IMASK_BABR 0x80000000 diff --git a/trunk/drivers/net/hamachi.c b/trunk/drivers/net/hamachi.c index 26151fa35df5..310ee035067c 100644 --- a/trunk/drivers/net/hamachi.c +++ b/trunk/drivers/net/hamachi.c @@ -1163,7 +1163,7 @@ static void hamachi_tx_timeout(struct net_device *dev) hmp->rx_ring[RX_RING_SIZE-1].status_n_length |= cpu_to_le32(DescEndRing); /* Trigger an immediate transmit demand. */ - dev->trans_start = jiffies; /* prevent tx timeout */ + dev->trans_start = jiffies; hmp->stats.tx_errors++; /* Restart the chip's Tx/Rx processes . */ @@ -1364,6 +1364,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev) hmp->tx_full = 1; netif_stop_queue(dev); } + dev->trans_start = jiffies; if (hamachi_debug > 4) { printk(KERN_DEBUG "%s: Hamachi transmit frame #%d queued in slot %d.\n", diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index ea17319624aa..8e93750d5120 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -3139,7 +3139,8 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = skb_shinfo(skb)->dma_head; + buffer_info->dma = map[count]; + count++; for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { struct skb_frag_struct *frag; @@ -3163,7 +3164,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[first].next_to_watch = i; - return count + 1; + return count; } static inline void igb_tx_queue_adv(struct igb_adapter *adapter, @@ -3343,6 +3344,7 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb, if (count) { igb_tx_queue_adv(adapter, tx_ring, tx_flags, count, skb->len, hdr_len); + netdev->trans_start = jiffies; /* Make sure there is space in the ring for the next send. */ igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4); } else { diff --git a/trunk/drivers/net/igbvf/netdev.c b/trunk/drivers/net/igbvf/netdev.c index 22aadb7884fa..44a8eef03a74 100644 --- a/trunk/drivers/net/igbvf/netdev.c +++ b/trunk/drivers/net/igbvf/netdev.c @@ -2119,7 +2119,8 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = skb_shinfo(skb)->dma_head; + buffer_info->dma = map[count]; + count++; for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { struct skb_frag_struct *frag; @@ -2143,7 +2144,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[first].next_to_watch = i; - return count + 1; + return count; } static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter, @@ -2269,6 +2270,7 @@ static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb, if (count) { igbvf_tx_queue_adv(adapter, tx_ring, tx_flags, count, skb->len, hdr_len); + netdev->trans_start = jiffies; /* Make sure there is space in the ring for the next send. */ igbvf_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 4); } else { diff --git a/trunk/drivers/net/ioc3-eth.c b/trunk/drivers/net/ioc3-eth.c index e3cfefab670c..c5593f4665a4 100644 --- a/trunk/drivers/net/ioc3-eth.c +++ b/trunk/drivers/net/ioc3-eth.c @@ -530,7 +530,7 @@ static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len) * case where the checksum is right the higher layers will still * drop the packet as appropriate. */ - if (eh->h_proto != htons(ETH_P_IP)) + if (eh->h_proto != ntohs(ETH_P_IP)) return; ih = (struct iphdr *) ((char *)eh + ETH_HLEN); diff --git a/trunk/drivers/net/irda/irda-usb.c b/trunk/drivers/net/irda/irda-usb.c index 394b2b17075e..006ba23110db 100644 --- a/trunk/drivers/net/irda/irda-usb.c +++ b/trunk/drivers/net/irda/irda-usb.c @@ -1859,42 +1859,6 @@ static void irda_usb_disconnect(struct usb_interface *intf) IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __func__); } -#ifdef CONFIG_PM -/* USB suspend, so power off the transmitter/receiver */ -static int irda_usb_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct irda_usb_cb *self = usb_get_intfdata(intf); - int i; - - netif_device_detach(self->netdev); - - if (self->tx_urb != NULL) - usb_kill_urb(self->tx_urb); - if (self->speed_urb != NULL) - usb_kill_urb(self->speed_urb); - for (i = 0; i < self->max_rx_urb; i++) { - if (self->rx_urb[i] != NULL) - usb_kill_urb(self->rx_urb[i]); - } - return 0; -} - -/* Coming out of suspend, so reset hardware */ -static int irda_usb_resume(struct usb_interface *intf) -{ - struct irda_usb_cb *self = usb_get_intfdata(intf); - int i; - - for (i = 0; i < self->max_rx_urb; i++) { - if (self->rx_urb[i] != NULL) - usb_submit_urb(self->rx_urb[i], GFP_KERNEL); - } - - netif_device_attach(self->netdev); - return 0; -} -#endif - /*------------------------------------------------------------------*/ /* * USB device callbacks @@ -1904,10 +1868,6 @@ static struct usb_driver irda_driver = { .probe = irda_usb_probe, .disconnect = irda_usb_disconnect, .id_table = dongles, -#ifdef CONFIG_PM - .suspend = irda_usb_suspend, - .resume = irda_usb_resume, -#endif }; /************************* MODULE CALLBACKS *************************/ diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index 9c897cf86b9f..04cb81a739c2 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -1300,7 +1300,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, buffer_info->length = size; WARN_ON(buffer_info->dma != 0); buffer_info->time_stamp = jiffies; - buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + buffer_info->dma = map[0] + offset; pci_map_single(adapter->pdev, skb->data + offset, size, @@ -1340,7 +1340,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, buffer_info->length = size; buffer_info->time_stamp = jiffies; - buffer_info->dma = map[f] + offset; + buffer_info->dma = map[f + 1] + offset; buffer_info->next_to_watch = 0; len -= size; @@ -1488,6 +1488,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (count) { ixgb_tx_queue(adapter, count, vlan_id, tx_flags); + netdev->trans_start = jiffies; /* Make sure there is space in the ring for the next send. */ ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED); diff --git a/trunk/drivers/net/ixgbe/ixgbe.h b/trunk/drivers/net/ixgbe/ixgbe.h index cd22323cfd22..05a24055ac2f 100644 --- a/trunk/drivers/net/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ixgbe/ixgbe.h @@ -121,18 +121,17 @@ struct ixgbe_queue_stats { struct ixgbe_ring { void *desc; /* descriptor ring memory */ + dma_addr_t dma; /* phys. address of descriptor ring */ + unsigned int size; /* length in bytes */ + unsigned int count; /* amount of descriptors */ + unsigned int next_to_use; + unsigned int next_to_clean; + + int queue_index; /* needed for multiqueue queue management */ union { struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_rx_buffer *rx_buffer_info; }; - u8 atr_sample_rate; - u8 atr_count; - u16 count; /* amount of descriptors */ - u16 rx_buf_len; - u16 next_to_use; - u16 next_to_clean; - - u8 queue_index; /* needed for multiqueue queue management */ u16 head; u16 tail; @@ -140,24 +139,23 @@ struct ixgbe_ring { unsigned int total_bytes; unsigned int total_packets; + u16 reg_idx; /* holds the special value that gets the hardware register + * offset associated with this ring, which is different + * for DCB and RSS modes */ + #ifdef CONFIG_IXGBE_DCA /* cpu for tx queue */ int cpu; #endif - - u16 work_limit; /* max work per interrupt */ - u16 reg_idx; /* holds the special value that gets - * the hardware register offset - * associated with this ring, which is - * different for DCB and RSS modes - */ - struct ixgbe_queue_stats stats; - unsigned long reinit_state; - u64 rsc_count; /* stat for coalesced packets */ + u64 v_idx; /* maps directly to the index for this ring in the hardware + * vector array, can also be used for finding the bit in EICR + * and friends that represents the vector for this ring */ - unsigned int size; /* length in bytes */ - dma_addr_t dma; /* phys. address of descriptor ring */ + + u16 work_limit; /* max work per interrupt */ + u16 rx_buf_len; + u64 rsc_count; /* stat for coalesced packets */ }; enum ixgbe_ring_f_enum { @@ -165,7 +163,6 @@ enum ixgbe_ring_f_enum { RING_F_DCB, RING_F_VMDQ, RING_F_RSS, - RING_F_FDIR, #ifdef IXGBE_FCOE RING_F_FCOE, #endif /* IXGBE_FCOE */ @@ -176,7 +173,6 @@ enum ixgbe_ring_f_enum { #define IXGBE_MAX_DCB_INDICES 8 #define IXGBE_MAX_RSS_INDICES 16 #define IXGBE_MAX_VMDQ_INDICES 16 -#define IXGBE_MAX_FDIR_INDICES 64 #ifdef IXGBE_FCOE #define IXGBE_MAX_FCOE_INDICES 8 #endif /* IXGBE_FCOE */ @@ -197,9 +193,6 @@ struct ixgbe_ring_feature { */ struct ixgbe_q_vector { struct ixgbe_adapter *adapter; - unsigned int v_idx; /* index of q_vector within array, also used for - * finding the bit in EICR and friends that - * represents the vector for this ring */ struct napi_struct napi; DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */ DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ @@ -208,6 +201,7 @@ struct ixgbe_q_vector { u8 tx_itr; u8 rx_itr; u32 eitr; + u32 v_idx; /* vector index in list */ }; /* Helper macros to switch between ints/sec and what the register uses. @@ -229,10 +223,6 @@ struct ixgbe_q_vector { #define IXGBE_TX_CTXTDESC_ADV(R, i) \ (&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i])) -#define IXGBE_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) -#define IXGBE_TX_DESC(R, i) IXGBE_GET_DESC(R, i, ixgbe_legacy_tx_desc) -#define IXGBE_RX_DESC(R, i) IXGBE_GET_DESC(R, i, ixgbe_legacy_rx_desc) - #define IXGBE_MAX_JUMBO_FRAME_SIZE 16128 #ifdef IXGBE_FCOE /* Use 3K as the baby jumbo frame size for FCoE */ @@ -325,13 +315,10 @@ struct ixgbe_adapter { #define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23) #define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 24) #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) -#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 26) -#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 27) +#define IXGBE_FLAG_RSC_CAPABLE (u32)(1 << 26) +#define IXGBE_FLAG_RSC_ENABLED (u32)(1 << 27) #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29) - u32 flags2; -#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1) -#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1) /* default to trying for four seconds */ #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) @@ -340,10 +327,6 @@ struct ixgbe_adapter { struct pci_dev *pdev; struct net_device_stats net_stats; - u32 test_icr; - struct ixgbe_ring test_tx_ring; - struct ixgbe_ring test_rx_ring; - /* structs defined in ixgbe_hw.h */ struct ixgbe_hw hw; u16 msg_enable; @@ -366,10 +349,6 @@ struct ixgbe_adapter { struct timer_list sfp_timer; struct work_struct multispeed_fiber_task; struct work_struct sfp_config_module_task; - u32 fdir_pballoc; - u32 atr_sample_rate; - spinlock_t fdir_perfect_lock; - struct work_struct fdir_reinit_task; #ifdef IXGBE_FCOE struct ixgbe_fcoe fcoe; #endif /* IXGBE_FCOE */ @@ -382,7 +361,6 @@ enum ixbge_state_t { __IXGBE_TESTING, __IXGBE_RESETTING, __IXGBE_DOWN, - __IXGBE_FDIR_INIT_DONE, __IXGBE_SFP_MODULE_NOT_FOUND }; @@ -415,63 +393,7 @@ extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *) extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); -extern void ixgbe_write_eitr(struct ixgbe_q_vector *); -extern int ethtool_ioctl(struct ifreq *ifr); -extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); -extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); -extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); -extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, - struct ixgbe_atr_input *input, - u8 queue); -extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, - struct ixgbe_atr_input *input, - u16 soft_id, - u8 queue); -extern u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key); -extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, - u16 vlan_id); -extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, - u32 src_addr); -extern s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, - u32 dst_addr); -extern s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, - u32 src_addr_1, u32 src_addr_2, - u32 src_addr_3, u32 src_addr_4); -extern s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 dst_addr_1, u32 dst_addr_2, - u32 dst_addr_3, u32 dst_addr_4); -extern s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, - u16 src_port); -extern s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, - u16 dst_port); -extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, - u16 flex_byte); -extern s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, - u8 vm_pool); -extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, - u8 l4type); -extern s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, - u16 *vlan_id); -extern s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, - u32 *src_addr); -extern s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, - u32 *dst_addr); -extern s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, - u32 *src_addr_1, u32 *src_addr_2, - u32 *src_addr_3, u32 *src_addr_4); -extern s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 *dst_addr_1, u32 *dst_addr_2, - u32 *dst_addr_3, u32 *dst_addr_4); -extern s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, - u16 *src_port); -extern s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, - u16 *dst_port); -extern s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, - u16 *flex_byte); -extern s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, - u8 *vm_pool); -extern s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, - u8 *l4type); +extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); extern int ixgbe_fso(struct ixgbe_adapter *adapter, diff --git a/trunk/drivers/net/ixgbe/ixgbe_82598.c b/trunk/drivers/net/ixgbe/ixgbe_82598.c index b9923047ce11..88e8350aa786 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_82598.c +++ b/trunk/drivers/net/ixgbe/ixgbe_82598.c @@ -293,17 +293,6 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) u32 rmcs_reg; u32 reg; -#ifdef CONFIG_DCB - if (hw->fc.requested_mode == ixgbe_fc_pfc) - goto out; - -#endif /* CONFIG_DCB */ - /* Negotiate the fc mode to use */ - ret_val = ixgbe_fc_autoneg(hw); - if (ret_val) - goto out; - - /* Disable any previous flow control settings */ fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); @@ -315,20 +304,14 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) * 0: Flow control is completely disabled * 1: Rx flow control is enabled (we can receive pause frames, * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but + * 2: Tx flow control is enabled (we can send pause frames but * we do not support receiving pause frames). * 3: Both Rx and Tx flow control (symmetric) are enabled. * other: Invalid. -#ifdef CONFIG_DCB - * 4: Priority Flow Control is enabled. -#endif */ switch (hw->fc.current_mode) { case ixgbe_fc_none: - /* - * Flow control is disabled by software override or autoneg. - * The code below will actually disable it in the HW. - */ + /* Flow control completely disabled by software override. */ break; case ixgbe_fc_rx_pause: /* @@ -353,11 +336,6 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) fctrl_reg |= IXGBE_FCTRL_RFCE; rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; break; -#ifdef CONFIG_DCB - case ixgbe_fc_pfc: - goto out; - break; -#endif /* CONFIG_DCB */ default: hw_dbg(hw, "Flow control param set incorrectly\n"); ret_val = -IXGBE_ERR_CONFIG; @@ -365,7 +343,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) break; } - /* Set 802.3x based flow control settings. */ + /* Enable 802.3x based flow control settings. */ fctrl_reg |= IXGBE_FCTRL_DPF; IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); @@ -398,6 +376,79 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) return ret_val; } +/** + * ixgbe_setup_fc_82598 - Configure flow control settings + * @hw: pointer to hardware structure + * @packetbuf_num: packet buffer number (0-7) + * + * Configures the flow control settings based on SW configuration. This + * function is used for 802.3x flow control configuration only. + **/ +static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num) +{ + s32 ret_val = 0; + ixgbe_link_speed speed; + bool link_up; + + /* Validate the packetbuf configuration */ + if (packetbuf_num < 0 || packetbuf_num > 7) { + hw_dbg(hw, "Invalid packet buffer number [%d], expected range is" + " 0-7\n", packetbuf_num); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* + * Validate the water mark configuration. Zero water marks are invalid + * because it causes the controller to just blast out fc packets. + */ + if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { + if (hw->fc.requested_mode != ixgbe_fc_none) { + hw_dbg(hw, "Invalid water mark configuration\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + } + + /* + * Validate the requested mode. Strict IEEE mode does not allow + * ixgbe_fc_rx_pause because it will cause testing anomalies. + */ + if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { + hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } + + /* + * 10gig parts do not have a word in the EEPROM to determine the + * default flow control setting, so we explicitly set it to full. + */ + if (hw->fc.requested_mode == ixgbe_fc_default) + hw->fc.requested_mode = ixgbe_fc_full; + + /* + * Save off the requested flow control mode for use later. Depending + * on the link partner's capabilities, we may or may not use this mode. + */ + + hw->fc.current_mode = hw->fc.requested_mode; + + /* Decide whether to use autoneg or not. */ + hw->mac.ops.check_link(hw, &speed, &link_up, false); + if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber && + (speed == IXGBE_LINK_SPEED_1GB_FULL)) + ret_val = ixgbe_fc_autoneg(hw); + + if (ret_val) + goto out; + + ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num); + +out: + return ret_val; +} + /** * ixgbe_setup_mac_link_82598 - Configures MAC link settings * @hw: pointer to hardware structure @@ -437,6 +488,13 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) } } + /* + * We want to save off the original Flow Control configuration just in + * case we get disconnected and then reconnected into a different hub + * or switch with different Flow Control capabilities. + */ + ixgbe_setup_fc_82598(hw, 0); + /* Add delay to filter out noises during initial link setup */ msleep(50); @@ -523,11 +581,6 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, else *speed = IXGBE_LINK_SPEED_1GB_FULL; - /* if link is down, zero out the current_mode */ - if (*link_up == false) { - hw->fc.current_mode = ixgbe_fc_none; - hw->fc.fc_was_autonegged = false; - } out: return 0; } @@ -1115,7 +1168,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = { .disable_mc = &ixgbe_disable_mc_generic, .clear_vfta = &ixgbe_clear_vfta_82598, .set_vfta = &ixgbe_set_vfta_82598, - .fc_enable = &ixgbe_fc_enable_82598, + .setup_fc = &ixgbe_setup_fc_82598, }; static struct ixgbe_eeprom_operations eeprom_ops_82598 = { diff --git a/trunk/drivers/net/ixgbe/ixgbe_82599.c b/trunk/drivers/net/ixgbe/ixgbe_82599.c index 1984cab7d48b..5d2783081a94 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_82599.c +++ b/trunk/drivers/net/ixgbe/ixgbe_82599.c @@ -71,10 +71,10 @@ s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw); s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw); s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); +s32 ixgbe_start_hw_rev_0_82599(struct ixgbe_hw *hw); s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw); s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw); u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw); -static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) { @@ -122,9 +122,10 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) IXGBE_WRITE_FLUSH(hw); hw->eeprom.ops.read(hw, ++data_offset, &data_value); } - /* Now restart DSP by setting Restart_AN */ - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, - (IXGBE_READ_REG(hw, IXGBE_AUTOC) | IXGBE_AUTOC_AN_RESTART)); + /* Now restart DSP */ + IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000102); + IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000b1d); + IXGBE_WRITE_FLUSH(hw); /* Release the semaphore */ ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); @@ -413,6 +414,9 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw) } } + /* Set up flow control */ + status = ixgbe_setup_fc_generic(hw, 0); + /* Add delay to filter out noises during initial link setup */ msleep(50); @@ -458,31 +462,11 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); bool link_up = false; bool negotiation; - int i; /* Mask off requested but non-supported speeds */ hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation); speed &= phy_link_speed; - /* Set autoneg_advertised value based on input link speed */ - hw->phy.autoneg_advertised = 0; - - if (speed & IXGBE_LINK_SPEED_10GB_FULL) - hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; - - if (speed & IXGBE_LINK_SPEED_1GB_FULL) - hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; - - /* - * When the driver changes the link speeds that it can support, - * it sets autotry_restart to true to indicate that we need to - * initiate a new autotry session with the link partner. To do - * so, we set the speed then disable and re-enable the tx laser, to - * alert the link partner that it also needs to restart autotry on its - * end. This is consistent with true clause 37 autoneg, which also - * involves a loss of signal. - */ - /* * Try each speed one by one, highest priority first. We do this in * software because 10gb fiber doesn't support speed autonegotiation. @@ -491,52 +475,21 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, speedcnt++; highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL; - /* If we already have link at this speed, just jump out */ - hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); - - if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up) - goto out; - - /* Set the module link speed */ + /* Set hardware SDP's */ esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - /* Allow module to change analog characteristics (1G->10G) */ - msleep(40); + ixgbe_setup_mac_link_speed_82599(hw, + IXGBE_LINK_SPEED_10GB_FULL, + autoneg, + autoneg_wait_to_complete); - status = ixgbe_setup_mac_link_speed_82599(hw, - IXGBE_LINK_SPEED_10GB_FULL, - autoneg, - autoneg_wait_to_complete); - if (status != 0) - goto out; - - /* Flap the tx laser if it has not already been done */ - if (hw->mac.autotry_restart) { - /* Disable tx laser; allow 100us to go dark per spec */ - esdp_reg |= IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - udelay(100); - - /* Enable tx laser; allow 2ms to light up per spec */ - esdp_reg &= ~IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - msleep(2); - - hw->mac.autotry_restart = false; - } - - /* The controller may take up to 500ms at 10g to acquire link */ - for (i = 0; i < 5; i++) { - /* Wait for the link partner to also set speed */ - msleep(100); + msleep(50); - /* If we have link, just jump out */ - hw->mac.ops.check_link(hw, &phy_link_speed, - &link_up, false); - if (link_up) - goto out; - } + /* If we have link, just jump out */ + hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); + if (link_up) + goto out; } if (speed & IXGBE_LINK_SPEED_1GB_FULL) { @@ -544,44 +497,16 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw, if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN) highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL; - /* If we already have link at this speed, just jump out */ - hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); - - if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up) - goto out; - - /* Set the module link speed */ + /* Set hardware SDP's */ esdp_reg &= ~IXGBE_ESDP_SDP5; esdp_reg |= IXGBE_ESDP_SDP5_DIR; IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - /* Allow module to change analog characteristics (10G->1G) */ - msleep(40); - - status = ixgbe_setup_mac_link_speed_82599(hw, - IXGBE_LINK_SPEED_1GB_FULL, - autoneg, - autoneg_wait_to_complete); - if (status != 0) - goto out; - - /* Flap the tx laser if it has not already been done */ - if (hw->mac.autotry_restart) { - /* Disable tx laser; allow 100us to go dark per spec */ - esdp_reg |= IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - udelay(100); - - /* Enable tx laser; allow 2ms to light up per spec */ - esdp_reg &= ~IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - msleep(2); - - hw->mac.autotry_restart = false; - } + ixgbe_setup_mac_link_speed_82599( + hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg, + autoneg_wait_to_complete); - /* Wait for the link partner to also set speed */ - msleep(100); + msleep(50); /* If we have link, just jump out */ hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false); @@ -647,11 +572,6 @@ s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed, else *speed = IXGBE_LINK_SPEED_100_FULL; - /* if link is down, zero out the current_mode */ - if (*link_up == false) { - hw->fc.current_mode = ixgbe_fc_none; - hw->fc.fc_was_autonegged = false; - } return 0; } @@ -672,7 +592,6 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, s32 status = 0; u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); - u32 start_autoc = autoc; u32 orig_autoc = 0; u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; @@ -685,11 +604,6 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg); speed &= link_capabilities; - if (speed == IXGBE_LINK_SPEED_UNKNOWN) { - status = IXGBE_ERR_LINK_SETUP; - goto out; - } - /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ if (hw->mac.orig_link_settings_stored) orig_autoc = hw->mac.orig_autoc; @@ -697,9 +611,11 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, orig_autoc = autoc; - if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || - link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || - link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { + if (speed == IXGBE_LINK_SPEED_UNKNOWN) { + status = IXGBE_ERR_LINK_SETUP; + } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || + link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN || + link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { /* Set KX4/KX/KR support according to speed requested */ autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); if (speed & IXGBE_LINK_SPEED_10GB_FULL) @@ -731,7 +647,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, } } - if (autoc != start_autoc) { + if (status == 0) { /* Restart link */ autoc |= IXGBE_AUTOC_AN_RESTART; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); @@ -758,11 +674,13 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, } } + /* Set up flow control */ + status = ixgbe_setup_fc_generic(hw, 0); + /* Add delay to filter out noises during initial link setup */ msleep(50); } -out: return status; } @@ -1164,931 +1082,6 @@ s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw) return 0; } -/** - * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables. - * @hw: pointer to hardware structure - **/ -s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) -{ - int i; - u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL); - fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE; - - /* - * Before starting reinitialization process, - * FDIRCMD.CMD must be zero. - */ - for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) { - if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) & - IXGBE_FDIRCMD_CMD_MASK)) - break; - udelay(10); - } - if (i >= IXGBE_FDIRCMD_CMD_POLL) { - hw_dbg(hw ,"Flow Director previous command isn't complete, " - "aborting table re-initialization. \n"); - return IXGBE_ERR_FDIR_REINIT_FAILED; - } - - IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0); - IXGBE_WRITE_FLUSH(hw); - /* - * 82599 adapters flow director init flow cannot be restarted, - * Workaround 82599 silicon errata by performing the following steps - * before re-writing the FDIRCTRL control register with the same value. - * - write 1 to bit 8 of FDIRCMD register & - * - write 0 to bit 8 of FDIRCMD register - */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, - (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) | - IXGBE_FDIRCMD_CLEARHT)); - IXGBE_WRITE_FLUSH(hw); - IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, - (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) & - ~IXGBE_FDIRCMD_CLEARHT)); - IXGBE_WRITE_FLUSH(hw); - /* - * Clear FDIR Hash register to clear any leftover hashes - * waiting to be programmed. - */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, 0x00); - IXGBE_WRITE_FLUSH(hw); - - IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); - IXGBE_WRITE_FLUSH(hw); - - /* Poll init-done after we write FDIRCTRL register */ - for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { - if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & - IXGBE_FDIRCTRL_INIT_DONE) - break; - udelay(10); - } - if (i >= IXGBE_FDIR_INIT_DONE_POLL) { - hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); - return IXGBE_ERR_FDIR_REINIT_FAILED; - } - - /* Clear FDIR statistics registers (read to clear) */ - IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT); - IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT); - IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); - IXGBE_READ_REG(hw, IXGBE_FDIRMISS); - IXGBE_READ_REG(hw, IXGBE_FDIRLEN); - - return 0; -} - -/** - * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters - * @hw: pointer to hardware structure - * @pballoc: which mode to allocate filters with - **/ -s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) -{ - u32 fdirctrl = 0; - u32 pbsize; - int i; - - /* - * Before enabling Flow Director, the Rx Packet Buffer size - * must be reduced. The new value is the current size minus - * flow director memory usage size. - */ - pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc)); - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), - (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize)); - - /* - * The defaults in the HW for RX PB 1-7 are not zero and so should be - * intialized to zero for non DCB mode otherwise actual total RX PB - * would be bigger than programmed and filter space would run into - * the PB 0 region. - */ - for (i = 1; i < 8; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); - - /* Send interrupt when 64 filters are left */ - fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; - - /* Set the maximum length per hash bucket to 0xA filters */ - fdirctrl |= 0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT; - - switch (pballoc) { - case IXGBE_FDIR_PBALLOC_64K: - /* 8k - 1 signature filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K; - break; - case IXGBE_FDIR_PBALLOC_128K: - /* 16k - 1 signature filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K; - break; - case IXGBE_FDIR_PBALLOC_256K: - /* 32k - 1 signature filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K; - break; - default: - /* bad value */ - return IXGBE_ERR_CONFIG; - }; - - /* Move the flexible bytes to use the ethertype - shift 6 words */ - fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT); - - fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS; - - /* Prime the keys for hashing */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, - htonl(IXGBE_ATR_BUCKET_HASH_KEY)); - IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, - htonl(IXGBE_ATR_SIGNATURE_HASH_KEY)); - - /* - * Poll init-done after we write the register. Estimated times: - * 10G: PBALLOC = 11b, timing is 60us - * 1G: PBALLOC = 11b, timing is 600us - * 100M: PBALLOC = 11b, timing is 6ms - * - * Multiple these timings by 4 if under full Rx load - * - * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for - * 1 msec per poll time. If we're at line rate and drop to 100M, then - * this might not finish in our poll time, but we can live with that - * for now. - */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); - IXGBE_WRITE_FLUSH(hw); - for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { - if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & - IXGBE_FDIRCTRL_INIT_DONE) - break; - msleep(1); - } - if (i >= IXGBE_FDIR_INIT_DONE_POLL) - hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); - - return 0; -} - -/** - * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters - * @hw: pointer to hardware structure - * @pballoc: which mode to allocate filters with - **/ -s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) -{ - u32 fdirctrl = 0; - u32 pbsize; - int i; - - /* - * Before enabling Flow Director, the Rx Packet Buffer size - * must be reduced. The new value is the current size minus - * flow director memory usage size. - */ - pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc)); - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), - (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize)); - - /* - * The defaults in the HW for RX PB 1-7 are not zero and so should be - * intialized to zero for non DCB mode otherwise actual total RX PB - * would be bigger than programmed and filter space would run into - * the PB 0 region. - */ - for (i = 1; i < 8; i++) - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0); - - /* Send interrupt when 64 filters are left */ - fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT; - - switch (pballoc) { - case IXGBE_FDIR_PBALLOC_64K: - /* 2k - 1 perfect filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K; - break; - case IXGBE_FDIR_PBALLOC_128K: - /* 4k - 1 perfect filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K; - break; - case IXGBE_FDIR_PBALLOC_256K: - /* 8k - 1 perfect filters */ - fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K; - break; - default: - /* bad value */ - return IXGBE_ERR_CONFIG; - }; - - /* Turn perfect match filtering on */ - fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH; - fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS; - - /* Move the flexible bytes to use the ethertype - shift 6 words */ - fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT); - - /* Prime the keys for hashing */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY, - htonl(IXGBE_ATR_BUCKET_HASH_KEY)); - IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY, - htonl(IXGBE_ATR_SIGNATURE_HASH_KEY)); - - /* - * Poll init-done after we write the register. Estimated times: - * 10G: PBALLOC = 11b, timing is 60us - * 1G: PBALLOC = 11b, timing is 600us - * 100M: PBALLOC = 11b, timing is 6ms - * - * Multiple these timings by 4 if under full Rx load - * - * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for - * 1 msec per poll time. If we're at line rate and drop to 100M, then - * this might not finish in our poll time, but we can live with that - * for now. - */ - - /* Set the maximum length per hash bucket to 0xA filters */ - fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT); - - IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl); - IXGBE_WRITE_FLUSH(hw); - for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) { - if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) & - IXGBE_FDIRCTRL_INIT_DONE) - break; - msleep(1); - } - if (i >= IXGBE_FDIR_INIT_DONE_POLL) - hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n"); - - return 0; -} - - -/** - * ixgbe_atr_compute_hash_82599 - Compute the hashes for SW ATR - * @stream: input bitstream to compute the hash on - * @key: 32-bit hash key - **/ -u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key) -{ - /* - * The algorithm is as follows: - * Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350 - * where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n] - * and A[n] x B[n] is bitwise AND between same length strings - * - * K[n] is 16 bits, defined as: - * for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15] - * for n modulo 32 < 15, K[n] = - * K[(n % 32:0) | (31:31 - (14 - (n % 32)))] - * - * S[n] is 16 bits, defined as: - * for n >= 15, S[n] = S[n:n - 15] - * for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))] - * - * To simplify for programming, the algorithm is implemented - * in software this way: - * - * Key[31:0], Stream[335:0] - * - * tmp_key[11 * 32 - 1:0] = 11{Key[31:0] = key concatenated 11 times - * int_key[350:0] = tmp_key[351:1] - * int_stream[365:0] = Stream[14:0] | Stream[335:0] | Stream[335:321] - * - * hash[15:0] = 0; - * for (i = 0; i < 351; i++) { - * if (int_key[i]) - * hash ^= int_stream[(i + 15):i]; - * } - */ - - union { - u64 fill[6]; - u32 key[11]; - u8 key_stream[44]; - } tmp_key; - - u8 *stream = (u8 *)atr_input; - u8 int_key[44]; /* upper-most bit unused */ - u8 hash_str[46]; /* upper-most 2 bits unused */ - u16 hash_result = 0; - int i, j, k, h; - - /* - * Initialize the fill member to prevent warnings - * on some compilers - */ - tmp_key.fill[0] = 0; - - /* First load the temporary key stream */ - for (i = 0; i < 6; i++) { - u64 fillkey = ((u64)key << 32) | key; - tmp_key.fill[i] = fillkey; - } - - /* - * Set the interim key for the hashing. Bit 352 is unused, so we must - * shift and compensate when building the key. - */ - - int_key[0] = tmp_key.key_stream[0] >> 1; - for (i = 1, j = 0; i < 44; i++) { - unsigned int this_key = tmp_key.key_stream[j] << 7; - j++; - int_key[i] = (u8)(this_key | (tmp_key.key_stream[j] >> 1)); - } - - /* - * Set the interim bit string for the hashing. Bits 368 and 367 are - * unused, so shift and compensate when building the string. - */ - hash_str[0] = (stream[40] & 0x7f) >> 1; - for (i = 1, j = 40; i < 46; i++) { - unsigned int this_str = stream[j] << 7; - j++; - if (j > 41) - j = 0; - hash_str[i] = (u8)(this_str | (stream[j] >> 1)); - } - - /* - * Now compute the hash. i is the index into hash_str, j is into our - * key stream, k is counting the number of bits, and h interates within - * each byte. - */ - for (i = 45, j = 43, k = 0; k < 351 && i >= 2 && j >= 0; i--, j--) { - for (h = 0; h < 8 && k < 351; h++, k++) { - if (int_key[j] & (1 << h)) { - /* - * Key bit is set, XOR in the current 16-bit - * string. Example of processing: - * h = 0, - * tmp = (hash_str[i - 2] & 0 << 16) | - * (hash_str[i - 1] & 0xff << 8) | - * (hash_str[i] & 0xff >> 0) - * So tmp = hash_str[15 + k:k], since the - * i + 2 clause rolls off the 16-bit value - * h = 7, - * tmp = (hash_str[i - 2] & 0x7f << 9) | - * (hash_str[i - 1] & 0xff << 1) | - * (hash_str[i] & 0x80 >> 7) - */ - int tmp = (hash_str[i] >> h); - tmp |= (hash_str[i - 1] << (8 - h)); - tmp |= (int)(hash_str[i - 2] & ((1 << h) - 1)) - << (16 - h); - hash_result ^= (u16)tmp; - } - } - } - - return hash_result; -} - -/** - * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream - * @input: input stream to modify - * @vlan: the VLAN id to load - **/ -s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan) -{ - input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] = vlan >> 8; - input->byte_stream[IXGBE_ATR_VLAN_OFFSET] = vlan & 0xff; - - return 0; -} - -/** - * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address - * @input: input stream to modify - * @src_addr: the IP address to load - **/ -s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr) -{ - input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] = src_addr >> 24; - input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] = - (src_addr >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] = - (src_addr >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET] = src_addr & 0xff; - - return 0; -} - -/** - * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address - * @input: input stream to modify - * @dst_addr: the IP address to load - **/ -s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) -{ - input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] = dst_addr >> 24; - input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] = - (dst_addr >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] = - (dst_addr >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET] = dst_addr & 0xff; - - return 0; -} - -/** - * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address - * @input: input stream to modify - * @src_addr_1: the first 4 bytes of the IP address to load - * @src_addr_2: the second 4 bytes of the IP address to load - * @src_addr_3: the third 4 bytes of the IP address to load - * @src_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, - u32 src_addr_1, u32 src_addr_2, - u32 src_addr_3, u32 src_addr_4) -{ - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] = - (src_addr_4 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] = - (src_addr_4 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] = - (src_addr_3 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] = - (src_addr_3 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] = - (src_addr_2 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] = - (src_addr_2 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] = - (src_addr_1 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] = - (src_addr_1 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24; - - return 0; -} - -/** - * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address - * @input: input stream to modify - * @dst_addr_1: the first 4 bytes of the IP address to load - * @dst_addr_2: the second 4 bytes of the IP address to load - * @dst_addr_3: the third 4 bytes of the IP address to load - * @dst_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 dst_addr_1, u32 dst_addr_2, - u32 dst_addr_3, u32 dst_addr_4) -{ - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] = - (dst_addr_4 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] = - (dst_addr_4 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] = - (dst_addr_3 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] = - (dst_addr_3 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] = - (dst_addr_2 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] = - (dst_addr_2 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] = - (dst_addr_1 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] = - (dst_addr_1 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24; - - return 0; -} - -/** - * ixgbe_atr_set_src_port_82599 - Sets the source port - * @input: input stream to modify - * @src_port: the source port to load - **/ -s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port) -{ - input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1] = src_port >> 8; - input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] = src_port & 0xff; - - return 0; -} - -/** - * ixgbe_atr_set_dst_port_82599 - Sets the destination port - * @input: input stream to modify - * @dst_port: the destination port to load - **/ -s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port) -{ - input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1] = dst_port >> 8; - input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] = dst_port & 0xff; - - return 0; -} - -/** - * ixgbe_atr_set_flex_byte_82599 - Sets the flexible bytes - * @input: input stream to modify - * @flex_bytes: the flexible bytes to load - **/ -s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte) -{ - input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] = flex_byte >> 8; - input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET] = flex_byte & 0xff; - - return 0; -} - -/** - * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool) -{ - input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool; - - return 0; -} - -/** - * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type - * @input: input stream to modify - * @l4type: the layer 4 type value to load - **/ -s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type) -{ - input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET] = l4type; - - return 0; -} - -/** - * ixgbe_atr_get_vlan_id_82599 - Gets the VLAN id from the ATR input stream - * @input: input stream to search - * @vlan: the VLAN id to load - **/ -s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan) -{ - *vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET]; - *vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8; - - return 0; -} - -/** - * ixgbe_atr_get_src_ipv4_82599 - Gets the source IPv4 address - * @input: input stream to search - * @src_addr: the IP address to load - **/ -s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr) -{ - *src_addr = input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET]; - *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] << 8; - *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] << 16; - *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] << 24; - - return 0; -} - -/** - * ixgbe_atr_get_dst_ipv4_82599 - Gets the destination IPv4 address - * @input: input stream to search - * @dst_addr: the IP address to load - **/ -s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr) -{ - *dst_addr = input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET]; - *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] << 8; - *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] << 16; - *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] << 24; - - return 0; -} - -/** - * ixgbe_atr_get_src_ipv6_82599 - Gets the source IPv6 address - * @input: input stream to search - * @src_addr_1: the first 4 bytes of the IP address to load - * @src_addr_2: the second 4 bytes of the IP address to load - * @src_addr_3: the third 4 bytes of the IP address to load - * @src_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, - u32 *src_addr_1, u32 *src_addr_2, - u32 *src_addr_3, u32 *src_addr_4) -{ - *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12]; - *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] << 8; - *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] << 16; - *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] << 24; - - *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8]; - *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] << 8; - *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] << 16; - *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] << 24; - - *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4]; - *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] << 8; - *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] << 16; - *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] << 24; - - *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET]; - *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] << 8; - *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] << 16; - *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] << 24; - - return 0; -} - -/** - * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address - * @input: input stream to search - * @dst_addr_1: the first 4 bytes of the IP address to load - * @dst_addr_2: the second 4 bytes of the IP address to load - * @dst_addr_3: the third 4 bytes of the IP address to load - * @dst_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 *dst_addr_1, u32 *dst_addr_2, - u32 *dst_addr_3, u32 *dst_addr_4) -{ - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12]; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24; - - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8]; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24; - - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4]; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24; - - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET]; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24; - - return 0; -} - -/** - * ixgbe_atr_get_src_port_82599 - Gets the source port - * @input: input stream to modify - * @src_port: the source port to load - * - * Even though the input is given in big-endian, the FDIRPORT registers - * expect the ports to be programmed in little-endian. Hence the need to swap - * endianness when retrieving the data. This can be confusing since the - * internal hash engine expects it to be big-endian. - **/ -s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port) -{ - *src_port = input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] << 8; - *src_port |= input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1]; - - return 0; -} - -/** - * ixgbe_atr_get_dst_port_82599 - Gets the destination port - * @input: input stream to modify - * @dst_port: the destination port to load - * - * Even though the input is given in big-endian, the FDIRPORT registers - * expect the ports to be programmed in little-endian. Hence the need to swap - * endianness when retrieving the data. This can be confusing since the - * internal hash engine expects it to be big-endian. - **/ -s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port) -{ - *dst_port = input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] << 8; - *dst_port |= input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1]; - - return 0; -} - -/** - * ixgbe_atr_get_flex_byte_82599 - Gets the flexible bytes - * @input: input stream to modify - * @flex_bytes: the flexible bytes to load - **/ -s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte) -{ - *flex_byte = input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET]; - *flex_byte |= input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] << 8; - - return 0; -} - -/** - * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool) -{ - *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET]; - - return 0; -} - -/** - * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type - * @input: input stream to modify - * @l4type: the layer 4 type value to load - **/ -s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type) -{ - *l4type = input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET]; - - return 0; -} - -/** - * ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter - * @hw: pointer to hardware structure - * @stream: input bitstream - * @queue: queue index to direct traffic to - **/ -s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, - struct ixgbe_atr_input *input, - u8 queue) -{ - u64 fdirhashcmd; - u64 fdircmd; - u32 fdirhash; - u16 bucket_hash, sig_hash; - u8 l4type; - - bucket_hash = ixgbe_atr_compute_hash_82599(input, - IXGBE_ATR_BUCKET_HASH_KEY); - - /* bucket_hash is only 15 bits */ - bucket_hash &= IXGBE_ATR_HASH_MASK; - - sig_hash = ixgbe_atr_compute_hash_82599(input, - IXGBE_ATR_SIGNATURE_HASH_KEY); - - /* Get the l4type in order to program FDIRCMD properly */ - /* lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 */ - ixgbe_atr_get_l4type_82599(input, &l4type); - - /* - * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits - * is for FDIRCMD. Then do a 64-bit register write from FDIRHASH. - */ - fdirhash = sig_hash << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash; - - fdircmd = (IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | - IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN); - - switch (l4type & IXGBE_ATR_L4TYPE_MASK) { - case IXGBE_ATR_L4TYPE_TCP: - fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP; - break; - case IXGBE_ATR_L4TYPE_UDP: - fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP; - break; - case IXGBE_ATR_L4TYPE_SCTP: - fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP; - break; - default: - hw_dbg(hw, "Error on l4type input\n"); - return IXGBE_ERR_CONFIG; - } - - if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) - fdircmd |= IXGBE_FDIRCMD_IPV6; - - fdircmd |= ((u64)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT); - fdirhashcmd = ((fdircmd << 32) | fdirhash); - - IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd); - - return 0; -} - -/** - * ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter - * @hw: pointer to hardware structure - * @input: input bitstream - * @queue: queue index to direct traffic to - * - * Note that the caller to this function must lock before calling, since the - * hardware writes must be protected from one another. - **/ -s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, - struct ixgbe_atr_input *input, - u16 soft_id, - u8 queue) -{ - u32 fdircmd = 0; - u32 fdirhash; - u32 src_ipv4, dst_ipv4; - u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4; - u16 src_port, dst_port, vlan_id, flex_bytes; - u16 bucket_hash; - u8 l4type; - - /* Get our input values */ - ixgbe_atr_get_l4type_82599(input, &l4type); - - /* - * Check l4type formatting, and bail out before we touch the hardware - * if there's a configuration issue - */ - switch (l4type & IXGBE_ATR_L4TYPE_MASK) { - case IXGBE_ATR_L4TYPE_TCP: - fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP; - break; - case IXGBE_ATR_L4TYPE_UDP: - fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP; - break; - case IXGBE_ATR_L4TYPE_SCTP: - fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP; - break; - default: - hw_dbg(hw, "Error on l4type input\n"); - return IXGBE_ERR_CONFIG; - } - - bucket_hash = ixgbe_atr_compute_hash_82599(input, - IXGBE_ATR_BUCKET_HASH_KEY); - - /* bucket_hash is only 15 bits */ - bucket_hash &= IXGBE_ATR_HASH_MASK; - - ixgbe_atr_get_vlan_id_82599(input, &vlan_id); - ixgbe_atr_get_src_port_82599(input, &src_port); - ixgbe_atr_get_dst_port_82599(input, &dst_port); - ixgbe_atr_get_flex_byte_82599(input, &flex_bytes); - - fdirhash = soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash; - - /* Now figure out if we're IPv4 or IPv6 */ - if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) { - /* IPv6 */ - ixgbe_atr_get_src_ipv6_82599(input, &src_ipv6_1, &src_ipv6_2, - &src_ipv6_3, &src_ipv6_4); - - IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), src_ipv6_1); - IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(1), src_ipv6_2); - IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), src_ipv6_3); - /* The last 4 bytes is the same register as IPv4 */ - IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv6_4); - - fdircmd |= IXGBE_FDIRCMD_IPV6; - fdircmd |= IXGBE_FDIRCMD_IPv6DMATCH; - } else { - /* IPv4 */ - ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4); - IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4); - - } - - ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4); - IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, dst_ipv4); - - IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id | - (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT))); - IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port | - (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); - - fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; - fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; - fdircmd |= IXGBE_FDIRCMD_LAST; - fdircmd |= IXGBE_FDIRCMD_QUEUE_EN; - fdircmd |= queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; - - IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); - IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd); - - return 0; -} /** * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register * @hw: pointer to hardware structure @@ -2142,9 +1135,8 @@ s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val) s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) { u32 q_num; - s32 ret_val; - ret_val = ixgbe_start_hw_generic(hw); + ixgbe_start_hw_generic(hw); /* Clear the rate limiters */ for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) { @@ -2153,13 +1145,7 @@ s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) } IXGBE_WRITE_FLUSH(hw); - /* We need to run link autotry after the driver loads */ - hw->mac.autotry_restart = true; - - if (ret_val == 0) - ret_val = ixgbe_verify_fw_version_82599(hw); - - return ret_val; + return 0; } /** @@ -2411,54 +1397,6 @@ s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr) return 0; } -/** - * ixgbe_verify_fw_version_82599 - verify fw version for 82599 - * @hw: pointer to hardware structure - * - * Verifies that installed the firmware version is 0.6 or higher - * for SFI devices. All 82599 SFI devices should have version 0.6 or higher. - * - * Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or - * if the FW version is not supported. - **/ -static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) -{ - s32 status = IXGBE_ERR_EEPROM_VERSION; - u16 fw_offset, fw_ptp_cfg_offset; - u16 fw_version = 0; - - /* firmware check is only necessary for SFI devices */ - if (hw->phy.media_type != ixgbe_media_type_fiber) { - status = 0; - goto fw_version_out; - } - - /* get the offset to the Firmware Module block */ - hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset); - - if ((fw_offset == 0) || (fw_offset == 0xFFFF)) - goto fw_version_out; - - /* get the offset to the Pass Through Patch Configuration block */ - hw->eeprom.ops.read(hw, (fw_offset + - IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR), - &fw_ptp_cfg_offset); - - if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF)) - goto fw_version_out; - - /* get the firmware version */ - hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset + - IXGBE_FW_PATCH_VERSION_4), - &fw_version); - - if (fw_version > 0x5) - status = 0; - -fw_version_out: - return status; -} - static struct ixgbe_mac_operations mac_ops_82599 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82599, @@ -2494,7 +1432,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .disable_mc = &ixgbe_disable_mc_generic, .clear_vfta = &ixgbe_clear_vfta_82599, .set_vfta = &ixgbe_set_vfta_82599, - .fc_enable = &ixgbe_fc_enable_generic, + .setup_fc = &ixgbe_setup_fc_generic, .init_uta_tables = &ixgbe_init_uta_tables_82599, .setup_sfp = &ixgbe_setup_sfp_modules_82599, }; diff --git a/trunk/drivers/net/ixgbe/ixgbe_common.c b/trunk/drivers/net/ixgbe/ixgbe_common.c index 96a185953777..0cc3c47cb453 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_common.c +++ b/trunk/drivers/net/ixgbe/ixgbe_common.c @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include "ixgbe.h" #include "ixgbe_common.h" @@ -85,9 +83,6 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); IXGBE_WRITE_FLUSH(hw); - /* Setup flow control */ - ixgbe_setup_fc(hw, 0); - /* Clear adapter stopped flag */ hw->adapter_stopped = false; @@ -106,17 +101,13 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) **/ s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) { - s32 status; - /* Reset the hardware */ - status = hw->mac.ops.reset_hw(hw); + hw->mac.ops.reset_hw(hw); - if (status == 0) { - /* Start the HW */ - status = hw->mac.ops.start_hw(hw); - } + /* Start the HW */ + hw->mac.ops.start_hw(hw); - return status; + return 0; } /** @@ -1365,14 +1356,15 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) * Drivers using secondary unicast addresses must set user_set_promisc when * manually putting the device into promiscuous mode. **/ -s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, - struct list_head *uc_list) +s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, + u32 addr_count, ixgbe_mc_addr_itr next) { + u8 *addr; u32 i; u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; u32 uc_addr_in_use; u32 fctrl; - struct netdev_hw_addr *ha; + u32 vmdq; /* * Clear accounting of old secondary address list, @@ -1390,9 +1382,10 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, } /* Add the new addresses */ - list_for_each_entry(ha, uc_list, list) { + for (i = 0; i < addr_count; i++) { hw_dbg(hw, " Adding the secondary addresses:\n"); - ixgbe_add_uc_addr(hw, ha->addr, 0); + addr = next(hw, &addr_list, &vmdq); + ixgbe_add_uc_addr(hw, addr, vmdq); } if (hw->addr_ctrl.overflow_promisc) { @@ -1584,16 +1577,17 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) } /** - * ixgbe_fc_enable_generic - Enable flow control + * ixgbe_fc_enable - Enable flow control * @hw: pointer to hardware structure * @packetbuf_num: packet buffer number (0-7) * * Enable flow control according to the current settings. **/ -s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) +s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num) { s32 ret_val = 0; - u32 mflcn_reg, fccfg_reg; + u32 mflcn_reg; + u32 fccfg_reg; u32 reg; u32 rx_pba_size; @@ -1602,12 +1596,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) goto out; #endif /* CONFIG_DCB */ - /* Negotiate the fc mode to use */ - ret_val = ixgbe_fc_autoneg(hw); - if (ret_val) - goto out; - /* Disable any previous flow control settings */ mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN); mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE); @@ -1627,10 +1616,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) */ switch (hw->fc.current_mode) { case ixgbe_fc_none: - /* - * Flow control is disabled by software override or autoneg. - * The code below will actually disable it in the HW. - */ + /* Flow control completely disabled by software override. */ break; case ixgbe_fc_rx_pause: /* @@ -1659,7 +1645,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) case ixgbe_fc_pfc: goto out; break; -#endif /* CONFIG_DCB */ +#endif default: hw_dbg(hw, "Flow control param set incorrectly\n"); ret_val = -IXGBE_ERR_CONFIG; @@ -1667,7 +1653,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) break; } - /* Set 802.3x based flow control settings. */ + /* Enable 802.3x based flow control settings. */ mflcn_reg |= IXGBE_MFLCN_DPF; IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); @@ -1675,12 +1661,10 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) reg = IXGBE_READ_REG(hw, IXGBE_MTQC); /* Thresholds are different for link flow control when in DCB mode */ if (reg & IXGBE_MTQC_RT_ENA) { - rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); - /* Always disable XON for LFC when in DCB mode */ - reg = (rx_pba_size >> 5) & 0xFFE0; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg); + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), 0); + rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); reg = (rx_pba_size >> 2) & 0xFFE0; if (hw->fc.current_mode & ixgbe_fc_tx_pause) reg |= IXGBE_FCRTH_FCEN; @@ -1725,41 +1709,100 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) * ixgbe_fc_autoneg - Configure flow control * @hw: pointer to hardware structure * - * Compares our advertised flow control capabilities to those advertised by - * our link partner, and determines the proper flow control mode to use. + * Negotiates flow control capabilities with link partner using autoneg and + * applies the results. **/ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) { s32 ret_val = 0; - ixgbe_link_speed speed; - u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; - bool link_up; + u32 i, reg, pcs_anadv_reg, pcs_lpab_reg; + + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); /* - * AN should have completed when the cable was plugged in. - * Look for reasons to bail out. Bail out if: - * - FC autoneg is disabled, or if - * - we don't have multispeed fiber, or if - * - we're not running at 1G, or if - * - link is not up, or if - * - link is up but AN did not complete, or if - * - link is up and AN completed but timed out - * - * Since we're being called from an LSC, link is already know to be up. - * So use link_up_wait_to_complete=false. + * The possible values of fc.current_mode are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but + * we do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * 4: Priority Flow Control is enabled. + * other: Invalid. */ - hw->mac.ops.check_link(hw, &speed, &link_up, false); - linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); - - if (hw->fc.disable_fc_autoneg || - !hw->phy.multispeed_fiber || - (speed != IXGBE_LINK_SPEED_1GB_FULL) || - !link_up || - ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || - ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) { - hw->fc.fc_was_autonegged = false; - hw->fc.current_mode = hw->fc.requested_mode; - hw_dbg(hw, "Autoneg FC was skipped.\n"); + switch (hw->fc.current_mode) { + case ixgbe_fc_none: + /* Flow control completely disabled by software override. */ + reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + break; + case ixgbe_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is + * disabled by software override. Since there really + * isn't a way to advertise that we are capable of RX + * Pause ONLY, we will advertise that we support both + * symmetric and asymmetric Rx PAUSE. Later, we will + * disable the adapter's ability to send PAUSE frames. + */ + reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + break; + case ixgbe_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is + * disabled by software override. + */ + reg |= (IXGBE_PCS1GANA_ASM_PAUSE); + reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); + break; + case ixgbe_fc_full: + /* Flow control (both Rx and Tx) is enabled by SW override. */ + reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); + break; +#ifdef CONFIG_DCB + case ixgbe_fc_pfc: + goto out; + break; +#endif + default: + hw_dbg(hw, "Flow control param set incorrectly\n"); + ret_val = -IXGBE_ERR_CONFIG; + goto out; + break; + } + + IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); + + /* Set PCS register for autoneg */ + /* Enable and restart autoneg */ + reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART; + + /* Disable AN timeout */ + if (hw->fc.strict_ieee) + reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; + + hw_dbg(hw, "Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg); + IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); + + /* See if autonegotiation has succeeded */ + hw->mac.autoneg_succeeded = 0; + for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { + msleep(10); + reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); + if ((reg & (IXGBE_PCS1GLSTA_LINK_OK | + IXGBE_PCS1GLSTA_AN_COMPLETE)) == + (IXGBE_PCS1GLSTA_LINK_OK | + IXGBE_PCS1GLSTA_AN_COMPLETE)) { + if (!(reg & IXGBE_PCS1GLSTA_AN_TIMED_OUT)) + hw->mac.autoneg_succeeded = 1; + break; + } + } + + if (!hw->mac.autoneg_succeeded) { + /* Autoneg failed to achieve a link, so we turn fc off */ + hw->fc.current_mode = ixgbe_fc_none; + hw_dbg(hw, "Flow Control = NONE.\n"); goto out; } @@ -1802,23 +1845,21 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw) hw_dbg(hw, "Flow Control = NONE.\n"); } - /* Record that current_mode is the result of a successful autoneg */ - hw->fc.fc_was_autonegged = true; - out: return ret_val; } /** - * ixgbe_setup_fc - Set up flow control + * ixgbe_setup_fc_generic - Set up flow control * @hw: pointer to hardware structure * - * Called at init time to set up flow control. + * Sets up flow control. **/ -s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) +s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num) { s32 ret_val = 0; - u32 reg; + ixgbe_link_speed speed; + bool link_up; #ifdef CONFIG_DCB if (hw->fc.requested_mode == ixgbe_fc_pfc) { @@ -1840,14 +1881,16 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) * because it causes the controller to just blast out fc packets. */ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { - hw_dbg(hw, "Invalid water mark configuration\n"); - ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; - goto out; + if (hw->fc.requested_mode != ixgbe_fc_none) { + hw_dbg(hw, "Invalid water mark configuration\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } } /* * Validate the requested mode. Strict IEEE mode does not allow - * ixgbe_fc_rx_pause because it will cause us to fail at UNH. + * ixgbe_fc_rx_pause because it will cause testing anomalies. */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict " @@ -1864,77 +1907,21 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) hw->fc.requested_mode = ixgbe_fc_full; /* - * Set up the 1G flow control advertisement registers so the HW will be - * able to do fc autoneg once the cable is plugged in. If we end up - * using 10g instead, this is harmless. + * Save off the requested flow control mode for use later. Depending + * on the link partner's capabilities, we may or may not use this mode. */ - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); + hw->fc.current_mode = hw->fc.requested_mode; - /* - * The possible values of fc.requested_mode are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but - * we do not support receiving pause frames). - * 3: Both Rx and Tx flow control (symmetric) are enabled. -#ifdef CONFIG_DCB - * 4: Priority Flow Control is enabled. -#endif - * other: Invalid. - */ - switch (hw->fc.requested_mode) { - case ixgbe_fc_none: - /* Flow control completely disabled by software override. */ - reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); - break; - case ixgbe_fc_rx_pause: - /* - * Rx Flow control is enabled and Tx Flow control is - * disabled by software override. Since there really - * isn't a way to advertise that we are capable of RX - * Pause ONLY, we will advertise that we support both - * symmetric and asymmetric Rx PAUSE. Later, we will - * disable the adapter's ability to send PAUSE frames. - */ - reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); - break; - case ixgbe_fc_tx_pause: - /* - * Tx Flow control is enabled, and Rx Flow control is - * disabled by software override. - */ - reg |= (IXGBE_PCS1GANA_ASM_PAUSE); - reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE); - break; - case ixgbe_fc_full: - /* Flow control (both Rx and Tx) is enabled by SW override. */ - reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE); - break; -#ifdef CONFIG_DCB - case ixgbe_fc_pfc: - goto out; - break; -#endif /* CONFIG_DCB */ - default: - hw_dbg(hw, "Flow control param set incorrectly\n"); - ret_val = -IXGBE_ERR_CONFIG; - goto out; - break; - } - - IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); - reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); - - /* Enable and restart autoneg to inform the link partner */ - reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART; + /* Decide whether to use autoneg or not. */ + hw->mac.ops.check_link(hw, &speed, &link_up, false); + if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber && + (speed == IXGBE_LINK_SPEED_1GB_FULL)) + ret_val = ixgbe_fc_autoneg(hw); - /* Disable AN timeout */ - if (hw->fc.strict_ieee) - reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; + if (ret_val) + goto out; - IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); - hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg); + ret_val = ixgbe_fc_enable(hw, packetbuf_num); out: return ret_val; @@ -2081,7 +2068,6 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) hw->mac.ops.check_link(hw, &speed, &link_up, false); if (!link_up) { - autoc_reg |= IXGBE_AUTOC_AN_RESTART; autoc_reg |= IXGBE_AUTOC_FLU; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); msleep(10); diff --git a/trunk/drivers/net/ixgbe/ixgbe_common.h b/trunk/drivers/net/ixgbe/ixgbe_common.h index 0d34d4d8244c..dd260890ad0a 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_common.h +++ b/trunk/drivers/net/ixgbe/ixgbe_common.h @@ -59,13 +59,13 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw); s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, ixgbe_mc_addr_itr func); -s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, - struct list_head *uc_list); +s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, + u32 addr_count, ixgbe_mc_addr_itr func); s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); -s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); -s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num); +s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num); +s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packtetbuf_num); s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw); s32 ixgbe_validate_mac_addr(u8 *mac_addr); diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c index 589f62c7062a..f4417fc3b0fd 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -295,7 +295,7 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, /* If PFC is disabled globally then fall back to LFC. */ if (!dcb_config->pfc_mode_enable) { for (i = 0; i < MAX_TRAFFIC_CLASS; i++) - hw->mac.ops.fc_enable(hw, i); + hw->mac.ops.setup_fc(hw, i); goto out; } diff --git a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c index 86f4f3e36f27..35255b8e90b7 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c @@ -68,8 +68,6 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)}, {"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)}, {"hw_rsc_count", IXGBE_STAT(rsc_count)}, - {"fdir_match", IXGBE_STAT(stats.fdirmatch)}, - {"fdir_miss", IXGBE_STAT(stats.fdirmiss)}, {"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)}, {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)}, {"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)}, @@ -120,13 +118,6 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { IXGBE_PB_STATS_LEN + \ IXGBE_QUEUE_STATS_LEN) -static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = { - "Register test (offline)", "Eeprom test (offline)", - "Interrupt test (offline)", "Loopback test (offline)", - "Link test (on/offline)" -}; -#define IXGBE_TEST_LEN sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN - static int ixgbe_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { @@ -138,12 +129,11 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->autoneg = AUTONEG_ENABLE; ecmd->transceiver = XCVR_EXTERNAL; - if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->mac.type == ixgbe_mac_82599EB)) { + if (hw->phy.media_type == ixgbe_media_type_copper) { ecmd->supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg); + SUPPORTED_TP | SUPPORTED_Autoneg); - ecmd->advertising = ADVERTISED_Autoneg; + ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg); if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) ecmd->advertising |= ADVERTISED_10000baseT_Full; if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) @@ -158,15 +148,7 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->advertising |= (ADVERTISED_10000baseT_Full | ADVERTISED_1000baseT_Full); - if (hw->phy.media_type == ixgbe_media_type_copper) { - ecmd->supported |= SUPPORTED_TP; - ecmd->advertising |= ADVERTISED_TP; - ecmd->port = PORT_TP; - } else { - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising |= ADVERTISED_FIBRE; - ecmd->port = PORT_FIBRE; - } + ecmd->port = PORT_TP; } else if (hw->phy.media_type == ixgbe_media_type_backplane) { /* Set as FIBRE until SERDES defined in kernel */ switch (hw->device_id) { @@ -214,10 +196,16 @@ static int ixgbe_set_settings(struct net_device *netdev, struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; u32 advertised, old; - s32 err = 0; + s32 err; - if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->mac.type == ixgbe_mac_82599EB)) { + switch (hw->phy.media_type) { + case ixgbe_media_type_fiber: + if ((ecmd->autoneg == AUTONEG_ENABLE) || + (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) + return -EINVAL; + /* in this case we currently only support 10Gb/FULL */ + break; + case ixgbe_media_type_copper: /* 10000/copper and 1000/copper must autoneg * this function does not support any duplex forcing, but can * limit the advertising of the adapter to only 10000 or 1000 */ @@ -233,23 +221,20 @@ static int ixgbe_set_settings(struct net_device *netdev, advertised |= IXGBE_LINK_SPEED_1GB_FULL; if (old == advertised) - return err; + break; /* this sets the link speed and restarts auto-neg */ - hw->mac.autotry_restart = true; err = hw->mac.ops.setup_link_speed(hw, advertised, true, true); if (err) { DPRINTK(PROBE, INFO, "setup link failed with code %d\n", err); hw->mac.ops.setup_link_speed(hw, old, true, true); } - } else { - /* in this case we currently only support 10Gb/FULL */ - if ((ecmd->autoneg == AUTONEG_ENABLE) || - (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) - return -EINVAL; + break; + default: + break; } - return err; + return 0; } static void ixgbe_get_pauseparam(struct net_device *netdev, @@ -291,7 +276,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_fc_info fc; #ifdef CONFIG_DCB if (adapter->dcb_cfg.pfc_mode_enable || @@ -300,37 +284,26 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, return -EINVAL; #endif - - fc = hw->fc; - if (pause->autoneg != AUTONEG_ENABLE) - fc.disable_fc_autoneg = true; + hw->fc.disable_fc_autoneg = true; else - fc.disable_fc_autoneg = false; + hw->fc.disable_fc_autoneg = false; if (pause->rx_pause && pause->tx_pause) - fc.requested_mode = ixgbe_fc_full; + hw->fc.requested_mode = ixgbe_fc_full; else if (pause->rx_pause && !pause->tx_pause) - fc.requested_mode = ixgbe_fc_rx_pause; + hw->fc.requested_mode = ixgbe_fc_rx_pause; else if (!pause->rx_pause && pause->tx_pause) - fc.requested_mode = ixgbe_fc_tx_pause; + hw->fc.requested_mode = ixgbe_fc_tx_pause; else if (!pause->rx_pause && !pause->tx_pause) - fc.requested_mode = ixgbe_fc_none; + hw->fc.requested_mode = ixgbe_fc_none; else return -EINVAL; #ifdef CONFIG_DCB - adapter->last_lfc_mode = fc.requested_mode; + adapter->last_lfc_mode = hw->fc.requested_mode; #endif - - /* if the thing changed then we'll update and use new autoneg */ - if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) { - hw->fc = fc; - if (netif_running(netdev)) - ixgbe_reinit_locked(adapter); - else - ixgbe_reset(adapter); - } + hw->mac.ops.setup_fc(hw, 0); return 0; } @@ -770,7 +743,6 @@ static void ixgbe_get_drvinfo(struct net_device *netdev, strncpy(drvinfo->fw_version, firmware_version, 32); strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); drvinfo->n_stats = IXGBE_STATS_LEN; - drvinfo->testinfo_len = IXGBE_TEST_LEN; drvinfo->regdump_len = ixgbe_get_regs_len(netdev); } @@ -842,6 +814,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, } goto err_setup; } + temp_tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; } need_update = true; } @@ -871,6 +844,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, } goto err_setup; } + temp_rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; } need_update = true; } @@ -910,8 +884,6 @@ static int ixgbe_set_ringparam(struct net_device *netdev, static int ixgbe_get_sset_count(struct net_device *netdev, int sset) { switch (sset) { - case ETH_SS_TEST: - return IXGBE_TEST_LEN; case ETH_SS_STATS: return IXGBE_STATS_LEN; default: @@ -966,10 +938,6 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, int i; switch (stringset) { - case ETH_SS_TEST: - memcpy(data, *ixgbe_gstrings_test, - IXGBE_TEST_LEN * ETH_GSTRING_LEN); - break; case ETH_SS_STATS: for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { memcpy(p, ixgbe_gstrings_stats[i].stat_string, @@ -1007,815 +975,6 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, } } -static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data) -{ - struct ixgbe_hw *hw = &adapter->hw; - bool link_up; - u32 link_speed = 0; - *data = 0; - - hw->mac.ops.check_link(hw, &link_speed, &link_up, true); - if (link_up) - return *data; - else - *data = 1; - return *data; -} - -/* ethtool register test data */ -struct ixgbe_reg_test { - u16 reg; - u8 array_len; - u8 test_type; - u32 mask; - u32 write; -}; - -/* In the hardware, registers are laid out either singly, in arrays - * spaced 0x40 bytes apart, or in contiguous tables. We assume - * most tests take place on arrays or single registers (handled - * as a single-element array) and special-case the tables. - * Table tests are always pattern tests. - * - * We also make provision for some required setup steps by specifying - * registers to be written without any read-back testing. - */ - -#define PATTERN_TEST 1 -#define SET_READ_TEST 2 -#define WRITE_NO_TEST 3 -#define TABLE32_TEST 4 -#define TABLE64_TEST_LO 5 -#define TABLE64_TEST_HI 6 - -/* default 82599 register test */ -static struct ixgbe_reg_test reg_test_82599[] = { - { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, - { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, - { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 }, - { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 }, - { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, - { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, - { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, - { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 }, - { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, - { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, - { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFF80 }, - { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000001, 0x00000001 }, - { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x8001FFFF, 0x800CFFFF }, - { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { 0, 0, 0, 0 } -}; - -/* default 82598 register test */ -static struct ixgbe_reg_test reg_test_82598[] = { - { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, - { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, - { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 }, - { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, - { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, - /* Enable all four RX queues before testing. */ - { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE }, - /* RDH is read-only for 82598, only test RDT. */ - { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF }, - { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 }, - { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 }, - { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_TIPG, 1, PATTERN_TEST, 0x000000FF, 0x000000FF }, - { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF }, - { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF }, - { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000003, 0x00000003 }, - { IXGBE_DTXCTL, 1, SET_READ_TEST, 0x00000005, 0x00000005 }, - { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF }, - { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x800CFFFF, 0x800CFFFF }, - { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF }, - { 0, 0, 0, 0 } -}; - -#define REG_PATTERN_TEST(R, M, W) \ -{ \ - u32 pat, val, before; \ - const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ - for (pat = 0; pat < ARRAY_SIZE(_test); pat++) { \ - before = readl(adapter->hw.hw_addr + R); \ - writel((_test[pat] & W), (adapter->hw.hw_addr + R)); \ - val = readl(adapter->hw.hw_addr + R); \ - if (val != (_test[pat] & W & M)) { \ - DPRINTK(DRV, ERR, "pattern test reg %04X failed: got "\ - "0x%08X expected 0x%08X\n", \ - R, val, (_test[pat] & W & M)); \ - *data = R; \ - writel(before, adapter->hw.hw_addr + R); \ - return 1; \ - } \ - writel(before, adapter->hw.hw_addr + R); \ - } \ -} - -#define REG_SET_AND_CHECK(R, M, W) \ -{ \ - u32 val, before; \ - before = readl(adapter->hw.hw_addr + R); \ - writel((W & M), (adapter->hw.hw_addr + R)); \ - val = readl(adapter->hw.hw_addr + R); \ - if ((W & M) != (val & M)) { \ - DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\ - "expected 0x%08X\n", R, (val & M), (W & M)); \ - *data = R; \ - writel(before, (adapter->hw.hw_addr + R)); \ - return 1; \ - } \ - writel(before, (adapter->hw.hw_addr + R)); \ -} - -static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) -{ - struct ixgbe_reg_test *test; - u32 value, before, after; - u32 i, toggle; - - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - toggle = 0x7FFFF30F; - test = reg_test_82599; - } else { - toggle = 0x7FFFF3FF; - test = reg_test_82598; - } - - /* - * Because the status register is such a special case, - * we handle it separately from the rest of the register - * tests. Some bits are read-only, some toggle, and some - * are writeable on newer MACs. - */ - before = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS); - value = (IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, toggle); - after = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle; - if (value != after) { - DPRINTK(DRV, ERR, "failed STATUS register test got: " - "0x%08X expected: 0x%08X\n", after, value); - *data = 1; - return 1; - } - /* restore previous status */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, before); - - /* - * Perform the remainder of the register test, looping through - * the test table until we either fail or reach the null entry. - */ - while (test->reg) { - for (i = 0; i < test->array_len; i++) { - switch (test->test_type) { - case PATTERN_TEST: - REG_PATTERN_TEST(test->reg + (i * 0x40), - test->mask, - test->write); - break; - case SET_READ_TEST: - REG_SET_AND_CHECK(test->reg + (i * 0x40), - test->mask, - test->write); - break; - case WRITE_NO_TEST: - writel(test->write, - (adapter->hw.hw_addr + test->reg) - + (i * 0x40)); - break; - case TABLE32_TEST: - REG_PATTERN_TEST(test->reg + (i * 4), - test->mask, - test->write); - break; - case TABLE64_TEST_LO: - REG_PATTERN_TEST(test->reg + (i * 8), - test->mask, - test->write); - break; - case TABLE64_TEST_HI: - REG_PATTERN_TEST((test->reg + 4) + (i * 8), - test->mask, - test->write); - break; - } - } - test++; - } - - *data = 0; - return 0; -} - -static int ixgbe_eeprom_test(struct ixgbe_adapter *adapter, u64 *data) -{ - struct ixgbe_hw *hw = &adapter->hw; - if (hw->eeprom.ops.validate_checksum(hw, NULL)) - *data = 1; - else - *data = 0; - return *data; -} - -static irqreturn_t ixgbe_test_intr(int irq, void *data) -{ - struct net_device *netdev = (struct net_device *) data; - struct ixgbe_adapter *adapter = netdev_priv(netdev); - - adapter->test_icr |= IXGBE_READ_REG(&adapter->hw, IXGBE_EICR); - - return IRQ_HANDLED; -} - -static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) -{ - struct net_device *netdev = adapter->netdev; - u32 mask, i = 0, shared_int = true; - u32 irq = adapter->pdev->irq; - - *data = 0; - - /* Hook up test interrupt handler just for this test */ - if (adapter->msix_entries) { - /* NOTE: we don't test MSI-X interrupts here, yet */ - return 0; - } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { - shared_int = false; - if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name, - netdev)) { - *data = 1; - return -1; - } - } else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED, - netdev->name, netdev)) { - shared_int = false; - } else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED, - netdev->name, netdev)) { - *data = 1; - return -1; - } - DPRINTK(HW, INFO, "testing %s interrupt\n", - (shared_int ? "shared" : "unshared")); - - /* Disable all the interrupts */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); - msleep(10); - - /* Test each interrupt */ - for (; i < 10; i++) { - /* Interrupt to test */ - mask = 1 << i; - - if (!shared_int) { - /* - * Disable the interrupts to be reported in - * the cause register and then force the same - * interrupt and see if one gets posted. If - * an interrupt was posted to the bus, the - * test failed. - */ - adapter->test_icr = 0; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, - ~mask & 0x00007FFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, - ~mask & 0x00007FFF); - msleep(10); - - if (adapter->test_icr & mask) { - *data = 3; - break; - } - } - - /* - * Enable the interrupt to be reported in the cause - * register and then force the same interrupt and see - * if one gets posted. If an interrupt was not posted - * to the bus, the test failed. - */ - adapter->test_icr = 0; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); - msleep(10); - - if (!(adapter->test_icr &mask)) { - *data = 4; - break; - } - - if (!shared_int) { - /* - * Disable the other interrupts to be reported in - * the cause register and then force the other - * interrupts and see if any get posted. If - * an interrupt was posted to the bus, the - * test failed. - */ - adapter->test_icr = 0; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, - ~mask & 0x00007FFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, - ~mask & 0x00007FFF); - msleep(10); - - if (adapter->test_icr) { - *data = 5; - break; - } - } - } - - /* Disable all the interrupts */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); - msleep(10); - - /* Unhook test interrupt handler */ - free_irq(irq, netdev); - - return *data; -} - -static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) -{ - struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; - struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; - struct ixgbe_hw *hw = &adapter->hw; - struct pci_dev *pdev = adapter->pdev; - u32 reg_ctl; - int i; - - /* shut down the DMA engines now so they can be reinitialized later */ - - /* first Rx */ - reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); - reg_ctl &= ~IXGBE_RXCTRL_RXEN; - IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl); - reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0)); - reg_ctl &= ~IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl); - - /* now Tx */ - reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0)); - reg_ctl &= ~IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl); - if (hw->mac.type == ixgbe_mac_82599EB) { - reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); - reg_ctl &= ~IXGBE_DMATXCTL_TE; - IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl); - } - - ixgbe_reset(adapter); - - if (tx_ring->desc && tx_ring->tx_buffer_info) { - for (i = 0; i < tx_ring->count; i++) { - struct ixgbe_tx_buffer *buf = - &(tx_ring->tx_buffer_info[i]); - if (buf->dma) - pci_unmap_single(pdev, buf->dma, buf->length, - PCI_DMA_TODEVICE); - if (buf->skb) - dev_kfree_skb(buf->skb); - } - } - - if (rx_ring->desc && rx_ring->rx_buffer_info) { - for (i = 0; i < rx_ring->count; i++) { - struct ixgbe_rx_buffer *buf = - &(rx_ring->rx_buffer_info[i]); - if (buf->dma) - pci_unmap_single(pdev, buf->dma, - IXGBE_RXBUFFER_2048, - PCI_DMA_FROMDEVICE); - if (buf->skb) - dev_kfree_skb(buf->skb); - } - } - - if (tx_ring->desc) { - pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, - tx_ring->dma); - tx_ring->desc = NULL; - } - if (rx_ring->desc) { - pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, - rx_ring->dma); - rx_ring->desc = NULL; - } - - kfree(tx_ring->tx_buffer_info); - tx_ring->tx_buffer_info = NULL; - kfree(rx_ring->rx_buffer_info); - rx_ring->rx_buffer_info = NULL; - - return; -} - -static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) -{ - struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; - struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; - struct pci_dev *pdev = adapter->pdev; - u32 rctl, reg_data; - int i, ret_val; - - /* Setup Tx descriptor ring and Tx buffers */ - - if (!tx_ring->count) - tx_ring->count = IXGBE_DEFAULT_TXD; - - tx_ring->tx_buffer_info = kcalloc(tx_ring->count, - sizeof(struct ixgbe_tx_buffer), - GFP_KERNEL); - if (!(tx_ring->tx_buffer_info)) { - ret_val = 1; - goto err_nomem; - } - - tx_ring->size = tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc); - tx_ring->size = ALIGN(tx_ring->size, 4096); - if (!(tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size, - &tx_ring->dma))) { - ret_val = 2; - goto err_nomem; - } - tx_ring->next_to_use = tx_ring->next_to_clean = 0; - - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0), - ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0), - ((u64) tx_ring->dma >> 32)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0), - tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data |= IXGBE_HLREG0_TXPADEN; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); - - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); - reg_data |= IXGBE_DMATXCTL_TE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); - } - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0)); - reg_data |= IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data); - - for (i = 0; i < tx_ring->count; i++) { - struct ixgbe_legacy_tx_desc *desc = IXGBE_TX_DESC(*tx_ring, i); - struct sk_buff *skb; - unsigned int size = 1024; - - skb = alloc_skb(size, GFP_KERNEL); - if (!skb) { - ret_val = 3; - goto err_nomem; - } - skb_put(skb, size); - tx_ring->tx_buffer_info[i].skb = skb; - tx_ring->tx_buffer_info[i].length = skb->len; - tx_ring->tx_buffer_info[i].dma = - pci_map_single(pdev, skb->data, skb->len, - PCI_DMA_TODEVICE); - desc->buffer_addr = cpu_to_le64(tx_ring->tx_buffer_info[i].dma); - desc->lower.data = cpu_to_le32(skb->len); - desc->lower.data |= cpu_to_le32(IXGBE_TXD_CMD_EOP | - IXGBE_TXD_CMD_IFCS | - IXGBE_TXD_CMD_RS); - desc->upper.data = 0; - } - - /* Setup Rx Descriptor ring and Rx buffers */ - - if (!rx_ring->count) - rx_ring->count = IXGBE_DEFAULT_RXD; - - rx_ring->rx_buffer_info = kcalloc(rx_ring->count, - sizeof(struct ixgbe_rx_buffer), - GFP_KERNEL); - if (!(rx_ring->rx_buffer_info)) { - ret_val = 4; - goto err_nomem; - } - - rx_ring->size = rx_ring->count * sizeof(struct ixgbe_legacy_rx_desc); - rx_ring->size = ALIGN(rx_ring->size, 4096); - if (!(rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size, - &rx_ring->dma))) { - ret_val = 5; - goto err_nomem; - } - rx_ring->next_to_use = rx_ring->next_to_clean = 0; - - rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0), - ((u64)rx_ring->dma & 0xFFFFFFFF)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0), - ((u64) rx_ring->dma >> 32)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); - reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data &= ~IXGBE_HLREG0_LPBK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL); -#define IXGBE_RDRXCTL_RDMTS_MASK 0x00000003 /* Receive Descriptor Minimum - Threshold Size mask */ - reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL); -#define IXGBE_MCSTCTRL_MO_MASK 0x00000003 /* Multicast Offset mask */ - reg_data &= ~IXGBE_MCSTCTRL_MO_MASK; - reg_data |= adapter->hw.mac.mc_filter_type; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0)); - reg_data |= IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - int j = adapter->rx_ring[0].reg_idx; - u32 k; - for (k = 0; k < 10; k++) { - if (IXGBE_READ_REG(&adapter->hw, - IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE) - break; - else - msleep(1); - } - } - - rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl); - - for (i = 0; i < rx_ring->count; i++) { - struct ixgbe_legacy_rx_desc *rx_desc = - IXGBE_RX_DESC(*rx_ring, i); - struct sk_buff *skb; - - skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); - if (!skb) { - ret_val = 6; - goto err_nomem; - } - skb_reserve(skb, NET_IP_ALIGN); - rx_ring->rx_buffer_info[i].skb = skb; - rx_ring->rx_buffer_info[i].dma = - pci_map_single(pdev, skb->data, IXGBE_RXBUFFER_2048, - PCI_DMA_FROMDEVICE); - rx_desc->buffer_addr = - cpu_to_le64(rx_ring->rx_buffer_info[i].dma); - memset(skb->data, 0x00, skb->len); - } - - return 0; - -err_nomem: - ixgbe_free_desc_rings(adapter); - return ret_val; -} - -static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 reg_data; - - /* right now we only support MAC loopback in the driver */ - - /* Setup MAC loopback */ - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data |= IXGBE_HLREG0_LPBK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC); - reg_data &= ~IXGBE_AUTOC_LMS_MASK; - reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data); - - /* Disable Atlas Tx lanes; re-enabled in reset path */ - if (hw->mac.type == ixgbe_mac_82598EB) { - u8 atlas; - - hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &atlas); - atlas |= IXGBE_ATLAS_PDN_TX_REG_EN; - hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, atlas); - - hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &atlas); - atlas |= IXGBE_ATLAS_PDN_TX_10G_QL_ALL; - hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, atlas); - - hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &atlas); - atlas |= IXGBE_ATLAS_PDN_TX_1G_QL_ALL; - hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, atlas); - - hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &atlas); - atlas |= IXGBE_ATLAS_PDN_TX_AN_QL_ALL; - hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, atlas); - } - - return 0; -} - -static void ixgbe_loopback_cleanup(struct ixgbe_adapter *adapter) -{ - u32 reg_data; - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data &= ~IXGBE_HLREG0_LPBK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); -} - -static void ixgbe_create_lbtest_frame(struct sk_buff *skb, - unsigned int frame_size) -{ - memset(skb->data, 0xFF, frame_size); - frame_size &= ~1; - memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); - memset(&skb->data[frame_size / 2 + 10], 0xBE, 1); - memset(&skb->data[frame_size / 2 + 12], 0xAF, 1); -} - -static int ixgbe_check_lbtest_frame(struct sk_buff *skb, - unsigned int frame_size) -{ - frame_size &= ~1; - if (*(skb->data + 3) == 0xFF) { - if ((*(skb->data + frame_size / 2 + 10) == 0xBE) && - (*(skb->data + frame_size / 2 + 12) == 0xAF)) { - return 0; - } - } - return 13; -} - -static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) -{ - struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; - struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; - struct pci_dev *pdev = adapter->pdev; - int i, j, k, l, lc, good_cnt, ret_val = 0; - unsigned long time; - - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1); - - /* - * Calculate the loop count based on the largest descriptor ring - * The idea is to wrap the largest ring a number of times using 64 - * send/receive pairs during each loop - */ - - if (rx_ring->count <= tx_ring->count) - lc = ((tx_ring->count / 64) * 2) + 1; - else - lc = ((rx_ring->count / 64) * 2) + 1; - - k = l = 0; - for (j = 0; j <= lc; j++) { - for (i = 0; i < 64; i++) { - ixgbe_create_lbtest_frame( - tx_ring->tx_buffer_info[k].skb, - 1024); - pci_dma_sync_single_for_device(pdev, - tx_ring->tx_buffer_info[k].dma, - tx_ring->tx_buffer_info[k].length, - PCI_DMA_TODEVICE); - if (unlikely(++k == tx_ring->count)) - k = 0; - } - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k); - msleep(200); - /* set the start time for the receive */ - time = jiffies; - good_cnt = 0; - do { - /* receive the sent packets */ - pci_dma_sync_single_for_cpu(pdev, - rx_ring->rx_buffer_info[l].dma, - IXGBE_RXBUFFER_2048, - PCI_DMA_FROMDEVICE); - ret_val = ixgbe_check_lbtest_frame( - rx_ring->rx_buffer_info[l].skb, 1024); - if (!ret_val) - good_cnt++; - if (++l == rx_ring->count) - l = 0; - /* - * time + 20 msecs (200 msecs on 2.4) is more than - * enough time to complete the receives, if it's - * exceeded, break and error off - */ - } while (good_cnt < 64 && jiffies < (time + 20)); - if (good_cnt != 64) { - /* ret_val is the same as mis-compare */ - ret_val = 13; - break; - } - if (jiffies >= (time + 20)) { - /* Error code for time out error */ - ret_val = 14; - break; - } - } - - return ret_val; -} - -static int ixgbe_loopback_test(struct ixgbe_adapter *adapter, u64 *data) -{ - *data = ixgbe_setup_desc_rings(adapter); - if (*data) - goto out; - *data = ixgbe_setup_loopback_test(adapter); - if (*data) - goto err_loopback; - *data = ixgbe_run_loopback_test(adapter); - ixgbe_loopback_cleanup(adapter); - -err_loopback: - ixgbe_free_desc_rings(adapter); -out: - return *data; -} - -static void ixgbe_diag_test(struct net_device *netdev, - struct ethtool_test *eth_test, u64 *data) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - bool if_running = netif_running(netdev); - - set_bit(__IXGBE_TESTING, &adapter->state); - if (eth_test->flags == ETH_TEST_FL_OFFLINE) { - /* Offline tests */ - - DPRINTK(HW, INFO, "offline testing starting\n"); - - /* Link test performed before hardware reset so autoneg doesn't - * interfere with test result */ - if (ixgbe_link_test(adapter, &data[4])) - eth_test->flags |= ETH_TEST_FL_FAILED; - - if (if_running) - /* indicate we're in test mode */ - dev_close(netdev); - else - ixgbe_reset(adapter); - - DPRINTK(HW, INFO, "register testing starting\n"); - if (ixgbe_reg_test(adapter, &data[0])) - eth_test->flags |= ETH_TEST_FL_FAILED; - - ixgbe_reset(adapter); - DPRINTK(HW, INFO, "eeprom testing starting\n"); - if (ixgbe_eeprom_test(adapter, &data[1])) - eth_test->flags |= ETH_TEST_FL_FAILED; - - ixgbe_reset(adapter); - DPRINTK(HW, INFO, "interrupt testing starting\n"); - if (ixgbe_intr_test(adapter, &data[2])) - eth_test->flags |= ETH_TEST_FL_FAILED; - - ixgbe_reset(adapter); - DPRINTK(HW, INFO, "loopback testing starting\n"); - if (ixgbe_loopback_test(adapter, &data[3])) - eth_test->flags |= ETH_TEST_FL_FAILED; - - ixgbe_reset(adapter); - - clear_bit(__IXGBE_TESTING, &adapter->state); - if (if_running) - dev_open(netdev); - } else { - DPRINTK(HW, INFO, "online testing starting\n"); - /* Online tests */ - if (ixgbe_link_test(adapter, &data[4])) - eth_test->flags |= ETH_TEST_FL_FAILED; - - /* Online tests aren't run; pass by default */ - data[0] = 0; - data[1] = 0; - data[2] = 0; - data[3] = 0; - - clear_bit(__IXGBE_TESTING, &adapter->state); - } - msleep_interruptible(4 * 1000); -} static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, struct ethtool_wolinfo *wol) @@ -1987,7 +1146,8 @@ static int ixgbe_set_coalesce(struct net_device *netdev, else /* rx only or mixed */ q_vector->eitr = adapter->eitr_param; - ixgbe_write_eitr(q_vector); + ixgbe_write_eitr(adapter, i, + EITR_INTS_PER_SEC_TO_REG(q_vector->eitr)); } return 0; @@ -1999,13 +1159,13 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) ethtool_op_set_flags(netdev, data); - if (!(adapter->flags & IXGBE_FLAG2_RSC_CAPABLE)) + if (!(adapter->flags & IXGBE_FLAG_RSC_CAPABLE)) return 0; /* if state changes we need to update adapter->flags and reset */ if ((!!(data & ETH_FLAG_LRO)) != - (!!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED))) { - adapter->flags ^= IXGBE_FLAG2_RSC_ENABLED; + (!!(adapter->flags & IXGBE_FLAG_RSC_ENABLED))) { + adapter->flags ^= IXGBE_FLAG_RSC_ENABLED; if (netif_running(netdev)) ixgbe_reinit_locked(adapter); else @@ -2041,7 +1201,6 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .set_msglevel = ixgbe_set_msglevel, .get_tso = ethtool_op_get_tso, .set_tso = ixgbe_set_tso, - .self_test = ixgbe_diag_test, .get_strings = ixgbe_get_strings, .phys_id = ixgbe_phys_id, .get_sset_count = ixgbe_get_sset_count, diff --git a/trunk/drivers/net/ixgbe/ixgbe_fcoe.c b/trunk/drivers/net/ixgbe/ixgbe_fcoe.c index 3c3bf1f07b81..d5939de8ba28 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/trunk/drivers/net/ixgbe/ixgbe_fcoe.c @@ -280,9 +280,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, * * This checks ddp status. * - * Returns : < 0 indicates an error or not a FCiE ddp, 0 indicates - * not passing the skb to ULD, > 0 indicates is the length of data - * being ddped. + * Returns : 0 for success and skb will not be delivered to ULD */ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, @@ -336,8 +334,6 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, /* return 0 to bypass going to ULD for DDPed data */ if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP) rc = 0; - else - rc = ddp->len; } ddp_out: diff --git a/trunk/drivers/net/ixgbe/ixgbe_fcoe.h b/trunk/drivers/net/ixgbe/ixgbe_fcoe.h index c5b50026a897..b7f9b63aa49f 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/trunk/drivers/net/ixgbe/ixgbe_fcoe.h @@ -28,7 +28,6 @@ #ifndef _IXGBE_FCOE_H #define _IXGBE_FCOE_H -#include #include /* shift bits within STAT fo FCSTAT */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index a551a96ce676..dff1da8ae5c4 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = "Intel(R) 10 Gigabit PCI Express Network Driver"; -#define DRV_VERSION "2.0.34-k2" +#define DRV_VERSION "2.0.24-k2" const char ixgbe_driver_version[] = DRV_VERSION; static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation."; @@ -186,22 +186,6 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, } } -static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, - u64 qmask) -{ - u32 mask; - - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - mask = (IXGBE_EIMS_RTX_QUEUE & qmask); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); - } else { - mask = (qmask & 0xFFFFFFFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); - mask = (qmask >> 32); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask); - } -} - static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, struct ixgbe_tx_buffer *tx_buffer_info) @@ -264,13 +248,14 @@ static void ixgbe_tx_timeout(struct net_device *netdev); /** * ixgbe_clean_tx_irq - Reclaim resources after transmit completes - * @q_vector: structure containing interrupt and ring information + * @adapter: board private structure * @tx_ring: tx ring to clean + * + * returns true if transmit work is done **/ -static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, +static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring) { - struct ixgbe_adapter *adapter = q_vector->adapter; struct net_device *netdev = adapter->netdev; union ixgbe_adv_tx_desc *tx_desc, *eop_desc; struct ixgbe_tx_buffer *tx_buffer_info; @@ -293,24 +278,12 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, if (cleaned && skb) { unsigned int segs, bytecount; - unsigned int hlen = skb_headlen(skb); /* gso_segs is currently only valid for tcp */ segs = skb_shinfo(skb)->gso_segs ?: 1; -#ifdef IXGBE_FCOE - /* adjust for FCoE Sequence Offload */ - if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) - && (skb->protocol == htons(ETH_P_FCOE)) && - skb_is_gso(skb)) { - hlen = skb_transport_offset(skb) + - sizeof(struct fc_frame_header) + - sizeof(struct fcoe_crc_eof); - segs = DIV_ROUND_UP(skb->len - hlen, - skb_shinfo(skb)->gso_size); - } -#endif /* IXGBE_FCOE */ /* multiply data chunks by size of headers */ - bytecount = ((segs - 1) * hlen) + skb->len; + bytecount = ((segs - 1) * skb_headlen(skb)) + + skb->len; total_packets += segs; total_bytes += bytecount; } @@ -356,8 +329,18 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } /* re-arm the interrupt */ - if (count >= tx_ring->work_limit) - ixgbe_irq_rearm_queues(adapter, ((u64)1 << q_vector->v_idx)); + if (count >= tx_ring->work_limit) { + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, + tx_ring->v_idx); + else if (tx_ring->v_idx & 0xFFFFFFFF) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), + tx_ring->v_idx); + else + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), + (tx_ring->v_idx >> 32)); + } + tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; @@ -695,9 +678,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, bool cleaned = false; int cleaned_count = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0; -#ifdef IXGBE_FCOE - int ddp_bytes = 0; -#endif /* IXGBE_FCOE */ i = rx_ring->next_to_clean; rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); @@ -728,7 +708,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(skb->data - NET_IP_ALIGN); rx_buffer_info->skb = NULL; - if (rx_buffer_info->dma) { + if (len && !skb_shinfo(skb)->nr_frags) { pci_unmap_single(pdev, rx_buffer_info->dma, rx_ring->rx_buf_len, PCI_DMA_FROMDEVICE); @@ -763,7 +743,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (adapter->flags & IXGBE_FLAG2_RSC_CAPABLE) + if (adapter->flags & IXGBE_FLAG_RSC_CAPABLE) rsc_count = ixgbe_get_rsc_count(rx_desc); if (rsc_count) { @@ -808,11 +788,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, skb->protocol = eth_type_trans(skb, adapter->netdev); #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); - if (!ddp_bytes) + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) + if (!ixgbe_fcoe_ddp(adapter, rx_desc, skb)) goto next_desc; - } #endif /* IXGBE_FCOE */ ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); @@ -838,21 +816,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (cleaned_count) ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); -#ifdef IXGBE_FCOE - /* include DDPed FCoE data */ - if (ddp_bytes > 0) { - unsigned int mss; - - mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) - - sizeof(struct fc_frame_header) - - sizeof(struct fcoe_crc_eof); - if (mss > 512) - mss &= ~511; - total_rx_bytes += ddp_bytes; - total_rx_packets += DIV_ROUND_UP(ddp_bytes, mss); - } -#endif /* IXGBE_FCOE */ - rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; adapter->net_stats.rx_bytes += total_rx_bytes; @@ -912,7 +875,12 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) /* rx only */ q_vector->eitr = adapter->eitr_param; - ixgbe_write_eitr(q_vector); + /* + * since this is initial set up don't need to call + * ixgbe_write_eitr helper + */ + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), + EITR_INTS_PER_SEC_TO_REG(q_vector->eitr)); } if (adapter->hw.mac.type == ixgbe_mac_82598EB) @@ -997,19 +965,17 @@ static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, /** * ixgbe_write_eitr - write EITR register in hardware specific way - * @q_vector: structure containing interrupt and ring information + * @adapter: pointer to adapter struct + * @v_idx: vector index into q_vector array + * @itr_reg: new value to be written in *register* format, not ints/s * * This function is made to be called by ethtool and by the driver * when it needs to update EITR registers at runtime. Hardware * specific quirks/differences are taken care of here. */ -void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) +void ixgbe_write_eitr(struct ixgbe_adapter *adapter, int v_idx, u32 itr_reg) { - struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_hw *hw = &adapter->hw; - int v_idx = q_vector->v_idx; - u32 itr_reg = EITR_INTS_PER_SEC_TO_REG(q_vector->eitr); - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { /* must write high and low 16 bits to reset counter */ itr_reg |= (itr_reg << 16); @@ -1028,7 +994,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) struct ixgbe_adapter *adapter = q_vector->adapter; u32 new_itr; u8 current_itr, ret_itr; - int i, r_idx; + int i, r_idx, v_idx = q_vector->v_idx; struct ixgbe_ring *rx_ring, *tx_ring; r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); @@ -1078,13 +1044,14 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) } if (new_itr != q_vector->eitr) { - /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); + u32 itr_reg; /* save the algorithm value here, not the smoothed one */ q_vector->eitr = new_itr; - - ixgbe_write_eitr(q_vector); + /* do an exponential smoothing */ + new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); + itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr); + ixgbe_write_eitr(adapter, v_idx, itr_reg); } return; @@ -1155,64 +1122,14 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) if (hw->mac.type == ixgbe_mac_82598EB) ixgbe_check_fan_failure(adapter, eicr); - if (hw->mac.type == ixgbe_mac_82599EB) { + if (hw->mac.type == ixgbe_mac_82599EB) ixgbe_check_sfp_event(adapter, eicr); - - /* Handle Flow Director Full threshold interrupt */ - if (eicr & IXGBE_EICR_FLOW_DIR) { - int i; - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR); - /* Disable transmits before FDIR Re-initialization */ - netif_tx_stop_all_queues(netdev); - for (i = 0; i < adapter->num_tx_queues; i++) { - struct ixgbe_ring *tx_ring = - &adapter->tx_ring[i]; - if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) - schedule_work(&adapter->fdir_reinit_task); - } - } - } if (!test_bit(__IXGBE_DOWN, &adapter->state)) IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); return IRQ_HANDLED; } -static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, - u64 qmask) -{ - u32 mask; - - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - mask = (IXGBE_EIMS_RTX_QUEUE & qmask); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); - } else { - mask = (qmask & 0xFFFFFFFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask); - mask = (qmask >> 32); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask); - } - /* skip the flush */ -} - -static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, - u64 qmask) -{ - u32 mask; - - if (adapter->hw.mac.type == ixgbe_mac_82598EB) { - mask = (IXGBE_EIMS_RTX_QUEUE & qmask); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask); - } else { - mask = (qmask & 0xFFFFFFFF); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), mask); - mask = (qmask >> 32); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), mask); - } - /* skip the flush */ -} - static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) { struct ixgbe_q_vector *q_vector = data; @@ -1226,16 +1143,17 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { tx_ring = &(adapter->tx_ring[r_idx]); +#ifdef CONFIG_IXGBE_DCA + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_tx_dca(adapter, tx_ring); +#endif tx_ring->total_bytes = 0; tx_ring->total_packets = 0; + ixgbe_clean_tx_irq(adapter, tx_ring); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, r_idx + 1); } - /* disable interrupts on this vector only */ - ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx)); - napi_schedule(&q_vector->napi); - return IRQ_HANDLED; } @@ -1267,7 +1185,13 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); rx_ring = &(adapter->rx_ring[r_idx]); /* disable interrupts on this vector only */ - ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx)); + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx); + else if (rx_ring->v_idx & 0xFFFFFFFF) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), rx_ring->v_idx); + else + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), + (rx_ring->v_idx >> 32)); napi_schedule(&q_vector->napi); return IRQ_HANDLED; @@ -1275,38 +1199,27 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) { - struct ixgbe_q_vector *q_vector = data; - struct ixgbe_adapter *adapter = q_vector->adapter; - struct ixgbe_ring *ring; - int r_idx; - int i; + ixgbe_msix_clean_rx(irq, data); + ixgbe_msix_clean_tx(irq, data); - if (!q_vector->txr_count && !q_vector->rxr_count) - return IRQ_HANDLED; + return IRQ_HANDLED; +} - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { - ring = &(adapter->tx_ring[r_idx]); - ring->total_bytes = 0; - ring->total_packets = 0; - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); - } +static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, + u64 qmask) +{ + u32 mask; - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { - ring = &(adapter->rx_ring[r_idx]); - ring->total_bytes = 0; - ring->total_packets = 0; - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + mask = (IXGBE_EIMS_RTX_QUEUE & qmask); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); + } else { + mask = (qmask & 0xFFFFFFFF); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask); + mask = (qmask >> 32); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask); } - - /* disable interrupts on this vector only */ - ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx)); - napi_schedule(&q_vector->napi); - - return IRQ_HANDLED; + /* skip the flush */ } /** @@ -1341,42 +1254,29 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) if (adapter->itr_setting & 1) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable_queues(adapter, - ((u64)1 << q_vector->v_idx)); + ixgbe_irq_enable_queues(adapter, rx_ring->v_idx); } return work_done; } /** - * ixgbe_clean_rxtx_many - msix (aka one shot) rx clean routine + * ixgbe_clean_rxonly_many - msix (aka one shot) rx clean routine * @napi: napi struct with our devices info in it * @budget: amount of work driver is allowed to do this pass, in packets * * This function will clean more than one rx queue associated with a * q_vector. **/ -static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) +static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; - struct ixgbe_ring *ring = NULL; + struct ixgbe_ring *rx_ring = NULL; int work_done = 0, i; long r_idx; - bool tx_clean_complete = true; - - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { - ring = &(adapter->tx_ring[r_idx]); -#ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_tx_dca(adapter, ring); -#endif - tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); - } + u64 enable_mask = 0; /* attempt to distribute budget to each queue fairly, but don't allow * the budget to go below 1 because we'll exit polling */ @@ -1384,71 +1284,31 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) budget = max(budget, 1); r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { - ring = &(adapter->rx_ring[r_idx]); + rx_ring = &(adapter->rx_ring[r_idx]); #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_rx_dca(adapter, ring); + ixgbe_update_rx_dca(adapter, rx_ring); #endif - ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget); + ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget); + enable_mask |= rx_ring->v_idx; r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - ring = &(adapter->rx_ring[r_idx]); + rx_ring = &(adapter->rx_ring[r_idx]); /* If all Rx work done, exit the polling mode */ if (work_done < budget) { napi_complete(napi); if (adapter->itr_setting & 1) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable_queues(adapter, - ((u64)1 << q_vector->v_idx)); + ixgbe_irq_enable_queues(adapter, enable_mask); return 0; } return work_done; } - -/** - * ixgbe_clean_txonly - msix (aka one shot) tx clean routine - * @napi: napi struct with our devices info in it - * @budget: amount of work driver is allowed to do this pass, in packets - * - * This function is optimized for cleaning one queue only on a single - * q_vector!!! - **/ -static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) -{ - struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); - struct ixgbe_adapter *adapter = q_vector->adapter; - struct ixgbe_ring *tx_ring = NULL; - int work_done = 0; - long r_idx; - - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - tx_ring = &(adapter->tx_ring[r_idx]); -#ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_tx_dca(adapter, tx_ring); -#endif - - if (!ixgbe_clean_tx_irq(q_vector, tx_ring)) - work_done = budget; - - /* If all Rx work done, exit the polling mode */ - if (work_done < budget) { - napi_complete(napi); - if (adapter->itr_setting & 1) - ixgbe_set_itr_msix(q_vector); - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); - } - - return work_done; -} - static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, int r_idx) { @@ -1456,6 +1316,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, set_bit(r_idx, q_vector->rxr_idx); q_vector->rxr_count++; + a->rx_ring[r_idx].v_idx = (u64)1 << v_idx; } static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, @@ -1465,6 +1326,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, set_bit(t_idx, q_vector->txr_idx); q_vector->txr_count++; + a->tx_ring[t_idx].v_idx = (u64)1 << v_idx; } /** @@ -1643,13 +1505,14 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) } if (new_itr != q_vector->eitr) { - /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); + u32 itr_reg; /* save the algorithm value here, not the smoothed one */ q_vector->eitr = new_itr; - - ixgbe_write_eitr(q_vector); + /* do an exponential smoothing */ + new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); + itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr); + ixgbe_write_eitr(adapter, 0, itr_reg); } return; @@ -1671,9 +1534,6 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) mask |= IXGBE_EIMS_GPI_SDP1; mask |= IXGBE_EIMS_GPI_SDP2; } - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) - mask |= IXGBE_EIMS_FLOW_DIR; IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); ixgbe_irq_enable_queues(adapter, ~0); @@ -2019,7 +1879,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype); } } else { - if (!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED) && + if (!(adapter->flags & IXGBE_FLAG_RSC_ENABLED) && (netdev->mtu <= ETH_DATA_LEN)) rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; else @@ -2148,7 +2008,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); } - if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) { + if (adapter->flags & IXGBE_FLAG_RSC_ENABLED) { /* Enable 82599 HW-RSC */ for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i].reg_idx; @@ -2321,7 +2181,11 @@ static void ixgbe_set_rx_mode(struct net_device *netdev) IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); /* reprogram secondary unicast list */ - hw->mac.ops.update_uc_addr_list(hw, &netdev->uc_list); + addr_count = netdev->uc_count; + if (addr_count) + addr_list = netdev->uc_list->dmi_addr; + hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count, + ixgbe_addr_list_itr); /* reprogram multicast list */ addr_count = netdev->mc_count; @@ -2344,15 +2208,12 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) for (q_idx = 0; q_idx < q_vectors; q_idx++) { struct napi_struct *napi; q_vector = adapter->q_vector[q_idx]; + if (!q_vector->rxr_count) + continue; napi = &q_vector->napi; - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - if (!q_vector->rxr_count || !q_vector->txr_count) { - if (q_vector->txr_count == 1) - napi->poll = &ixgbe_clean_txonly; - else if (q_vector->rxr_count == 1) - napi->poll = &ixgbe_clean_rxonly; - } - } + if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) && + (q_vector->rxr_count > 1)) + napi->poll = &ixgbe_clean_rxonly_many; napi_enable(napi); } @@ -2370,6 +2231,8 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter) for (q_idx = 0; q_idx < q_vectors; q_idx++) { q_vector = adapter->q_vector[q_idx]; + if (!q_vector->rxr_count) + continue; napi_disable(&q_vector->napi); } } @@ -2427,7 +2290,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) static void ixgbe_configure(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; - struct ixgbe_hw *hw = &adapter->hw; int i; ixgbe_set_rx_mode(netdev); @@ -2449,15 +2311,6 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) ixgbe_configure_fcoe(adapter); #endif /* IXGBE_FCOE */ - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { - for (i = 0; i < adapter->num_tx_queues; i++) - adapter->tx_ring[i].atr_sample_rate = - adapter->atr_sample_rate; - ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc); - } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { - ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc); - } - ixgbe_configure_tx(adapter); ixgbe_configure_rx(adapter); for (i = 0; i < adapter->num_rx_queues; i++) @@ -2714,10 +2567,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) DPRINTK(PROBE, ERR, "link_config FAILED %d\n", err); } - for (i = 0; i < adapter->num_tx_queues; i++) - set_bit(__IXGBE_FDIR_INIT_DONE, - &(adapter->tx_ring[i].reinit_state)); - /* enable transmits */ netif_tx_start_all_queues(netdev); @@ -2753,28 +2602,12 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) int err; err = hw->mac.ops.init_hw(hw); - switch (err) { - case 0: - case IXGBE_ERR_SFP_NOT_PRESENT: - break; - case IXGBE_ERR_MASTER_REQUESTS_PENDING: - dev_err(&adapter->pdev->dev, "master disable timed out\n"); - break; - case IXGBE_ERR_EEPROM_VERSION: - /* We are running on a pre-production device, log a warning */ - dev_warn(&adapter->pdev->dev, "This device is a pre-production " - "adapter/LOM. Please be aware there may be issues " - "associated with your hardware. If you are " - "experiencing problems please contact your Intel or " - "hardware representative who provided you with this " - "hardware.\n"); - break; - default: - dev_err(&adapter->pdev->dev, "Hardware Error: %d\n", err); - } + if (err && (err != IXGBE_ERR_SFP_NOT_PRESENT)) + dev_err(&adapter->pdev->dev, "Hardware Error\n"); /* reprogram the RAR[0] in case user changed it. */ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); + } /** @@ -2922,10 +2755,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter) del_timer_sync(&adapter->watchdog_timer); cancel_work_sync(&adapter->watchdog_task); - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) - cancel_work_sync(&adapter->fdir_reinit_task); - /* disable transmits in the hardware now that interrupts are off */ for (i = 0; i < adapter->num_tx_queues; i++) { j = adapter->tx_ring[i].reg_idx; @@ -2973,7 +2802,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) } #endif - tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring); + tx_clean_complete = ixgbe_clean_tx_irq(adapter, adapter->tx_ring); ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget); if (!tx_clean_complete) @@ -3060,38 +2889,6 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) return ret; } -/** - * ixgbe_set_fdir_queues: Allocate queues for Flow Director - * @adapter: board private structure to initialize - * - * Flow Director is an advanced Rx filter, attempting to get Rx flows back - * to the original CPU that initiated the Tx session. This runs in addition - * to RSS, so if a packet doesn't match an FDIR filter, we can still spread the - * Rx load across CPUs using RSS. - * - **/ -static bool inline ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter) -{ - bool ret = false; - struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR]; - - f_fdir->indices = min((int)num_online_cpus(), f_fdir->indices); - f_fdir->mask = 0; - - /* Flow Director must have RSS enabled */ - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED && - ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)))) { - adapter->num_tx_queues = f_fdir->indices; - adapter->num_rx_queues = f_fdir->indices; - ret = true; - } else { - adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - } - return ret; -} - #ifdef IXGBE_FCOE /** * ixgbe_set_fcoe_queues: Allocate queues for Fiber Channel over Ethernet (FCoE) @@ -3156,9 +2953,6 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) goto done; #endif - if (ixgbe_set_fdir_queues(adapter)) - goto done; - if (ixgbe_set_rss_queues(adapter)) goto done; @@ -3329,31 +3123,6 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) } #endif -/** - * ixgbe_cache_ring_fdir - Descriptor ring to register mapping for Flow Director - * @adapter: board private structure to initialize - * - * Cache the descriptor ring offsets for Flow Director to the assigned rings. - * - **/ -static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) -{ - int i; - bool ret = false; - - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED && - ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))) { - for (i = 0; i < adapter->num_rx_queues; i++) - adapter->rx_ring[i].reg_idx = i; - for (i = 0; i < adapter->num_tx_queues; i++) - adapter->tx_ring[i].reg_idx = i; - ret = true; - } - - return ret; -} - #ifdef IXGBE_FCOE /** * ixgbe_cache_ring_fcoe - Descriptor ring to register mapping for the FCoE @@ -3414,9 +3183,6 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) return; #endif - if (ixgbe_cache_ring_fdir(adapter)) - return; - if (ixgbe_cache_ring_rss(adapter)) return; } @@ -3510,9 +3276,6 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; - adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - adapter->atr_sample_rate = 0; ixgbe_set_num_queues(adapter); err = pci_enable_msi(adapter->pdev); @@ -3546,7 +3309,7 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; napi_vectors = adapter->num_rx_queues; - poll = &ixgbe_clean_rxtx_many; + poll = &ixgbe_clean_rxonly; } else { num_q_vectors = 1; napi_vectors = 1; @@ -3558,9 +3321,11 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) if (!q_vector) goto err_out; q_vector->adapter = adapter; - q_vector->eitr = adapter->eitr_param; q_vector->v_idx = q_idx; - netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64); + q_vector->eitr = adapter->eitr_param; + if (q_idx < napi_vectors) + netif_napi_add(adapter->netdev, &q_vector->napi, + (*poll), 64); adapter->q_vector[q_idx] = q_vector; } @@ -3588,16 +3353,22 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) static void ixgbe_free_q_vectors(struct ixgbe_adapter *adapter) { int q_idx, num_q_vectors; + int napi_vectors; - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - else + napi_vectors = adapter->num_rx_queues; + } else { num_q_vectors = 1; + napi_vectors = 1; + } for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { struct ixgbe_q_vector *q_vector = adapter->q_vector[q_idx]; + adapter->q_vector[q_idx] = NULL; - netif_napi_del(&q_vector->napi); + if (q_idx < napi_vectors) + netif_napi_del(&q_vector->napi); kfree(q_vector); } } @@ -3776,13 +3547,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598; } else if (hw->mac.type == ixgbe_mac_82599EB) { adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; - adapter->flags |= IXGBE_FLAG2_RSC_CAPABLE; - adapter->flags |= IXGBE_FLAG2_RSC_ENABLED; - adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->ring_feature[RING_F_FDIR].indices = - IXGBE_MAX_FDIR_INDICES; - adapter->atr_sample_rate = 20; - adapter->fdir_pballoc = 0; + adapter->flags |= IXGBE_FLAG_RSC_CAPABLE; + adapter->flags |= IXGBE_FLAG_RSC_ENABLED; #ifdef IXGBE_FCOE adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE; @@ -4372,8 +4138,6 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); - adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); #ifdef IXGBE_FCOE adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); @@ -4449,43 +4213,57 @@ static void ixgbe_watchdog(unsigned long data) { struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; struct ixgbe_hw *hw = &adapter->hw; - u64 eics = 0; - int i; - - /* - * Do the watchdog outside of interrupt context due to the lovely - * delays that some of the newer hardware requires - */ - - if (test_bit(__IXGBE_DOWN, &adapter->state)) - goto watchdog_short_circuit; - if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { - /* - * for legacy and MSI interrupts don't set any bits - * that are enabled for EIAM, because this operation - * would set *both* EIMS and EICS for any bit in EIAM - */ - IXGBE_WRITE_REG(hw, IXGBE_EICS, - (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); - goto watchdog_reschedule; - } + /* Do the watchdog outside of interrupt context due to the lovely + * delays that some of the newer hardware requires */ + if (!test_bit(__IXGBE_DOWN, &adapter->state)) { + u64 eics = 0; + int i; - /* get one bit for every active tx/rx interrupt vector */ - for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { - struct ixgbe_q_vector *qv = adapter->q_vector[i]; - if (qv->rxr_count || qv->txr_count) + for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) eics |= ((u64)1 << i); - } - /* Cause software interrupt to ensure rx rings are cleaned */ - ixgbe_irq_rearm_queues(adapter, eics); - -watchdog_reschedule: - /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ)); + /* Cause software interrupt to ensure rx rings are cleaned */ + switch (hw->mac.type) { + case ixgbe_mac_82598EB: + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + IXGBE_WRITE_REG(hw, IXGBE_EICS, (u32)eics); + } else { + /* + * for legacy and MSI interrupts don't set any + * bits that are enabled for EIAM, because this + * operation would set *both* EIMS and EICS for + * any bit in EIAM + */ + IXGBE_WRITE_REG(hw, IXGBE_EICS, + (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); + } + break; + case ixgbe_mac_82599EB: + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(0), + (u32)(eics & 0xFFFFFFFF)); + IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1), + (u32)(eics >> 32)); + } else { + /* + * for legacy and MSI interrupts don't set any + * bits that are enabled for EIAM, because this + * operation would set *both* EIMS and EICS for + * any bit in EIAM + */ + IXGBE_WRITE_REG(hw, IXGBE_EICS, + (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); + } + break; + default: + break; + } + /* Reset the timer */ + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + 2 * HZ)); + } -watchdog_short_circuit: schedule_work(&adapter->watchdog_task); } @@ -4538,30 +4316,6 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK; } -/** - * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table - * @work: pointer to work_struct containing our data - **/ -static void ixgbe_fdir_reinit_task(struct work_struct *work) -{ - struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - fdir_reinit_task); - struct ixgbe_hw *hw = &adapter->hw; - int i; - - if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { - for (i = 0; i < adapter->num_tx_queues; i++) - set_bit(__IXGBE_FDIR_INIT_DONE, - &(adapter->tx_ring[i].reinit_state)); - } else { - DPRINTK(PROBE, ERR, "failed to finish FDIR re-initialization, " - "ignored adding FDIR ATR filters \n"); - } - /* Done FDIR Re-initialization, enable transmits */ - netif_tx_start_all_queues(adapter->netdev); -} - /** * ixgbe_watchdog_task - worker thread to bring link up * @work: pointer to work_struct containing our data @@ -4587,12 +4341,12 @@ static void ixgbe_watchdog_task(struct work_struct *work) #ifdef CONFIG_DCB if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { for (i = 0; i < MAX_TRAFFIC_CLASS; i++) - hw->mac.ops.fc_enable(hw, i); + hw->mac.ops.setup_fc(hw, i); } else { - hw->mac.ops.fc_enable(hw, 0); + hw->mac.ops.setup_fc(hw, 0); } #else - hw->mac.ops.fc_enable(hw, 0); + hw->mac.ops.setup_fc(hw, 0); #endif } @@ -4869,7 +4623,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); tx_buffer_info->length = size; - tx_buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + tx_buffer_info->dma = map[0] + offset; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -4901,7 +4655,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); tx_buffer_info->length = size; - tx_buffer_info->dma = map[f] + offset; + tx_buffer_info->dma = map[f + 1] + offset; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -4989,58 +4743,6 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, writel(i, adapter->hw.hw_addr + tx_ring->tail); } -static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, - int queue, u32 tx_flags) -{ - /* Right now, we support IPv4 only */ - struct ixgbe_atr_input atr_input; - struct tcphdr *th; - struct udphdr *uh; - struct iphdr *iph = ip_hdr(skb); - struct ethhdr *eth = (struct ethhdr *)skb->data; - u16 vlan_id, src_port, dst_port, flex_bytes; - u32 src_ipv4_addr, dst_ipv4_addr; - u8 l4type = 0; - - /* check if we're UDP or TCP */ - if (iph->protocol == IPPROTO_TCP) { - th = tcp_hdr(skb); - src_port = th->source; - dst_port = th->dest; - l4type |= IXGBE_ATR_L4TYPE_TCP; - /* l4type IPv4 type is 0, no need to assign */ - } else if(iph->protocol == IPPROTO_UDP) { - uh = udp_hdr(skb); - src_port = uh->source; - dst_port = uh->dest; - l4type |= IXGBE_ATR_L4TYPE_UDP; - /* l4type IPv4 type is 0, no need to assign */ - } else { - /* Unsupported L4 header, just bail here */ - return; - } - - memset(&atr_input, 0, sizeof(struct ixgbe_atr_input)); - - vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >> - IXGBE_TX_FLAGS_VLAN_SHIFT; - src_ipv4_addr = iph->saddr; - dst_ipv4_addr = iph->daddr; - flex_bytes = eth->h_proto; - - ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id); - ixgbe_atr_set_src_port_82599(&atr_input, dst_port); - ixgbe_atr_set_dst_port_82599(&atr_input, src_port); - ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes); - ixgbe_atr_set_l4type_82599(&atr_input, l4type); - /* src and dst are inverted, think how the receiver sees them */ - ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr); - ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr); - - /* This assumes the Rx queue and Tx queue are bound to the same CPU */ - ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue); -} - static int __ixgbe_maybe_stop_tx(struct net_device *netdev, struct ixgbe_ring *tx_ring, int size) { @@ -5075,9 +4777,6 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) { struct ixgbe_adapter *adapter = netdev_priv(dev); - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) - return smp_processor_id(); - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) return 0; /* All traffic should default to class 0 */ @@ -5162,19 +4861,9 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first); if (count) { - /* add the ATR filter if ATR is on */ - if (tx_ring->atr_sample_rate) { - ++tx_ring->atr_count; - if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) && - test_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) { - ixgbe_atr(adapter, skb, tx_ring->queue_index, - tx_flags); - tx_ring->atr_count = 0; - } - } ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len, hdr_len); + netdev->trans_start = jiffies; ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED); } else { @@ -5555,12 +5244,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_FCOE_CRC; netdev->features |= NETIF_F_FSO; netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; - DPRINTK(DRV, INFO, "FCoE enabled, " - "disabling Flow Director\n"); - adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags &= - ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - adapter->atr_sample_rate = 0; } else { adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; } @@ -5570,7 +5253,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; - if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) + if (adapter->flags & IXGBE_FLAG_RSC_ENABLED) netdev->features |= NETIF_F_LRO; /* make sure the EEPROM is good */ @@ -5604,9 +5287,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, case IXGBE_DEV_ID_82599_KX4: adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | IXGBE_WUFC_MC | IXGBE_WUFC_BC); - /* Enable ACPI wakeup in GRC */ - IXGBE_WRITE_REG(hw, IXGBE_GRC, - (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME)); break; default: adapter->wol = 0; @@ -5649,17 +5329,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version); /* reset the hardware with the new settings */ - err = hw->mac.ops.start_hw(hw); + hw->mac.ops.start_hw(hw); - if (err == IXGBE_ERR_EEPROM_VERSION) { - /* We are running on a pre-production device, log a warning */ - dev_warn(&pdev->dev, "This device is a pre-production " - "adapter/LOM. Please be aware there may be issues " - "associated with your hardware. If you are " - "experiencing problems please contact your Intel or " - "hardware representative who provided you with this " - "hardware.\n"); - } strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); if (err) @@ -5668,10 +5339,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) - INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task); - #ifdef CONFIG_IXGBE_DCA if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; @@ -5734,9 +5401,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) cancel_work_sync(&adapter->sfp_task); cancel_work_sync(&adapter->multispeed_fiber_task); cancel_work_sync(&adapter->sfp_config_module_task); - if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || - adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) - cancel_work_sync(&adapter->fdir_reinit_task); flush_scheduled_work(); #ifdef CONFIG_IXGBE_DCA diff --git a/trunk/drivers/net/ixgbe/ixgbe_phy.c b/trunk/drivers/net/ixgbe/ixgbe_phy.c index 453e966762f0..e43d6248d7d4 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_phy.c +++ b/trunk/drivers/net/ixgbe/ixgbe_phy.c @@ -606,7 +606,6 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->phy.sfp_setup_needed = true; /* Determine if the SFP+ PHY is dual speed or not. */ - hw->phy.multispeed_fiber = false; if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && diff --git a/trunk/drivers/net/ixgbe/ixgbe_type.h b/trunk/drivers/net/ixgbe/ixgbe_type.h index fa87309dc087..df1f7034c284 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_type.h +++ b/trunk/drivers/net/ixgbe/ixgbe_type.h @@ -30,7 +30,6 @@ #include #include -#include /* Vendor ID */ #define IXGBE_INTEL_VENDOR_ID 0x8086 @@ -231,34 +230,6 @@ #define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */ #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */ -/* Flow Director registers */ -#define IXGBE_FDIRCTRL 0x0EE00 -#define IXGBE_FDIRHKEY 0x0EE68 -#define IXGBE_FDIRSKEY 0x0EE6C -#define IXGBE_FDIRDIP4M 0x0EE3C -#define IXGBE_FDIRSIP4M 0x0EE40 -#define IXGBE_FDIRTCPM 0x0EE44 -#define IXGBE_FDIRUDPM 0x0EE48 -#define IXGBE_FDIRIP6M 0x0EE74 -#define IXGBE_FDIRM 0x0EE70 - -/* Flow Director Stats registers */ -#define IXGBE_FDIRFREE 0x0EE38 -#define IXGBE_FDIRLEN 0x0EE4C -#define IXGBE_FDIRUSTAT 0x0EE50 -#define IXGBE_FDIRFSTAT 0x0EE54 -#define IXGBE_FDIRMATCH 0x0EE58 -#define IXGBE_FDIRMISS 0x0EE5C - -/* Flow Director Programming registers */ -#define IXGBE_FDIRSIPv6(_i) (0x0EE0C + ((_i) * 4)) /* 3 of these (0-2) */ -#define IXGBE_FDIRIPSA 0x0EE18 -#define IXGBE_FDIRIPDA 0x0EE1C -#define IXGBE_FDIRPORT 0x0EE20 -#define IXGBE_FDIRVLAN 0x0EE24 -#define IXGBE_FDIRHASH 0x0EE28 -#define IXGBE_FDIRCMD 0x0EE2C - /* Transmit DMA registers */ #define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/ #define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40)) @@ -1293,10 +1264,8 @@ #define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */ /* ESDP Bit Masks */ -#define IXGBE_ESDP_SDP0 0x00000001 /* SDP0 Data Value */ -#define IXGBE_ESDP_SDP1 0x00000002 /* SDP1 Data Value */ -#define IXGBE_ESDP_SDP2 0x00000004 /* SDP2 Data Value */ -#define IXGBE_ESDP_SDP3 0x00000008 /* SDP3 Data Value */ +#define IXGBE_ESDP_SDP0 0x00000001 +#define IXGBE_ESDP_SDP1 0x00000002 #define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */ #define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */ #define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */ @@ -1396,6 +1365,8 @@ #define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ +#define FIBER_LINK_UP_LIMIT 50 + /* PCS1GLSTA Bit Masks */ #define IXGBE_PCS1GLSTA_LINK_OK 1 #define IXGBE_PCS1GLSTA_SYNK_OK 0x10 @@ -1516,8 +1487,6 @@ #define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3 #define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 #define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 -#define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4 -#define IXGBE_FW_PATCH_VERSION_4 0x7 /* PCI Bus Info */ #define IXGBE_PCI_LINK_STATUS 0xB2 @@ -1682,9 +1651,6 @@ #define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */ #define IXGBE_RXDADV_ERR_FCEOFE 0x80000000 /* FCoEFe/IPE */ #define IXGBE_RXDADV_ERR_FCERR 0x00700000 /* FCERR/FDIRERR */ -#define IXGBE_RXDADV_ERR_FDIR_LEN 0x00100000 /* FDIR Length error */ -#define IXGBE_RXDADV_ERR_FDIR_DROP 0x00200000 /* FDIR Drop error */ -#define IXGBE_RXDADV_ERR_FDIR_COLL 0x00400000 /* FDIR Collision error */ #define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */ #define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */ #define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */ @@ -1817,82 +1783,6 @@ #endif -enum ixgbe_fdir_pballoc_type { - IXGBE_FDIR_PBALLOC_64K = 0, - IXGBE_FDIR_PBALLOC_128K, - IXGBE_FDIR_PBALLOC_256K, -}; -#define IXGBE_FDIR_PBALLOC_SIZE_SHIFT 16 - -/* Flow Director register values */ -#define IXGBE_FDIRCTRL_PBALLOC_64K 0x00000001 -#define IXGBE_FDIRCTRL_PBALLOC_128K 0x00000002 -#define IXGBE_FDIRCTRL_PBALLOC_256K 0x00000003 -#define IXGBE_FDIRCTRL_INIT_DONE 0x00000008 -#define IXGBE_FDIRCTRL_PERFECT_MATCH 0x00000010 -#define IXGBE_FDIRCTRL_REPORT_STATUS 0x00000020 -#define IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS 0x00000080 -#define IXGBE_FDIRCTRL_DROP_Q_SHIFT 8 -#define IXGBE_FDIRCTRL_FLEX_SHIFT 16 -#define IXGBE_FDIRCTRL_SEARCHLIM 0x00800000 -#define IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT 24 -#define IXGBE_FDIRCTRL_FULL_THRESH_MASK 0xF0000000 -#define IXGBE_FDIRCTRL_FULL_THRESH_SHIFT 28 - -#define IXGBE_FDIRTCPM_DPORTM_SHIFT 16 -#define IXGBE_FDIRUDPM_DPORTM_SHIFT 16 -#define IXGBE_FDIRIP6M_DIPM_SHIFT 16 -#define IXGBE_FDIRM_VLANID 0x00000001 -#define IXGBE_FDIRM_VLANP 0x00000002 -#define IXGBE_FDIRM_POOL 0x00000004 -#define IXGBE_FDIRM_L3P 0x00000008 -#define IXGBE_FDIRM_L4P 0x00000010 -#define IXGBE_FDIRM_FLEX 0x00000020 -#define IXGBE_FDIRM_DIPv6 0x00000040 - -#define IXGBE_FDIRFREE_FREE_MASK 0xFFFF -#define IXGBE_FDIRFREE_FREE_SHIFT 0 -#define IXGBE_FDIRFREE_COLL_MASK 0x7FFF0000 -#define IXGBE_FDIRFREE_COLL_SHIFT 16 -#define IXGBE_FDIRLEN_MAXLEN_MASK 0x3F -#define IXGBE_FDIRLEN_MAXLEN_SHIFT 0 -#define IXGBE_FDIRLEN_MAXHASH_MASK 0x7FFF0000 -#define IXGBE_FDIRLEN_MAXHASH_SHIFT 16 -#define IXGBE_FDIRUSTAT_ADD_MASK 0xFFFF -#define IXGBE_FDIRUSTAT_ADD_SHIFT 0 -#define IXGBE_FDIRUSTAT_REMOVE_MASK 0xFFFF0000 -#define IXGBE_FDIRUSTAT_REMOVE_SHIFT 16 -#define IXGBE_FDIRFSTAT_FADD_MASK 0x00FF -#define IXGBE_FDIRFSTAT_FADD_SHIFT 0 -#define IXGBE_FDIRFSTAT_FREMOVE_MASK 0xFF00 -#define IXGBE_FDIRFSTAT_FREMOVE_SHIFT 8 -#define IXGBE_FDIRPORT_DESTINATION_SHIFT 16 -#define IXGBE_FDIRVLAN_FLEX_SHIFT 16 -#define IXGBE_FDIRHASH_BUCKET_VALID_SHIFT 15 -#define IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT 16 - -#define IXGBE_FDIRCMD_CMD_MASK 0x00000003 -#define IXGBE_FDIRCMD_CMD_ADD_FLOW 0x00000001 -#define IXGBE_FDIRCMD_CMD_REMOVE_FLOW 0x00000002 -#define IXGBE_FDIRCMD_CMD_QUERY_REM_FILT 0x00000003 -#define IXGBE_FDIRCMD_CMD_QUERY_REM_HASH 0x00000007 -#define IXGBE_FDIRCMD_FILTER_UPDATE 0x00000008 -#define IXGBE_FDIRCMD_IPv6DMATCH 0x00000010 -#define IXGBE_FDIRCMD_L4TYPE_UDP 0x00000020 -#define IXGBE_FDIRCMD_L4TYPE_TCP 0x00000040 -#define IXGBE_FDIRCMD_L4TYPE_SCTP 0x00000060 -#define IXGBE_FDIRCMD_IPV6 0x00000080 -#define IXGBE_FDIRCMD_CLEARHT 0x00000100 -#define IXGBE_FDIRCMD_DROP 0x00000200 -#define IXGBE_FDIRCMD_INT 0x00000400 -#define IXGBE_FDIRCMD_LAST 0x00000800 -#define IXGBE_FDIRCMD_COLLISION 0x00001000 -#define IXGBE_FDIRCMD_QUEUE_EN 0x00008000 -#define IXGBE_FDIRCMD_RX_QUEUE_SHIFT 16 -#define IXGBE_FDIRCMD_VT_POOL_SHIFT 24 -#define IXGBE_FDIR_INIT_DONE_POLL 10 -#define IXGBE_FDIRCMD_CMD_POLL 10 - /* Transmit Descriptor - Legacy */ struct ixgbe_legacy_tx_desc { u64 buffer_addr; /* Address of the descriptor's data buffer */ @@ -2066,45 +1956,6 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800 #define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000 -/* Software ATR hash keys */ -#define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D -#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17 - -/* Software ATR input stream offsets and masks */ -#define IXGBE_ATR_VLAN_OFFSET 0 -#define IXGBE_ATR_SRC_IPV6_OFFSET 2 -#define IXGBE_ATR_SRC_IPV4_OFFSET 14 -#define IXGBE_ATR_DST_IPV6_OFFSET 18 -#define IXGBE_ATR_DST_IPV4_OFFSET 30 -#define IXGBE_ATR_SRC_PORT_OFFSET 34 -#define IXGBE_ATR_DST_PORT_OFFSET 36 -#define IXGBE_ATR_FLEX_BYTE_OFFSET 38 -#define IXGBE_ATR_VM_POOL_OFFSET 40 -#define IXGBE_ATR_L4TYPE_OFFSET 41 - -#define IXGBE_ATR_L4TYPE_MASK 0x3 -#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4 -#define IXGBE_ATR_L4TYPE_UDP 0x1 -#define IXGBE_ATR_L4TYPE_TCP 0x2 -#define IXGBE_ATR_L4TYPE_SCTP 0x3 -#define IXGBE_ATR_HASH_MASK 0x7fff - -/* Flow Director ATR input struct. */ -struct ixgbe_atr_input { - /* Byte layout in order, all values with MSB first: - * - * vlan_id - 2 bytes - * src_ip - 16 bytes - * dst_ip - 16 bytes - * src_port - 2 bytes - * dst_port - 2 bytes - * flex_bytes - 2 bytes - * vm_pool - 1 byte - * l4type - 1 byte - */ - u8 byte_stream[42]; -}; - enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, ixgbe_eeprom_spi, @@ -2240,8 +2091,7 @@ struct ixgbe_fc_info { u16 pause_time; /* Flow Control Pause timer */ bool send_xon; /* Flow control send XON */ bool strict_ieee; /* Strict IEEE mode */ - bool disable_fc_autoneg; /* Do not autonegotiate FC */ - bool fc_was_autonegged; /* Is current_mode the result of autonegging? */ + bool disable_fc_autoneg; /* Turn off autoneg FC mode */ enum ixgbe_fc_mode current_mode; /* FC mode in effect */ enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */ }; @@ -2373,7 +2223,8 @@ struct ixgbe_mac_operations { s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32); s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32); s32 (*init_rx_addrs)(struct ixgbe_hw *); - s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct list_head *); + s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32, + ixgbe_mc_addr_itr); s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32, ixgbe_mc_addr_itr); s32 (*enable_mc)(struct ixgbe_hw *); @@ -2383,7 +2234,7 @@ struct ixgbe_mac_operations { s32 (*init_uta_tables)(struct ixgbe_hw *); /* Flow Control */ - s32 (*fc_enable)(struct ixgbe_hw *, s32); + s32 (*setup_fc)(struct ixgbe_hw *, s32); }; struct ixgbe_phy_operations { @@ -2430,7 +2281,6 @@ struct ixgbe_mac_info { bool orig_link_settings_stored; bool autoneg; bool autoneg_succeeded; - bool autotry_restart; }; struct ixgbe_phy_info { @@ -2496,8 +2346,6 @@ struct ixgbe_info { #define IXGBE_ERR_SFP_NOT_SUPPORTED -19 #define IXGBE_ERR_SFP_NOT_PRESENT -20 #define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21 -#define IXGBE_ERR_FDIR_REINIT_FAILED -23 -#define IXGBE_ERR_EEPROM_VERSION -24 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #endif /* _IXGBE_TYPE_H_ */ diff --git a/trunk/drivers/net/jme.c b/trunk/drivers/net/jme.c index 1e3c63d67b91..621a7c0c46ba 100644 --- a/trunk/drivers/net/jme.c +++ b/trunk/drivers/net/jme.c @@ -1939,6 +1939,7 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) TXCS_SELECT_QUEUE0 | TXCS_QUEUE0S | TXCS_ENABLE); + netdev->trans_start = jiffies; tx_dbg(jme, "xmit: %d+%d@%lu\n", idx, skb_shinfo(skb)->nr_frags + 2, diff --git a/trunk/drivers/net/korina.c b/trunk/drivers/net/korina.c index b4cf602c32b0..dc238567cae1 100644 --- a/trunk/drivers/net/korina.c +++ b/trunk/drivers/net/korina.c @@ -133,7 +133,6 @@ struct korina_private { int dma_halt_cnt; int dma_run_cnt; struct napi_struct napi; - struct timer_list media_check_timer; struct mii_if_info mii_if; struct net_device *dev; int phy_addr; @@ -665,15 +664,6 @@ static void korina_check_media(struct net_device *dev, unsigned int init_media) &lp->eth_regs->ethmac2); } -static void korina_poll_media(unsigned long data) -{ - struct net_device *dev = (struct net_device *) data; - struct korina_private *lp = netdev_priv(dev); - - korina_check_media(dev, 0); - mod_timer(&lp->media_check_timer, jiffies + HZ); -} - static void korina_set_carrier(struct mii_if_info *mii) { if (mii->force_media) { @@ -1044,7 +1034,6 @@ static int korina_open(struct net_device *dev) dev->name, lp->und_irq); goto err_free_ovr_irq; } - mod_timer(&lp->media_check_timer, jiffies + 1); out: return ret; @@ -1064,8 +1053,6 @@ static int korina_close(struct net_device *dev) struct korina_private *lp = netdev_priv(dev); u32 tmp; - del_timer(&lp->media_check_timer); - /* Disable interrupts */ disable_irq(lp->rx_irq); disable_irq(lp->tx_irq); @@ -1196,7 +1183,6 @@ static int korina_probe(struct platform_device *pdev) ": cannot register net device %d\n", rc); goto probe_err_register; } - setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev); out: return rc; diff --git a/trunk/drivers/net/ks8842.c b/trunk/drivers/net/ks8842.c deleted file mode 100644 index 39b0aea2aab3..000000000000 --- a/trunk/drivers/net/ks8842.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - * ks8842_main.c timberdale KS8842 ethernet driver - * Copyright (c) 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Supports: - * The Micrel KS8842 behind the timberdale FPGA - */ - -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "ks8842" - -/* Timberdale specific Registers */ -#define REG_TIMB_RST 0x1c - -/* KS8842 registers */ - -#define REG_SELECT_BANK 0x0e - -/* bank 0 registers */ -#define REG_QRFCR 0x04 - -/* bank 2 registers */ -#define REG_MARL 0x00 -#define REG_MARM 0x02 -#define REG_MARH 0x04 - -/* bank 3 registers */ -#define REG_GRR 0x06 - -/* bank 16 registers */ -#define REG_TXCR 0x00 -#define REG_TXSR 0x02 -#define REG_RXCR 0x04 -#define REG_TXMIR 0x08 -#define REG_RXMIR 0x0A - -/* bank 17 registers */ -#define REG_TXQCR 0x00 -#define REG_RXQCR 0x02 -#define REG_TXFDPR 0x04 -#define REG_RXFDPR 0x06 -#define REG_QMU_DATA_LO 0x08 -#define REG_QMU_DATA_HI 0x0A - -/* bank 18 registers */ -#define REG_IER 0x00 -#define IRQ_LINK_CHANGE 0x8000 -#define IRQ_TX 0x4000 -#define IRQ_RX 0x2000 -#define IRQ_RX_OVERRUN 0x0800 -#define IRQ_TX_STOPPED 0x0200 -#define IRQ_RX_STOPPED 0x0100 -#define IRQ_RX_ERROR 0x0080 -#define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \ - IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR) -#define REG_ISR 0x02 -#define REG_RXSR 0x04 -#define RXSR_VALID 0x8000 -#define RXSR_BROADCAST 0x80 -#define RXSR_MULTICAST 0x40 -#define RXSR_UNICAST 0x20 -#define RXSR_FRAMETYPE 0x08 -#define RXSR_TOO_LONG 0x04 -#define RXSR_RUNT 0x02 -#define RXSR_CRC_ERROR 0x01 -#define RXSR_ERROR (RXSR_TOO_LONG | RXSR_RUNT | RXSR_CRC_ERROR) - -/* bank 32 registers */ -#define REG_SW_ID_AND_ENABLE 0x00 -#define REG_SGCR1 0x02 -#define REG_SGCR2 0x04 -#define REG_SGCR3 0x06 - -/* bank 39 registers */ -#define REG_MACAR1 0x00 -#define REG_MACAR2 0x02 -#define REG_MACAR3 0x04 - -/* bank 45 registers */ -#define REG_P1MBCR 0x00 -#define REG_P1MBSR 0x02 - -/* bank 46 registers */ -#define REG_P2MBCR 0x00 -#define REG_P2MBSR 0x02 - -/* bank 48 registers */ -#define REG_P1CR2 0x02 - -/* bank 49 registers */ -#define REG_P1CR4 0x02 -#define REG_P1SR 0x04 - -struct ks8842_adapter { - void __iomem *hw_addr; - int irq; - struct tasklet_struct tasklet; - spinlock_t lock; /* spinlock to be interrupt safe */ - struct platform_device *pdev; -}; - -static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank) -{ - iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK); -} - -static inline void ks8842_write8(struct ks8842_adapter *adapter, u16 bank, - u8 value, int offset) -{ - ks8842_select_bank(adapter, bank); - iowrite8(value, adapter->hw_addr + offset); -} - -static inline void ks8842_write16(struct ks8842_adapter *adapter, u16 bank, - u16 value, int offset) -{ - ks8842_select_bank(adapter, bank); - iowrite16(value, adapter->hw_addr + offset); -} - -static inline void ks8842_enable_bits(struct ks8842_adapter *adapter, u16 bank, - u16 bits, int offset) -{ - u16 reg; - ks8842_select_bank(adapter, bank); - reg = ioread16(adapter->hw_addr + offset); - reg |= bits; - iowrite16(reg, adapter->hw_addr + offset); -} - -static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank, - u16 bits, int offset) -{ - u16 reg; - ks8842_select_bank(adapter, bank); - reg = ioread16(adapter->hw_addr + offset); - reg &= ~bits; - iowrite16(reg, adapter->hw_addr + offset); -} - -static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank, - u32 value, int offset) -{ - ks8842_select_bank(adapter, bank); - iowrite32(value, adapter->hw_addr + offset); -} - -static inline u8 ks8842_read8(struct ks8842_adapter *adapter, u16 bank, - int offset) -{ - ks8842_select_bank(adapter, bank); - return ioread8(adapter->hw_addr + offset); -} - -static inline u16 ks8842_read16(struct ks8842_adapter *adapter, u16 bank, - int offset) -{ - ks8842_select_bank(adapter, bank); - return ioread16(adapter->hw_addr + offset); -} - -static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank, - int offset) -{ - ks8842_select_bank(adapter, bank); - return ioread32(adapter->hw_addr + offset); -} - -static void ks8842_reset(struct ks8842_adapter *adapter) -{ - /* The KS8842 goes haywire when doing softare reset - * a work around in the timberdale IP is implemented to - * do a hardware reset instead - ks8842_write16(adapter, 3, 1, REG_GRR); - msleep(10); - iowrite16(0, adapter->hw_addr + REG_GRR); - */ - iowrite16(32, adapter->hw_addr + REG_SELECT_BANK); - iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST); - msleep(20); -} - -static void ks8842_update_link_status(struct net_device *netdev, - struct ks8842_adapter *adapter) -{ - /* check the status of the link */ - if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) { - netif_carrier_on(netdev); - netif_wake_queue(netdev); - } else { - netif_stop_queue(netdev); - netif_carrier_off(netdev); - } -} - -static void ks8842_enable_tx(struct ks8842_adapter *adapter) -{ - ks8842_enable_bits(adapter, 16, 0x01, REG_TXCR); -} - -static void ks8842_disable_tx(struct ks8842_adapter *adapter) -{ - ks8842_clear_bits(adapter, 16, 0x01, REG_TXCR); -} - -static void ks8842_enable_rx(struct ks8842_adapter *adapter) -{ - ks8842_enable_bits(adapter, 16, 0x01, REG_RXCR); -} - -static void ks8842_disable_rx(struct ks8842_adapter *adapter) -{ - ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR); -} - -static void ks8842_reset_hw(struct ks8842_adapter *adapter) -{ - /* reset the HW */ - ks8842_reset(adapter); - - /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */ - ks8842_write16(adapter, 16, 0x000E, REG_TXCR); - - /* enable the receiver, uni + multi + broadcast + flow ctrl - + crc strip */ - ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400, - REG_RXCR); - - /* TX frame pointer autoincrement */ - ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR); - - /* RX frame pointer autoincrement */ - ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR); - - /* RX 2 kb high watermark */ - ks8842_write16(adapter, 0, 0x1000, REG_QRFCR); - - /* aggresive back off in half duplex */ - ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1); - - /* enable no excessive collison drop */ - ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2); - - /* Enable port 1 force flow control / back pressure / transmit / recv */ - ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2); - - /* restart port auto-negotiation */ - ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4); - /* only advertise 10Mbps */ - ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4); - - /* Enable the transmitter */ - ks8842_enable_tx(adapter); - - /* Enable the receiver */ - ks8842_enable_rx(adapter); - - /* clear all interrupts */ - ks8842_write16(adapter, 18, 0xffff, REG_ISR); - - /* enable interrupts */ - ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); - - /* enable the switch */ - ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE); -} - -static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest) -{ - int i; - u16 mac; - - for (i = 0; i < ETH_ALEN; i++) - dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i); - - /* make sure the switch port uses the same MAC as the QMU */ - mac = ks8842_read16(adapter, 2, REG_MARL); - ks8842_write16(adapter, 39, mac, REG_MACAR1); - mac = ks8842_read16(adapter, 2, REG_MARM); - ks8842_write16(adapter, 39, mac, REG_MACAR2); - mac = ks8842_read16(adapter, 2, REG_MARH); - ks8842_write16(adapter, 39, mac, REG_MACAR3); -} - -static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter) -{ - return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff; -} - -static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - int len = skb->len; - u32 *ptr = (u32 *)skb->data; - u32 ctrl; - - dev_dbg(&adapter->pdev->dev, - "%s: len %u head %p data %p tail %p end %p\n", - __func__, skb->len, skb->head, skb->data, - skb_tail_pointer(skb), skb_end_pointer(skb)); - - /* check FIFO buffer space, we need space for CRC and command bits */ - if (ks8842_tx_fifo_space(adapter) < len + 8) - return NETDEV_TX_BUSY; - - /* the control word, enable IRQ, port 1 and the length */ - ctrl = 0x8000 | 0x100 | (len << 16); - ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO); - - netdev->stats.tx_bytes += len; - - /* copy buffer */ - while (len > 0) { - iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO); - len -= sizeof(u32); - ptr++; - } - - /* enqueue packet */ - ks8842_write16(adapter, 17, 1, REG_TXQCR); - - dev_kfree_skb(skb); - - return NETDEV_TX_OK; -} - -static void ks8842_rx_frame(struct net_device *netdev, - struct ks8842_adapter *adapter) -{ - u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO); - int len = (status >> 16) & 0x7ff; - - status &= 0xffff; - - dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n", - __func__, status); - - /* check the status */ - if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { - struct sk_buff *skb = netdev_alloc_skb(netdev, len + 2); - - dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n", - __func__, len); - if (skb) { - u32 *data; - - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += len; - if (status & RXSR_MULTICAST) - netdev->stats.multicast++; - - /* Align socket buffer in 4-byte boundary for - better performance. */ - skb_reserve(skb, 2); - data = (u32 *)skb_put(skb, len); - - ks8842_select_bank(adapter, 17); - while (len > 0) { - *data++ = ioread32(adapter->hw_addr + - REG_QMU_DATA_LO); - len -= sizeof(u32); - } - - skb->protocol = eth_type_trans(skb, netdev); - netif_rx(skb); - } else - netdev->stats.rx_dropped++; - } else { - dev_dbg(&adapter->pdev->dev, "RX error, status: %x\n", status); - netdev->stats.rx_errors++; - if (status & RXSR_TOO_LONG) - netdev->stats.rx_length_errors++; - if (status & RXSR_CRC_ERROR) - netdev->stats.rx_crc_errors++; - if (status & RXSR_RUNT) - netdev->stats.rx_frame_errors++; - } - - /* set high watermark to 3K */ - ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR); - - /* release the frame */ - ks8842_write16(adapter, 17, 0x01, REG_RXQCR); - - /* set high watermark to 2K */ - ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR); -} - -void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter) -{ - u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; - dev_dbg(&adapter->pdev->dev, "%s Entry - rx_data: %d\n", - __func__, rx_data); - while (rx_data) { - ks8842_rx_frame(netdev, adapter); - rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; - } -} - -void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter) -{ - u16 sr = ks8842_read16(adapter, 16, REG_TXSR); - dev_dbg(&adapter->pdev->dev, "%s - entry, sr: %x\n", __func__, sr); - netdev->stats.tx_packets++; - if (netif_queue_stopped(netdev)) - netif_wake_queue(netdev); -} - -void ks8842_handle_rx_overrun(struct net_device *netdev, - struct ks8842_adapter *adapter) -{ - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - netdev->stats.rx_errors++; - netdev->stats.rx_fifo_errors++; -} - -void ks8842_tasklet(unsigned long arg) -{ - struct net_device *netdev = (struct net_device *)arg; - struct ks8842_adapter *adapter = netdev_priv(netdev); - u16 isr; - unsigned long flags; - u16 entry_bank; - - /* read current bank to be able to set it back */ - spin_lock_irqsave(&adapter->lock, flags); - entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); - spin_unlock_irqrestore(&adapter->lock, flags); - - isr = ks8842_read16(adapter, 18, REG_ISR); - dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr); - - /* Ack */ - ks8842_write16(adapter, 18, isr, REG_ISR); - - if (!netif_running(netdev)) - return; - - if (isr & IRQ_LINK_CHANGE) - ks8842_update_link_status(netdev, adapter); - - if (isr & (IRQ_RX | IRQ_RX_ERROR)) - ks8842_handle_rx(netdev, adapter); - - if (isr & IRQ_TX) - ks8842_handle_tx(netdev, adapter); - - if (isr & IRQ_RX_OVERRUN) - ks8842_handle_rx_overrun(netdev, adapter); - - if (isr & IRQ_TX_STOPPED) { - ks8842_disable_tx(adapter); - ks8842_enable_tx(adapter); - } - - if (isr & IRQ_RX_STOPPED) { - ks8842_disable_rx(adapter); - ks8842_enable_rx(adapter); - } - - /* re-enable interrupts, put back the bank selection register */ - spin_lock_irqsave(&adapter->lock, flags); - ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); - iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -static irqreturn_t ks8842_irq(int irq, void *devid) -{ - struct ks8842_adapter *adapter = devid; - u16 isr; - u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); - irqreturn_t ret = IRQ_NONE; - - isr = ks8842_read16(adapter, 18, REG_ISR); - dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr); - - if (isr) { - /* disable IRQ */ - ks8842_write16(adapter, 18, 0x00, REG_IER); - - /* schedule tasklet */ - tasklet_schedule(&adapter->tasklet); - - ret = IRQ_HANDLED; - } - - iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); - - return ret; -} - - -/* Netdevice operations */ - -static int ks8842_open(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - int err; - - dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__); - - /* reset the HW */ - ks8842_reset_hw(adapter); - - ks8842_update_link_status(netdev, adapter); - - err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME, - adapter); - if (err) { - printk(KERN_ERR "Failed to request IRQ: %d: %d\n", - adapter->irq, err); - return err; - } - - return 0; -} - -static int ks8842_close(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - - dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__); - - /* free the irq */ - free_irq(adapter->irq, adapter); - - /* disable the switch */ - ks8842_write16(adapter, 32, 0x0, REG_SW_ID_AND_ENABLE); - - return 0; -} - -static int ks8842_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - int ret; - struct ks8842_adapter *adapter = netdev_priv(netdev); - - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - - ret = ks8842_tx_frame(skb, netdev); - - if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8) - netif_stop_queue(netdev); - - return ret; -} - -static int ks8842_set_mac(struct net_device *netdev, void *p) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - struct sockaddr *addr = p; - char *mac = (u8 *)addr->sa_data; - int i; - - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(netdev->dev_addr, mac, netdev->addr_len); - - spin_lock_irqsave(&adapter->lock, flags); - for (i = 0; i < ETH_ALEN; i++) { - ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i); - ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1], - REG_MACAR1 + i); - } - spin_unlock_irqrestore(&adapter->lock, flags); - return 0; -} - -static void ks8842_tx_timeout(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - - spin_lock_irqsave(&adapter->lock, flags); - /* disable interrupts */ - ks8842_write16(adapter, 18, 0, REG_IER); - ks8842_write16(adapter, 18, 0xFFFF, REG_ISR); - spin_unlock_irqrestore(&adapter->lock, flags); - - ks8842_reset_hw(adapter); - - ks8842_update_link_status(netdev, adapter); -} - -static const struct net_device_ops ks8842_netdev_ops = { - .ndo_open = ks8842_open, - .ndo_stop = ks8842_close, - .ndo_start_xmit = ks8842_xmit_frame, - .ndo_set_mac_address = ks8842_set_mac, - .ndo_tx_timeout = ks8842_tx_timeout, - .ndo_validate_addr = eth_validate_addr -}; - -static struct ethtool_ops ks8842_ethtool_ops = { - .get_link = ethtool_op_get_link, -}; - -static int __devinit ks8842_probe(struct platform_device *pdev) -{ - int err = -ENOMEM; - struct resource *iomem; - struct net_device *netdev; - struct ks8842_adapter *adapter; - u16 id; - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME)) - goto err_mem_region; - - netdev = alloc_etherdev(sizeof(struct ks8842_adapter)); - if (!netdev) - goto err_alloc_etherdev; - - SET_NETDEV_DEV(netdev, &pdev->dev); - - adapter = netdev_priv(netdev); - adapter->hw_addr = ioremap(iomem->start, resource_size(iomem)); - if (!adapter->hw_addr) - goto err_ioremap; - - adapter->irq = platform_get_irq(pdev, 0); - if (adapter->irq < 0) { - err = adapter->irq; - goto err_get_irq; - } - - adapter->pdev = pdev; - - tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev); - spin_lock_init(&adapter->lock); - - netdev->netdev_ops = &ks8842_netdev_ops; - netdev->ethtool_ops = &ks8842_ethtool_ops; - - ks8842_read_mac_addr(adapter, netdev->dev_addr); - - id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE); - - strcpy(netdev->name, "eth%d"); - err = register_netdev(netdev); - if (err) - goto err_register; - - platform_set_drvdata(pdev, netdev); - - printk(KERN_INFO DRV_NAME - " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n", - (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); - - return 0; - -err_register: -err_get_irq: - iounmap(adapter->hw_addr); -err_ioremap: - free_netdev(netdev); -err_alloc_etherdev: - release_mem_region(iomem->start, resource_size(iomem)); -err_mem_region: - return err; -} - -static int __devexit ks8842_remove(struct platform_device *pdev) -{ - struct net_device *netdev = platform_get_drvdata(pdev); - struct ks8842_adapter *adapter = netdev_priv(netdev); - struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - unregister_netdev(netdev); - tasklet_kill(&adapter->tasklet); - iounmap(adapter->hw_addr); - free_netdev(netdev); - release_mem_region(iomem->start, resource_size(iomem)); - platform_set_drvdata(pdev, NULL); - return 0; -} - - -static struct platform_driver ks8842_platform_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ks8842_probe, - .remove = ks8842_remove, -}; - -static int __init ks8842_init(void) -{ - return platform_driver_register(&ks8842_platform_driver); -} - -static void __exit ks8842_exit(void) -{ - platform_driver_unregister(&ks8842_platform_driver); -} - -module_init(ks8842_init); -module_exit(ks8842_exit); - -MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver"); -MODULE_AUTHOR("Mocean Laboratories "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:ks8842"); - diff --git a/trunk/drivers/net/mac8390.c b/trunk/drivers/net/mac8390.c index f8fa0c3f0f64..8e884869a05b 100644 --- a/trunk/drivers/net/mac8390.c +++ b/trunk/drivers/net/mac8390.c @@ -304,7 +304,7 @@ struct net_device * __init mac8390_probe(int unit) if (!MACH_IS_MAC) return ERR_PTR(-ENODEV); - dev = ____alloc_ei_netdev(0); + dev = alloc_ei_netdev(); if (!dev) return ERR_PTR(-ENOMEM); @@ -481,15 +481,15 @@ void cleanup_module(void) static const struct net_device_ops mac8390_netdev_ops = { .ndo_open = mac8390_open, .ndo_stop = mac8390_close, - .ndo_start_xmit = __ei_start_xmit, - .ndo_tx_timeout = __ei_tx_timeout, - .ndo_get_stats = __ei_get_stats, - .ndo_set_multicast_list = __ei_set_multicast_list, + .ndo_start_xmit = ei_start_xmit, + .ndo_tx_timeout = ei_tx_timeout, + .ndo_get_stats = ei_get_stats, + .ndo_set_multicast_list = ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, + .ndo_poll_controller = ei_poll, #endif }; @@ -620,12 +620,19 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd /* Good, done, now spit out some messages */ printk(KERN_INFO "%s: %s in slot %X (type %s)\n", - dev->name, ndev->board->name, ndev->board->slot, cardname[type]); - printk(KERN_INFO - "MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n", - dev->dev_addr, dev->irq, - (unsigned int)(dev->mem_end - dev->mem_start) >> 10, - dev->mem_start, access_bitmode ? 32 : 16); + dev->name, ndev->board->name, ndev->board->slot, cardname[type]); + printk(KERN_INFO "MAC "); + { + int i; + for (i = 0; i < 6; i++) { + printk("%2.2x", dev->dev_addr[i]); + if (i < 5) + printk(":"); + } + } + printk(" IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n", + dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4, + dev->mem_start, access_bitmode?32:16); return 0; } diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 99eed9f37c84..d5334b41e4b4 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -232,7 +232,7 @@ static int macvlan_open(struct net_device *dev) if (macvlan_addr_busy(vlan->port, dev->dev_addr)) goto out; - err = dev_unicast_add(lowerdev, dev->dev_addr); + err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN); if (err < 0) goto out; if (dev->flags & IFF_ALLMULTI) { @@ -244,7 +244,7 @@ static int macvlan_open(struct net_device *dev) return 0; del_unicast: - dev_unicast_delete(lowerdev, dev->dev_addr); + dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN); out: return err; } @@ -258,7 +258,7 @@ static int macvlan_stop(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(lowerdev, -1); - dev_unicast_delete(lowerdev, dev->dev_addr); + dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN); macvlan_hash_del(vlan); return 0; @@ -282,11 +282,10 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p) if (macvlan_addr_busy(vlan->port, addr->sa_data)) return -EBUSY; - err = dev_unicast_add(lowerdev, addr->sa_data); - if (err) + if ((err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN))) return err; - dev_unicast_delete(lowerdev, dev->dev_addr); + dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN); macvlan_hash_change_addr(vlan, addr->sa_data); } @@ -359,7 +358,6 @@ static int macvlan_init(struct net_device *dev) (lowerdev->state & MACVLAN_STATE_MASK); dev->features = lowerdev->features & MACVLAN_FEATURES; dev->iflink = lowerdev->ifindex; - dev->hard_header_len = lowerdev->hard_header_len; macvlan_set_lockdep_class(dev); diff --git a/trunk/drivers/net/mdio.c b/trunk/drivers/net/mdio.c index dc45e9856c35..66483035f683 100644 --- a/trunk/drivers/net/mdio.c +++ b/trunk/drivers/net/mdio.c @@ -296,23 +296,6 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || ecmd->speed == SPEED_10000); } - - /* 10GBASE-T MDI/MDI-X */ - if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) { - switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, - MDIO_PMA_10GBT_SWAPPOL)) { - case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: - ecmd->eth_tp_mdix = ETH_TP_MDI; - break; - case 0: - ecmd->eth_tp_mdix = ETH_TP_MDI_X; - break; - default: - /* It's complicated... */ - ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; - break; - } - } } EXPORT_SYMBOL(mdio45_ethtool_gset_npage); diff --git a/trunk/drivers/net/mlx4/Makefile b/trunk/drivers/net/mlx4/Makefile index 1fd068e1d930..21040a0d81fe 100644 --- a/trunk/drivers/net/mlx4/Makefile +++ b/trunk/drivers/net/mlx4/Makefile @@ -5,5 +5,5 @@ mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \ obj-$(CONFIG_MLX4_EN) += mlx4_en.o -mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \ +mlx4_en-y := en_main.o en_tx.o en_rx.o en_params.o en_port.o en_cq.o \ en_resources.o en_netdev.o diff --git a/trunk/drivers/net/mlx4/en_main.c b/trunk/drivers/net/mlx4/en_main.c index 9ed4a158f895..510633fd57f6 100644 --- a/trunk/drivers/net/mlx4/en_main.c +++ b/trunk/drivers/net/mlx4/en_main.c @@ -51,55 +51,6 @@ static const char mlx4_en_version[] = DRV_NAME ": Mellanox ConnectX HCA Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; -#define MLX4_EN_PARM_INT(X, def_val, desc) \ - static unsigned int X = def_val;\ - module_param(X , uint, 0444); \ - MODULE_PARM_DESC(X, desc); - - -/* - * Device scope module parameters - */ - - -/* Use a XOR rathern than Toeplitz hash function for RSS */ -MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS"); - -/* RSS hash type mask - default to */ -MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask"); - -/* Number of LRO sessions per Rx ring (rounded up to a power of two) */ -MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS, - "Number of LRO sessions per ring or disabled (0)"); - -/* Priority pausing */ -MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]." - " Per priority bit mask"); -MLX4_EN_PARM_INT(pfcrx, 0, "Priority based Flow Control policy on RX[7:0]." - " Per priority bit mask"); - -static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) -{ - struct mlx4_en_profile *params = &mdev->profile; - int i; - - params->rss_xor = (rss_xor != 0); - params->rss_mask = rss_mask & 0x1f; - params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); - for (i = 1; i <= MLX4_MAX_PORTS; i++) { - params->prof[i].rx_pause = 1; - params->prof[i].rx_ppp = pfcrx; - params->prof[i].tx_pause = 1; - params->prof[i].tx_ppp = pfctx; - params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE; - params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; - params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS + - (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS; - } - - return 0; -} - static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr, enum mlx4_dev_event event, int port) { @@ -243,11 +194,28 @@ static void *mlx4_en_add(struct mlx4_dev *dev) /* Create a netdev for each port */ mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) { mlx4_info(mdev, "Activating port:%d\n", i); - if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i])) + if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i])) { mdev->pndev[i] = NULL; + goto err_free_netdev; + } } return mdev; + +err_free_netdev: + mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) { + if (mdev->pndev[i]) + mlx4_en_destroy_netdev(mdev->pndev[i]); + } + + mutex_lock(&mdev->state_lock); + mdev->device_up = false; + mutex_unlock(&mdev->state_lock); + flush_workqueue(mdev->workqueue); + + /* Stop event queue before we drop down to release shared SW state */ + destroy_workqueue(mdev->workqueue); + err_mr: mlx4_mr_free(dev, &mdev->mr); err_uar: diff --git a/trunk/drivers/net/mlx4/en_netdev.c b/trunk/drivers/net/mlx4/en_netdev.c index 0a7e78ade63f..0cd185a2e089 100644 --- a/trunk/drivers/net/mlx4/en_netdev.c +++ b/trunk/drivers/net/mlx4/en_netdev.c @@ -51,14 +51,14 @@ static void mlx4_en_vlan_rx_register(struct net_device *dev, struct vlan_group * struct mlx4_en_dev *mdev = priv->mdev; int err; - en_dbg(HW, priv, "Registering VLAN group:%p\n", grp); + mlx4_dbg(HW, priv, "Registering VLAN group:%p\n", grp); priv->vlgrp = grp; mutex_lock(&mdev->state_lock); if (mdev->device_up && priv->port_up) { err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, grp); if (err) - en_err(priv, "Failed configuring VLAN filter\n"); + mlx4_err(mdev, "Failed configuring VLAN filter\n"); } mutex_unlock(&mdev->state_lock); } @@ -72,15 +72,15 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) if (!priv->vlgrp) return; - en_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n", - vid, vlan_group_get_device(priv->vlgrp, vid)); + mlx4_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n", + vid, vlan_group_get_device(priv->vlgrp, vid)); /* Add VID to port VLAN filter */ mutex_lock(&mdev->state_lock); if (mdev->device_up && priv->port_up) { err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); if (err) - en_err(priv, "Failed configuring VLAN filter\n"); + mlx4_err(mdev, "Failed configuring VLAN filter\n"); } mutex_unlock(&mdev->state_lock); } @@ -94,8 +94,9 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) if (!priv->vlgrp) return; - en_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp entry:%p)\n", - vid, priv->vlgrp, vlan_group_get_device(priv->vlgrp, vid)); + mlx4_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp " + "entry:%p)\n", vid, priv->vlgrp, + vlan_group_get_device(priv->vlgrp, vid)); vlan_group_set_device(priv->vlgrp, vid, NULL); /* Remove VID from port VLAN filter */ @@ -103,7 +104,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) if (mdev->device_up && priv->port_up) { err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); if (err) - en_err(priv, "Failed configuring VLAN filter\n"); + mlx4_err(mdev, "Failed configuring VLAN filter\n"); } mutex_unlock(&mdev->state_lock); } @@ -149,10 +150,9 @@ static void mlx4_en_do_set_mac(struct work_struct *work) err = mlx4_register_mac(mdev->dev, priv->port, priv->mac, &priv->mac_index); if (err) - en_err(priv, "Failed changing HW MAC address\n"); + mlx4_err(mdev, "Failed changing HW MAC address\n"); } else - en_dbg(HW, priv, "Port is down while " - "registering mac, exiting...\n"); + mlx4_dbg(HW, priv, "Port is down, exiting...\n"); mutex_unlock(&mdev->state_lock); } @@ -174,6 +174,7 @@ static void mlx4_en_clear_list(struct net_device *dev) static void mlx4_en_cache_mclist(struct net_device *dev) { struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; struct dev_mc_list *mclist; struct dev_mc_list *tmp; struct dev_mc_list *plist = NULL; @@ -181,7 +182,7 @@ static void mlx4_en_cache_mclist(struct net_device *dev) for (mclist = dev->mc_list; mclist; mclist = mclist->next) { tmp = kmalloc(sizeof(struct dev_mc_list), GFP_ATOMIC); if (!tmp) { - en_err(priv, "failed to allocate multicast list\n"); + mlx4_err(mdev, "failed to allocate multicast list\n"); mlx4_en_clear_list(dev); return; } @@ -218,13 +219,13 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) mutex_lock(&mdev->state_lock); if (!mdev->device_up) { - en_dbg(HW, priv, "Card is not up, " - "ignoring multicast change.\n"); + mlx4_dbg(HW, priv, "Card is not up, ignoring " + "multicast change.\n"); goto out; } if (!priv->port_up) { - en_dbg(HW, priv, "Port is down, " - "ignoring multicast change.\n"); + mlx4_dbg(HW, priv, "Port is down, ignoring " + "multicast change.\n"); goto out; } @@ -235,27 +236,29 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) if (dev->flags & IFF_PROMISC) { if (!(priv->flags & MLX4_EN_FLAG_PROMISC)) { if (netif_msg_rx_status(priv)) - en_warn(priv, "Entering promiscuous mode\n"); + mlx4_warn(mdev, "Port:%d entering promiscuous mode\n", + priv->port); priv->flags |= MLX4_EN_FLAG_PROMISC; /* Enable promiscouos mode */ err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 1); if (err) - en_err(priv, "Failed enabling " - "promiscous mode\n"); + mlx4_err(mdev, "Failed enabling " + "promiscous mode\n"); /* Disable port multicast filter (unconditionally) */ err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 0, MLX4_MCAST_DISABLE); if (err) - en_err(priv, "Failed disabling " - "multicast filter\n"); + mlx4_err(mdev, "Failed disabling " + "multicast filter\n"); /* Disable port VLAN filter */ err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL); if (err) - en_err(priv, "Failed disabling VLAN filter\n"); + mlx4_err(mdev, "Failed disabling " + "VLAN filter\n"); } goto out; } @@ -266,19 +269,20 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) if (priv->flags & MLX4_EN_FLAG_PROMISC) { if (netif_msg_rx_status(priv)) - en_warn(priv, "Leaving promiscuous mode\n"); + mlx4_warn(mdev, "Port:%d leaving promiscuous mode\n", + priv->port); priv->flags &= ~MLX4_EN_FLAG_PROMISC; /* Disable promiscouos mode */ err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 0); if (err) - en_err(priv, "Failed disabling promiscous mode\n"); + mlx4_err(mdev, "Failed disabling promiscous mode\n"); /* Enable port VLAN filter */ err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp); if (err) - en_err(priv, "Failed enabling VLAN filter\n"); + mlx4_err(mdev, "Failed enabling VLAN filter\n"); } /* Enable/disable the multicast filter according to IFF_ALLMULTI */ @@ -286,12 +290,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 0, MLX4_MCAST_DISABLE); if (err) - en_err(priv, "Failed disabling multicast filter\n"); + mlx4_err(mdev, "Failed disabling multicast filter\n"); } else { err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 0, MLX4_MCAST_DISABLE); if (err) - en_err(priv, "Failed disabling multicast filter\n"); + mlx4_err(mdev, "Failed disabling multicast filter\n"); /* Flush mcast filter and init it with broadcast address */ mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST, @@ -310,7 +314,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 0, MLX4_MCAST_ENABLE); if (err) - en_err(priv, "Failed enabling multicast filter\n"); + mlx4_err(mdev, "Failed enabling multicast filter\n"); mlx4_en_clear_list(dev); } @@ -342,10 +346,10 @@ static void mlx4_en_tx_timeout(struct net_device *dev) struct mlx4_en_dev *mdev = priv->mdev; if (netif_msg_timer(priv)) - en_warn(priv, "Tx timeout called on port:%d\n", priv->port); + mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port); priv->port_stats.tx_timeout++; - en_dbg(DRV, priv, "Scheduling watchdog\n"); + mlx4_dbg(DRV, priv, "Scheduling watchdog\n"); queue_work(mdev->workqueue, &priv->watchdog_task); } @@ -372,10 +376,10 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv) * satisfy our coelsing target. * - moder_time is set to a fixed value. */ - priv->rx_frames = MLX4_EN_RX_COAL_TARGET; + priv->rx_frames = MLX4_EN_RX_COAL_TARGET / priv->dev->mtu + 1; priv->rx_usecs = MLX4_EN_RX_COAL_TIME; - en_dbg(INTR, priv, "Default coalesing params for mtu:%d - " - "rx_frames:%d rx_usecs:%d\n", + mlx4_dbg(INTR, priv, "Default coalesing params for mtu:%d - " + "rx_frames:%d rx_usecs:%d\n", priv->dev->mtu, priv->rx_frames, priv->rx_usecs); /* Setup cq moderation params */ @@ -408,6 +412,7 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv) static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv) { unsigned long period = (unsigned long) (jiffies - priv->last_moder_jiffies); + struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_en_cq *cq; unsigned long packets; unsigned long rate; @@ -467,11 +472,11 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv) moder_time = priv->rx_usecs; } - en_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n", - tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period); + mlx4_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n", + tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period); - en_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu " - "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n", + mlx4_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu " + "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n", priv->last_moder_time, moder_time, period, packets, avg_pkt_size, rate); @@ -482,7 +487,8 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv) cq->moder_time = moder_time; err = mlx4_en_set_cq_moder(priv, cq); if (err) { - en_err(priv, "Failed modifying moderation for cq:%d\n", i); + mlx4_err(mdev, "Failed modifying moderation for cq:%d " + "on port:%d\n", i, priv->port); break; } } @@ -505,7 +511,8 @@ static void mlx4_en_do_get_stats(struct work_struct *work) err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0); if (err) - en_dbg(HW, priv, "Could not update stats \n"); + mlx4_dbg(HW, priv, "Could not update stats for " + "port:%d\n", priv->port); mutex_lock(&mdev->state_lock); if (mdev->device_up) { @@ -529,10 +536,12 @@ static void mlx4_en_linkstate(struct work_struct *work) * report to system log */ if (priv->last_link_state != linkstate) { if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) { - en_dbg(LINK, priv, "Link Down\n"); + if (netif_msg_link(priv)) + mlx4_info(mdev, "Port %d - link down\n", priv->port); netif_carrier_off(priv->dev); } else { - en_dbg(LINK, priv, "Link Up\n"); + if (netif_msg_link(priv)) + mlx4_info(mdev, "Port %d - link up\n", priv->port); netif_carrier_on(priv->dev); } } @@ -554,19 +563,19 @@ int mlx4_en_start_port(struct net_device *dev) int j; if (priv->port_up) { - en_dbg(DRV, priv, "start port called while port already up\n"); + mlx4_dbg(DRV, priv, "start port called while port already up\n"); return 0; } /* Calculate Rx buf size */ dev->mtu = min(dev->mtu, priv->max_mtu); mlx4_en_calc_rx_buf(dev); - en_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size); + mlx4_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size); /* Configure rx cq's and rings */ err = mlx4_en_activate_rx_rings(priv); if (err) { - en_err(priv, "Failed to activate RX rings\n"); + mlx4_err(mdev, "Failed to activate RX rings\n"); return err; } for (i = 0; i < priv->rx_ring_num; i++) { @@ -574,14 +583,14 @@ int mlx4_en_start_port(struct net_device *dev) err = mlx4_en_activate_cq(priv, cq); if (err) { - en_err(priv, "Failed activating Rx CQ\n"); + mlx4_err(mdev, "Failed activating Rx CQ\n"); goto cq_err; } for (j = 0; j < cq->size; j++) cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK; err = mlx4_en_set_cq_moder(priv, cq); if (err) { - en_err(priv, "Failed setting cq moderation parameters"); + mlx4_err(mdev, "Failed setting cq moderation parameters"); mlx4_en_deactivate_cq(priv, cq); goto cq_err; } @@ -592,7 +601,7 @@ int mlx4_en_start_port(struct net_device *dev) err = mlx4_en_config_rss_steer(priv); if (err) { - en_err(priv, "Failed configuring rss steering\n"); + mlx4_err(mdev, "Failed configuring rss steering\n"); goto cq_err; } @@ -602,16 +611,16 @@ int mlx4_en_start_port(struct net_device *dev) cq = &priv->tx_cq[i]; err = mlx4_en_activate_cq(priv, cq); if (err) { - en_err(priv, "Failed allocating Tx CQ\n"); + mlx4_err(mdev, "Failed allocating Tx CQ\n"); goto tx_err; } err = mlx4_en_set_cq_moder(priv, cq); if (err) { - en_err(priv, "Failed setting cq moderation parameters"); + mlx4_err(mdev, "Failed setting cq moderation parameters"); mlx4_en_deactivate_cq(priv, cq); goto tx_err; } - en_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i); + mlx4_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i); cq->buf->wqe_index = cpu_to_be16(0xffff); /* Configure ring */ @@ -619,7 +628,7 @@ int mlx4_en_start_port(struct net_device *dev) err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn, priv->rx_ring[0].srq.srqn); if (err) { - en_err(priv, "Failed allocating Tx ring\n"); + mlx4_err(mdev, "Failed allocating Tx ring\n"); mlx4_en_deactivate_cq(priv, cq); goto tx_err; } @@ -637,30 +646,30 @@ int mlx4_en_start_port(struct net_device *dev) priv->prof->rx_pause, priv->prof->rx_ppp); if (err) { - en_err(priv, "Failed setting port general configurations " - "for port %d, with error %d\n", priv->port, err); + mlx4_err(mdev, "Failed setting port general configurations" + " for port %d, with error %d\n", priv->port, err); goto tx_err; } /* Set default qp number */ err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 0); if (err) { - en_err(priv, "Failed setting default qp numbers\n"); + mlx4_err(mdev, "Failed setting default qp numbers\n"); goto tx_err; } /* Set port mac number */ - en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port); + mlx4_dbg(DRV, priv, "Setting mac for port %d\n", priv->port); err = mlx4_register_mac(mdev->dev, priv->port, priv->mac, &priv->mac_index); if (err) { - en_err(priv, "Failed setting port mac\n"); + mlx4_err(mdev, "Failed setting port mac\n"); goto tx_err; } /* Init port */ - en_dbg(HW, priv, "Initializing port\n"); + mlx4_dbg(HW, priv, "Initializing port\n"); err = mlx4_INIT_PORT(mdev->dev, priv->port); if (err) { - en_err(priv, "Failed Initializing port\n"); + mlx4_err(mdev, "Failed Initializing port\n"); goto mac_err; } @@ -697,7 +706,8 @@ void mlx4_en_stop_port(struct net_device *dev) int i; if (!priv->port_up) { - en_dbg(DRV, priv, "stop port called while port already down\n"); + mlx4_dbg(DRV, priv, "stop port (%d) called while port already down\n", + priv->port); return; } netif_stop_queue(dev); @@ -742,13 +752,13 @@ static void mlx4_en_restart(struct work_struct *work) struct mlx4_en_dev *mdev = priv->mdev; struct net_device *dev = priv->dev; - en_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port); + mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port); mutex_lock(&mdev->state_lock); if (priv->port_up) { mlx4_en_stop_port(dev); if (mlx4_en_start_port(dev)) - en_err(priv, "Failed restarting port %d\n", priv->port); + mlx4_err(mdev, "Failed restarting port %d\n", priv->port); } mutex_unlock(&mdev->state_lock); } @@ -764,14 +774,14 @@ static int mlx4_en_open(struct net_device *dev) mutex_lock(&mdev->state_lock); if (!mdev->device_up) { - en_err(priv, "Cannot open - device down/disabled\n"); + mlx4_err(mdev, "Cannot open - device down/disabled\n"); err = -EBUSY; goto out; } /* Reset HW statistics and performance counters */ if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1)) - en_dbg(HW, priv, "Failed dumping statistics\n"); + mlx4_dbg(HW, priv, "Failed dumping statistics\n"); memset(&priv->stats, 0, sizeof(priv->stats)); memset(&priv->pstats, 0, sizeof(priv->pstats)); @@ -788,7 +798,7 @@ static int mlx4_en_open(struct net_device *dev) mlx4_en_set_default_moderation(priv); err = mlx4_en_start_port(dev); if (err) - en_err(priv, "Failed starting port:%d\n", priv->port); + mlx4_err(mdev, "Failed starting port:%d\n", priv->port); out: mutex_unlock(&mdev->state_lock); @@ -801,7 +811,8 @@ static int mlx4_en_close(struct net_device *dev) struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; - en_dbg(IFDOWN, priv, "Close port called\n"); + if (netif_msg_ifdown(priv)) + mlx4_info(mdev, "Close called for port:%d\n", priv->port); mutex_lock(&mdev->state_lock); @@ -833,6 +844,7 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv) int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) { + struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_en_port_profile *prof = priv->prof; int i; @@ -861,7 +873,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) return 0; err: - en_err(priv, "Failed to allocate NIC resources\n"); + mlx4_err(mdev, "Failed to allocate NIC resources\n"); return -ENOMEM; } @@ -871,7 +883,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev) struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_dev *mdev = priv->mdev; - en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port); + mlx4_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port); /* Unregister device - this will close the port if it was up */ if (priv->registered) @@ -900,11 +912,11 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu) struct mlx4_en_dev *mdev = priv->mdev; int err = 0; - en_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n", + mlx4_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n", dev->mtu, new_mtu); if ((new_mtu < MLX4_EN_MIN_MTU) || (new_mtu > priv->max_mtu)) { - en_err(priv, "Bad MTU size:%d.\n", new_mtu); + mlx4_err(mdev, "Bad MTU size:%d.\n", new_mtu); return -EPERM; } dev->mtu = new_mtu; @@ -914,13 +926,13 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu) if (!mdev->device_up) { /* NIC is probably restarting - let watchdog task reset * the port */ - en_dbg(DRV, priv, "Change MTU called with card down!?\n"); + mlx4_dbg(DRV, priv, "Change MTU called with card down!?\n"); } else { mlx4_en_stop_port(dev); mlx4_en_set_default_moderation(priv); err = mlx4_en_start_port(dev); if (err) { - en_err(priv, "Failed restarting port:%d\n", + mlx4_err(mdev, "Failed restarting port:%d\n", priv->port); queue_work(mdev->workqueue, &priv->watchdog_task); } @@ -934,7 +946,6 @@ static const struct net_device_ops mlx4_netdev_ops = { .ndo_open = mlx4_en_open, .ndo_stop = mlx4_en_close, .ndo_start_xmit = mlx4_en_xmit, - .ndo_select_queue = mlx4_en_select_queue, .ndo_get_stats = mlx4_en_get_stats, .ndo_set_multicast_list = mlx4_en_set_multicast, .ndo_set_mac_address = mlx4_en_set_mac, @@ -957,7 +968,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, int i; int err; - dev = alloc_etherdev_mq(sizeof(struct mlx4_en_priv), prof->tx_ring_num); + dev = alloc_etherdev(sizeof(struct mlx4_en_priv)); if (dev == NULL) { mlx4_err(mdev, "Net device allocation failed\n"); return -ENOMEM; @@ -995,7 +1006,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port]; priv->mac = mdev->dev->caps.def_mac[priv->port]; if (ILLEGAL_MAC(priv->mac)) { - en_err(priv, "Port: %d, invalid mac burned: 0x%llx, quiting\n", + mlx4_err(mdev, "Port: %d, invalid mac burned: 0x%llx, quiting\n", priv->port, priv->mac); err = -EINVAL; goto out; @@ -1014,17 +1025,19 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, err = mlx4_alloc_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE); if (err) { - en_err(priv, "Failed to allocate page for rx qps\n"); + mlx4_err(mdev, "Failed to allocate page for rx qps\n"); goto out; } priv->allocated = 1; + /* Populate Tx priority mappings */ + mlx4_en_set_prio_map(priv, priv->tx_prio_map, prof->tx_ring_num); + /* * Initialize netdev entry points */ dev->netdev_ops = &mlx4_netdev_ops; dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT; - dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS; SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops); @@ -1038,9 +1051,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, * Set driver features */ dev->features |= NETIF_F_SG; - dev->vlan_features |= NETIF_F_SG; dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; dev->features |= NETIF_F_HIGHDMA; dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | @@ -1050,8 +1061,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, if (mdev->LSO_support) { dev->features |= NETIF_F_TSO; dev->features |= NETIF_F_TSO6; - dev->vlan_features |= NETIF_F_TSO; - dev->vlan_features |= NETIF_F_TSO6; } mdev->pndev[port] = dev; @@ -1059,13 +1068,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, netif_carrier_off(dev); err = register_netdev(dev); if (err) { - en_err(priv, "Netdev registration failed for port %d\n", port); + mlx4_err(mdev, "Netdev registration failed\n"); goto out; } - - en_warn(priv, "Using %d TX rings\n", prof->tx_ring_num); - en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num); - priv->registered = 1; queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); return 0; diff --git a/trunk/drivers/net/mlx4/en_ethtool.c b/trunk/drivers/net/mlx4/en_params.c similarity index 86% rename from trunk/drivers/net/mlx4/en_ethtool.c rename to trunk/drivers/net/mlx4/en_params.c index 091f99052c91..c1bd040b9e05 100644 --- a/trunk/drivers/net/mlx4/en_ethtool.c +++ b/trunk/drivers/net/mlx4/en_params.c @@ -38,6 +38,64 @@ #include "mlx4_en.h" #include "en_port.h" +#define MLX4_EN_PARM_INT(X, def_val, desc) \ + static unsigned int X = def_val;\ + module_param(X , uint, 0444); \ + MODULE_PARM_DESC(X, desc); + + +/* + * Device scope module parameters + */ + + +/* Use a XOR rathern than Toeplitz hash function for RSS */ +MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS"); + +/* RSS hash type mask - default to */ +MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask"); + +/* Number of LRO sessions per Rx ring (rounded up to a power of two) */ +MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS, + "Number of LRO sessions per ring or disabled (0)"); + +/* Priority pausing */ +MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]." + " Per priority bit mask"); +MLX4_EN_PARM_INT(pfcrx, 0, "Priority based Flow Control policy on RX[7:0]." + " Per priority bit mask"); + +int mlx4_en_get_profile(struct mlx4_en_dev *mdev) +{ + struct mlx4_en_profile *params = &mdev->profile; + int i; + + params->rss_xor = (rss_xor != 0); + params->rss_mask = rss_mask & 0x1f; + params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); + for (i = 1; i <= MLX4_MAX_PORTS; i++) { + params->prof[i].rx_pause = 1; + params->prof[i].rx_ppp = pfcrx; + params->prof[i].tx_pause = 1; + params->prof[i].tx_ppp = pfctx; + params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE; + params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; + } + if (pfcrx || pfctx) { + params->prof[1].tx_ring_num = MLX4_EN_TX_RING_NUM; + params->prof[2].tx_ring_num = MLX4_EN_TX_RING_NUM; + } else { + params->prof[1].tx_ring_num = 1; + params->prof[2].tx_ring_num = 1; + } + + return 0; +} + + +/* + * Ethtool support + */ static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv) { @@ -268,7 +326,8 @@ static int mlx4_en_set_coalesce(struct net_device *dev, priv->rx_frames = (coal->rx_max_coalesced_frames == MLX4_EN_AUTO_CONF) ? - MLX4_EN_RX_COAL_TARGET : + MLX4_EN_RX_COAL_TARGET / + priv->dev->mtu + 1 : coal->rx_max_coalesced_frames; priv->rx_usecs = (coal->rx_coalesce_usecs == MLX4_EN_AUTO_CONF) ? @@ -312,7 +371,7 @@ static int mlx4_en_set_pauseparam(struct net_device *dev, priv->prof->rx_pause, priv->prof->rx_ppp); if (err) - en_err(priv, "Failed setting pause params\n"); + mlx4_err(mdev, "Failed setting pause params to\n"); return err; } @@ -362,13 +421,13 @@ static int mlx4_en_set_ringparam(struct net_device *dev, err = mlx4_en_alloc_resources(priv); if (err) { - en_err(priv, "Failed reallocating port resources\n"); + mlx4_err(mdev, "Failed reallocating port resources\n"); goto out; } if (port_up) { err = mlx4_en_start_port(dev); if (err) - en_err(priv, "Failed starting port\n"); + mlx4_err(mdev, "Failed starting port\n"); } out: diff --git a/trunk/drivers/net/mlx4/en_rx.c b/trunk/drivers/net/mlx4/en_rx.c index 5a14899c1e25..6bfab6e5ba1d 100644 --- a/trunk/drivers/net/mlx4/en_rx.c +++ b/trunk/drivers/net/mlx4/en_rx.c @@ -114,8 +114,8 @@ static int mlx4_en_init_allocator(struct mlx4_en_priv *priv, goto out; page_alloc->offset = priv->frag_info[i].frag_align; - en_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n", - i, page_alloc->page); + mlx4_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n", + i, page_alloc->page); } return 0; @@ -136,8 +136,8 @@ static void mlx4_en_destroy_allocator(struct mlx4_en_priv *priv, for (i = 0; i < priv->num_frags; i++) { page_alloc = &ring->page_alloc[i]; - en_dbg(DRV, priv, "Freeing allocator:%d count:%d\n", - i, page_count(page_alloc->page)); + mlx4_dbg(DRV, priv, "Freeing allocator:%d count:%d\n", + i, page_count(page_alloc->page)); put_page(page_alloc->page); page_alloc->page = NULL; @@ -214,10 +214,10 @@ static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv, skb_frags = ring->rx_info + (index << priv->log_rx_info); for (nr = 0; nr < priv->num_frags; nr++) { - en_dbg(DRV, priv, "Freeing fragment:%d\n", nr); + mlx4_dbg(DRV, priv, "Freeing fragment:%d\n", nr); dma = be64_to_cpu(rx_desc->data[nr].addr); - en_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma); + mlx4_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma); pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size, PCI_DMA_FROMDEVICE); put_page(skb_frags[nr].page); @@ -226,6 +226,7 @@ static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv, static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv) { + struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_en_rx_ring *ring; int ring_ind; int buf_ind; @@ -238,14 +239,14 @@ static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv) if (mlx4_en_prepare_rx_desc(priv, ring, ring->actual_size)) { if (ring->actual_size < MLX4_EN_MIN_RX_SIZE) { - en_err(priv, "Failed to allocate " - "enough rx buffers\n"); + mlx4_err(mdev, "Failed to allocate " + "enough rx buffers\n"); return -ENOMEM; } else { new_size = rounddown_pow_of_two(ring->actual_size); - en_warn(priv, "Only %d buffers allocated " - "reducing ring size to %d", - ring->actual_size, new_size); + mlx4_warn(mdev, "Only %d buffers allocated " + "reducing ring size to %d", + ring->actual_size, new_size); goto reduce_rings; } } @@ -281,7 +282,8 @@ static int mlx4_en_fill_rx_buf(struct net_device *dev, ring->size_mask); if (err) { if (netif_msg_rx_err(priv)) - en_warn(priv, "Failed preparing rx descriptor\n"); + mlx4_warn(priv->mdev, + "Failed preparing rx descriptor\n"); priv->port_stats.rx_alloc_failed++; break; } @@ -299,14 +301,14 @@ static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv, { int index; - en_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n", - ring->cons, ring->prod); + mlx4_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n", + ring->cons, ring->prod); /* Unmap and free Rx buffers */ BUG_ON((u32) (ring->prod - ring->cons) > ring->actual_size); while (ring->cons != ring->prod) { index = ring->cons & ring->size_mask; - en_dbg(DRV, priv, "Processing descriptor:%d\n", index); + mlx4_dbg(DRV, priv, "Processing descriptor:%d\n", index); mlx4_en_free_rx_desc(priv, ring, index); ++ring->cons; } @@ -371,10 +373,10 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, sizeof(struct skb_frag_struct)); ring->rx_info = vmalloc(tmp); if (!ring->rx_info) { - en_err(priv, "Failed allocating rx_info ring\n"); + mlx4_err(mdev, "Failed allocating rx_info ring\n"); return -ENOMEM; } - en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n", + mlx4_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n", ring->rx_info, tmp); err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres, @@ -384,7 +386,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, err = mlx4_en_map_buffer(&ring->wqres.buf); if (err) { - en_err(priv, "Failed to map RX buffer\n"); + mlx4_err(mdev, "Failed to map RX buffer\n"); goto err_hwq; } ring->buf = ring->wqres.buf.direct.buf; @@ -402,7 +404,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, sizeof(struct net_lro_desc), GFP_KERNEL); if (!ring->lro.lro_arr) { - en_err(priv, "Failed to allocate lro array\n"); + mlx4_err(mdev, "Failed to allocate lro array\n"); goto err_map; } ring->lro.get_frag_header = mlx4_en_get_frag_header; @@ -453,7 +455,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) /* Initialize page allocators */ err = mlx4_en_init_allocator(priv, ring); if (err) { - en_err(priv, "Failed initializing ring allocator\n"); + mlx4_err(mdev, "Failed initializing ring allocator\n"); ring_ind--; goto err_allocator; } @@ -484,7 +486,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) err = mlx4_srq_alloc(mdev->dev, mdev->priv_pdn, &ring->wqres.mtt, ring->wqres.db.dma, &ring->srq); if (err){ - en_err(priv, "Failed to allocate srq\n"); + mlx4_err(mdev, "Failed to allocate srq\n"); ring_ind--; goto err_srq; } @@ -599,7 +601,7 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, skb = dev_alloc_skb(SMALL_PACKET_SIZE + NET_IP_ALIGN); if (!skb) { - en_dbg(RX_ERR, priv, "Failed allocating skb\n"); + mlx4_dbg(RX_ERR, priv, "Failed allocating skb\n"); return NULL; } skb->dev = priv->dev; @@ -678,6 +680,7 @@ static void mlx4_en_copy_desc(struct mlx4_en_priv *priv, int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) { struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_cqe *cqe; struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring]; struct skb_frag_struct *skb_frags; @@ -714,14 +717,14 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud /* Drop packet on bad receive or bad checksum */ if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == MLX4_CQE_OPCODE_ERROR)) { - en_err(priv, "CQE completed in error - vendor " + mlx4_err(mdev, "CQE completed in error - vendor " "syndrom:%d syndrom:%d\n", ((struct mlx4_err_cqe *) cqe)->vendor_err_syndrome, ((struct mlx4_err_cqe *) cqe)->syndrome); goto next; } if (unlikely(cqe->badfcs_enc & MLX4_CQE_BAD_FCS)) { - en_dbg(RX_ERR, priv, "Accepted frame with bad FCS\n"); + mlx4_dbg(RX_ERR, priv, "Accepted frame with bad FCS\n"); goto next; } @@ -871,7 +874,7 @@ static int mlx4_en_last_alloc_offset(struct mlx4_en_priv *priv, u16 stride, u16 u16 res = MLX4_EN_ALLOC_SIZE % stride; u16 offset = MLX4_EN_ALLOC_SIZE - stride - res + align; - en_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d " + mlx4_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d " "res:%d offset:%d\n", stride, align, res, offset); return offset; } @@ -916,10 +919,10 @@ void mlx4_en_calc_rx_buf(struct net_device *dev) priv->rx_skb_size = eff_mtu; priv->log_rx_info = ROUNDUP_LOG2(i * sizeof(struct skb_frag_struct)); - en_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d " + mlx4_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d " "num_frags:%d):\n", eff_mtu, priv->num_frags); for (i = 0; i < priv->num_frags; i++) { - en_dbg(DRV, priv, " frag:%d - size:%d prefix:%d align:%d " + mlx4_dbg(DRV, priv, " frag:%d - size:%d prefix:%d align:%d " "stride:%d last_offset:%d\n", i, priv->frag_info[i].frag_size, priv->frag_info[i].frag_prefix_size, @@ -939,12 +942,12 @@ void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv, int i; rss_map->size = roundup_pow_of_two(num_entries); - en_dbg(DRV, priv, "Setting default RSS map of %d entires\n", - rss_map->size); + mlx4_dbg(DRV, priv, "Setting default RSS map of %d entires\n", + rss_map->size); for (i = 0; i < rss_map->size; i++) { rss_map->map[i] = i % num_rings; - en_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]); + mlx4_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]); } } @@ -959,13 +962,13 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, context = kmalloc(sizeof *context , GFP_KERNEL); if (!context) { - en_err(priv, "Failed to allocate qp context\n"); + mlx4_err(mdev, "Failed to allocate qp context\n"); return -ENOMEM; } err = mlx4_qp_alloc(mdev->dev, qpn, qp); if (err) { - en_err(priv, "Failed to allocate qp #%x\n", qpn); + mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn); goto out; } qp->event = mlx4_en_sqp_event; @@ -997,11 +1000,12 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) int err = 0; int good_qps = 0; - en_dbg(DRV, priv, "Configuring rss steering\n"); + mlx4_dbg(DRV, priv, "Configuring rss steering for port %u\n", priv->port); err = mlx4_qp_reserve_range(mdev->dev, rss_map->size, rss_map->size, &rss_map->base_qpn); if (err) { - en_err(priv, "Failed reserving %d qps\n", rss_map->size); + mlx4_err(mdev, "Failed reserving %d qps for port %u\n", + rss_map->size, priv->port); return err; } @@ -1021,13 +1025,13 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) /* Configure RSS indirection qp */ err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &priv->base_qpn); if (err) { - en_err(priv, "Failed to reserve range for RSS " - "indirection qp\n"); + mlx4_err(mdev, "Failed to reserve range for RSS " + "indirection qp\n"); goto rss_err; } err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, &rss_map->indir_qp); if (err) { - en_err(priv, "Failed to allocate RSS indirection QP\n"); + mlx4_err(mdev, "Failed to allocate RSS indirection QP\n"); goto reserve_err; } rss_map->indir_qp.event = mlx4_en_sqp_event; diff --git a/trunk/drivers/net/mlx4/en_tx.c b/trunk/drivers/net/mlx4/en_tx.c index 5dc7466ad035..ac6fc499b280 100644 --- a/trunk/drivers/net/mlx4/en_tx.c +++ b/trunk/drivers/net/mlx4/en_tx.c @@ -68,15 +68,15 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, tmp = size * sizeof(struct mlx4_en_tx_info); ring->tx_info = vmalloc(tmp); if (!ring->tx_info) { - en_err(priv, "Failed allocating tx_info ring\n"); + mlx4_err(mdev, "Failed allocating tx_info ring\n"); return -ENOMEM; } - en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n", + mlx4_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n", ring->tx_info, tmp); ring->bounce_buf = kmalloc(MAX_DESC_SIZE, GFP_KERNEL); if (!ring->bounce_buf) { - en_err(priv, "Failed allocating bounce buffer\n"); + mlx4_err(mdev, "Failed allocating bounce buffer\n"); err = -ENOMEM; goto err_tx; } @@ -85,31 +85,31 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres, ring->buf_size, 2 * PAGE_SIZE); if (err) { - en_err(priv, "Failed allocating hwq resources\n"); + mlx4_err(mdev, "Failed allocating hwq resources\n"); goto err_bounce; } err = mlx4_en_map_buffer(&ring->wqres.buf); if (err) { - en_err(priv, "Failed to map TX buffer\n"); + mlx4_err(mdev, "Failed to map TX buffer\n"); goto err_hwq_res; } ring->buf = ring->wqres.buf.direct.buf; - en_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d " - "buf_size:%d dma:%llx\n", ring, ring->buf, ring->size, - ring->buf_size, (unsigned long long) ring->wqres.buf.direct.map); + mlx4_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d " + "buf_size:%d dma:%llx\n", ring, ring->buf, ring->size, + ring->buf_size, (unsigned long long) ring->wqres.buf.direct.map); err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &ring->qpn); if (err) { - en_err(priv, "Failed reserving qp for tx ring.\n"); + mlx4_err(mdev, "Failed reserving qp for tx ring.\n"); goto err_map; } err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->qp); if (err) { - en_err(priv, "Failed allocating qp %d\n", ring->qpn); + mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn); goto err_reserve; } ring->qp.event = mlx4_en_sqp_event; @@ -135,7 +135,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring) { struct mlx4_en_dev *mdev = priv->mdev; - en_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn); + mlx4_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn); mlx4_qp_remove(mdev->dev, &ring->qp); mlx4_qp_free(mdev->dev, &ring->qp); @@ -274,12 +274,12 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring) /* Skip last polled descriptor */ ring->cons += ring->last_nr_txbb; - en_dbg(DRV, priv, "Freeing Tx buf - cons:0x%x prod:0x%x\n", + mlx4_dbg(DRV, priv, "Freeing Tx buf - cons:0x%x prod:0x%x\n", ring->cons, ring->prod); if ((u32) (ring->prod - ring->cons) > ring->size) { if (netif_msg_tx_err(priv)) - en_warn(priv, "Tx consumer passed producer!\n"); + mlx4_warn(priv->mdev, "Tx consumer passed producer!\n"); return 0; } @@ -292,11 +292,39 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring) } if (cnt) - en_dbg(DRV, priv, "Freed %d uncompleted tx descriptors\n", cnt); + mlx4_dbg(DRV, priv, "Freed %d uncompleted tx descriptors\n", cnt); return cnt; } +void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num) +{ + int block = 8 / ring_num; + int extra = 8 - (block * ring_num); + int num = 0; + u16 ring = 1; + int prio; + + if (ring_num == 1) { + for (prio = 0; prio < 8; prio++) + prio_map[prio] = 0; + return; + } + + for (prio = 0; prio < 8; prio++) { + if (extra && (num == block + 1)) { + ring++; + num = 0; + extra--; + } else if (!extra && (num == block)) { + ring++; + num = 0; + } + prio_map[prio] = ring; + mlx4_dbg(DRV, priv, " prio:%d --> ring:%d\n", prio, ring); + num++; + } +} static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) { @@ -358,8 +386,18 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) if (unlikely(ring->blocked)) { if ((u32) (ring->prod - ring->cons) <= ring->size - HEADROOM - MAX_DESC_TXBBS) { + + /* TODO: support multiqueue netdevs. Currently, we block + * when *any* ring is full. Note that: + * - 2 Tx rings can unblock at the same time and call + * netif_wake_queue(), which is OK since this + * operation is idempotent. + * - We might wake the queue just after another ring + * stopped it. This is no big deal because the next + * transmission on that ring would stop the queue. + */ ring->blocked = 0; - netif_tx_wake_queue(netdev_get_tx_queue(dev, cq->ring)); + netif_wake_queue(dev); priv->port_stats.wake_queue++; } } @@ -388,7 +426,7 @@ void mlx4_en_poll_tx_cq(unsigned long data) INC_PERF_COUNTER(priv->pstats.tx_poll); - if (!spin_trylock_irq(&ring->comp_lock)) { + if (!spin_trylock(&ring->comp_lock)) { mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT); return; } @@ -401,7 +439,7 @@ void mlx4_en_poll_tx_cq(unsigned long data) if (inflight && priv->port_up) mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT); - spin_unlock_irq(&ring->comp_lock); + spin_unlock(&ring->comp_lock); } static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv, @@ -444,9 +482,9 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind) /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */ if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0) - if (spin_trylock_irq(&ring->comp_lock)) { + if (spin_trylock(&ring->comp_lock)) { mlx4_en_process_tx_cq(priv->dev, cq); - spin_unlock_irq(&ring->comp_lock); + spin_unlock(&ring->comp_lock); } } @@ -501,6 +539,7 @@ static int get_real_size(struct sk_buff *skb, struct net_device *dev, int *lso_header_size) { struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; int real_size; if (skb_is_gso(skb)) { @@ -514,14 +553,14 @@ static int get_real_size(struct sk_buff *skb, struct net_device *dev, real_size += DS_SIZE; else { if (netif_msg_tx_err(priv)) - en_warn(priv, "Non-linear headers\n"); + mlx4_warn(mdev, "Non-linear headers\n"); dev_kfree_skb_any(skb); return 0; } } if (unlikely(*lso_header_size > MAX_LSO_HDR_SIZE)) { if (netif_msg_tx_err(priv)) - en_warn(priv, "LSO header size too big\n"); + mlx4_warn(mdev, "LSO header size too big\n"); dev_kfree_skb_any(skb); return 0; } @@ -578,20 +617,21 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f; } -u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) +static int get_vlan_info(struct mlx4_en_priv *priv, struct sk_buff *skb, + u16 *vlan_tag) { - struct mlx4_en_priv *priv = netdev_priv(dev); - u16 vlan_tag = 0; + int tx_ind; - /* If we support per priority flow control and the packet contains - * a vlan tag, send the packet to the TX ring assigned to that priority - */ - if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) { - vlan_tag = vlan_tx_tag_get(skb); - return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13); + /* Obtain VLAN information if present */ + if (priv->vlgrp && vlan_tx_tag_present(skb)) { + *vlan_tag = vlan_tx_tag_get(skb); + /* Set the Tx ring to use according to vlan priority */ + tx_ind = priv->tx_prio_map[*vlan_tag >> 13]; + } else { + *vlan_tag = 0; + tx_ind = 0; } - - return skb_tx_hash(dev, skb); + return tx_ind; } int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) @@ -611,7 +651,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) dma_addr_t dma; u32 index; __be32 op_own; - u16 vlan_tag = 0; + u16 vlan_tag; int i; int lso_header_size; void *fragptr; @@ -629,21 +669,20 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) nr_txbb = desc_size / TXBB_SIZE; if (unlikely(nr_txbb > MAX_DESC_TXBBS)) { if (netif_msg_tx_err(priv)) - en_warn(priv, "Oversized header or SG list\n"); + mlx4_warn(mdev, "Oversized header or SG list\n"); dev_kfree_skb_any(skb); return NETDEV_TX_OK; } - tx_ind = skb->queue_mapping; + tx_ind = get_vlan_info(priv, skb, &vlan_tag); ring = &priv->tx_ring[tx_ind]; - if (priv->vlgrp && vlan_tx_tag_present(skb)) - vlan_tag = vlan_tx_tag_get(skb); /* Check available TXBBs And 2K spare for prefetch */ if (unlikely(((int)(ring->prod - ring->cons)) > ring->size - HEADROOM - MAX_DESC_TXBBS)) { - /* every full Tx ring stops queue */ - netif_tx_stop_queue(netdev_get_tx_queue(dev, tx_ind)); + /* every full Tx ring stops queue. + * TODO: implement multi-queue support (per-queue stop) */ + netif_stop_queue(dev); ring->blocked = 1; priv->port_stats.queue_stopped++; @@ -656,7 +695,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) /* Now that we know what Tx ring to use */ if (unlikely(!priv->port_up)) { if (netif_msg_tx_err(priv)) - en_warn(priv, "xmit: port down!\n"); + mlx4_warn(mdev, "xmit: port down!\n"); dev_kfree_skb_any(skb); return NETDEV_TX_OK; } @@ -780,6 +819,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) /* Ring doorbell! */ wmb(); writel(ring->doorbell_qpn, mdev->uar_map + MLX4_SEND_DOORBELL); + dev->trans_start = jiffies; /* Poll CQ here */ mlx4_en_xmit_poll(priv, tx_ind); diff --git a/trunk/drivers/net/mlx4/eq.c b/trunk/drivers/net/mlx4/eq.c index dee188761a3c..8830dcb92ec8 100644 --- a/trunk/drivers/net/mlx4/eq.c +++ b/trunk/drivers/net/mlx4/eq.c @@ -623,10 +623,8 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE, (dev->flags & MLX4_FLAG_MSI_X) ? i : 0, &priv->eq_table.eq[i]); - if (err) { - --i; + if (err) goto err_out_unmap; - } } err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE, diff --git a/trunk/drivers/net/mlx4/mlx4_en.h b/trunk/drivers/net/mlx4/mlx4_en.h index d43a9e4c2aea..ef840abbcd39 100644 --- a/trunk/drivers/net/mlx4/mlx4_en.h +++ b/trunk/drivers/net/mlx4/mlx4_en.h @@ -49,42 +49,26 @@ #include "en_port.h" #define DRV_NAME "mlx4_en" -#define DRV_VERSION "1.4.1.1" -#define DRV_RELDATE "June 2009" +#define DRV_VERSION "1.4.0" +#define DRV_RELDATE "Sep 2008" #define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) -#define en_print(level, priv, format, arg...) \ - { \ - if ((priv)->registered) \ - printk(level "%s: %s: " format, DRV_NAME, \ - (priv->dev)->name, ## arg); \ - else \ - printk(level "%s: %s: Port %d: " format, \ - DRV_NAME, dev_name(&priv->mdev->pdev->dev), \ - (priv)->port, ## arg); \ - } - -#define en_dbg(mlevel, priv, format, arg...) \ - { \ - if (NETIF_MSG_##mlevel & priv->msg_enable) \ - en_print(KERN_DEBUG, priv, format, ## arg) \ - } -#define en_warn(priv, format, arg...) \ - en_print(KERN_WARNING, priv, format, ## arg) -#define en_err(priv, format, arg...) \ - en_print(KERN_ERR, priv, format, ## arg) +#define mlx4_dbg(mlevel, priv, format, arg...) \ + if (NETIF_MSG_##mlevel & priv->msg_enable) \ + printk(KERN_DEBUG "%s %s: " format , DRV_NAME ,\ + (dev_name(&priv->mdev->pdev->dev)) , ## arg) #define mlx4_err(mdev, format, arg...) \ printk(KERN_ERR "%s %s: " format , DRV_NAME ,\ - dev_name(&mdev->pdev->dev) , ## arg) + (dev_name(&mdev->pdev->dev)) , ## arg) #define mlx4_info(mdev, format, arg...) \ printk(KERN_INFO "%s %s: " format , DRV_NAME ,\ - dev_name(&mdev->pdev->dev) , ## arg) + (dev_name(&mdev->pdev->dev)) , ## arg) #define mlx4_warn(mdev, format, arg...) \ printk(KERN_WARNING "%s %s: " format , DRV_NAME ,\ - dev_name(&mdev->pdev->dev) , ## arg) + (dev_name(&mdev->pdev->dev)) , ## arg) /* * Device constants @@ -139,14 +123,12 @@ enum { #define MLX4_EN_MIN_RX_SIZE (MLX4_EN_ALLOC_SIZE / SMP_CACHE_BYTES) #define MLX4_EN_MIN_TX_SIZE (4096 / TXBB_SIZE) -#define MLX4_EN_SMALL_PKT_SIZE 64 -#define MLX4_EN_NUM_TX_RINGS 8 -#define MLX4_EN_NUM_PPP_RINGS 8 -#define MLX4_EN_DEF_TX_RING_SIZE 512 +#define MLX4_EN_TX_RING_NUM 9 +#define MLX4_EN_DEF_TX_RING_SIZE 1024 #define MLX4_EN_DEF_RX_RING_SIZE 1024 -/* Target number of packets to coalesce with interrupt moderation */ -#define MLX4_EN_RX_COAL_TARGET 44 +/* Target number of bytes to coalesce with interrupt moderation */ +#define MLX4_EN_RX_COAL_TARGET 0x20000 #define MLX4_EN_RX_COAL_TIME 0x10 #define MLX4_EN_TX_COAL_PKTS 5 @@ -480,6 +462,7 @@ struct mlx4_en_priv { int base_qpn; struct mlx4_en_rss_map rss_map; + u16 tx_prio_map[8]; u32 flags; #define MLX4_EN_FLAG_PROMISC 0x1 u32 tx_ring_num; @@ -517,6 +500,8 @@ void mlx4_en_stop_port(struct net_device *dev); void mlx4_en_free_resources(struct mlx4_en_priv *priv); int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); +int mlx4_en_get_profile(struct mlx4_en_dev *mdev); + int mlx4_en_create_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, int entries, int ring, enum cq_type mode); void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); @@ -527,7 +512,6 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); void mlx4_en_poll_tx_cq(unsigned long data); void mlx4_en_tx_irq(struct mlx4_cq *mcq); -u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb); int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev); int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring, @@ -562,6 +546,7 @@ void mlx4_en_calc_rx_buf(struct net_device *dev); void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv, struct mlx4_en_rss_map *rss_map, int num_entries, int num_rings); +void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num); int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv); void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv); int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring); diff --git a/trunk/drivers/net/mlx4/mr.c b/trunk/drivers/net/mlx4/mr.c index 0a467785f065..0caf74cae8bc 100644 --- a/trunk/drivers/net/mlx4/mr.c +++ b/trunk/drivers/net/mlx4/mr.c @@ -402,8 +402,7 @@ static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt, for (i = 0; i < npages; ++i) mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT); - dma_sync_single_for_cpu(&dev->pdev->dev, dma_handle, - npages * sizeof (u64), DMA_TO_DEVICE); + dma_sync_single(&dev->pdev->dev, dma_handle, npages * sizeof (u64), DMA_TO_DEVICE); return 0; } @@ -550,8 +549,8 @@ int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list for (i = 0; i < npages; ++i) fmr->mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT); - dma_sync_single_for_cpu(&dev->pdev->dev, fmr->dma_handle, - npages * sizeof(u64), DMA_TO_DEVICE); + dma_sync_single(&dev->pdev->dev, fmr->dma_handle, + npages * sizeof(u64), DMA_TO_DEVICE); fmr->mpt->key = cpu_to_be32(key); fmr->mpt->lkey = cpu_to_be32(key); diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index b4e18a58cb1b..1361ddc8d31f 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -55,7 +55,6 @@ #include #include #include -#include static char mv643xx_eth_driver_name[] = "mv643xx_eth"; static char mv643xx_eth_driver_version[] = "1.4"; @@ -1722,20 +1721,20 @@ static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr) static u32 uc_addr_filter_mask(struct net_device *dev) { - struct netdev_hw_addr *ha; + struct dev_addr_list *uc_ptr; u32 nibbles; if (dev->flags & IFF_PROMISC) return 0; nibbles = 1 << (dev->dev_addr[5] & 0x0f); - list_for_each_entry(ha, &dev->uc_list, list) { - if (memcmp(dev->dev_addr, ha->addr, 5)) + for (uc_ptr = dev->uc_list; uc_ptr != NULL; uc_ptr = uc_ptr->next) { + if (memcmp(dev->dev_addr, uc_ptr->da_addr, 5)) return 0; - if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0) + if ((dev->dev_addr[5] ^ uc_ptr->da_addr[5]) & 0xf0) return 0; - nibbles |= 1 << (ha->addr[5] & 0x0f); + nibbles |= 1 << (uc_ptr->da_addr[5] & 0x0f); } return nibbles; diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index c9a30d3a66fb..7e28b4610122 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -2892,6 +2892,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev) tx->stop_queue++; netif_tx_stop_queue(netdev_queue); } + dev->trans_start = jiffies; return 0; abort_linearize: diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index 6f77ad58e3b3..4a51c31330da 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -178,8 +178,10 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; - vfree(rds_ring->rx_buf_arr); - rds_ring->rx_buf_arr = NULL; + if (rds_ring->rx_buf_arr) { + vfree(rds_ring->rx_buf_arr); + rds_ring->rx_buf_arr = NULL; + } } kfree(recv_ctx->rds_rings); @@ -188,7 +190,8 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) return; tx_ring = adapter->tx_ring; - vfree(tx_ring->cmd_buf_arr); + if (tx_ring->cmd_buf_arr) + vfree(tx_ring->cmd_buf_arr); } int netxen_alloc_sw_resources(struct netxen_adapter *adapter) diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 98737ef72936..50477f5c3ecb 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -1496,6 +1496,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) netxen_nic_update_cmd_producer(adapter, tx_ring, producer); adapter->stats.xmitcalled++; + netdev->trans_start = jiffies; return NETDEV_TX_OK; diff --git a/trunk/drivers/net/niu.c b/trunk/drivers/net/niu.c index fa61a12c5e15..0d9de5ac4130 100644 --- a/trunk/drivers/net/niu.c +++ b/trunk/drivers/net/niu.c @@ -22,7 +22,6 @@ #include #include #include -#include #include @@ -6363,7 +6362,6 @@ static void niu_set_rx_mode(struct net_device *dev) struct niu *np = netdev_priv(dev); int i, alt_cnt, err; struct dev_addr_list *addr; - struct netdev_hw_addr *ha; unsigned long flags; u16 hash[16] = { 0, }; @@ -6385,8 +6383,9 @@ static void niu_set_rx_mode(struct net_device *dev) if (alt_cnt) { int index = 0; - list_for_each_entry(ha, &dev->uc_list, list) { - err = niu_set_alt_mac(np, index, ha->addr); + for (addr = dev->uc_list; addr; addr = addr->next) { + err = niu_set_alt_mac(np, index, + addr->da_addr); if (err) printk(KERN_WARNING PFX "%s: Error %d " "adding alt mac %d\n", @@ -6778,6 +6777,8 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_tx_wake_queue(txq); } + dev->trans_start = jiffies; + out: return NETDEV_TX_OK; diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c index 940962ae8f23..d531614a90b5 100644 --- a/trunk/drivers/net/ns83820.c +++ b/trunk/drivers/net/ns83820.c @@ -1204,7 +1204,9 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev)) netif_start_queue(ndev); - return NETDEV_TX_OK; + /* set the transmit start time to catch transmit timeouts */ + ndev->trans_start = jiffies; + return 0; } static void ns83820_update_stats(struct ns83820 *dev) @@ -1624,7 +1626,7 @@ static void ns83820_tx_watch(unsigned long data) ); #endif - if (time_after(jiffies, dev_trans_start(ndev) + 1*HZ) && + if (time_after(jiffies, ndev->trans_start + 1*HZ) && dev->tx_done_idx != dev->tx_free_idx) { printk(KERN_DEBUG "%s: ns83820_tx_watch: %u %u %d\n", ndev->name, diff --git a/trunk/drivers/net/phy/marvell.c b/trunk/drivers/net/phy/marvell.c index dd6f54d1b495..7a3ec9d39a9a 100644 --- a/trunk/drivers/net/phy/marvell.c +++ b/trunk/drivers/net/phy/marvell.c @@ -243,7 +243,6 @@ static int m88e1111_config_init(struct phy_device *phydev) temp &= ~(MII_M1111_HWCFG_MODE_MASK); temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK; - temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO; err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); if (err < 0) diff --git a/trunk/drivers/net/pppol2tp.c b/trunk/drivers/net/pppol2tp.c index e7935d09c896..5981debcde5e 100644 --- a/trunk/drivers/net/pppol2tp.c +++ b/trunk/drivers/net/pppol2tp.c @@ -433,7 +433,8 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s * to the inner packet either */ secpath_reset(skb); - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; nf_reset(skb); po = pppox_sk(session_sock); @@ -975,7 +976,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh /* Calculate UDP checksum if configured to do so */ if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT) skb->ip_summed = CHECKSUM_NONE; - else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { + else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) { skb->ip_summed = CHECKSUM_COMPLETE; csum = skb_checksum(skb, 0, udp_len, 0); uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, @@ -1171,14 +1172,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) nf_reset(skb); /* Get routing info from the tunnel socket */ - skb_dst_drop(skb); - skb_dst_set(skb, dst_clone(__sk_dst_get(sk_tun))); + dst_release(skb->dst); + skb->dst = dst_clone(__sk_dst_get(sk_tun)); pppol2tp_skb_set_owner_w(skb, sk_tun); /* Calculate UDP checksum if configured to do so */ if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT) skb->ip_summed = CHECKSUM_NONE; - else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { + else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) { skb->ip_summed = CHECKSUM_COMPLETE; csum = skb_checksum(skb, 0, udp_len, 0); uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index 8a823ecc99a9..cadc32c94c1e 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -2617,6 +2617,7 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) &port_regs->CommonRegs.reqQProducerIndex, qdev->req_producer_index); + ndev->trans_start = jiffies; if (netif_msg_tx_queued(qdev)) printk(KERN_DEBUG PFX "%s: tx queued, slot %d, len %d\n", ndev->name, qdev->req_producer_index, skb->len); diff --git a/trunk/drivers/net/qlge/qlge.h b/trunk/drivers/net/qlge/qlge.h index 156e02e8905d..fcb159e4df54 100644 --- a/trunk/drivers/net/qlge/qlge.h +++ b/trunk/drivers/net/qlge/qlge.h @@ -27,8 +27,6 @@ "%s: " fmt, __func__, ##args); \ } while (0) -#define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ - #define QLGE_VENDOR_ID 0x1077 #define QLGE_DEVICE_ID_8012 0x8012 #define QLGE_DEVICE_ID_8000 0x8000 @@ -41,18 +39,7 @@ #define NUM_SMALL_BUFFERS 512 #define NUM_LARGE_BUFFERS 512 -#define DB_PAGE_SIZE 4096 - -/* Calculate the number of (4k) pages required to - * contain a buffer queue of the given length. - */ -#define MAX_DB_PAGES_PER_BQ(x) \ - (((x * sizeof(u64)) / DB_PAGE_SIZE) + \ - (((x * sizeof(u64)) % DB_PAGE_SIZE) ? 1 : 0)) -#define RX_RING_SHADOW_SPACE (sizeof(u64) + \ - MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \ - MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64)) #define SMALL_BUFFER_SIZE 256 #define LARGE_BUFFER_SIZE PAGE_SIZE #define MAX_SPLIT_SIZE 1023 @@ -63,7 +50,7 @@ #define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */ #define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2) #define UDELAY_COUNT 3 -#define UDELAY_DELAY 100 +#define UDELAY_DELAY 10 #define TX_DESC_PER_IOCB 8 @@ -76,16 +63,7 @@ #define TX_DESC_PER_OAL 0 #endif -/* MPI test register definitions. This register - * is used for determining alternate NIC function's - * PCI->func number. - */ -enum { - MPI_TEST_FUNC_PORT_CFG = 0x1002, - MPI_TEST_NIC1_FUNC_SHIFT = 1, - MPI_TEST_NIC2_FUNC_SHIFT = 5, - MPI_TEST_NIC_FUNC_MASK = 0x00000007, -}; +#define DB_PAGE_SIZE 4096 /* * Processor Address Register (PROC_ADDR) bit definitions. @@ -1452,10 +1430,7 @@ struct ql_adapter { /* Hardware information */ u32 chip_rev_id; - u32 fw_rev_id; u32 func; /* PCI function for this adapter */ - u32 alt_func; /* PCI function for alternate adapter */ - u32 port; /* Port number this adapter */ spinlock_t adapter_lock; spinlock_t hw_lock; @@ -1605,8 +1580,6 @@ void ql_mpi_idc_work(struct work_struct *work); void ql_mpi_port_cfg_work(struct work_struct *work); int ql_mb_get_fw_state(struct ql_adapter *qdev); int ql_cam_route_initialize(struct ql_adapter *qdev); -int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); -int ql_mb_about_fw(struct ql_adapter *qdev); #if 1 #define QL_ALL_DUMP diff --git a/trunk/drivers/net/qlge/qlge_ethtool.c b/trunk/drivers/net/qlge/qlge_ethtool.c index 37c99fe79770..913b2a5fafc9 100644 --- a/trunk/drivers/net/qlge/qlge_ethtool.c +++ b/trunk/drivers/net/qlge/qlge_ethtool.c @@ -293,10 +293,7 @@ static void ql_get_drvinfo(struct net_device *ndev, struct ql_adapter *qdev = netdev_priv(ndev); strncpy(drvinfo->driver, qlge_driver_name, 32); strncpy(drvinfo->version, qlge_driver_version, 32); - snprintf(drvinfo->fw_version, 32, "v%d.%d.%d", - (qdev->fw_rev_id & 0x00ff0000) >> 16, - (qdev->fw_rev_id & 0x0000ff00) >> 8, - (qdev->fw_rev_id & 0x000000ff)); + strncpy(drvinfo->fw_version, "N/A", 32); strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); drvinfo->n_stats = 0; drvinfo->testinfo_len = 0; @@ -404,7 +401,6 @@ const struct ethtool_ops qlge_ethtool_ops = { .get_rx_csum = ql_get_rx_csum, .set_rx_csum = ql_set_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_tso = ethtool_op_get_tso, diff --git a/trunk/drivers/net/qlge/qlge_main.c b/trunk/drivers/net/qlge/qlge_main.c index b9a5f59d6c9b..c92ced247947 100644 --- a/trunk/drivers/net/qlge/qlge_main.c +++ b/trunk/drivers/net/qlge/qlge_main.c @@ -675,12 +675,11 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev) int status; __le32 *p = (__le32 *)&qdev->flash; u32 offset; - u8 mac_addr[6]; /* Get flash offset for function and adjust * for dword access. */ - if (!qdev->port) + if (!qdev->func) offset = FUNC0_FLASH_OFFSET / sizeof(u32); else offset = FUNC1_FLASH_OFFSET / sizeof(u32); @@ -706,26 +705,14 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev) goto exit; } - /* Extract either manufacturer or BOFM modified - * MAC address. - */ - if (qdev->flash.flash_params_8000.data_type1 == 2) - memcpy(mac_addr, - qdev->flash.flash_params_8000.mac_addr1, - qdev->ndev->addr_len); - else - memcpy(mac_addr, - qdev->flash.flash_params_8000.mac_addr, - qdev->ndev->addr_len); - - if (!is_valid_ether_addr(mac_addr)) { + if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) { QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n"); status = -EINVAL; goto exit; } memcpy(qdev->ndev->dev_addr, - mac_addr, + qdev->flash.flash_params_8000.mac_addr, qdev->ndev->addr_len); exit: @@ -744,7 +731,7 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev) /* Second function's parameters follow the first * function's. */ - if (qdev->port) + if (qdev->func) offset = size; if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) @@ -850,13 +837,6 @@ int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data) static int ql_8000_port_initialize(struct ql_adapter *qdev) { int status; - /* - * Get MPI firmware version for driver banner - * and ethool info. - */ - status = ql_mb_about_fw(qdev); - if (status) - goto exit; status = ql_mb_get_fw_state(qdev); if (status) goto exit; @@ -1538,22 +1518,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, return; } - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n", - ib_mac_rsp->flags2); - dev_kfree_skb_any(skb); - return; - } - - /* The max framesize filter on this chip is set higher than - * MTU since FCoE uses 2k frames. - */ - if (skb->len > ndev->mtu + ETH_HLEN) { - dev_kfree_skb_any(skb); - return; - } - prefetch(skb->data); skb->dev = ndev; if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) { @@ -1576,6 +1540,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, * csum or frame errors. */ if (qdev->rx_csum && + !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { /* TCP frame. */ if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { @@ -2143,6 +2108,7 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev) wmb(); ql_write_db_reg(tx_ring->prod_idx, tx_ring->prod_idx_db_reg); + ndev->trans_start = jiffies; QPRINTK(qdev, TX_QUEUED, DEBUG, "tx queued, slot %d, len %d\n", tx_ring->prod_idx, skb->len); @@ -2237,7 +2203,7 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev, &tx_ring->wq_base_dma); if ((tx_ring->wq_base == NULL) - || tx_ring->wq_base_dma & WQ_ADDR_ALIGN) { + || tx_ring->wq_base_dma & (tx_ring->wq_size - 1)) { QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n"); return -ENOMEM; } @@ -2552,16 +2518,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) { struct cqicb *cqicb = &rx_ring->cqicb; void *shadow_reg = qdev->rx_ring_shadow_reg_area + - (rx_ring->cq_id * RX_RING_SHADOW_SPACE); + (rx_ring->cq_id * sizeof(u64) * 4); u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma + - (rx_ring->cq_id * RX_RING_SHADOW_SPACE); + (rx_ring->cq_id * sizeof(u64) * 4); void __iomem *doorbell_area = qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id)); int err = 0; u16 bq_len; u64 tmp; - __le64 *base_indirect_ptr; - int page_entries; /* Set up the shadow registers for this ring. */ rx_ring->prod_idx_sh_reg = shadow_reg; @@ -2570,8 +2534,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) shadow_reg_dma += sizeof(u64); rx_ring->lbq_base_indirect = shadow_reg; rx_ring->lbq_base_indirect_dma = shadow_reg_dma; - shadow_reg += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); - shadow_reg_dma += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); + shadow_reg += sizeof(u64); + shadow_reg_dma += sizeof(u64); rx_ring->sbq_base_indirect = shadow_reg; rx_ring->sbq_base_indirect_dma = shadow_reg_dma; @@ -2608,14 +2572,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->lbq_len) { cqicb->flags |= FLAGS_LL; /* Load lbq values */ tmp = (u64)rx_ring->lbq_base_dma;; - base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect; - page_entries = 0; - do { - *base_indirect_ptr = cpu_to_le64(tmp); - tmp += DB_PAGE_SIZE; - base_indirect_ptr++; - page_entries++; - } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); + *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp); cqicb->lbq_addr = cpu_to_le64(rx_ring->lbq_base_indirect_dma); bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 : @@ -2632,14 +2589,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->sbq_len) { cqicb->flags |= FLAGS_LS; /* Load sbq values */ tmp = (u64)rx_ring->sbq_base_dma;; - base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect; - page_entries = 0; - do { - *base_indirect_ptr = cpu_to_le64(tmp); - tmp += DB_PAGE_SIZE; - base_indirect_ptr++; - page_entries++; - } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->sbq_len)); + *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp); cqicb->sbq_addr = cpu_to_le64(rx_ring->sbq_base_indirect_dma); cqicb->sbq_buf_size = @@ -3236,10 +3186,9 @@ static void ql_display_dev_info(struct net_device *ndev) struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); QPRINTK(qdev, PROBE, INFO, - "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " + "Function #%d, NIC Roll %d, NIC Rev = %d, " "XG Roll = %d, XG Rev = %d.\n", qdev->func, - qdev->port, qdev->chip_rev_id & 0x0000000f, qdev->chip_rev_id >> 4 & 0x0000000f, qdev->chip_rev_id >> 8 & 0x0000000f, @@ -3315,6 +3264,7 @@ static int ql_adapter_up(struct ql_adapter *qdev) err = ql_adapter_initialize(qdev); if (err) { QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n"); + spin_unlock(&qdev->hw_lock); goto err_init; } set_bit(QL_ADAPTER_UP, &qdev->flags); @@ -3411,6 +3361,7 @@ static int ql_configure_rings(struct ql_adapter *qdev) * completion handler rx_rings. */ qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1; + netif_set_gso_max_size(qdev->ndev, 65536); for (i = 0; i < qdev->tx_ring_count; i++) { tx_ring = &qdev->tx_ring[i]; @@ -3693,53 +3644,12 @@ static struct nic_operations qla8000_nic_ops = { .port_initialize = ql_8000_port_initialize, }; -/* Find the pcie function number for the other NIC - * on this chip. Since both NIC functions share a - * common firmware we have the lowest enabled function - * do any common work. Examples would be resetting - * after a fatal firmware error, or doing a firmware - * coredump. - */ -static int ql_get_alt_pcie_func(struct ql_adapter *qdev) -{ - int status = 0; - u32 temp; - u32 nic_func1, nic_func2; - - status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG, - &temp); - if (status) - return status; - - nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) & - MPI_TEST_NIC_FUNC_MASK); - nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) & - MPI_TEST_NIC_FUNC_MASK); - - if (qdev->func == nic_func1) - qdev->alt_func = nic_func2; - else if (qdev->func == nic_func2) - qdev->alt_func = nic_func1; - else - status = -EIO; - - return status; -} -static int ql_get_board_info(struct ql_adapter *qdev) +static void ql_get_board_info(struct ql_adapter *qdev) { - int status; qdev->func = (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT; - if (qdev->func > 3) - return -EIO; - - status = ql_get_alt_pcie_func(qdev); - if (status) - return status; - - qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1; - if (qdev->port) { + if (qdev->func) { qdev->xg_sem_mask = SEM_XGMAC1_MASK; qdev->port_link_up = STS_PL1; qdev->port_init = STS_PI1; @@ -3758,7 +3668,6 @@ static int ql_get_board_info(struct ql_adapter *qdev) qdev->nic_ops = &qla8012_nic_ops; else if (qdev->device_id == QLGE_DEVICE_ID_8000) qdev->nic_ops = &qla8000_nic_ops; - return status; } static void ql_release_all(struct pci_dev *pdev) @@ -3853,12 +3762,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, qdev->ndev = ndev; qdev->pdev = pdev; - err = ql_get_board_info(qdev); - if (err) { - dev_err(&pdev->dev, "Register access failed.\n"); - err = -EIO; - goto err_out; - } + ql_get_board_info(qdev); qdev->msg_enable = netif_msg_init(debug, default_msg); spin_lock_init(&qdev->hw_lock); spin_lock_init(&qdev->stats_lock); diff --git a/trunk/drivers/net/qlge/qlge_mpi.c b/trunk/drivers/net/qlge/qlge_mpi.c index a67c14a7befd..9f81b797f10b 100644 --- a/trunk/drivers/net/qlge/qlge_mpi.c +++ b/trunk/drivers/net/qlge/qlge_mpi.c @@ -90,14 +90,14 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp) */ static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev) { - int count = 100; + int count = 50; /* TODO: arbitrary for now. */ u32 value; do { value = ql_read32(qdev, STS); if (value & STS_PI) return 0; - mdelay(UDELAY_DELAY); /* 100ms */ + udelay(UDELAY_DELAY); /* 10us */ } while (--count); return -ETIMEDOUT; } @@ -453,13 +453,6 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) } end: ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); - /* Restore the original mailbox count to - * what the caller asked for. This can get - * changed when a mailbox command is waiting - * for a response and an AEN arrives and - * is handled. - * */ - mbcp->out_count = orig_count; return status; } @@ -547,40 +540,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) return status; } - -/* Get MPI firmware version. This will be used for - * driver banner and for ethtool info. - * Returns zero on success. - */ -int ql_mb_about_fw(struct ql_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status = 0; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 1; - mbcp->out_count = 3; - - mbcp->mbox_in[0] = MB_CMD_ABOUT_FW; - - status = ql_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - QPRINTK(qdev, DRV, ERR, - "Failed about firmware command\n"); - status = -EIO; - } - - /* Store the firmware version */ - qdev->fw_rev_id = mbcp->mbox_out[1]; - - return status; -} - /* Get functional state for MPI firmware. * Returns zero on success. */ @@ -795,6 +754,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) { struct ql_adapter *qdev = container_of(work, struct ql_adapter, mpi_port_cfg_work.work); + struct net_device *ndev = qdev->ndev; int status; status = ql_mb_get_port_cfg(qdev); @@ -804,7 +764,9 @@ void ql_mpi_port_cfg_work(struct work_struct *work) goto err; } - if (qdev->link_config & CFG_JUMBO_FRAME_SIZE && + if (ndev->mtu <= 2500) + goto end; + else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE && qdev->max_frame_size == CFG_DEFAULT_MAX_FRAME_SIZE) goto end; @@ -869,19 +831,13 @@ void ql_mpi_work(struct work_struct *work) container_of(work, struct ql_adapter, mpi_work.work); struct mbox_params mbc; struct mbox_params *mbcp = &mbc; - int err = 0; mutex_lock(&qdev->mpi_mutex); while (ql_read32(qdev, STS) & STS_PI) { memset(mbcp, 0, sizeof(struct mbox_params)); mbcp->out_count = 1; - /* Don't continue if an async event - * did not complete properly. - */ - err = ql_mpi_handler(qdev, mbcp); - if (err) - break; + ql_mpi_handler(qdev, mbcp); } mutex_unlock(&qdev->mpi_mutex); diff --git a/trunk/drivers/net/r6040.c b/trunk/drivers/net/r6040.c index ed63d23a6452..1508b124e3d8 100644 --- a/trunk/drivers/net/r6040.c +++ b/trunk/drivers/net/r6040.c @@ -401,9 +401,6 @@ static void r6040_init_mac_regs(struct net_device *dev) * we may got called by r6040_tx_timeout which has left * some unsent tx buffers */ iowrite16(0x01, ioaddr + MTPR); - - /* Check media */ - mii_check_media(&lp->mii_if, 1, 1); } static void r6040_tx_timeout(struct net_device *dev) @@ -531,8 +528,6 @@ static int r6040_phy_mode_chk(struct net_device *dev) phy_dat = 0x0000; } - mii_check_media(&lp->mii_if, 0, 1); - return phy_dat; }; @@ -815,6 +810,7 @@ static void r6040_timer(unsigned long data) lp->phy_mode = phy_mode; lp->mcr0 = (lp->mcr0 & 0x7fff) | phy_mode; iowrite16(lp->mcr0, ioaddr); + printk(KERN_INFO "Link Change %x \n", ioread16(ioaddr)); } /* Timer active again */ diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 007c881896d2..0ec0605bcebd 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -3279,6 +3279,8 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); txd->opts1 = cpu_to_le32(status); + dev->trans_start = jiffies; + tp->cur_tx += frags + 1; smp_wmb(); @@ -3379,7 +3381,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev, rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); if (status & LastFrag) { - dev_kfree_skb(tx_skb->skb); + dev_kfree_skb_irq(tx_skb->skb); tx_skb->skb = NULL; } dirty_tx++; @@ -3561,64 +3563,54 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) int handled = 0; int status; - /* loop handling interrupts until we have no new ones or - * we hit a invalid/hotplug case. - */ status = RTL_R16(IntrStatus); - while (status && status != 0xffff) { - handled = 1; - /* Handle all of the error cases first. These will reset - * the chip, so just exit the loop. - */ - if (unlikely(!netif_running(dev))) { - rtl8169_asic_down(ioaddr); - break; - } + /* hotplug/major error/no more work/shared irq */ + if ((status == 0xffff) || !status) + goto out; - /* Work around for rx fifo overflow */ - if (unlikely(status & RxFIFOOver) && - (tp->mac_version == RTL_GIGA_MAC_VER_11)) { - netif_stop_queue(dev); - rtl8169_tx_timeout(dev); - break; - } + handled = 1; - if (unlikely(status & SYSErr)) { - rtl8169_pcierr_interrupt(dev); - break; - } + if (unlikely(!netif_running(dev))) { + rtl8169_asic_down(ioaddr); + goto out; + } - if (status & LinkChg) - rtl8169_check_link_status(dev, tp, ioaddr); + status &= tp->intr_mask; + RTL_W16(IntrStatus, + (status & RxFIFOOver) ? (status | RxOverflow) : status); - /* We need to see the lastest version of tp->intr_mask to - * avoid ignoring an MSI interrupt and having to wait for - * another event which may never come. - */ - smp_rmb(); - if (status & tp->intr_mask & tp->napi_event) { - RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); - tp->intr_mask = ~tp->napi_event; - - if (likely(napi_schedule_prep(&tp->napi))) - __napi_schedule(&tp->napi); - else if (netif_msg_intr(tp)) { - printk(KERN_INFO "%s: interrupt %04x in poll\n", - dev->name, status); - } - } + if (!(status & tp->intr_event)) + goto out; - /* We only get a new MSI interrupt when all active irq - * sources on the chip have been acknowledged. So, ack - * everything we've seen and check if new sources have become - * active to avoid blocking all interrupts from the chip. - */ - RTL_W16(IntrStatus, - (status & RxFIFOOver) ? (status | RxOverflow) : status); - status = RTL_R16(IntrStatus); + /* Work around for rx fifo overflow */ + if (unlikely(status & RxFIFOOver) && + (tp->mac_version == RTL_GIGA_MAC_VER_11)) { + netif_stop_queue(dev); + rtl8169_tx_timeout(dev); + goto out; } + if (unlikely(status & SYSErr)) { + rtl8169_pcierr_interrupt(dev); + goto out; + } + + if (status & LinkChg) + rtl8169_check_link_status(dev, tp, ioaddr); + + if (status & tp->napi_event) { + RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); + tp->intr_mask = ~tp->napi_event; + + if (likely(napi_schedule_prep(&tp->napi))) + __napi_schedule(&tp->napi); + else if (netif_msg_intr(tp)) { + printk(KERN_INFO "%s: interrupt %04x in poll\n", + dev->name, status); + } + } +out: return IRQ_RETVAL(handled); } @@ -3634,15 +3626,13 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) if (work_done < budget) { napi_complete(napi); - - /* We need for force the visibility of tp->intr_mask - * for other CPUs, as we can loose an MSI interrupt - * and potentially wait for a retransmit timeout if we don't. - * The posted write to IntrMask is safe, as it will - * eventually make it to the chip and we won't loose anything - * until it does. - */ tp->intr_mask = 0xffff; + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ smp_wmb(); RTL_W16(IntrMask, tp->intr_event); } diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 458daa06ed41..80562ea77de3 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -1764,7 +1764,7 @@ static int init_nic(struct s2io_nic *nic) * by then we return error. */ time = 0; - while (true) { + while (TRUE) { val64 = readq(&bar0->rti_command_mem); if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) break; @@ -2137,7 +2137,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) herc = (sp->device_type == XFRAME_II_DEVICE); - if (flag == false) { + if (flag == FALSE) { if ((!herc && (sp->pdev->revision >= 4)) || herc) { if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE)) ret = 1; @@ -3587,7 +3587,7 @@ static void s2io_reset(struct s2io_nic * sp) writeq(val64, &bar0->pcc_err_reg); } - sp->device_enabled_once = false; + sp->device_enabled_once = FALSE; } /** @@ -4299,6 +4299,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) s2io_stop_tx_queue(sp, fifo->fifo_no); } mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; + dev->trans_start = jiffies; spin_unlock_irqrestore(&fifo->tx_lock, flags); if (sp->config.intr_type == MSI_X) @@ -5572,10 +5573,10 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, val64 = readq(&bar0->rmac_pause_cfg); if (val64 & RMAC_PAUSE_GEN_ENABLE) - ep->tx_pause = true; + ep->tx_pause = TRUE; if (val64 & RMAC_PAUSE_RX_ENABLE) - ep->rx_pause = true; - ep->autoneg = false; + ep->rx_pause = TRUE; + ep->autoneg = FALSE; } /** @@ -6806,7 +6807,7 @@ static void s2io_set_link(struct work_struct *work) val64 |= ADAPTER_LED_ON; writeq(val64, &bar0->adapter_control); } - nic->device_enabled_once = true; + nic->device_enabled_once = TRUE; } else { DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); @@ -7754,7 +7755,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) struct s2io_nic *sp; struct net_device *dev; int i, j, ret; - int dma_flag = false; + int dma_flag = FALSE; u32 mac_up, mac_down; u64 val64 = 0, tmp64 = 0; struct XENA_dev_config __iomem *bar0 = NULL; @@ -7777,7 +7778,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); - dma_flag = true; + dma_flag = TRUE; if (pci_set_consistent_dma_mask (pdev, DMA_BIT_MASK(64))) { DBG_PRINT(ERR_DBG, @@ -7818,7 +7819,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) sp->dev = dev; sp->pdev = pdev; sp->high_dma_flag = dma_flag; - sp->device_enabled_once = false; + sp->device_enabled_once = FALSE; if (rx_ring_mode == 1) sp->rxd_mode = RXD_MODE_1; if (rx_ring_mode == 2) @@ -7964,7 +7965,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - if (sp->high_dma_flag == true) + if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; dev->features |= NETIF_F_TSO; dev->features |= NETIF_F_TSO6; diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index d5c5be6c07b9..55cb943f23f8 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -18,6 +18,15 @@ #define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz)) #define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff) +#ifndef BOOL +#define BOOL int +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + #undef SUCCESS #define SUCCESS 0 #define FAILURE -1 diff --git a/trunk/drivers/net/sfc/selftest.c b/trunk/drivers/net/sfc/selftest.c index b67ccca3fc1a..043795715955 100644 --- a/trunk/drivers/net/sfc/selftest.c +++ b/trunk/drivers/net/sfc/selftest.c @@ -438,7 +438,6 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue) kfree_skb(skb); return -EPIPE; } - efx->net_dev->trans_start = jiffies; } return 0; diff --git a/trunk/drivers/net/sfc/tenxpress.c b/trunk/drivers/net/sfc/tenxpress.c index f4d509015f75..db723c58f6f1 100644 --- a/trunk/drivers/net/sfc/tenxpress.c +++ b/trunk/drivers/net/sfc/tenxpress.c @@ -63,7 +63,6 @@ /* extended status register */ #define PMA_PMD_XSTATUS_REG 49153 -#define PMA_PMD_XSTAT_MDIX_LBN 14 #define PMA_PMD_XSTAT_FLP_LBN (12) /* LED control register */ @@ -742,17 +741,9 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); - if (efx->phy_type != PHY_TYPE_SFX7101) { + if (efx->phy_type != PHY_TYPE_SFX7101) ecmd->supported |= (SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full); - if (ecmd->speed != SPEED_10000) { - ecmd->eth_tp_mdix = - (efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XSTATUS_REG) & - (1 << PMA_PMD_XSTAT_MDIX_LBN)) - ? ETH_TP_MDI_X : ETH_TP_MDI; - } - } /* In loopback, the PHY automatically brings up the correct interface, * but doesn't advertise the correct speed. So override it */ diff --git a/trunk/drivers/net/sfc/tx.c b/trunk/drivers/net/sfc/tx.c index 14a14788566c..d6681edb7014 100644 --- a/trunk/drivers/net/sfc/tx.c +++ b/trunk/drivers/net/sfc/tx.c @@ -360,6 +360,13 @@ inline int efx_xmit(struct efx_nic *efx, /* Map fragments for DMA and add to TX queue */ rc = efx_enqueue_skb(tx_queue, skb); + if (unlikely(rc != NETDEV_TX_OK)) + goto out; + + /* Update last TX timer */ + efx->net_dev->trans_start = jiffies; + + out: return rc; } diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index e2247669a495..55ccd51d247e 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -47,7 +47,7 @@ #define PHY_ID_ANY 0x1f #define MII_REG_ANY 0x1f -#define DRV_VERSION "1.3" +#define DRV_VERSION "1.2" #define DRV_NAME "sis190" #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION #define PFX DRV_NAME ": " @@ -317,7 +317,6 @@ static struct mii_chip_info { unsigned int type; u32 feature; } mii_chip_table[] = { - { "Atheros PHY", { 0x004d, 0xd010 }, LAN, 0 }, { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 }, { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, @@ -348,7 +347,7 @@ static struct { u32 msg_enable; } debug = { -1 }; -MODULE_DESCRIPTION("SiS sis190/191 Gigabit Ethernet driver"); +MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver"); module_param(rx_copybreak, int, 0); MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param_named(debug, debug.msg_enable, int, 0); @@ -540,8 +539,8 @@ static bool sis190_try_rx_copy(struct sis190_private *tp, if (!skb) goto out; - pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size, + PCI_DMA_FROMDEVICE); skb_reserve(skb, 2); skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); *sk_buff = skb; @@ -943,9 +942,9 @@ static void sis190_phy_task(struct work_struct *work) u32 ctl; const char *msg; } reg31[] = { - { LPA_1000FULL, 0x07000c00 | 0x00001000, + { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000, "1000 Mbps Full Duplex" }, - { LPA_1000HALF, 0x07000c00, + { LPA_1000XHALF | LPA_SLCT, 0x07000c00, "1000 Mbps Half Duplex" }, { LPA_100FULL, 0x04000800 | 0x00001000, "100 Mbps Full Duplex" }, @@ -956,35 +955,22 @@ static void sis190_phy_task(struct work_struct *work) { LPA_10HALF, 0x04000400, "10 Mbps Half Duplex" }, { 0, 0x04000400, "unknown" } - }, *p = NULL; - u16 adv, autoexp, gigadv, gigrec; + }, *p; + u16 adv; val = mdio_read(ioaddr, phy_id, 0x1f); net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); val = mdio_read(ioaddr, phy_id, MII_LPA); adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); - autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION); - net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n", - dev->name, val, adv, autoexp); - - if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) { - /* check for gigabit speed */ - gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000); - gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000); - val = (gigadv & (gigrec >> 2)); - if (val & ADVERTISE_1000FULL) - p = reg31; - else if (val & ADVERTISE_1000HALF) - p = reg31 + 1; - } - if (!p) { - val &= adv; + net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n", + dev->name, val, adv); - for (p = reg31; p->val; p++) { - if ((val & p->val) == p->val) - break; - } + val &= adv; + + for (p = reg31; p->val; p++) { + if ((val & p->val) == p->val) + break; } p->ctl |= SIS_R32(StationControl) & ~0x0f001c00; @@ -1218,6 +1204,8 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev) SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb); + dev->trans_start = jiffies; + dirty_tx = tp->dirty_tx; if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) { netif_stop_queue(dev); @@ -1327,15 +1315,12 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp, ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? LAN : HOME) : p->type; tp->features |= p->feature; - net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", - pci_name(tp->pci_dev), p->name, phy_id); - } else { + } else phy->type = UNKNOWN; - net_probe(tp, KERN_INFO - "%s: unknown PHY 0x%x:0x%x transceiver at address %d\n", - pci_name(tp->pci_dev), - phy->id[0], (phy->id[1] & 0xfff0), phy_id); - } + + net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", + pci_name(tp->pci_dev), + (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); } static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp) diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index 60d502eef4fc..c11cdd08ec57 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -2837,6 +2837,8 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); } + dev->trans_start = jiffies; + return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 6b5946fe8ae2..a2ff9cb1e7ac 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -1690,6 +1690,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); + dev->trans_start = jiffies; return NETDEV_TX_OK; mapping_unwind: diff --git a/trunk/drivers/net/smsc911x.c b/trunk/drivers/net/smsc911x.c index b60639bd181b..3cff84078a9e 100644 --- a/trunk/drivers/net/smsc911x.c +++ b/trunk/drivers/net/smsc911x.c @@ -2155,7 +2155,7 @@ static int smsc911x_resume(struct platform_device *pdev) static struct platform_driver smsc911x_driver = { .probe = smsc911x_drv_probe, - .remove = __devexit_p(smsc911x_drv_remove), + .remove = smsc911x_drv_remove, .driver = { .name = SMSC_CHIPNAME, }, diff --git a/trunk/drivers/net/sundance.c b/trunk/drivers/net/sundance.c index 545f81b34ad7..c399b1955c1e 100644 --- a/trunk/drivers/net/sundance.c +++ b/trunk/drivers/net/sundance.c @@ -369,6 +369,7 @@ struct netdev_private { struct sk_buff* tx_skbuff[TX_RING_SIZE]; dma_addr_t tx_ring_dma; dma_addr_t rx_ring_dma; + struct net_device_stats stats; struct timer_list timer; /* Media monitoring timer. */ /* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock; @@ -974,7 +975,7 @@ static void tx_timeout(struct net_device *dev) dev->if_port = 0; dev->trans_start = jiffies; - dev->stats.tx_errors++; + np->stats.tx_errors++; if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) { netif_wake_queue(dev); } @@ -1122,7 +1123,7 @@ reset_tx (struct net_device *dev) else dev_kfree_skb (skb); np->tx_skbuff[i] = NULL; - dev->stats.tx_dropped++; + np->stats.tx_dropped++; } } np->cur_tx = np->dirty_tx = 0; @@ -1180,15 +1181,15 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) if (netif_msg_tx_err(np)) printk("%s: Transmit error status %4.4x.\n", dev->name, tx_status); - dev->stats.tx_errors++; + np->stats.tx_errors++; if (tx_status & 0x10) - dev->stats.tx_fifo_errors++; + np->stats.tx_fifo_errors++; if (tx_status & 0x08) - dev->stats.collisions++; + np->stats.collisions++; if (tx_status & 0x04) - dev->stats.tx_fifo_errors++; + np->stats.tx_fifo_errors++; if (tx_status & 0x02) - dev->stats.tx_window_errors++; + np->stats.tx_window_errors++; /* ** This reset has been verified on @@ -1312,15 +1313,11 @@ static void rx_poll(unsigned long data) if (netif_msg_rx_err(np)) printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n", frame_status); - dev->stats.rx_errors++; - if (frame_status & 0x00100000) - dev->stats.rx_length_errors++; - if (frame_status & 0x00010000) - dev->stats.rx_fifo_errors++; - if (frame_status & 0x00060000) - dev->stats.rx_frame_errors++; - if (frame_status & 0x00080000) - dev->stats.rx_crc_errors++; + np->stats.rx_errors++; + if (frame_status & 0x00100000) np->stats.rx_length_errors++; + if (frame_status & 0x00010000) np->stats.rx_fifo_errors++; + if (frame_status & 0x00060000) np->stats.rx_frame_errors++; + if (frame_status & 0x00080000) np->stats.rx_crc_errors++; if (frame_status & 0x00100000) { printk(KERN_WARNING "%s: Oversized Ethernet frame," " status %8.8x.\n", @@ -1488,22 +1485,22 @@ static struct net_device_stats *get_stats(struct net_device *dev) the vulnerability window is very small and statistics are non-critical. */ /* The chip only need report frame silently dropped. */ - dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed); - dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK); - dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK); - dev->stats.collisions += ioread8(ioaddr + StatsLateColl); - dev->stats.collisions += ioread8(ioaddr + StatsMultiColl); - dev->stats.collisions += ioread8(ioaddr + StatsOneColl); - dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError); + np->stats.rx_missed_errors += ioread8(ioaddr + RxMissed); + np->stats.tx_packets += ioread16(ioaddr + TxFramesOK); + np->stats.rx_packets += ioread16(ioaddr + RxFramesOK); + np->stats.collisions += ioread8(ioaddr + StatsLateColl); + np->stats.collisions += ioread8(ioaddr + StatsMultiColl); + np->stats.collisions += ioread8(ioaddr + StatsOneColl); + np->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError); ioread8(ioaddr + StatsTxDefer); for (i = StatsTxDefer; i <= StatsMcastRx; i++) ioread8(ioaddr + i); - dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow); - dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16; - dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow); - dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16; + np->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow); + np->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16; + np->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow); + np->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16; - return &dev->stats; + return &np->stats; } static void set_rx_mode(struct net_device *dev) diff --git a/trunk/drivers/net/tehuti.c b/trunk/drivers/net/tehuti.c index 3c2679cd196b..7f4a9683ba1e 100644 --- a/trunk/drivers/net/tehuti.c +++ b/trunk/drivers/net/tehuti.c @@ -948,7 +948,8 @@ static void print_rxfd(struct rxf_desc *rxfd); static void bdx_rxdb_destroy(struct rxdb *db) { - vfree(db); + if (db) + vfree(db); } static struct rxdb *bdx_rxdb_create(int nelem) @@ -1481,8 +1482,10 @@ static void bdx_tx_db_close(struct txdb *d) { BDX_ASSERT(d == NULL); - vfree(d->start); - d->start = NULL; + if (d->start) { + vfree(d->start); + d->start = NULL; + } } /************************************************************************* @@ -1715,9 +1718,8 @@ static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev) WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR); #endif -#ifdef BDX_LLTX - ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ -#endif + ndev->trans_start = jiffies; + priv->net_stats.tx_packets++; priv->net_stats.tx_bytes += skb->len; diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 46a3f86125be..eb65e25989f3 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -5021,7 +5021,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, /* New SKB is guaranteed to be linear. */ entry = *start; ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE); - new_addr = skb_shinfo(new_skb)->dma_head; + new_addr = skb_shinfo(new_skb)->dma_maps[0]; /* Make sure new skb does not cross any 4G boundaries. * Drop the packet if it does. @@ -5155,7 +5155,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) sp = skb_shinfo(skb); - mapping = sp->dma_head; + mapping = sp->dma_maps[0]; tp->tx_buffers[entry].skb = skb; @@ -5173,7 +5173,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; len = frag->size; - mapping = sp->dma_maps[i]; + mapping = sp->dma_maps[i + 1]; tp->tx_buffers[entry].skb = NULL; tg3_set_txd(tp, entry, mapping, len, @@ -5194,7 +5194,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) } out_unlock: - mmiowb(); + mmiowb(); + + dev->trans_start = jiffies; return NETDEV_TX_OK; } @@ -5331,7 +5333,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) sp = skb_shinfo(skb); - mapping = sp->dma_head; + mapping = sp->dma_maps[0]; tp->tx_buffers[entry].skb = skb; @@ -5356,7 +5358,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; len = frag->size; - mapping = sp->dma_maps[i]; + mapping = sp->dma_maps[i + 1]; tp->tx_buffers[entry].skb = NULL; @@ -5405,7 +5407,9 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) } out_unlock: - mmiowb(); + mmiowb(); + + dev->trans_start = jiffies; return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/tulip/Kconfig b/trunk/drivers/net/tulip/Kconfig index 1cc8cf4425d1..d913405bc393 100644 --- a/trunk/drivers/net/tulip/Kconfig +++ b/trunk/drivers/net/tulip/Kconfig @@ -27,18 +27,6 @@ config DE2104X To compile this driver as a module, choose M here. The module will be called de2104x. -config DE2104X_DSL - int "Descriptor Skip Length in 32 bit longwords" - depends on DE2104X - range 0 31 - default 0 - help - Setting this value allows to align ring buffer descriptors into their - own cache lines. Value of 4 corresponds to the typical 32 byte line - (the descriptor is 16 bytes). This is necessary on systems that lack - cache coherence, an example is PowerMac 5500. Otherwise 0 is safe. - Default is 0, and range is 0 to 31. - config TULIP tristate "DECchip Tulip (dc2114x) PCI support" depends on PCI diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index e7609a05032d..d4c5ecc51f77 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -82,13 +82,6 @@ MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copi NETIF_MSG_RX_ERR | \ NETIF_MSG_TX_ERR) -/* Descriptor skip length in 32 bit longwords. */ -#ifndef CONFIG_DE2104X_DSL -#define DSL 0 -#else -#define DSL CONFIG_DE2104X_DSL -#endif - #define DE_RX_RING_SIZE 64 #define DE_TX_RING_SIZE 64 #define DE_RING_BYTES \ @@ -160,7 +153,6 @@ enum { CmdReset = (1 << 0), CacheAlign16 = 0x00008000, BurstLen4 = 0x00000400, - DescSkipLen = (DSL << 2), /* Rx/TxPoll bits */ NormalTxPoll = (1 << 0), @@ -254,7 +246,7 @@ static const u32 de_intr_mask = * Set the programmable burst length to 4 longwords for all: * DMA errors result without these values. Cache align 16 long. */ -static const u32 de_bus_mode = CacheAlign16 | BurstLen4 | DescSkipLen; +static const u32 de_bus_mode = CacheAlign16 | BurstLen4; struct de_srom_media_block { u8 opts; @@ -274,9 +266,6 @@ struct de_desc { __le32 opts2; __le32 addr1; __le32 addr2; -#if DSL - __le32 skip[DSL]; -#endif }; struct media_info { diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 811d3517fce0..4cda69b6b28c 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -565,13 +565,9 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) return -EFAULT; - if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && - gso.csum_start + gso.csum_offset + 2 > gso.hdr_len) - gso.hdr_len = gso.csum_start + gso.csum_offset + 2; - if (gso.hdr_len > len) return -EINVAL; - offset += sizeof(gso); + offset += sizeof(pi); } if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { @@ -848,12 +844,12 @@ static void tun_sock_write_space(struct sock *sk) if (!sock_writeable(sk)) return; - if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) - return; - if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) wake_up_interruptible_sync(sk->sk_sleep); + if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) + return; + tun = container_of(sk, struct tun_sock, sk)->tun; kill_fasync(&tun->fasync, SIGIO, POLL_OUT); } @@ -1322,22 +1318,21 @@ static int tun_chr_open(struct inode *inode, struct file * file) static int tun_chr_close(struct inode *inode, struct file *file) { struct tun_file *tfile = file->private_data; - struct tun_struct *tun; + struct tun_struct *tun = __tun_get(tfile); - rtnl_lock(); - tun = __tun_get(tfile); if (tun) { DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); + rtnl_lock(); __tun_detach(tun); /* If desireable, unregister the netdevice. */ if (!(tun->flags & TUN_PERSIST)) unregister_netdevice(tun->dev); + rtnl_unlock(); } - rtnl_unlock(); tun = tfile->tun; if (tun) diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index fd6140bd9aae..0cf22c4f123b 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved. * * Author: Shlomi Gridish * Li Yang @@ -65,8 +65,6 @@ static DEFINE_SPINLOCK(ugeth_lock); -static void uec_configure_serdes(struct net_device *dev); - static struct { u32 msg_enable; } debug = { -1 }; @@ -1412,9 +1410,6 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) { upsmr |= UCC_GETH_UPSMR_TBIM; } - if ((ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII)) - upsmr |= UCC_GETH_UPSMR_SGMM; - out_be32(&uf_regs->upsmr, upsmr); /* Disable autonegotiation in tbi mode, because by default it @@ -1559,9 +1554,6 @@ static int init_phy(struct net_device *dev) return -ENODEV; } - if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII) - uec_configure_serdes(dev); - phydev->supported &= (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half | @@ -1577,41 +1569,7 @@ static int init_phy(struct net_device *dev) return 0; } -/* Initialize TBI PHY interface for communicating with the - * SERDES lynx PHY on the chip. We communicate with this PHY - * through the MDIO bus on each controller, treating it as a - * "normal" PHY at the address found in the UTBIPA register. We assume - * that the UTBIPA register is valid. Either the MDIO bus code will set - * it to a value that doesn't conflict with other PHYs on the bus, or the - * value doesn't matter, as there are no other PHYs on the bus. - */ -static void uec_configure_serdes(struct net_device *dev) -{ - struct ucc_geth_private *ugeth = netdev_priv(dev); - - if (!ugeth->tbiphy) { - printk(KERN_WARNING "SGMII mode requires that the device " - "tree specify a tbi-handle\n"); - return; - } - - /* - * If the link is already up, we must already be ok, and don't need to - * configure and reset the TBI<->SerDes link. Maybe U-Boot configured - * everything for us? Resetting it takes the link down and requires - * several seconds for it to come back. - */ - if (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) - return; - - /* Single clk mode, mii mode off(for serdes communication) */ - phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS); - phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT); - - phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS); - -} static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) { @@ -3565,8 +3523,6 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type) return PHY_INTERFACE_MODE_RGMII_RXID; if (strcasecmp(phy_connection_type, "rtbi") == 0) return PHY_INTERFACE_MODE_RTBI; - if (strcasecmp(phy_connection_type, "sgmii") == 0) - return PHY_INTERFACE_MODE_SGMII; return PHY_INTERFACE_MODE_MII; } @@ -3611,7 +3567,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI, - PHY_INTERFACE_MODE_SGMII, }; ugeth_vdbg("%s: IN", __func__); @@ -3727,7 +3682,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma case PHY_INTERFACE_MODE_RGMII_TXID: case PHY_INTERFACE_MODE_TBI: case PHY_INTERFACE_MODE_RTBI: - case PHY_INTERFACE_MODE_SGMII: max_speed = SPEED_1000; break; default: @@ -3802,37 +3756,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ugeth->ndev = dev; ugeth->node = np; - /* Find the TBI PHY. If it's not there, we don't support SGMII */ - ph = of_get_property(np, "tbi-handle", NULL); - if (ph) { - struct device_node *tbi = of_find_node_by_phandle(*ph); - struct of_device *ofdev; - struct mii_bus *bus; - const unsigned int *id; - - if (!tbi) - return 0; - - mdio = of_get_parent(tbi); - if (!mdio) - return 0; - - ofdev = of_find_device_by_node(mdio); - - of_node_put(mdio); - - id = of_get_property(tbi, "reg", NULL); - if (!id) - return 0; - of_node_put(tbi); - - bus = dev_get_drvdata(&ofdev->dev); - if (!bus) - return 0; - - ugeth->tbiphy = bus->phy_map[*id]; - } - return 0; } diff --git a/trunk/drivers/net/ucc_geth.h b/trunk/drivers/net/ucc_geth.h index deb962bb68ef..dca628a922ba 100644 --- a/trunk/drivers/net/ucc_geth.h +++ b/trunk/drivers/net/ucc_geth.h @@ -1,5 +1,5 @@ /* - * Copyright (C) Freescale Semicondutor, Inc. 2006-2009. All rights reserved. + * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. * * Author: Shlomi Gridish * @@ -193,31 +193,6 @@ struct ucc_geth { #define ENET_TBI_MII_JD 0x10 /* Jitter diagnostics */ #define ENET_TBI_MII_TBICON 0x11 /* TBI control */ -/* TBI MDIO register bit fields*/ -#define TBISR_LSTATUS 0x0004 -#define TBICON_CLK_SELECT 0x0020 -#define TBIANA_ASYMMETRIC_PAUSE 0x0100 -#define TBIANA_SYMMETRIC_PAUSE 0x0080 -#define TBIANA_HALF_DUPLEX 0x0040 -#define TBIANA_FULL_DUPLEX 0x0020 -#define TBICR_PHY_RESET 0x8000 -#define TBICR_ANEG_ENABLE 0x1000 -#define TBICR_RESTART_ANEG 0x0200 -#define TBICR_FULL_DUPLEX 0x0100 -#define TBICR_SPEED1_SET 0x0040 - -#define TBIANA_SETTINGS ( \ - TBIANA_ASYMMETRIC_PAUSE \ - | TBIANA_SYMMETRIC_PAUSE \ - | TBIANA_FULL_DUPLEX \ - ) -#define TBICR_SETTINGS ( \ - TBICR_PHY_RESET \ - | TBICR_ANEG_ENABLE \ - | TBICR_FULL_DUPLEX \ - | TBICR_SPEED1_SET \ - ) - /* UCC GETH MACCFG1 (MAC Configuration 1 Register) */ #define MACCFG1_FLOW_RX 0x00000020 /* Flow Control Rx */ @@ -1213,7 +1188,6 @@ struct ucc_geth_private { struct ugeth_mii_info *mii_info; struct phy_device *phydev; - struct phy_device *tbiphy; phy_interface_t phy_interface; int max_speed; uint32_t msg_enable; diff --git a/trunk/drivers/net/usb/hso.c b/trunk/drivers/net/usb/hso.c index e3580f42c899..837135f0390a 100644 --- a/trunk/drivers/net/usb/hso.c +++ b/trunk/drivers/net/usb/hso.c @@ -899,14 +899,15 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, continue; } /* Allocate an sk_buff */ - odev->skb_rx_buf = netdev_alloc_skb(odev->net, - frame_len); + odev->skb_rx_buf = dev_alloc_skb(frame_len); if (!odev->skb_rx_buf) { /* We got no receive buffer. */ D1("could not allocate memory"); odev->rx_parse_state = WAIT_SYNC; return; } + /* Here's where it came from */ + odev->skb_rx_buf->dev = odev->net; /* Copy what we got so far. make room for iphdr * after tail. */ @@ -2480,10 +2481,10 @@ static int add_net_device(struct hso_device *hso_dev) return 0; } -static int hso_rfkill_set_block(void *data, bool blocked) +static int hso_radio_toggle(void *data, enum rfkill_state state) { struct hso_device *hso_dev = data; - int enabled = !blocked; + int enabled = (state == RFKILL_STATE_UNBLOCKED); int rv; mutex_lock(&hso_dev->mutex); @@ -2497,10 +2498,6 @@ static int hso_rfkill_set_block(void *data, bool blocked) return rv; } -static const struct rfkill_ops hso_rfkill_ops = { - .set_block = hso_rfkill_set_block, -}; - /* Creates and sets up everything for rfkill */ static void hso_create_rfkill(struct hso_device *hso_dev, struct usb_interface *interface) @@ -2509,25 +2506,29 @@ static void hso_create_rfkill(struct hso_device *hso_dev, struct device *dev = &hso_net->net->dev; char *rfkn; - rfkn = kzalloc(20, GFP_KERNEL); - if (!rfkn) - dev_err(dev, "%s - Out of memory\n", __func__); - - snprintf(rfkn, 20, "hso-%d", - interface->altsetting->desc.bInterfaceNumber); - - hso_net->rfkill = rfkill_alloc(rfkn, - &interface_to_usbdev(interface)->dev, - RFKILL_TYPE_WWAN, - &hso_rfkill_ops, hso_dev); + hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev, + RFKILL_TYPE_WWAN); if (!hso_net->rfkill) { dev_err(dev, "%s - Out of memory\n", __func__); - kfree(rfkn); return; } + rfkn = kzalloc(20, GFP_KERNEL); + if (!rfkn) { + rfkill_free(hso_net->rfkill); + hso_net->rfkill = NULL; + dev_err(dev, "%s - Out of memory\n", __func__); + return; + } + snprintf(rfkn, 20, "hso-%d", + interface->altsetting->desc.bInterfaceNumber); + hso_net->rfkill->name = rfkn; + hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED; + hso_net->rfkill->data = hso_dev; + hso_net->rfkill->toggle_radio = hso_radio_toggle; if (rfkill_register(hso_net->rfkill) < 0) { - rfkill_destroy(hso_net->rfkill); kfree(rfkn); + hso_net->rfkill->name = NULL; + rfkill_free(hso_net->rfkill); hso_net->rfkill = NULL; dev_err(dev, "%s - Failed to register rfkill\n", __func__); return; @@ -3164,10 +3165,8 @@ static void hso_free_interface(struct usb_interface *interface) hso_stop_net_device(network_table[i]); cancel_work_sync(&network_table[i]->async_put_intf); cancel_work_sync(&network_table[i]->async_get_intf); - if (rfk) { + if (rfk) rfkill_unregister(rfk); - rfkill_destroy(rfk); - } hso_free_net_device(network_table[i]); } } diff --git a/trunk/drivers/net/usb/rtl8150.c b/trunk/drivers/net/usb/rtl8150.c index fcc6fa0905d1..f9fb454ffa8b 100644 --- a/trunk/drivers/net/usb/rtl8150.c +++ b/trunk/drivers/net/usb/rtl8150.c @@ -221,8 +221,7 @@ static void ctrl_callback(struct urb *urb) case -ENOENT: break; default: - if (printk_ratelimit()) - dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status); + dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status); } dev = urb->context; clear_bit(RX_REG_SET, &dev->flags); @@ -443,12 +442,10 @@ static void read_bulk_callback(struct urb *urb) case -ENOENT: return; /* the urb is in unlink state */ case -ETIME: - if (printk_ratelimit()) - dev_warn(&urb->dev->dev, "may be reset is needed?..\n"); + dev_warn(&urb->dev->dev, "may be reset is needed?..\n"); goto goon; default: - if (printk_ratelimit()) - dev_warn(&urb->dev->dev, "Rx status %d\n", status); + dev_warn(&urb->dev->dev, "Rx status %d\n", status); goto goon; } diff --git a/trunk/drivers/net/veth.c b/trunk/drivers/net/veth.c index 87197dd9c788..8e56fcf0a0e3 100644 --- a/trunk/drivers/net/veth.c +++ b/trunk/drivers/net/veth.c @@ -176,6 +176,8 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev) if (dev->features & NETIF_F_NO_CSUM) skb->ip_summed = rcv_priv->ip_summed; + dst_release(skb->dst); + skb->dst = NULL; skb->mark = 0; secpath_reset(skb); nf_reset(skb); diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c index d3489a3c4c03..45daba726b66 100644 --- a/trunk/drivers/net/via-rhine.c +++ b/trunk/drivers/net/via-rhine.c @@ -388,6 +388,7 @@ struct rhine_private { long pioaddr; struct net_device *dev; struct napi_struct napi; + struct net_device_stats stats; spinlock_t lock; /* Frequently used values: keep some adjacent for cache effect. */ @@ -1208,7 +1209,7 @@ static void rhine_tx_timeout(struct net_device *dev) enable_irq(rp->pdev->irq); dev->trans_start = jiffies; - dev->stats.tx_errors++; + rp->stats.tx_errors++; netif_wake_queue(dev); } @@ -1236,7 +1237,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev) /* packet too long, drop it */ dev_kfree_skb(skb); rp->tx_skbuff[entry] = NULL; - dev->stats.tx_dropped++; + rp->stats.tx_dropped++; return 0; } @@ -1377,33 +1378,29 @@ static void rhine_tx(struct net_device *dev) printk(KERN_DEBUG "%s: Transmit error, " "Tx status %8.8x.\n", dev->name, txstatus); - dev->stats.tx_errors++; - if (txstatus & 0x0400) - dev->stats.tx_carrier_errors++; - if (txstatus & 0x0200) - dev->stats.tx_window_errors++; - if (txstatus & 0x0100) - dev->stats.tx_aborted_errors++; - if (txstatus & 0x0080) - dev->stats.tx_heartbeat_errors++; + rp->stats.tx_errors++; + if (txstatus & 0x0400) rp->stats.tx_carrier_errors++; + if (txstatus & 0x0200) rp->stats.tx_window_errors++; + if (txstatus & 0x0100) rp->stats.tx_aborted_errors++; + if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++; if (((rp->quirks & rqRhineI) && txstatus & 0x0002) || (txstatus & 0x0800) || (txstatus & 0x1000)) { - dev->stats.tx_fifo_errors++; + rp->stats.tx_fifo_errors++; rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn); break; /* Keep the skb - we try again */ } /* Transmitter restarted in 'abnormal' handler. */ } else { if (rp->quirks & rqRhineI) - dev->stats.collisions += (txstatus >> 3) & 0x0F; + rp->stats.collisions += (txstatus >> 3) & 0x0F; else - dev->stats.collisions += txstatus & 0x0F; + rp->stats.collisions += txstatus & 0x0F; if (debug > 6) printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n", (txstatus >> 3) & 0xF, txstatus & 0xF); - dev->stats.tx_bytes += rp->tx_skbuff[entry]->len; - dev->stats.tx_packets++; + rp->stats.tx_bytes += rp->tx_skbuff[entry]->len; + rp->stats.tx_packets++; } /* Free the original skb. */ if (rp->tx_skbuff_dma[entry]) { @@ -1458,24 +1455,21 @@ static int rhine_rx(struct net_device *dev, int limit) printk(KERN_WARNING "%s: Oversized Ethernet " "frame %p vs %p.\n", dev->name, rp->rx_head_desc, &rp->rx_ring[entry]); - dev->stats.rx_length_errors++; + rp->stats.rx_length_errors++; } else if (desc_status & RxErr) { /* There was a error. */ if (debug > 2) printk(KERN_DEBUG "rhine_rx() Rx " "error was %8.8x.\n", desc_status); - dev->stats.rx_errors++; - if (desc_status & 0x0030) - dev->stats.rx_length_errors++; - if (desc_status & 0x0048) - dev->stats.rx_fifo_errors++; - if (desc_status & 0x0004) - dev->stats.rx_frame_errors++; + rp->stats.rx_errors++; + if (desc_status & 0x0030) rp->stats.rx_length_errors++; + if (desc_status & 0x0048) rp->stats.rx_fifo_errors++; + if (desc_status & 0x0004) rp->stats.rx_frame_errors++; if (desc_status & 0x0002) { /* this can also be updated outside the interrupt handler */ spin_lock(&rp->lock); - dev->stats.rx_crc_errors++; + rp->stats.rx_crc_errors++; spin_unlock(&rp->lock); } } @@ -1519,8 +1513,8 @@ static int rhine_rx(struct net_device *dev, int limit) } skb->protocol = eth_type_trans(skb, dev); netif_receive_skb(skb); - dev->stats.rx_bytes += pkt_len; - dev->stats.rx_packets++; + rp->stats.rx_bytes += pkt_len; + rp->stats.rx_packets++; } entry = (++rp->cur_rx) % RX_RING_SIZE; rp->rx_head_desc = &rp->rx_ring[entry]; @@ -1605,8 +1599,8 @@ static void rhine_error(struct net_device *dev, int intr_status) if (intr_status & IntrLinkChange) rhine_check_media(dev, 0); if (intr_status & IntrStatsMax) { - dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); - dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); + rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); + rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); clear_tally_counters(ioaddr); } if (intr_status & IntrTxAborted) { @@ -1660,12 +1654,12 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev) unsigned long flags; spin_lock_irqsave(&rp->lock, flags); - dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); - dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); + rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); + rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); clear_tally_counters(ioaddr); spin_unlock_irqrestore(&rp->lock, flags); - return &dev->stats; + return &rp->stats; } static void rhine_set_rx_mode(struct net_device *dev) diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index e2a7725e567e..754a4b182c1d 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -1385,7 +1385,7 @@ static void velocity_free_td_ring(struct velocity_info *vptr) static int velocity_rx_srv(struct velocity_info *vptr, int status) { - struct net_device_stats *stats = &vptr->dev->stats; + struct net_device_stats *stats = &vptr->stats; int rd_curr = vptr->rx.curr; int works = 0; @@ -1519,7 +1519,7 @@ static inline void velocity_iph_realign(struct velocity_info *vptr, static int velocity_receive_frame(struct velocity_info *vptr, int idx) { void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int); - struct net_device_stats *stats = &vptr->dev->stats; + struct net_device_stats *stats = &vptr->stats; struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]); struct rx_desc *rd = &(vptr->rx.ring[idx]); int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff; @@ -1532,7 +1532,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx) } if (rd->rdesc0.RSR & RSR_MAR) - stats->multicast++; + vptr->stats.multicast++; skb = rd_info->skb; @@ -1634,7 +1634,7 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status) int idx; int works = 0; struct velocity_td_info *tdinfo; - struct net_device_stats *stats = &vptr->dev->stats; + struct net_device_stats *stats = &vptr->stats; for (qnum = 0; qnum < vptr->tx.numq; qnum++) { for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0; @@ -2324,22 +2324,22 @@ static struct net_device_stats *velocity_get_stats(struct net_device *dev) /* If the hardware is down, don't touch MII */ if(!netif_running(dev)) - return &dev->stats; + return &vptr->stats; spin_lock_irq(&vptr->lock); velocity_update_hw_mibs(vptr); spin_unlock_irq(&vptr->lock); - dev->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts]; - dev->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts]; - dev->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors]; + vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts]; + vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts]; + vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors]; // unsigned long rx_dropped; /* no space in linux buffers */ - dev->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions]; + vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions]; /* detailed rx_errors: */ // unsigned long rx_length_errors; // unsigned long rx_over_errors; /* receiver ring buff overflow */ - dev->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE]; + vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE]; // unsigned long rx_frame_errors; /* recv'd frame alignment error */ // unsigned long rx_fifo_errors; /* recv'r fifo overrun */ // unsigned long rx_missed_errors; /* receiver missed packet */ @@ -2347,7 +2347,7 @@ static struct net_device_stats *velocity_get_stats(struct net_device *dev) /* detailed tx_errors */ // unsigned long tx_fifo_errors; - return &dev->stats; + return &vptr->stats; } diff --git a/trunk/drivers/net/via-velocity.h b/trunk/drivers/net/via-velocity.h index 4cd3f6c97379..ea43e1832afb 100644 --- a/trunk/drivers/net/via-velocity.h +++ b/trunk/drivers/net/via-velocity.h @@ -1503,6 +1503,7 @@ struct velocity_info { struct pci_dev *pdev; struct net_device *dev; + struct net_device_stats stats; struct vlan_group *vlgrp; u8 ip_addr[4]; diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 09bd4410fa65..6cc5bcd34fb0 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -470,7 +470,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) } if (skb_is_gso(skb)) { - hdr->hdr_len = skb_headlen(skb); + hdr->hdr_len = skb_transport_header(skb) - skb->data; hdr->gso_size = skb_shinfo(skb)->gso_size; if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; @@ -680,7 +680,6 @@ static void virtnet_set_rx_mode(struct net_device *dev) u8 promisc, allmulti; struct virtio_net_ctrl_mac *mac_data; struct dev_addr_list *addr; - struct netdev_hw_addr *ha; void *buf; int i; @@ -719,9 +718,9 @@ static void virtnet_set_rx_mode(struct net_device *dev) /* Store the unicast list and count in the front of the buffer */ mac_data->entries = dev->uc_count; - i = 0; - list_for_each_entry(ha, &dev->uc_list, list) - memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN); + addr = dev->uc_list; + for (i = 0; i < dev->uc_count; i++, addr = addr->next) + memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN); sg_set_buf(&sg[0], mac_data, sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN)); diff --git a/trunk/drivers/net/vxge/vxge-config.c b/trunk/drivers/net/vxge/vxge-config.c index 26cde573af43..6b41c884a337 100644 --- a/trunk/drivers/net/vxge/vxge-config.c +++ b/trunk/drivers/net/vxge/vxge-config.c @@ -1884,13 +1884,17 @@ void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) mempool->memblock_size, dma_object); } - vfree(mempool->items_arr); + if (mempool->items_arr) + vfree(mempool->items_arr); - vfree(mempool->memblocks_dma_arr); + if (mempool->memblocks_dma_arr) + vfree(mempool->memblocks_dma_arr); - vfree(mempool->memblocks_priv_arr); + if (mempool->memblocks_priv_arr) + vfree(mempool->memblocks_priv_arr); - vfree(mempool->memblocks_arr); + if (mempool->memblocks_arr) + vfree(mempool->memblocks_arr); vfree(mempool); } diff --git a/trunk/drivers/net/vxge/vxge-main.c b/trunk/drivers/net/vxge/vxge-main.c index 6c838b3e063a..b7f08f3e524b 100644 --- a/trunk/drivers/net/vxge/vxge-main.c +++ b/trunk/drivers/net/vxge/vxge-main.c @@ -677,7 +677,7 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr, return VXGE_HW_OK; } -/* select a vpath to transmit the packet */ +/* select a vpath to trasmit the packet */ static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb, int *do_lock) { @@ -992,9 +992,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN); vxge_hw_fifo_txdl_post(fifo_hw, dtr); -#ifdef NETIF_F_LLTX - dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ -#endif + dev->trans_start = jiffies; spin_unlock_irqrestore(&fifo->tx_lock, flags); VXGE_COMPLETE_VPATH_TX(fifo); diff --git a/trunk/drivers/net/wan/ixp4xx_hss.c b/trunk/drivers/net/wan/ixp4xx_hss.c index 08b1a284b690..765a7f5d6aa4 100644 --- a/trunk/drivers/net/wan/ixp4xx_hss.c +++ b/trunk/drivers/net/wan/ixp4xx_hss.c @@ -731,8 +731,8 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget) dma_unmap_single(&dev->dev, desc->data, RX_SIZE, DMA_FROM_DEVICE); #else - dma_sync_single_for_cpu(&dev->dev, desc->data, - RX_SIZE, DMA_FROM_DEVICE); + dma_sync_single(&dev->dev, desc->data, + RX_SIZE, DMA_FROM_DEVICE); memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n], ALIGN(desc->pkt_len, 4) / 4); #endif diff --git a/trunk/drivers/net/wimax/i2400m/control.c b/trunk/drivers/net/wimax/i2400m/control.c index 07308686dbcf..b3cadb626fe0 100644 --- a/trunk/drivers/net/wimax/i2400m/control.c +++ b/trunk/drivers/net/wimax/i2400m/control.c @@ -292,6 +292,8 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m, d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state); + if (unlikely(i2400m->ready == 0)) /* act if up */ + goto out; if (i2400m->state != i2400m_state) { i2400m->state = i2400m_state; wake_up_all(&i2400m->state_wq); @@ -339,6 +341,7 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m, i2400m->bus_reset(i2400m, I2400M_RT_WARM); break; }; +out: d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n", i2400m, ss, i2400m_state); } @@ -369,6 +372,8 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m, d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status); + if (unlikely(i2400m->ready == 0)) /* act if up */ + goto out; switch (status) { case I2400M_MEDIA_STATUS_LINK_UP: netif_carrier_on(net_dev); @@ -388,59 +393,14 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m, dev_err(dev, "HW BUG? unknown media status %u\n", status); }; +out: d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n", i2400m, ms, status); } /* - * Process a TLV from a 'state report' - * - * @i2400m: device descriptor - * @tlv: pointer to the TLV header; it has been already validated for - * consistent size. - * @tag: for error messages - * - * Act on the TLVs from a 'state report'. - */ -static -void i2400m_report_state_parse_tlv(struct i2400m *i2400m, - const struct i2400m_tlv_hdr *tlv, - const char *tag) -{ - struct device *dev = i2400m_dev(i2400m); - const struct i2400m_tlv_media_status *ms; - const struct i2400m_tlv_system_state *ss; - const struct i2400m_tlv_rf_switches_status *rfss; - - if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, sizeof(*ss))) { - ss = container_of(tlv, typeof(*ss), hdr); - d_printf(2, dev, "%s: system state TLV " - "found (0x%04x), state 0x%08x\n", - tag, I2400M_TLV_SYSTEM_STATE, - le32_to_cpu(ss->state)); - i2400m_report_tlv_system_state(i2400m, ss); - } - if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, sizeof(*rfss))) { - rfss = container_of(tlv, typeof(*rfss), hdr); - d_printf(2, dev, "%s: RF status TLV " - "found (0x%04x), sw 0x%02x hw 0x%02x\n", - tag, I2400M_TLV_RF_STATUS, - le32_to_cpu(rfss->sw_rf_switch), - le32_to_cpu(rfss->hw_rf_switch)); - i2400m_report_tlv_rf_switches_status(i2400m, rfss); - } - if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, sizeof(*ms))) { - ms = container_of(tlv, typeof(*ms), hdr); - d_printf(2, dev, "%s: Media Status TLV: %u\n", - tag, le32_to_cpu(ms->media_status)); - i2400m_report_tlv_media_status(i2400m, ms); - } -} - - -/* - * Parse a 'state report' and extract information + * Parse a 'state report' and extract carrier on/off information * * @i2400m: device descriptor * @l3l4_hdr: pointer to message; it has been already validated for @@ -449,7 +409,13 @@ void i2400m_report_state_parse_tlv(struct i2400m *i2400m, * declaration is assumed to be congruent with @size (as in * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) * - * Walk over the TLVs in a report state and act on them. + * Extract from the report state the system state TLV and infer from + * there if we have a carrier or not. Update our local state and tell + * netdev. + * + * When setting the carrier, it's fine to set OFF twice (for example), + * as netif_carrier_off() will not generate two OFF events (just on + * the transitions). */ static void i2400m_report_state_hook(struct i2400m *i2400m, @@ -458,6 +424,9 @@ void i2400m_report_state_hook(struct i2400m *i2400m, { struct device *dev = i2400m_dev(i2400m); const struct i2400m_tlv_hdr *tlv; + const struct i2400m_tlv_system_state *ss; + const struct i2400m_tlv_rf_switches_status *rfss; + const struct i2400m_tlv_media_status *ms; size_t tlv_size = le16_to_cpu(l3l4_hdr->length); d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n", @@ -465,8 +434,34 @@ void i2400m_report_state_hook(struct i2400m *i2400m, tlv = NULL; while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl, - tlv_size, tlv))) - i2400m_report_state_parse_tlv(i2400m, tlv, tag); + tlv_size, tlv))) { + if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, + sizeof(*ss))) { + ss = container_of(tlv, typeof(*ss), hdr); + d_printf(2, dev, "%s: system state TLV " + "found (0x%04x), state 0x%08x\n", + tag, I2400M_TLV_SYSTEM_STATE, + le32_to_cpu(ss->state)); + i2400m_report_tlv_system_state(i2400m, ss); + } + if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, + sizeof(*rfss))) { + rfss = container_of(tlv, typeof(*rfss), hdr); + d_printf(2, dev, "%s: RF status TLV " + "found (0x%04x), sw 0x%02x hw 0x%02x\n", + tag, I2400M_TLV_RF_STATUS, + le32_to_cpu(rfss->sw_rf_switch), + le32_to_cpu(rfss->hw_rf_switch)); + i2400m_report_tlv_rf_switches_status(i2400m, rfss); + } + if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, + sizeof(*ms))) { + ms = container_of(tlv, typeof(*ms), hdr); + d_printf(2, dev, "%s: Media Status TLV: %u\n", + tag, le32_to_cpu(ms->media_status)); + i2400m_report_tlv_media_status(i2400m, ms); + } + } d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n", i2400m, l3l4_hdr, size, tag); } @@ -505,15 +500,8 @@ void i2400m_report_hook(struct i2400m *i2400m, * it. */ case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */ if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) { - if (i2400m_power_save_disabled) - d_printf(1, dev, "ready for powersave, " - "not requesting (disabled by module " - "parameter)\n"); - else { - d_printf(1, dev, "ready for powersave, " - "requesting\n"); - i2400m_cmd_enter_powersave(i2400m); - } + d_printf(1, dev, "ready for powersave, requesting\n"); + i2400m_cmd_enter_powersave(i2400m); } break; }; @@ -695,9 +683,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m, d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n", i2400m, buf, buf_len); - rmb(); /* Make sure we see what i2400m_dev_reset_handle() */ if (i2400m->boot_mode) - return ERR_PTR(-EL3RST); + return ERR_PTR(-ENODEV); msg_l3l4_hdr = buf; /* Check msg & payload consistency */ @@ -734,8 +721,6 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m, ack_timeout = HZ; }; - if (unlikely(i2400m->trace_msg_from_user)) - wimax_msg(&i2400m->wimax_dev, "echo", buf, buf_len, GFP_KERNEL); /* The RX path in rx.c will put any response for this message * in i2400m->ack_skb and wake us up. If we cancel the wait, * we need to change the value of i2400m->ack_skb to something @@ -770,9 +755,6 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m, ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len); /* Check the ack and deliver it if it is ok */ - if (unlikely(i2400m->trace_msg_from_user)) - wimax_msg(&i2400m->wimax_dev, "echo", - ack_l3l4_hdr, ack_len, GFP_KERNEL); result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len); if (result < 0) { dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n", @@ -1397,16 +1379,16 @@ int i2400m_dev_initialize(struct i2400m *i2400m) * * @i2400m: device descriptor * - * Release resources acquired during the running of the device; in - * theory, should also tell the device to go to sleep, switch off the - * radio, all that, but at this point, in most cases (driver - * disconnection, reset handling) we can't even talk to the device. + * Gracefully stops the device, moving it to the lowest power + * consumption state possible. */ void i2400m_dev_shutdown(struct i2400m *i2400m) { + int result = -ENODEV; struct device *dev = i2400m_dev(i2400m); d_fnstart(3, dev, "(i2400m %p)\n", i2400m); - d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); + result = i2400m->bus_reset(i2400m, I2400M_RT_WARM); + d_fnend(3, dev, "(i2400m %p) = void [%d]\n", i2400m, result); return; } diff --git a/trunk/drivers/net/wimax/i2400m/driver.c b/trunk/drivers/net/wimax/i2400m/driver.c index 304f0443ca4b..07a54bad237b 100644 --- a/trunk/drivers/net/wimax/i2400m/driver.c +++ b/trunk/drivers/net/wimax/i2400m/driver.c @@ -62,7 +62,6 @@ * unregister_netdev() */ #include "i2400m.h" -#include #include #include #include @@ -82,14 +81,6 @@ module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644); MODULE_PARM_DESC(rx_reorder_disabled, "If true, RX reordering will be disabled."); -int i2400m_power_save_disabled; /* 0 (power saving enabled) by default */ -module_param_named(power_save_disabled, i2400m_power_save_disabled, int, 0644); -MODULE_PARM_DESC(power_save_disabled, - "If true, the driver will not tell the device to enter " - "power saving mode when it reports it is ready for it. " - "False by default (so the device is told to do power " - "saving)."); - /** * i2400m_queue_work - schedule work on a i2400m's queue * @@ -180,6 +171,7 @@ int i2400m_schedule_work(struct i2400m *i2400m, int result; struct i2400m_work *iw; + BUG_ON(i2400m->work_queue == NULL); result = -ENOMEM; iw = kzalloc(sizeof(*iw), gfp_flags); if (iw == NULL) @@ -242,6 +234,9 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev, result = PTR_ERR(ack_skb); if (IS_ERR(ack_skb)) goto error_msg_to_dev; + if (unlikely(i2400m->trace_msg_from_user)) + wimax_msg(&i2400m->wimax_dev, "trace", + msg_buf, msg_len, GFP_KERNEL); result = wimax_msg_send(&i2400m->wimax_dev, ack_skb); error_msg_to_dev: d_fnend(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu " @@ -384,11 +379,6 @@ int i2400m_check_mac_addr(struct i2400m *i2400m) * Uploads firmware and brings up all the resources needed to be able * to communicate with the device. * - * The workqueue has to be setup early, at least before RX handling - * (it's only real user for now) so it can process reports as they - * arrive. We also want to destroy it if we retry, to make sure it is - * flushed...easier like this. - * * TX needs to be setup before the bus-specific code (otherwise on * shutdown, the bus-tx code could try to access it). */ @@ -399,7 +389,7 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) struct wimax_dev *wimax_dev = &i2400m->wimax_dev; struct net_device *net_dev = wimax_dev->net_dev; struct device *dev = i2400m_dev(i2400m); - int times = i2400m->bus_bm_retries; + int times = 3; d_fnstart(3, dev, "(i2400m %p)\n", i2400m); retry: @@ -414,15 +404,15 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) result = i2400m_rx_setup(i2400m); if (result < 0) goto error_rx_setup; + result = i2400m->bus_dev_start(i2400m); + if (result < 0) + goto error_bus_dev_start; i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name); if (i2400m->work_queue == NULL) { result = -ENOMEM; dev_err(dev, "cannot create workqueue\n"); goto error_create_workqueue; } - result = i2400m->bus_dev_start(i2400m); - if (result < 0) - goto error_bus_dev_start; result = i2400m_firmware_check(i2400m); /* fw versions ok? */ if (result < 0) goto error_fw_check; @@ -444,17 +434,17 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) error_dev_initialize: error_check_mac_addr: error_fw_check: - i2400m->bus_dev_stop(i2400m); -error_bus_dev_start: destroy_workqueue(i2400m->work_queue); error_create_workqueue: + i2400m->bus_dev_stop(i2400m); +error_bus_dev_start: i2400m_rx_release(i2400m); error_rx_setup: i2400m_tx_release(i2400m); error_tx_setup: error_bootstrap: - if (result == -EL3RST && times-- > 0) { - flags = I2400M_BRI_SOFT|I2400M_BRI_MAC_REINIT; + if (result == -ERESTARTSYS && times-- > 0) { + flags = I2400M_BRI_SOFT; goto retry; } d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", @@ -483,9 +473,7 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags) * * Returns: 0 if ok, < 0 errno code on error. * - * Releases all the resources allocated to communicate with the - * device. Note we cannot destroy the workqueue earlier as until RX is - * fully destroyed, it could still try to schedule jobs. + * Releases all the resources allocated to communicate with the device. */ static void __i2400m_dev_stop(struct i2400m *i2400m) @@ -497,8 +485,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m) wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); i2400m_dev_shutdown(i2400m); i2400m->ready = 0; - i2400m->bus_dev_stop(i2400m); destroy_workqueue(i2400m->work_queue); + i2400m->bus_dev_stop(i2400m); i2400m_rx_release(i2400m); i2400m_tx_release(i2400m); wimax_state_change(wimax_dev, WIMAX_ST_DOWN); @@ -560,7 +548,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws) * i2400m_dev_stop() [we are shutting down anyway, so * ignore it] or we are resetting somewhere else. */ dev_err(dev, "device rebooted\n"); - i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST); + i2400m_msg_to_dev_cancel_wait(i2400m, -ERESTARTSYS); complete(&i2400m->msg_completion); goto out; } @@ -610,8 +598,6 @@ void __i2400m_dev_reset_handle(struct work_struct *ws) */ int i2400m_dev_reset_handle(struct i2400m *i2400m) { - i2400m->boot_mode = 1; - wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */ return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle, GFP_ATOMIC); } @@ -664,7 +650,6 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) result = i2400m_read_mac_addr(i2400m); if (result < 0) goto error_read_mac_addr; - random_ether_addr(i2400m->src_mac_addr); result = register_netdev(net_dev); /* Okey dokey, bring it up */ if (result < 0) { diff --git a/trunk/drivers/net/wimax/i2400m/fw.c b/trunk/drivers/net/wimax/i2400m/fw.c index e81750e54452..675c6ce810c0 100644 --- a/trunk/drivers/net/wimax/i2400m/fw.c +++ b/trunk/drivers/net/wimax/i2400m/fw.c @@ -397,7 +397,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk, unsigned int direct, unsigned int do_csum) { int ret; - size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_ALIGN); + size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_PAD); struct device *dev = i2400m_dev(i2400m); struct { struct i2400m_bootrom_header cmd; @@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m, cmd = (void *) bcf + offset; if (i2400m->sboot == 0) { struct i2400m_bootrom_header jump_ack; - d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n", + d_printf(3, dev, "unsecure boot, jumping to 0x%08x\n", le32_to_cpu(cmd->target_addr)); i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP); cmd->data_size = 0; ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), &jump_ack, sizeof(jump_ack), 0); } else { - d_printf(1, dev, "secure boot, jumping to 0x%08x\n", + d_printf(3, dev, "secure boot, jumping to 0x%08x\n", le32_to_cpu(cmd->target_addr)); cmd_buf = i2400m->bm_cmd_buf; memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd)); @@ -696,7 +696,8 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags) return result; error_timeout: - dev_err(dev, "Timed out waiting for reboot ack\n"); + dev_err(dev, "Timed out waiting for reboot ack, resetting\n"); + i2400m->bus_reset(i2400m, I2400M_RT_BUS); result = -ETIMEDOUT; goto exit_timeout; } @@ -769,21 +770,40 @@ int i2400m_read_mac_addr(struct i2400m *i2400m) static int i2400m_dnload_init_nonsigned(struct i2400m *i2400m) { - unsigned i = 0; - int ret = 0; +#define POKE(a, d) { \ + .address = cpu_to_le32(a), \ + .data = cpu_to_le32(d) \ +} + static const struct { + __le32 address; + __le32 data; + } i2400m_pokes[] = { + POKE(0x081A58, 0xA7810230), + POKE(0x080040, 0x00000000), + POKE(0x080048, 0x00000082), + POKE(0x08004C, 0x0000081F), + POKE(0x080054, 0x00000085), + POKE(0x080058, 0x00000180), + POKE(0x08005C, 0x00000018), + POKE(0x080060, 0x00000010), + POKE(0x080574, 0x00000001), + POKE(0x080550, 0x00000005), + POKE(0xAE0000, 0x00000000), + }; +#undef POKE + unsigned i; + int ret; struct device *dev = i2400m_dev(i2400m); + + dev_warn(dev, "WARNING!!! non-signed boot UNTESTED PATH!\n"); + d_fnstart(5, dev, "(i2400m %p)\n", i2400m); - if (i2400m->bus_bm_pokes_table) { - while (i2400m->bus_bm_pokes_table[i].address) { - ret = i2400m_download_chunk( - i2400m, - &i2400m->bus_bm_pokes_table[i].data, - sizeof(i2400m->bus_bm_pokes_table[i].data), - i2400m->bus_bm_pokes_table[i].address, 1, 1); - if (ret < 0) - break; - i++; - } + for (i = 0; i < ARRAY_SIZE(i2400m_pokes); i++) { + ret = i2400m_download_chunk(i2400m, &i2400m_pokes[i].data, + sizeof(i2400m_pokes[i].data), + i2400m_pokes[i].address, 1, 1); + if (ret < 0) + break; } d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); return ret; @@ -960,12 +980,11 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, { int ret = 0; struct device *dev = i2400m_dev(i2400m); - int count = i2400m->bus_bm_retries; + int count = I2400M_BOOT_RETRIES; d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n", i2400m, bcf, bcf_size); i2400m->boot_mode = 1; - wmb(); /* Make sure other readers see it */ hw_reboot: if (count-- == 0) { ret = -ERESTARTSYS; @@ -1014,7 +1033,6 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf, d_printf(2, dev, "fw %s successfully uploaded\n", i2400m->fw_name); i2400m->boot_mode = 0; - wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */ error_dnload_finalize: error_dnload_bcf: error_dnload_init: diff --git a/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h b/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h index 9c4e3189f7b5..08c2fb739234 100644 --- a/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h +++ b/trunk/drivers/net/wimax/i2400m/i2400m-sdio.h @@ -78,8 +78,6 @@ enum { /* The number of ticks to wait for the device to signal that * it is ready */ I2400MS_INIT_SLEEP_INTERVAL = 10, - /* How long to wait for the device to settle after reset */ - I2400MS_SETTLE_TIME = 40, }; @@ -107,10 +105,6 @@ struct i2400ms { char tx_wq_name[32]; struct dentry *debugfs_dentry; - - wait_queue_head_t bm_wfa_wq; - int bm_wait_result; - size_t bm_ack_size; }; @@ -135,7 +129,4 @@ extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *, extern ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *, struct i2400m_bootrom_header *, size_t); -extern void i2400ms_bus_bm_release(struct i2400m *); -extern int i2400ms_bus_bm_setup(struct i2400m *); - #endif /* #ifndef __I2400M_SDIO_H__ */ diff --git a/trunk/drivers/net/wimax/i2400m/i2400m.h b/trunk/drivers/net/wimax/i2400m/i2400m.h index 1fe5da4cf0a0..3ae2df38b59a 100644 --- a/trunk/drivers/net/wimax/i2400m/i2400m.h +++ b/trunk/drivers/net/wimax/i2400m/i2400m.h @@ -150,33 +150,11 @@ enum { /* Firmware uploading */ I2400M_BOOT_RETRIES = 3, - I3200_BOOT_RETRIES = 3, /* Size of the Boot Mode Command buffer */ I2400M_BM_CMD_BUF_SIZE = 16 * 1024, I2400M_BM_ACK_BUF_SIZE = 256, }; -/** - * struct i2400m_poke_table - Hardware poke table for the Intel 2400m - * - * This structure will be used to create a device specific poke table - * to put the device in a consistant state at boot time. - * - * @address: The device address to poke - * - * @data: The data value to poke to the device address - * - */ -struct i2400m_poke_table{ - __le32 address; - __le32 data; -}; - -#define I2400M_FW_POKE(a, d) { \ - .address = cpu_to_le32(a), \ - .data = cpu_to_le32(d) \ -} - /** * i2400m_reset_type - methods to reset a device @@ -246,17 +224,6 @@ struct i2400m_roq; * process, so it cannot rely on common infrastructure being laid * out. * - * @bus_bm_retries: [fill] How many times shall a firmware upload / - * device initialization be retried? Different models of the same - * device might need different values, hence it is set by the - * bus-specific driver. Note this value is used in two places, - * i2400m_fw_dnload() and __i2400m_dev_start(); they won't become - * multiplicative (__i2400m_dev_start() calling N times - * i2400m_fw_dnload() and this trying N times to download the - * firmware), as if __i2400m_dev_start() only retries if the - * firmware crashed while initializing the device (not in a - * general case). - * * @bus_bm_cmd_send: [fill] Function called to send a boot-mode * command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This * is synchronous and has to return 0 if ok or < 0 errno code in @@ -285,12 +252,6 @@ struct i2400m_roq; * address provided in boot mode is kind of broken and needs to * be re-read later on. * - * @bus_bm_pokes_table: [fill/optional] A table of device addresses - * and values that will be poked at device init time to move the - * device to the correct state for the type of boot/firmware being - * used. This table MUST be terminated with (0x000000, - * 0x00000000) or bad things will happen. - * * * @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX * stack. Due to the way a net_device is allocated, we need to @@ -362,10 +323,6 @@ struct i2400m_roq; * delivered. Then the driver can release them to the host. See * drivers/net/i2400m/rx.c for details. * - * @src_mac_addr: MAC address used to make ethernet packets be coming - * from. This is generated at i2400m_setup() time and used during - * the life cycle of the instance. See i2400m_fake_eth_header(). - * * @init_mutex: Mutex used for serializing the device bringup * sequence; this way if the device reboots in the middle, we * don't try to do a bringup again while we are tearing down the @@ -438,8 +395,6 @@ struct i2400m { size_t bus_tx_block_size; size_t bus_pl_size_max; - unsigned bus_bm_retries; - int (*bus_dev_start)(struct i2400m *); void (*bus_dev_stop)(struct i2400m *); void (*bus_tx_kick)(struct i2400m *); @@ -451,7 +406,6 @@ struct i2400m { struct i2400m_bootrom_header *, size_t); const char **bus_fw_names; unsigned bus_bm_mac_addr_impaired:1; - const struct i2400m_poke_table *bus_bm_pokes_table; spinlock_t tx_lock; /* protect TX state */ void *tx_buf; @@ -467,7 +421,6 @@ struct i2400m { unsigned rx_pl_num, rx_pl_max, rx_pl_min, rx_num, rx_size_acc, rx_size_min, rx_size_max; struct i2400m_roq *rx_roq; /* not under rx_lock! */ - u8 src_mac_addr[ETH_HLEN]; struct mutex msg_mutex; /* serialize command execution */ struct completion msg_completion; @@ -751,7 +704,6 @@ static const __le32 i2400m_SBOOT_BARKER[4] = { cpu_to_le32(I2400M_SBOOT_BARKER) }; -extern int i2400m_power_save_disabled; /* * Utility functions diff --git a/trunk/drivers/net/wimax/i2400m/netdev.c b/trunk/drivers/net/wimax/i2400m/netdev.c index 9653f478b382..6b1fe7a81f25 100644 --- a/trunk/drivers/net/wimax/i2400m/netdev.c +++ b/trunk/drivers/net/wimax/i2400m/netdev.c @@ -404,12 +404,10 @@ static void i2400m_rx_fake_eth_header(struct net_device *net_dev, void *_eth_hdr, __be16 protocol) { - struct i2400m *i2400m = net_dev_to_i2400m(net_dev); struct ethhdr *eth_hdr = _eth_hdr; memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest)); - memcpy(eth_hdr->h_source, i2400m->src_mac_addr, - sizeof(eth_hdr->h_source)); + memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest)); eth_hdr->h_proto = protocol; } diff --git a/trunk/drivers/net/wimax/i2400m/op-rfkill.c b/trunk/drivers/net/wimax/i2400m/op-rfkill.c index 43927b5d7ad6..487ec58cea46 100644 --- a/trunk/drivers/net/wimax/i2400m/op-rfkill.c +++ b/trunk/drivers/net/wimax/i2400m/op-rfkill.c @@ -54,10 +54,8 @@ int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state) /* state == WIMAX_RF_ON */ return i2400m->state != I2400M_SS_RF_OFF && i2400m->state != I2400M_SS_RF_SHUTDOWN; - else { + else BUG(); - return -EINVAL; /* shut gcc warnings on certain arches */ - } } diff --git a/trunk/drivers/net/wimax/i2400m/rx.c b/trunk/drivers/net/wimax/i2400m/rx.c index 07c32e68909f..f9fc38902322 100644 --- a/trunk/drivers/net/wimax/i2400m/rx.c +++ b/trunk/drivers/net/wimax/i2400m/rx.c @@ -177,8 +177,7 @@ void i2400m_report_hook_work(struct work_struct *ws) struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws); struct i2400m_report_hook_args *args = (void *) iw->pl; - if (iw->i2400m->ready) - i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size); + i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size); kfree_skb(args->skb_rx); i2400m_put(iw->i2400m); kfree(iw); @@ -310,9 +309,6 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx, skb_get(skb_rx); i2400m_queue_work(i2400m, i2400m_report_hook_work, GFP_KERNEL, &args, sizeof(args)); - if (unlikely(i2400m->trace_msg_from_user)) - wimax_msg(&i2400m->wimax_dev, "echo", - l3l4_hdr, size, GFP_KERNEL); result = wimax_msg(&i2400m->wimax_dev, NULL, l3l4_hdr, size, GFP_KERNEL); if (result < 0) @@ -1148,7 +1144,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) num_pls = le16_to_cpu(msg_hdr->num_pls); pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ num_pls * sizeof(msg_hdr->pld[0]); - pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN); + pl_itr = ALIGN(pl_itr, I2400M_PL_PAD); if (pl_itr > skb->len) { /* got all the payload descriptors? */ dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " "%u payload descriptors (%zu each, total %zu)\n", @@ -1166,7 +1162,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) single_last = num_pls == 1 || i == num_pls - 1; i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i], skb->data + pl_itr); - pl_itr += ALIGN(pl_size, I2400M_PL_ALIGN); + pl_itr += ALIGN(pl_size, I2400M_PL_PAD); cond_resched(); /* Don't monopolize */ } kfree_skb(skb); diff --git a/trunk/drivers/net/wimax/i2400m/sdio-fw.c b/trunk/drivers/net/wimax/i2400m/sdio-fw.c index 7d6ec0f475f8..3487205d8f50 100644 --- a/trunk/drivers/net/wimax/i2400m/sdio-fw.c +++ b/trunk/drivers/net/wimax/i2400m/sdio-fw.c @@ -46,24 +46,17 @@ * Inaky Perez-Gonzalez * - SDIO rehash for changes in the bus-driver model * - * Dirk Brandewie - * - Make it IRQ based, not polling - * * THE PROCEDURE * * See fw.c for the generic description of this procedure. * * This file implements only the SDIO specifics. It boils down to how * to send a command and waiting for an acknowledgement from the - * device. - * - * All this code is sequential -- all i2400ms_bus_bm_*() functions are - * executed in the same thread, except i2400ms_bm_irq() [on its own by - * the SDIO driver]. This makes it possible to avoid locking. + * device. We do polled reads. * * COMMAND EXECUTION * - * The generic firmware upload code will call i2400m_bus_bm_cmd_send() + * THe generic firmware upload code will call i2400m_bus_bm_cmd_send() * to send commands. * * The SDIO devices expects things in 256 byte blocks, so it will pad @@ -71,15 +64,12 @@ * * ACK RECEPTION * - * This works in IRQ mode -- the fw loader says when to wait for data - * and for that it calls i2400ms_bus_bm_wait_for_ack(). + * This works in polling mode -- the fw loader says when to wait for + * data and for that it calls i2400ms_bus_bm_wait_for_ack(). * - * This checks if there is any data available (RX size > 0); if not, - * waits for the IRQ handler to notify about it. Once there is data, - * it is read and passed to the caller. Doing it this way we don't - * need much coordination/locking, and it makes it much more difficult - * for an interrupt to be lost and the wait_for_ack() function getting - * stuck even when data is pending. + * This will poll the device for data until it is received. We need to + * receive at least as much bytes as where asked for (although it'll + * always be a multiple of 256 bytes). */ #include #include "i2400m-sdio.h" @@ -88,7 +78,6 @@ #define D_SUBMODULE fw #include "sdio-debug-levels.h" - /* * Send a boot-mode command to the SDIO function * @@ -150,7 +139,7 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m, /* - * Read an ack from the device's boot-mode + * Read an ack from the device's boot-mode (polling) * * @i2400m: * @_ack: pointer to where to store the read data @@ -161,49 +150,75 @@ ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m, * The ACK for a BM command is always at least sizeof(*ack) bytes, so * check for that. We don't need to check for device reboots * + * NOTE: We do an artificial timeout of 1 sec over the SDIO timeout; + * this way we have control over it...there is no way that I know + * of setting an SDIO transaction timeout. */ ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m, struct i2400m_bootrom_header *ack, size_t ack_size) { - ssize_t result; + int result; + ssize_t rx_size; + u64 timeout; struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); struct sdio_func *func = i2400ms->func; struct device *dev = &func->dev; - int size; BUG_ON(sizeof(*ack) > ack_size); d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n", i2400m, ack, ack_size); - spin_lock(&i2400m->rx_lock); - i2400ms->bm_ack_size = -EINPROGRESS; - spin_unlock(&i2400m->rx_lock); + timeout = get_jiffies_64() + 2 * HZ; + sdio_claim_host(func); + while (1) { + if (time_after64(get_jiffies_64(), timeout)) { + rx_size = -ETIMEDOUT; + dev_err(dev, "timeout waiting for ack data\n"); + goto error_timedout; + } - result = wait_event_timeout(i2400ms->bm_wfa_wq, - i2400ms->bm_ack_size != -EINPROGRESS, - 2 * HZ); - if (result == 0) { - result = -ETIMEDOUT; - dev_err(dev, "BM: error waiting for an ack\n"); - goto error_timeout; - } + /* Find the RX size, check if it fits or not -- it if + * doesn't fit, fail, as we have no way to dispose of + * the extra data. */ + rx_size = __i2400ms_rx_get_size(i2400ms); + if (rx_size < 0) + goto error_rx_get_size; + result = -ENOSPC; /* Check it fits */ + if (rx_size < sizeof(*ack)) { + rx_size = -EIO; + dev_err(dev, "HW BUG? received is too small (%zu vs " + "%zu needed)\n", sizeof(*ack), rx_size); + goto error_too_small; + } + if (rx_size > I2400M_BM_ACK_BUF_SIZE) { + dev_err(dev, "SW BUG? BM_ACK_BUF is too small (%u vs " + "%zu needed)\n", I2400M_BM_ACK_BUF_SIZE, + rx_size); + goto error_too_small; + } - spin_lock(&i2400m->rx_lock); - result = i2400ms->bm_ack_size; - BUG_ON(result == -EINPROGRESS); - if (result < 0) /* so we exit when rx_release() is called */ - dev_err(dev, "BM: %s failed: %zd\n", __func__, result); - else { - size = min(ack_size, i2400ms->bm_ack_size); - memcpy(ack, i2400m->bm_ack_buf, size); + /* Read it */ + result = sdio_memcpy_fromio(func, i2400m->bm_ack_buf, + I2400MS_DATA_ADDR, rx_size); + if (result == -ETIMEDOUT || result == -ETIME) + continue; + if (result < 0) { + dev_err(dev, "BM SDIO receive (%zu B) failed: %d\n", + rx_size, result); + goto error_read; + } else + break; } - i2400ms->bm_ack_size = -EINPROGRESS; - spin_unlock(&i2400m->rx_lock); - -error_timeout: - d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %zd\n", - i2400m, ack, ack_size, result); - return result; + rx_size = min((ssize_t)ack_size, rx_size); + memcpy(ack, i2400m->bm_ack_buf, rx_size); +error_read: +error_too_small: +error_rx_get_size: +error_timedout: + sdio_release_host(func); + d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %ld\n", + i2400m, ack, ack_size, (long) rx_size); + return rx_size; } diff --git a/trunk/drivers/net/wimax/i2400m/sdio-rx.c b/trunk/drivers/net/wimax/i2400m/sdio-rx.c index 321beadf6e47..a3008b904f7d 100644 --- a/trunk/drivers/net/wimax/i2400m/sdio-rx.c +++ b/trunk/drivers/net/wimax/i2400m/sdio-rx.c @@ -69,13 +69,6 @@ #define D_SUBMODULE rx #include "sdio-debug-levels.h" -static const __le32 i2400m_ACK_BARKER[4] = { - __constant_cpu_to_le32(I2400M_ACK_BARKER), - __constant_cpu_to_le32(I2400M_ACK_BARKER), - __constant_cpu_to_le32(I2400M_ACK_BARKER), - __constant_cpu_to_le32(I2400M_ACK_BARKER) -}; - /* * Read and return the amount of bytes available for RX @@ -138,35 +131,25 @@ void i2400ms_rx(struct i2400ms *i2400ms) ret = rx_size; goto error_get_size; } - ret = -ENOMEM; skb = alloc_skb(rx_size, GFP_ATOMIC); if (NULL == skb) { dev_err(dev, "RX: unable to alloc skb\n"); goto error_alloc_skb; } + ret = sdio_memcpy_fromio(func, skb->data, I2400MS_DATA_ADDR, rx_size); if (ret < 0) { dev_err(dev, "RX: SDIO data read failed: %d\n", ret); goto error_memcpy_fromio; } - - rmb(); /* make sure we get boot_mode from dev_reset_handle */ - if (i2400m->boot_mode == 1) { - spin_lock(&i2400m->rx_lock); - i2400ms->bm_ack_size = rx_size; - spin_unlock(&i2400m->rx_lock); - memcpy(i2400m->bm_ack_buf, skb->data, rx_size); - wake_up(&i2400ms->bm_wfa_wq); - dev_err(dev, "RX: SDIO boot mode message\n"); - kfree_skb(skb); - } else if (unlikely(!memcmp(skb->data, i2400m_NBOOT_BARKER, - sizeof(i2400m_NBOOT_BARKER)) - || !memcmp(skb->data, i2400m_SBOOT_BARKER, - sizeof(i2400m_SBOOT_BARKER)))) { + /* Check if device has reset */ + if (!memcmp(skb->data, i2400m_NBOOT_BARKER, + sizeof(i2400m_NBOOT_BARKER)) + || !memcmp(skb->data, i2400m_SBOOT_BARKER, + sizeof(i2400m_SBOOT_BARKER))) { ret = i2400m_dev_reset_handle(i2400m); - dev_err(dev, "RX: SDIO reboot barker\n"); kfree_skb(skb); } else { skb_put(skb, rx_size); @@ -196,6 +179,7 @@ void i2400ms_irq(struct sdio_func *func) { int ret; struct i2400ms *i2400ms = sdio_get_drvdata(func); + struct i2400m *i2400m = &i2400ms->i2400m; struct device *dev = &func->dev; int val; @@ -210,7 +194,10 @@ void i2400ms_irq(struct sdio_func *func) goto error_no_irq; } sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret); - i2400ms_rx(i2400ms); + if (WARN_ON(i2400m->boot_mode != 0)) + dev_err(dev, "RX: SW BUG? boot mode and IRQ is up?\n"); + else + i2400ms_rx(i2400ms); error_no_irq: d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms); return; @@ -227,15 +214,8 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms) int result; struct sdio_func *func = i2400ms->func; struct device *dev = &func->dev; - struct i2400m *i2400m = &i2400ms->i2400m; d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); - - init_waitqueue_head(&i2400ms->bm_wfa_wq); - spin_lock(&i2400m->rx_lock); - i2400ms->bm_wait_result = -EINPROGRESS; - spin_unlock(&i2400m->rx_lock); - sdio_claim_host(func); result = sdio_claim_irq(func, i2400ms_irq); if (result < 0) { @@ -265,13 +245,8 @@ void i2400ms_rx_release(struct i2400ms *i2400ms) int result; struct sdio_func *func = i2400ms->func; struct device *dev = &func->dev; - struct i2400m *i2400m = &i2400ms->i2400m; d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); - spin_lock(&i2400m->rx_lock); - i2400ms->bm_ack_size = -EINTR; - spin_unlock(&i2400m->rx_lock); - wake_up_all(&i2400ms->bm_wfa_wq); sdio_claim_host(func); sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result); sdio_release_irq(func); diff --git a/trunk/drivers/net/wimax/i2400m/sdio.c b/trunk/drivers/net/wimax/i2400m/sdio.c index 2538825d1c66..5ac5e76701cd 100644 --- a/trunk/drivers/net/wimax/i2400m/sdio.c +++ b/trunk/drivers/net/wimax/i2400m/sdio.c @@ -78,14 +78,6 @@ static const char *i2400ms_bus_fw_names[] = { }; -static const struct i2400m_poke_table i2400ms_pokes[] = { - I2400M_FW_POKE(0x6BE260, 0x00000088), - I2400M_FW_POKE(0x080550, 0x00000005), - I2400M_FW_POKE(0xAE0000, 0x00000000), - I2400M_FW_POKE(0x000000, 0x00000000), /* MUST be 0 terminated or bad - * things will happen */ -}; - /* * Enable the SDIO function * @@ -156,14 +148,19 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m) d_fnstart(3, dev, "(i2400m %p)\n", i2400m); msleep(200); + result = i2400ms_rx_setup(i2400ms); + if (result < 0) + goto error_rx_setup; result = i2400ms_tx_setup(i2400ms); if (result < 0) goto error_tx_setup; d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); return result; -error_tx_setup: i2400ms_tx_release(i2400ms); +error_tx_setup: + i2400ms_rx_release(i2400ms); +error_rx_setup: d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); return result; } @@ -177,6 +174,7 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m) struct device *dev = &func->dev; d_fnstart(3, dev, "(i2400m %p)\n", i2400m); + i2400ms_rx_release(i2400ms); i2400ms_tx_release(i2400ms); d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); } @@ -257,7 +255,7 @@ int __i2400ms_send_barker(struct i2400ms *i2400ms, static int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) { - int result = 0; + int result; struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); struct device *dev = i2400m_dev(i2400m); @@ -282,25 +280,8 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) sizeof(i2400m_COLD_BOOT_BARKER)); else if (rt == I2400M_RT_BUS) { do_bus_reset: - /* call netif_tx_disable() before sending IOE disable, - * so that all the tx from network layer are stopped - * while IOE is being reset. Make sure it is called - * only after register_netdev() was issued. - */ - if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED) - netif_tx_disable(i2400m->wimax_dev.net_dev); - - i2400ms_rx_release(i2400ms); - sdio_claim_host(i2400ms->func); - sdio_disable_func(i2400ms->func); - sdio_release_host(i2400ms->func); - - /* Wait for the device to settle */ - msleep(40); - - result = i2400ms_enable_function(i2400ms->func); - if (result >= 0) - i2400ms_rx_setup(i2400ms); + dev_err(dev, "FIXME: SDIO bus reset not implemented\n"); + result = rt == I2400M_RT_WARM ? -ENODEV : -ENOSYS; } else BUG(); if (result < 0 && rt != I2400M_RT_BUS) { @@ -423,22 +404,10 @@ int i2400ms_probe(struct sdio_func *func, i2400m->bus_dev_stop = i2400ms_bus_dev_stop; i2400m->bus_tx_kick = i2400ms_bus_tx_kick; i2400m->bus_reset = i2400ms_bus_reset; - /* The iwmc3200-wimax sometimes requires the driver to try - * hard when we paint it into a corner. */ - i2400m->bus_bm_retries = I3200_BOOT_RETRIES; i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send; i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack; i2400m->bus_fw_names = i2400ms_bus_fw_names; i2400m->bus_bm_mac_addr_impaired = 1; - i2400m->bus_bm_pokes_table = &i2400ms_pokes[0]; - - sdio_claim_host(func); - result = sdio_set_block_size(func, I2400MS_BLK_SIZE); - sdio_release_host(func); - if (result < 0) { - dev_err(dev, "Failed to set block size: %d\n", result); - goto error_set_blk_size; - } result = i2400ms_enable_function(i2400ms->func); if (result < 0) { @@ -446,9 +415,13 @@ int i2400ms_probe(struct sdio_func *func, goto error_func_enable; } - result = i2400ms_rx_setup(i2400ms); - if (result < 0) - goto error_rx_setup; + sdio_claim_host(func); + result = sdio_set_block_size(func, I2400MS_BLK_SIZE); + if (result < 0) { + dev_err(dev, "Failed to set block size: %d\n", result); + goto error_set_blk_size; + } + sdio_release_host(func); result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT); if (result < 0) { @@ -467,14 +440,12 @@ int i2400ms_probe(struct sdio_func *func, error_debugfs_add: i2400m_release(i2400m); error_setup: - i2400ms_rx_release(i2400ms); -error_rx_setup: + sdio_set_drvdata(func, NULL); sdio_claim_host(func); +error_set_blk_size: sdio_disable_func(func); sdio_release_host(func); error_func_enable: -error_set_blk_size: - sdio_set_drvdata(func, NULL); free_netdev(net_dev); error_alloc_netdev: return result; @@ -491,7 +462,6 @@ void i2400ms_remove(struct sdio_func *func) d_fnstart(3, dev, "SDIO func %p\n", func); debugfs_remove_recursive(i2400ms->debugfs_dentry); - i2400ms_rx_release(i2400ms); i2400m_release(i2400m); sdio_set_drvdata(func, NULL); sdio_claim_host(func); diff --git a/trunk/drivers/net/wimax/i2400m/tx.c b/trunk/drivers/net/wimax/i2400m/tx.c index fa16ccf8e26a..613a88ffd651 100644 --- a/trunk/drivers/net/wimax/i2400m/tx.c +++ b/trunk/drivers/net/wimax/i2400m/tx.c @@ -277,48 +277,6 @@ enum { #define TAIL_FULL ((void *)~(unsigned long)NULL) -/* - * Calculate how much tail room is available - * - * Note the trick here. This path is ONLY caleed for Case A (see - * i2400m_tx_fifo_push() below), where we have: - * - * Case A - * N ___________ - * | tail room | - * | | - * |<- IN ->| - * | | - * | data | - * | | - * |<- OUT ->| - * | | - * | head room | - * 0 ----------- - * - * When calculating the tail_room, tx_in might get to be zero if - * i2400m->tx_in is right at the end of the buffer (really full - * buffer) if there is no head room. In this case, tail_room would be - * I2400M_TX_BUF_SIZE, although it is actually zero. Hence the final - * mod (%) operation. However, when doing this kind of optimization, - * i2400m->tx_in being zero would fail, so we treat is an a special - * case. - */ -static inline -size_t __i2400m_tx_tail_room(struct i2400m *i2400m) -{ - size_t tail_room; - size_t tx_in; - - if (unlikely(i2400m->tx_in) == 0) - return I2400M_TX_BUF_SIZE; - tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE; - tail_room = I2400M_TX_BUF_SIZE - tx_in; - tail_room %= I2400M_TX_BUF_SIZE; - return tail_room; -} - - /* * Allocate @size bytes in the TX fifo, return a pointer to it * @@ -380,7 +338,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding) return NULL; } /* Is there space at the tail? */ - tail_room = __i2400m_tx_tail_room(i2400m); + tail_room = I2400M_TX_BUF_SIZE - i2400m->tx_in % I2400M_TX_BUF_SIZE; if (tail_room < needed_size) { if (i2400m->tx_out % I2400M_TX_BUF_SIZE < i2400m->tx_in % I2400M_TX_BUF_SIZE) { @@ -409,29 +367,17 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding) * (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the * header). * - * Tail room can get to be zero if a message was opened when there was - * space only for a header. _tx_close() will mark it as to-skip (as it - * will have no payloads) and there will be no more space to flush, so - * nothing has to be done here. This is probably cheaper than ensuring - * in _tx_new() that there is some space for payloads...as we could - * always possibly hit the same problem if the payload wouldn't fit. - * * Note: * * Assumes i2400m->tx_lock is taken, and we use that as a barrier - * - * This path is only taken for Case A FIFO situations [see - * i2400m_tx_fifo_push()] */ static void i2400m_tx_skip_tail(struct i2400m *i2400m) { struct device *dev = i2400m_dev(i2400m); size_t tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE; - size_t tail_room = __i2400m_tx_tail_room(i2400m); + size_t tail_room = I2400M_TX_BUF_SIZE - tx_in; struct i2400m_msg_hdr *msg = i2400m->tx_buf + tx_in; - if (unlikely(tail_room == 0)) - return; BUG_ON(tail_room < sizeof(*msg)); msg->size = tail_room | I2400M_TX_SKIP; d_printf(2, dev, "skip tail: skipping %zu bytes @%zu\n", @@ -528,18 +474,10 @@ void i2400m_tx_close(struct i2400m *i2400m) struct i2400m_msg_hdr *tx_msg_moved; size_t aligned_size, padding, hdr_size; void *pad_buf; - unsigned num_pls; if (tx_msg->size & I2400M_TX_SKIP) /* a skipper? nothing to do */ goto out; - num_pls = le16_to_cpu(tx_msg->num_pls); - /* We can get this situation when a new message was started - * and there was no space to add payloads before hitting the - tail (and taking padding into consideration). */ - if (num_pls == 0) { - tx_msg->size |= I2400M_TX_SKIP; - goto out; - } + /* Relocate the message header * * Find the current header size, align it to 16 and if we need @@ -553,7 +491,7 @@ void i2400m_tx_close(struct i2400m *i2400m) */ hdr_size = sizeof(*tx_msg) + le16_to_cpu(tx_msg->num_pls) * sizeof(tx_msg->pld[0]); - hdr_size = ALIGN(hdr_size, I2400M_PL_ALIGN); + hdr_size = ALIGN(hdr_size, I2400M_PL_PAD); tx_msg->offset = I2400M_TX_PLD_SIZE - hdr_size; tx_msg_moved = (void *) tx_msg + tx_msg->offset; memmove(tx_msg_moved, tx_msg, hdr_size); @@ -636,7 +574,7 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len, d_fnstart(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u)\n", i2400m, buf, buf_len, pl_type); - padded_len = ALIGN(buf_len, I2400M_PL_ALIGN); + padded_len = ALIGN(buf_len, I2400M_PL_PAD); d_printf(5, dev, "padded_len %zd buf_len %zd\n", padded_len, buf_len); /* If there is no current TX message, create one; if the * current one is out of payload slots or we have a singleton, @@ -653,8 +591,6 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len, i2400m_tx_close(i2400m); i2400m_tx_new(i2400m); } - if (i2400m->tx_msg == NULL) - goto error_tx_new; if (i2400m->tx_msg->size + padded_len > I2400M_TX_BUF_SIZE / 2) { d_printf(2, dev, "TX: message too big, going new\n"); i2400m_tx_close(i2400m); @@ -837,6 +773,7 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m) n = i2400m->tx_out / I2400M_TX_BUF_SIZE; i2400m->tx_out %= I2400M_TX_BUF_SIZE; i2400m->tx_in -= n * I2400M_TX_BUF_SIZE; + netif_start_queue(i2400m->wimax_dev.net_dev); spin_unlock_irqrestore(&i2400m->tx_lock, flags); d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); } diff --git a/trunk/drivers/net/wimax/i2400m/usb.c b/trunk/drivers/net/wimax/i2400m/usb.c index cfdaf69da9d1..ca4151a9e222 100644 --- a/trunk/drivers/net/wimax/i2400m/usb.c +++ b/trunk/drivers/net/wimax/i2400m/usb.c @@ -254,10 +254,8 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) dev_err(dev, "USB reset failed (%d), giving up!\n", result); } - } else { - result = -EINVAL; /* shut gcc up in certain arches */ + } else BUG(); - } if (result < 0 && result != -EINVAL /* device is gone */ && rt != I2400M_RT_BUS) { @@ -401,7 +399,6 @@ int i2400mu_probe(struct usb_interface *iface, i2400m->bus_dev_stop = i2400mu_bus_dev_stop; i2400m->bus_tx_kick = i2400mu_bus_tx_kick; i2400m->bus_reset = i2400mu_bus_reset; - i2400m->bus_bm_retries = I2400M_BOOT_RETRIES; i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send; i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack; i2400m->bus_fw_names = i2400mu_bus_fw_names; @@ -508,52 +505,27 @@ int i2400mu_suspend(struct usb_interface *iface, pm_message_t pm_msg) #ifdef CONFIG_PM struct usb_device *usb_dev = i2400mu->usb_dev; #endif - unsigned is_autosuspend = 0; struct i2400m *i2400m = &i2400mu->i2400m; -#ifdef CONFIG_PM - if (usb_dev->auto_pm > 0) - is_autosuspend = 1; -#endif - d_fnstart(3, dev, "(iface %p pm_msg %u)\n", iface, pm_msg.event); if (i2400m->updown == 0) goto no_firmware; - if (i2400m->state == I2400M_SS_DATA_PATH_CONNECTED && is_autosuspend) { - /* ugh -- the device is connected and this suspend - * request is an autosuspend one (not a system standby - * / hibernate). - * - * The only way the device can go to standby is if the - * link with the base station is in IDLE mode; that - * were the case, we'd be in status - * I2400M_SS_CONNECTED_IDLE. But we are not. - * - * If we *tell* him to go power save now, it'll reset - * as a precautionary measure, so if this is an - * autosuspend thing, say no and it'll come back - * later, when the link is IDLE - */ - result = -EBADF; - d_printf(1, dev, "fw up, link up, not-idle, autosuspend: " - "not entering powersave\n"); - goto error_not_now; - } - d_printf(1, dev, "fw up: entering powersave\n"); + d_printf(1, dev, "fw up, requesting standby\n"); atomic_dec(&i2400mu->do_autopm); result = i2400m_cmd_enter_powersave(i2400m); atomic_inc(&i2400mu->do_autopm); - if (result < 0 && !is_autosuspend) { +#ifdef CONFIG_PM + if (result < 0 && usb_dev->auto_pm == 0) { /* System suspend, can't fail */ dev_err(dev, "failed to suspend, will reset on resume\n"); result = 0; } +#endif if (result < 0) goto error_enter_powersave; i2400mu_notification_release(i2400mu); - d_printf(1, dev, "powersave requested\n"); + d_printf(1, dev, "fw up, got standby\n"); error_enter_powersave: -error_not_now: no_firmware: d_fnend(3, dev, "(iface %p pm_msg %u) = %d\n", iface, pm_msg.event, result); diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index fb7541c28e58..a67d29290ba0 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -153,7 +153,7 @@ config LIBERTAS_SDIO config LIBERTAS_SPI tristate "Marvell Libertas 8686 SPI 802.11b/g cards" - depends on LIBERTAS && SPI + depends on LIBERTAS && SPI && GENERIC_GPIO ---help--- A driver for Marvell Libertas 8686 SPI devices. @@ -333,11 +333,11 @@ config USB_ZD1201 config USB_NET_RNDIS_WLAN tristate "Wireless RNDIS USB support" depends on USB && WLAN_80211 && EXPERIMENTAL - depends on CFG80211 select USB_USBNET select USB_NET_CDCETHER select USB_NET_RNDIS_HOST select WIRELESS_EXT + select CFG80211 ---help--- This is a driver for wireless RNDIS devices. These are USB based adapters found in devices such as: @@ -431,7 +431,6 @@ config RTL8187 ASUS P5B Deluxe Toshiba Satellite Pro series of laptops Asus Wireless Link - Linksys WUSB54GC-EU Thanks to Realtek for their support! diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index 4efbdbe6d6bf..cea7f1466c54 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -1873,18 +1873,18 @@ static void at76_dwork_hw_scan(struct work_struct *work) if (ret != CMD_STATUS_COMPLETE) { queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, SCAN_POLL_INTERVAL); - mutex_unlock(&priv->mtx); - return; + goto exit; } + ieee80211_scan_completed(priv->hw, false); + if (is_valid_ether_addr(priv->bssid)) at76_join(priv); - mutex_unlock(&priv->mtx); - - ieee80211_scan_completed(priv->hw, false); - ieee80211_wake_queues(priv->hw); + +exit: + mutex_unlock(&priv->mtx); } static int at76_hw_scan(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/ath/ar9170/ar9170.h b/trunk/drivers/net/wireless/ath/ar9170/ar9170.h index bb97981fb248..17bd3eaf3e03 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/trunk/drivers/net/wireless/ath/ar9170/ar9170.h @@ -91,7 +91,6 @@ struct ar9170_led { struct led_classdev l; char name[32]; unsigned int toggled; - bool last_state; bool registered; }; @@ -102,6 +101,7 @@ enum ar9170_device_state { AR9170_STOPPED, AR9170_IDLE, AR9170_STARTED, + AR9170_ASSOCIATED, }; struct ar9170_rxstream_mpdu_merge { @@ -109,11 +109,6 @@ struct ar9170_rxstream_mpdu_merge { bool has_plcp; }; -#define AR9170_QUEUE_TIMEOUT 64 -#define AR9170_TX_TIMEOUT 8 -#define AR9170_JANITOR_DELAY 128 -#define AR9170_TX_INVALID_RATE 0xffffffff - struct ar9170 { struct ieee80211_hw *hw; struct mutex mutex; @@ -122,11 +117,10 @@ struct ar9170 { int (*open)(struct ar9170 *); void (*stop)(struct ar9170 *); - int (*tx)(struct ar9170 *, struct sk_buff *); + int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int); int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , void *, u32 , void *); void (*callback_cmd)(struct ar9170 *, u32 , void *); - int (*flush)(struct ar9170 *); /* interface mode settings */ struct ieee80211_vif *vif; @@ -146,7 +140,7 @@ struct ar9170 { struct work_struct filter_config_work; u64 cur_mc_hash, want_mc_hash; u32 cur_filter, want_filter; - unsigned long filter_changed; + unsigned int filter_changed; unsigned int filter_state; bool sniffer_enabled; @@ -183,10 +177,10 @@ struct ar9170 { struct ar9170_eeprom eeprom; struct ath_regulatory regulatory; - /* tx queues - as seen by hw - */ - struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; - struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; - struct delayed_work tx_janitor; + /* global tx status for unregistered Stations. */ + struct sk_buff_head global_tx_status; + struct sk_buff_head global_tx_status_waste; + struct delayed_work tx_status_janitor; /* rxstream mpdu merge */ struct ar9170_rxstream_mpdu_merge rx_mpdu; @@ -195,21 +189,13 @@ struct ar9170 { }; struct ar9170_sta_info { + struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; }; -#define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) -#define AR9170_TX_FLAG_NO_ACK BIT(1) -#define AR9170_TX_FLAG_BLOCK_ACK BIT(2) - -struct ar9170_tx_info { - unsigned long timeout; - unsigned int flags; -}; - -#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) -#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) +#define IS_STARTED(a) (a->state >= AR9170_STARTED) +#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) -#define AR9170_FILTER_CHANGED_MODE BIT(0) +#define AR9170_FILTER_CHANGED_PROMISC BIT(0) #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) #define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2) @@ -218,9 +204,8 @@ void *ar9170_alloc(size_t priv_size); int ar9170_register(struct ar9170 *ar, struct device *pdev); void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); void ar9170_unregister(struct ar9170 *ar); -void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); -void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); -int ar9170_nag_limiter(struct ar9170 *ar); +void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, + bool update_statistics, u16 tx_status); /* MAC */ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -230,9 +215,6 @@ int ar9170_update_multicast(struct ar9170 *ar); int ar9170_update_frame_filter(struct ar9170 *ar); int ar9170_set_operating_mode(struct ar9170 *ar); int ar9170_set_beacon_timers(struct ar9170 *ar); -int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); -int ar9170_set_slot_time(struct ar9170 *ar); -int ar9170_set_basic_rates(struct ar9170 *ar); int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry); int ar9170_update_beacon(struct ar9170 *ar); void ar9170_new_beacon(struct work_struct *work); diff --git a/trunk/drivers/net/wireless/ath/ar9170/hw.h b/trunk/drivers/net/wireless/ath/ar9170/hw.h index 6cbfb2f83391..3293e0fb24fb 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/hw.h +++ b/trunk/drivers/net/wireless/ath/ar9170/hw.h @@ -207,8 +207,7 @@ enum ar9170_cmd { #define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44) #define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48) -#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C) -#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0) +#define AR9170_MAC_REG_AMPDU_SET (AR9170_MAC_REG_BASE + 0xba0) #define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00) #define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50) @@ -377,6 +376,7 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) #define AR9170_RX_ERROR_FATAL 0x80 struct ar9170_cmd_tx_status { + __le16 unkn; u8 dst[ETH_ALEN]; __le32 rate; __le16 status; @@ -394,7 +394,6 @@ struct ar9170_cmd_ba_failed_count { struct ar9170_cmd_response { u8 flag; u8 type; - __le16 padding; union { struct ar9170_cmd_tx_status tx_status; @@ -420,7 +419,4 @@ enum ar9170_txq { __AR9170_NUM_TXQ, }; -#define AR9170_TXQ_DEPTH 32 -#define AR9170_TX_MAX_PENDING 128 - #endif /* __AR9170_HW_H */ diff --git a/trunk/drivers/net/wireless/ath/ar9170/led.c b/trunk/drivers/net/wireless/ath/ar9170/led.c index 63fda6cd2101..341cead7f606 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/led.c +++ b/trunk/drivers/net/wireless/ath/ar9170/led.c @@ -74,7 +74,7 @@ static void ar9170_update_leds(struct work_struct *work) mutex_lock(&ar->mutex); for (i = 0; i < AR9170_NUM_LEDS; i++) - if (ar->leds[i].registered && ar->leds[i].toggled) { + if (ar->leds[i].toggled) { led_val |= 1 << i; tmp = 70 + 200 / (ar->leds[i].toggled); @@ -101,15 +101,9 @@ static void ar9170_led_brightness_set(struct led_classdev *led, struct ar9170_led *arl = container_of(led, struct ar9170_led, l); struct ar9170 *ar = arl->ar; - if (unlikely(!arl->registered)) - return ; - - if (arl->last_state != !!brightness) { - arl->toggled++; - arl->last_state = !!brightness; - } + arl->toggled++; - if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) + if (likely(IS_ACCEPTING_CMD(ar) && brightness)) queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10); } @@ -142,14 +136,13 @@ void ar9170_unregister_leds(struct ar9170 *ar) { int i; + cancel_delayed_work_sync(&ar->led_work); + for (i = 0; i < AR9170_NUM_LEDS; i++) if (ar->leds[i].registered) { led_classdev_unregister(&ar->leds[i].l); ar->leds[i].registered = false; - ar->leds[i].toggled = 0; } - - cancel_delayed_work_sync(&ar->led_work); } int ar9170_register_leds(struct ar9170 *ar) diff --git a/trunk/drivers/net/wireless/ath/ar9170/mac.c b/trunk/drivers/net/wireless/ath/ar9170/mac.c index d9f1f46de183..43aeb69685d3 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/mac.c +++ b/trunk/drivers/net/wireless/ath/ar9170/mac.c @@ -38,55 +38,6 @@ #include "ar9170.h" #include "cmd.h" -int ar9170_set_dyn_sifs_ack(struct ar9170 *ar) -{ - u32 val; - - if (conf_is_ht40(&ar->hw->conf)) - val = 0x010a; - else { - if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) - val = 0x105; - else - val = 0x104; - } - - return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val); -} - -int ar9170_set_slot_time(struct ar9170 *ar) -{ - u32 slottime = 20; - - if (!ar->vif) - return 0; - - if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || - ar->vif->bss_conf.use_short_slot) - slottime = 9; - - return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10); -} - -int ar9170_set_basic_rates(struct ar9170 *ar) -{ - u8 cck, ofdm; - - if (!ar->vif) - return 0; - - ofdm = ar->vif->bss_conf.basic_rates >> 4; - - /* FIXME: is still necessary? */ - if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) - cck = 0; - else - cck = ar->vif->bss_conf.basic_rates & 0xf; - - return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE, - ofdm << 8 | cck); -} - int ar9170_set_qos(struct ar9170 *ar) { ar9170_regwrite_begin(ar); @@ -133,7 +84,7 @@ static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity) val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0); ar9170_regwrite_begin(ar); - ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val); + ar9170_regwrite(AR9170_MAC_REG_AMPDU_SET, val); ar9170_regwrite_finish(); return ar9170_regwrite_result(); @@ -447,10 +398,10 @@ int ar9170_update_beacon(struct ar9170 *ar) /* XXX: use skb->cb info */ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, - ((skb->len + 4) << (3 + 16)) + 0x0400); + ((skb->len + 4) << (3+16)) + 0x0400); else ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, - ((skb->len + 4) << 16) + 0x001b); + ((skb->len + 4) << (3+16)) + 0x0400); ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4); ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS); diff --git a/trunk/drivers/net/wireless/ath/ar9170/main.c b/trunk/drivers/net/wireless/ath/ar9170/main.c index 9d38cf60a0db..99df9ddae9cb 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/main.c +++ b/trunk/drivers/net/wireless/ath/ar9170/main.c @@ -146,6 +146,7 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = { { \ .ht_supported = true, \ .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ + IEEE80211_HT_CAP_SM_PS | \ IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ IEEE80211_HT_CAP_SGI_40 | \ IEEE80211_HT_CAP_DSSSCCK40 | \ @@ -173,122 +174,59 @@ static struct ieee80211_supported_band ar9170_band_5GHz = { .ht_cap = AR9170_HT_CAP, }; -static void ar9170_tx(struct ar9170 *ar); - #ifdef AR9170_QUEUE_DEBUG +/* + * In case some wants works with AR9170's crazy tx_status queueing techniques. + * He might need this rather useful probing function. + * + * NOTE: caller must hold the queue's spinlock! + */ + static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) { struct ar9170_tx_control *txc = (void *) skb->data; - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; - struct ieee80211_hdr *hdr = (void *) txc->frame_data; + struct ieee80211_hdr *hdr = (void *)txc->frame_data; - printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x " - "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", + printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] " + "mac_control:%04x, phy_control:%08x]\n", wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), - ieee80211_get_DA(hdr), arinfo->flags, - le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), - jiffies_to_msecs(arinfo->timeout - jiffies)); + ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control), + le32_to_cpu(txc->phy_control)); } -static void __ar9170_dump_txqueue(struct ar9170 *ar, - struct sk_buff_head *queue) +static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar, + struct sk_buff_head *queue) { struct sk_buff *skb; int i = 0; printk(KERN_DEBUG "---[ cut here ]---\n"); - printk(KERN_DEBUG "%s: %d entries in queue.\n", + printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n", wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); skb_queue_walk(queue, skb) { - printk(KERN_DEBUG "index:%d => \n", i++); + struct ar9170_tx_control *txc = (void *) skb->data; + struct ieee80211_hdr *hdr = (void *)txc->frame_data; + + printk(KERN_DEBUG "index:%d => \n", i); ar9170_print_txheader(ar, skb); } - if (i != skb_queue_len(queue)) - printk(KERN_DEBUG "WARNING: queue frame counter " - "mismatch %d != %d\n", skb_queue_len(queue), i); printk(KERN_DEBUG "---[ end ]---\n"); } +#endif /* AR9170_QUEUE_DEBUG */ -static void ar9170_dump_txqueue(struct ar9170 *ar, - struct sk_buff_head *queue) -{ - unsigned long flags; - - spin_lock_irqsave(&queue->lock, flags); - __ar9170_dump_txqueue(ar, queue); - spin_unlock_irqrestore(&queue->lock, flags); -} - -static void __ar9170_dump_txstats(struct ar9170 *ar) -{ - int i; - - printk(KERN_DEBUG "%s: QoS queue stats\n", - wiphy_name(ar->hw->wiphy)); - - for (i = 0; i < __AR9170_NUM_TXQ; i++) - printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n", - wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit, - ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i])); -} - -static void ar9170_dump_txstats(struct ar9170 *ar) +void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, + bool valid_status, u16 tx_status) { + struct ieee80211_tx_info *txinfo; + unsigned int retries = 0, queue = skb_get_queue_mapping(skb); unsigned long flags; spin_lock_irqsave(&ar->tx_stats_lock, flags); - __ar9170_dump_txstats(ar); + ar->tx_stats[queue].len--; + if (ieee80211_queue_stopped(ar->hw, queue)) + ieee80211_wake_queue(ar->hw, queue); spin_unlock_irqrestore(&ar->tx_stats_lock, flags); -} -#endif /* AR9170_QUEUE_DEBUG */ - -/* caller must guarantee exclusive access for _bin_ queue. */ -static void ar9170_recycle_expired(struct ar9170 *ar, - struct sk_buff_head *queue, - struct sk_buff_head *bin) -{ - struct sk_buff *skb, *old = NULL; - unsigned long flags; - - spin_lock_irqsave(&queue->lock, flags); - while ((skb = skb_peek(queue))) { - struct ieee80211_tx_info *txinfo; - struct ar9170_tx_info *arinfo; - - txinfo = IEEE80211_SKB_CB(skb); - arinfo = (void *) txinfo->rate_driver_data; - - if (time_is_before_jiffies(arinfo->timeout)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " - "recycle \n", wiphy_name(ar->hw->wiphy), - jiffies, arinfo->timeout); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - __skb_unlink(skb, queue); - __skb_queue_tail(bin, skb); - } else { - break; - } - - if (unlikely(old == skb)) { - /* bail out - queue is shot. */ - - WARN_ON(1); - break; - } - old = skb; - } - spin_unlock_irqrestore(&queue->lock, flags); -} - -static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, - u16 tx_status) -{ - struct ieee80211_tx_info *txinfo; - unsigned int retries = 0; txinfo = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(txinfo); @@ -310,61 +248,45 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, break; } - txinfo->status.rates[0].count = retries + 1; + if (valid_status) + txinfo->status.rates[0].count = retries + 1; + skb_pull(skb, sizeof(struct ar9170_tx_control)); ieee80211_tx_status_irqsafe(ar->hw, skb); } -void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) +static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar, + const u8 *mac, + const u32 queue, + struct sk_buff_head *q) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data; - unsigned int queue = skb_get_queue_mapping(skb); unsigned long flags; + struct sk_buff *skb; - spin_lock_irqsave(&ar->tx_stats_lock, flags); - ar->tx_stats[queue].len--; - - if (skb_queue_empty(&ar->tx_pending[queue])) { -#ifdef AR9170_QUEUE_STOP_DEBUG - printk(KERN_DEBUG "%s: wake queue %d\n", - wiphy_name(ar->hw->wiphy), queue); - __ar9170_dump_txstats(ar); -#endif /* AR9170_QUEUE_STOP_DEBUG */ - ieee80211_wake_queue(ar->hw, queue); - } - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - - if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { - dev_kfree_skb_any(skb); - } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) { - arinfo->timeout = jiffies + - msecs_to_jiffies(AR9170_TX_TIMEOUT); + spin_lock_irqsave(&q->lock, flags); + skb_queue_walk(q, skb) { + struct ar9170_tx_control *txc = (void *) skb->data; + struct ieee80211_hdr *hdr = (void *) txc->frame_data; + u32 txc_queue = (le32_to_cpu(txc->phy_control) & + AR9170_TX_PHY_QOS_MASK) >> + AR9170_TX_PHY_QOS_SHIFT; - skb_queue_tail(&ar->tx_status[queue], skb); - } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) { - ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); - } else { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: unsupported frame flags!\n", - wiphy_name(ar->hw->wiphy)); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - dev_kfree_skb_any(skb); - } + if ((queue != txc_queue) || + (compare_ether_addr(ieee80211_get_DA(hdr), mac))) + continue; - if (!ar->tx_stats[queue].len && - !skb_queue_empty(&ar->tx_pending[queue])) { - ar9170_tx(ar); + __skb_unlink(skb, q); + spin_unlock_irqrestore(&q->lock, flags); + return skb; } + spin_unlock_irqrestore(&q->lock, flags); + return NULL; } -static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, - const u8 *mac, - struct sk_buff_head *queue, - const u32 rate) +static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac, + const u32 queue) { - unsigned long flags; + struct ieee80211_sta *sta; struct sk_buff *skb; /* @@ -375,94 +297,85 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, * the firmware provided (-> destination MAC, and phy_control) - * and hope that we picked the right one... */ - - spin_lock_irqsave(&queue->lock, flags); - skb_queue_walk(queue, skb) { - struct ar9170_tx_control *txc = (void *) skb->data; - struct ieee80211_hdr *hdr = (void *) txc->frame_data; - u32 r; - - if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", - wiphy_name(ar->hw->wiphy), mac, - ieee80211_get_DA(hdr)); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - continue; - } - - r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >> - AR9170_TX_PHY_MCS_SHIFT; - - if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", - wiphy_name(ar->hw->wiphy), rate, r); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - continue; - } - - __skb_unlink(skb, queue); - spin_unlock_irqrestore(&queue->lock, flags); - return skb; + rcu_read_lock(); + sta = ieee80211_find_sta(ar->hw, mac); + + if (likely(sta)) { + struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv; + skb = skb_dequeue(&sta_priv->tx_status[queue]); + rcu_read_unlock(); + if (likely(skb)) + return skb; + } else + rcu_read_unlock(); + + /* scan the waste queue for candidates */ + skb = ar9170_find_skb_in_queue(ar, mac, queue, + &ar->global_tx_status_waste); + if (!skb) { + /* so it still _must_ be in the global list. */ + skb = ar9170_find_skb_in_queue(ar, mac, queue, + &ar->global_tx_status); } #ifdef AR9170_QUEUE_DEBUG - printk(KERN_ERR "%s: ESS:[%pM] does not have any " - "outstanding frames in queue.\n", - wiphy_name(ar->hw->wiphy), mac); - __ar9170_dump_txqueue(ar, queue); + if (unlikely((!skb) && net_ratelimit())) { + printk(KERN_ERR "%s: ESS:[%pM] does not have any " + "outstanding frames in this queue (%d).\n", + wiphy_name(ar->hw->wiphy), mac, queue); + } #endif /* AR9170_QUEUE_DEBUG */ - spin_unlock_irqrestore(&queue->lock, flags); - - return NULL; + return skb; } /* - * This worker tries to keeps an maintain tx_status queues. - * So we can guarantee that incoming tx_status reports are - * actually for a pending frame. + * This worker tries to keep the global tx_status queue empty. + * So we can guarantee that incoming tx_status reports for + * unregistered stations are always synced with the actual + * frame - which we think - belongs to. */ -static void ar9170_tx_janitor(struct work_struct *work) +static void ar9170_tx_status_janitor(struct work_struct *work) { struct ar9170 *ar = container_of(work, struct ar9170, - tx_janitor.work); - struct sk_buff_head waste; - unsigned int i; - bool resched = false; + tx_status_janitor.work); + struct sk_buff *skb; if (unlikely(!IS_STARTED(ar))) return ; - skb_queue_head_init(&waste); - - for (i = 0; i < __AR9170_NUM_TXQ; i++) { + mutex_lock(&ar->mutex); + /* recycle the garbage back to mac80211... one by one. */ + while ((skb = skb_dequeue(&ar->global_tx_status_waste))) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", - wiphy_name(ar->hw->wiphy), i); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); - ar9170_dump_txqueue(ar, &ar->tx_status[i]); + printk(KERN_DEBUG "%s: dispose queued frame =>\n", + wiphy_name(ar->hw->wiphy)); + ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ + ar9170_handle_tx_status(ar, skb, false, + AR9170_TX_STATUS_FAILED); + } - ar9170_recycle_expired(ar, &ar->tx_status[i], &waste); - ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste); - skb_queue_purge(&waste); + while ((skb = skb_dequeue(&ar->global_tx_status))) { +#ifdef AR9170_QUEUE_DEBUG + printk(KERN_DEBUG "%s: moving frame into waste queue =>\n", + wiphy_name(ar->hw->wiphy)); - if (!skb_queue_empty(&ar->tx_status[i]) || - !skb_queue_empty(&ar->tx_pending[i])) - resched = true; + ar9170_print_txheader(ar, skb); +#endif /* AR9170_QUEUE_DEBUG */ + skb_queue_tail(&ar->global_tx_status_waste, skb); } - if (resched) - queue_delayed_work(ar->hw->workqueue, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); + /* recall the janitor in 100ms - if there's garbage in the can. */ + if (skb_queue_len(&ar->global_tx_status_waste) > 0) + queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, + msecs_to_jiffies(100)); + + mutex_unlock(&ar->mutex); } -void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) +static void ar9170_handle_command_response(struct ar9170 *ar, + void *buf, u32 len) { struct ar9170_cmd_response *cmd = (void *) buf; @@ -486,21 +399,15 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) */ struct sk_buff *skb; - u32 phy = le32_to_cpu(cmd->tx_status.rate); - u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> - AR9170_TX_PHY_QOS_SHIFT; -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n", - wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q); -#endif /* AR9170_QUEUE_DEBUG */ + u32 queue = (le32_to_cpu(cmd->tx_status.rate) & + AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT; - skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, - &ar->tx_status[q], - AR9170_TX_INVALID_RATE); + skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue); if (unlikely(!skb)) return ; - ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status)); + ar9170_handle_tx_status(ar, skb, true, + le16_to_cpu(cmd->tx_status.status)); break; } @@ -540,38 +447,6 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) /* retransmission issue / SIFS/EIFS collision ?! */ break; - /* firmware debug */ - case 0xca: - printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4); - break; - case 0xcb: - len -= 4; - - switch (len) { - case 1: - printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n", - *((char *)buf + 4)); - break; - case 2: - printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n", - le16_to_cpup((__le16 *)((char *)buf + 4))); - break; - case 4: - printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n", - le32_to_cpup((__le32 *)((char *)buf + 4))); - break; - case 8: - printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n", - (unsigned long)le64_to_cpup( - (__le64 *)((char *)buf + 4))); - break; - } - break; - case 0xcc: - print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE, - (char *)buf + 4, len - 4); - break; - default: printk(KERN_INFO "received unhandled event %x\n", cmd->type); print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); @@ -585,7 +460,7 @@ static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) ar->rx_mpdu.has_plcp = false; } -int ar9170_nag_limiter(struct ar9170 *ar) +static int ar9170_nag_limiter(struct ar9170 *ar) { bool print_message; @@ -1082,12 +957,10 @@ static int ar9170_op_start(struct ieee80211_hw *hw) mutex_lock(&ar->mutex); - ar->filter_changed = 0; - /* reinitialize queues statistics */ memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); - for (i = 0; i < __AR9170_NUM_TXQ; i++) - ar->tx_stats[i].limit = AR9170_TXQ_DEPTH; + for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++) + ar->tx_stats[i].limit = 8; /* reset QoS defaults */ AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ @@ -1133,17 +1006,18 @@ static int ar9170_op_start(struct ieee80211_hw *hw) static void ar9170_op_stop(struct ieee80211_hw *hw) { struct ar9170 *ar = hw->priv; - unsigned int i; if (IS_STARTED(ar)) ar->state = AR9170_IDLE; flush_workqueue(ar->hw->workqueue); - cancel_delayed_work_sync(&ar->tx_janitor); + mutex_lock(&ar->mutex); + cancel_delayed_work_sync(&ar->tx_status_janitor); cancel_work_sync(&ar->filter_config_work); cancel_work_sync(&ar->beacon_work); - mutex_lock(&ar->mutex); + skb_queue_purge(&ar->global_tx_status_waste); + skb_queue_purge(&ar->global_tx_status); if (IS_ACCEPTING_CMD(ar)) { ar9170_set_leds_state(ar, 0); @@ -1153,32 +1027,51 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) ar->stop(ar); } - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - skb_queue_purge(&ar->tx_pending[i]); - skb_queue_purge(&ar->tx_status[i]); - } mutex_unlock(&ar->mutex); } -static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) +int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { + struct ar9170 *ar = hw->priv; struct ieee80211_hdr *hdr; struct ar9170_tx_control *txc; struct ieee80211_tx_info *info; + struct ieee80211_rate *rate = NULL; struct ieee80211_tx_rate *txrate; - struct ar9170_tx_info *arinfo; unsigned int queue = skb_get_queue_mapping(skb); + unsigned long flags = 0; + struct ar9170_sta_info *sta_info = NULL; + u32 power, chains; u16 keytype = 0; u16 len, icv = 0; + int err; + bool tx_status; - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); + if (unlikely(!IS_STARTED(ar))) + goto err_free; hdr = (void *)skb->data; info = IEEE80211_SKB_CB(skb); len = skb->len; + spin_lock_irqsave(&ar->tx_stats_lock, flags); + if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) { + spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + return NETDEV_TX_OK; + } + + ar->tx_stats[queue].len++; + ar->tx_stats[queue].count++; + if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len) + ieee80211_stop_queue(hw, queue); + + spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + txc = (void *)skb_push(skb, sizeof(*txc)); + tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) || + ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0)); + if (info->control.hw_key) { icv = info->control.hw_key->icv_len; @@ -1194,7 +1087,7 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) break; default: WARN_ON(1); - goto err_out; + goto err_dequeue; } } @@ -1211,65 +1104,16 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_NO_ACK) txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); + txrate = &info->control.rates[0]; + if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); - arinfo = (void *)info->rate_driver_data; - arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT); - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - if (unlikely(!info->control.sta)) - goto err_out; - - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); - arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK; - goto out; - } - - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); - /* - * WARNING: - * Putting the QoS queue bits into an unexplored territory is - * certainly not elegant. - * - * In my defense: This idea provides a reasonable way to - * smuggle valuable information to the tx_status callback. - * Also, the idea behind this bit-abuse came straight from - * the original driver code. - */ - - txc->phy_control |= - cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); - arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; - } else { - arinfo->flags = AR9170_TX_FLAG_NO_ACK; - } - -out: - return 0; - -err_out: - skb_pull(skb, sizeof(*txc)); - return -EINVAL; -} - -static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ar9170_tx_control *txc; - struct ieee80211_tx_info *info; - struct ieee80211_rate *rate = NULL; - struct ieee80211_tx_rate *txrate; - u32 power, chains; - - txc = (void *) skb->data; - info = IEEE80211_SKB_CB(skb); - txrate = &info->control.rates[0]; - if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); @@ -1289,12 +1133,9 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) u32 r = txrate->idx; u8 *txpower; - /* heavy clip control */ - txc->phy_control |= cpu_to_le32((r & 0x7) << 7); - r <<= AR9170_TX_PHY_MCS_SHIFT; - BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK); - + if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK)) + goto err_dequeue; txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); @@ -1356,154 +1197,53 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) chains = AR9170_TX_PHY_TXCHAIN_1; } txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); -} -static void ar9170_tx(struct ar9170 *ar) -{ - struct sk_buff *skb; - unsigned long flags; - struct ieee80211_tx_info *info; - struct ar9170_tx_info *arinfo; - unsigned int i, frames, frames_failed, remaining_space; - int err; - bool schedule_garbagecollector = false; - - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); - - if (unlikely(!IS_STARTED(ar))) - return ; - - remaining_space = AR9170_TX_MAX_PENDING; - - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - spin_lock_irqsave(&ar->tx_stats_lock, flags); - if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: queue %d full\n", - wiphy_name(ar->hw->wiphy), i); - - __ar9170_dump_txstats(ar); - printk(KERN_DEBUG "stuck frames: ===> \n"); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); - ar9170_dump_txqueue(ar, &ar->tx_status[i]); -#endif /* AR9170_QUEUE_DEBUG */ - ieee80211_stop_queue(ar->hw, i); - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - continue; - } - - frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, - skb_queue_len(&ar->tx_pending[i])); - - if (remaining_space < frames) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: tx quota reached queue:%d, " - "remaining slots:%d, needed:%d\n", - wiphy_name(ar->hw->wiphy), i, remaining_space, - frames); - - ar9170_dump_txstats(ar); -#endif /* AR9170_QUEUE_DEBUG */ - frames = remaining_space; - } - - ar->tx_stats[i].len += frames; - ar->tx_stats[i].count += frames; - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - - if (!frames) - continue; - - frames_failed = 0; - while (frames) { - skb = skb_dequeue(&ar->tx_pending[i]); - if (unlikely(!skb)) { - frames_failed += frames; - frames = 0; - break; - } - - info = IEEE80211_SKB_CB(skb); - arinfo = (void *) info->rate_driver_data; - - /* TODO: cancel stuck frames */ - arinfo->timeout = jiffies + - msecs_to_jiffies(AR9170_TX_TIMEOUT); - -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: send frame q:%d =>\n", - wiphy_name(ar->hw->wiphy), i); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - - err = ar->tx(ar, skb); - if (unlikely(err)) { - frames_failed++; - dev_kfree_skb_any(skb); - } else { - remaining_space--; - schedule_garbagecollector = true; - } - - frames--; - } - -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", - wiphy_name(ar->hw->wiphy), i); + if (tx_status) { + txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); + /* + * WARNING: + * Putting the QoS queue bits into an unexplored territory is + * certainly not elegant. + * + * In my defense: This idea provides a reasonable way to + * smuggle valuable information to the tx_status callback. + * Also, the idea behind this bit-abuse came straight from + * the original driver code. + */ - printk(KERN_DEBUG "%s: unprocessed pending frames left:\n", - wiphy_name(ar->hw->wiphy)); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); -#endif /* AR9170_QUEUE_DEBUG */ + txc->phy_control |= + cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); - if (unlikely(frames_failed)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: frames failed =>\n", - wiphy_name(ar->hw->wiphy), frames_failed); -#endif /* AR9170_QUEUE_DEBUG */ + if (info->control.sta) { + sta_info = (void *) info->control.sta->drv_priv; + skb_queue_tail(&sta_info->tx_status[queue], skb); + } else { + skb_queue_tail(&ar->global_tx_status, skb); - spin_lock_irqsave(&ar->tx_stats_lock, flags); - ar->tx_stats[i].len -= frames_failed; - ar->tx_stats[i].count -= frames_failed; - ieee80211_wake_queue(ar->hw, i); - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + queue_delayed_work(ar->hw->workqueue, + &ar->tx_status_janitor, + msecs_to_jiffies(100)); } } - if (schedule_garbagecollector) - queue_delayed_work(ar->hw->workqueue, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); -} - -int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct ar9170 *ar = hw->priv; - struct ieee80211_tx_info *info; - - if (unlikely(!IS_STARTED(ar))) - goto err_free; - - if (unlikely(ar9170_tx_prepare(ar, skb))) - goto err_free; - - info = IEEE80211_SKB_CB(skb); - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - /* drop frame, we do not allow TX A-MPDU aggregation yet. */ - goto err_free; - } else { - unsigned int queue = skb_get_queue_mapping(skb); - - ar9170_tx_prepare_phy(ar, skb); - skb_queue_tail(&ar->tx_pending[queue], skb); + err = ar->tx(ar, skb, tx_status, 0); + if (unlikely(tx_status && err)) { + if (info->control.sta) + skb_unlink(skb, &sta_info->tx_status[queue]); + else + skb_unlink(skb, &ar->global_tx_status); } - ar9170_tx(ar); return NETDEV_TX_OK; +err_dequeue: + spin_lock_irqsave(&ar->tx_stats_lock, flags); + ar->tx_stats[queue].len--; + ar->tx_stats[queue].count--; + spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + err_free: - dev_kfree_skb_any(skb); + dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -1566,6 +1306,11 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&ar->mutex); + if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { + /* TODO */ + err = 0; + } + if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* TODO */ err = 0; @@ -1599,21 +1344,15 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - - /* adjust slot time for 5 GHz */ - err = ar9170_set_slot_time(ar); - if (err) - goto out; - - err = ar9170_set_dyn_sifs_ack(ar); - if (err) - goto out; - err = ar9170_set_channel(ar, hw->conf.channel, AR9170_RFI_NONE, nl80211_to_ar9170(hw->conf.channel_type)); if (err) goto out; + /* adjust slot time for 5 GHz */ + if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) + err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, + 9 << 10); } out: @@ -1631,26 +1370,20 @@ static void ar9170_set_filters(struct work_struct *work) return ; mutex_lock(&ar->mutex); - if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE, - &ar->filter_changed)) { + if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) { err = ar9170_set_operating_mode(ar); if (err) goto unlock; } - if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST, - &ar->filter_changed)) { + if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) { err = ar9170_update_multicast(ar); if (err) goto unlock; } - if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, - &ar->filter_changed)) { + if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER) err = ar9170_update_frame_filter(ar); - if (err) - goto unlock; - } unlock: mutex_unlock(&ar->mutex); @@ -1680,7 +1413,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, int i; /* always get broadcast frames */ - mchash = 1ULL << (0xff >> 2); + mchash = 1ULL << (0xff>>2); for (i = 0; i < mc_count; i++) { if (WARN_ON(!mclist)) @@ -1690,7 +1423,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, } ar->want_mc_hash = mchash; } - set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed); + ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST; } if (changed_flags & FIF_CONTROL) { @@ -1706,14 +1439,12 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, else ar->want_filter = ar->cur_filter & ~filter; - set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, - &ar->filter_changed); + ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER; } if (changed_flags & FIF_PROMISC_IN_BSS) { ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; - set_bit(AR9170_FILTER_CHANGED_MODE, - &ar->filter_changed); + ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC; } if (likely(IS_STARTED(ar))) @@ -1733,32 +1464,27 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID) { memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN); err = ar9170_set_operating_mode(ar); - if (err) - goto out; } if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) { err = ar9170_update_beacon(ar); - if (err) - goto out; - - err = ar9170_set_beacon_timers(ar); - if (err) - goto out; + if (!err) + ar9170_set_beacon_timers(ar); } + ar9170_regwrite_begin(ar); + if (changed & BSS_CHANGED_ASSOC) { + ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state; + #ifndef CONFIG_AR9170_LEDS /* enable assoc LED. */ err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0); #endif /* CONFIG_AR9170_LEDS */ } - if (changed & BSS_CHANGED_BEACON_INT) { + if (changed & BSS_CHANGED_BEACON_INT) err = ar9170_set_beacon_timers(ar); - if (err) - goto out; - } if (changed & BSS_CHANGED_HT) { /* TODO */ @@ -1766,18 +1492,31 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_SLOT) { - err = ar9170_set_slot_time(ar); - if (err) - goto out; + u32 slottime = 20; + + if (bss_conf->use_short_slot) + slottime = 9; + + ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10); } if (changed & BSS_CHANGED_BASIC_RATES) { - err = ar9170_set_basic_rates(ar); - if (err) - goto out; + u32 cck, ofdm; + + if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) { + ofdm = bss_conf->basic_rates; + cck = 0; + } else { + /* four cck rates */ + cck = bss_conf->basic_rates & 0xf; + ofdm = bss_conf->basic_rates >> 4; + } + ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, + ofdm << 8 | cck); } -out: + ar9170_regwrite_finish(); + err = ar9170_regwrite_result(); mutex_unlock(&ar->mutex); } @@ -1929,6 +1668,43 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { + struct ar9170 *ar = hw->priv; + struct ar9170_sta_info *info = (void *) sta->drv_priv; + struct sk_buff *skb; + unsigned int i; + + switch (cmd) { + case STA_NOTIFY_ADD: + for (i = 0; i < ar->hw->queues; i++) + skb_queue_head_init(&info->tx_status[i]); + break; + + case STA_NOTIFY_REMOVE: + + /* + * transfer all outstanding frames that need a tx_status + * reports to the global tx_status queue + */ + + for (i = 0; i < ar->hw->queues; i++) { + while ((skb = skb_dequeue(&info->tx_status[i]))) { +#ifdef AR9170_QUEUE_DEBUG + printk(KERN_DEBUG "%s: queueing frame in " + "global tx_status queue =>\n", + wiphy_name(ar->hw->wiphy)); + + ar9170_print_txheader(ar, skb); +#endif /* AR9170_QUEUE_DEBUG */ + skb_queue_tail(&ar->global_tx_status, skb); + } + } + queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, + msecs_to_jiffies(100)); + break; + + default: + break; + } } static int ar9170_get_stats(struct ieee80211_hw *hw, @@ -1967,7 +1743,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, int ret; mutex_lock(&ar->mutex); - if ((param) && !(queue > __AR9170_NUM_TXQ)) { + if ((param) && !(queue > ar->hw->queues)) { memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], param, sizeof(*param)); @@ -2043,14 +1819,12 @@ void *ar9170_alloc(size_t priv_size) mutex_init(&ar->mutex); spin_lock_init(&ar->cmdlock); spin_lock_init(&ar->tx_stats_lock); - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - skb_queue_head_init(&ar->tx_status[i]); - skb_queue_head_init(&ar->tx_pending[i]); - } + skb_queue_head_init(&ar->global_tx_status); + skb_queue_head_init(&ar->global_tx_status_waste); ar9170_rx_reset_rx_mpdu(ar); INIT_WORK(&ar->filter_config_work, ar9170_set_filters); INIT_WORK(&ar->beacon_work, ar9170_new_beacon); - INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); + INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); /* all hw supports 2.4 GHz, so set channel to 1 by default */ ar->channel = &ar9170_2ghz_chantable[0]; diff --git a/trunk/drivers/net/wireless/ath/ar9170/phy.c b/trunk/drivers/net/wireless/ath/ar9170/phy.c index df86f70cd817..6ce20754b8e7 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/phy.c +++ b/trunk/drivers/net/wireless/ath/ar9170/phy.c @@ -401,7 +401,7 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) int i, err; u32 val; bool is_2ghz = band == IEEE80211_BAND_2GHZ; - bool is_40mhz = conf_is_ht40(&ar->hw->conf); + bool is_40mhz = false; /* XXX: for now */ ar9170_regwrite_begin(ar); @@ -1200,7 +1200,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, return -ENOSYS; } - if (ar->eeprom.tx_mask != 1) + if (0 /* 2 streams capable */) tmp |= 0x100; err = ar9170_write_reg(ar, 0x1c5804, tmp); @@ -1214,7 +1214,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, freqpar = ar9170_get_hw_dyn_params(channel, bw); vals[0] = cpu_to_le32(channel->center_freq * 1000); - vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf)); + vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1); vals[2] = cpu_to_le32(offs << 2 | 1); vals[3] = cpu_to_le32(freqpar->coeff_exp); vals[4] = cpu_to_le32(freqpar->coeff_man); diff --git a/trunk/drivers/net/wireless/ath/ar9170/usb.c b/trunk/drivers/net/wireless/ath/ar9170/usb.c index 754b1f8d8da9..d7c13c0177ca 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/usb.c +++ b/trunk/drivers/net/wireless/ath/ar9170/usb.c @@ -51,14 +51,9 @@ MODULE_AUTHOR("Johannes Berg "); MODULE_AUTHOR("Christian Lamparter "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); -MODULE_FIRMWARE("ar9170.fw"); MODULE_FIRMWARE("ar9170-1.fw"); MODULE_FIRMWARE("ar9170-2.fw"); -enum ar9170_requirements { - AR9170_REQ_FW1_ONLY = 1, -}; - static struct usb_device_id ar9170_usb_ids[] = { /* Atheros 9170 */ { USB_DEVICE(0x0cf3, 0x9170) }, @@ -86,74 +81,25 @@ static struct usb_device_id ar9170_usb_ids[] = { { USB_DEVICE(0x2019, 0x5304) }, /* IO-Data WNGDNUS2 */ { USB_DEVICE(0x04bb, 0x093f) }, - /* AVM FRITZ!WLAN USB Stick N */ - { USB_DEVICE(0x057C, 0x8401) }, - /* AVM FRITZ!WLAN USB Stick N 2.4 */ - { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, /* terminate */ {} }; MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); -static void ar9170_usb_submit_urb(struct ar9170_usb *aru) -{ - struct urb *urb; - unsigned long flags; - int err; - - if (unlikely(!IS_STARTED(&aru->common))) - return ; - - spin_lock_irqsave(&aru->tx_urb_lock, flags); - if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) { - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - return ; - } - aru->tx_submitted_urbs++; - - urb = usb_get_from_anchor(&aru->tx_pending); - if (!urb) { - aru->tx_submitted_urbs--; - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - - return ; - } - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - - aru->tx_pending_urbs--; - usb_anchor_urb(urb, &aru->tx_submitted); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { - if (ar9170_nag_limiter(&aru->common)) - dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", - err); - - usb_unanchor_urb(urb); - aru->tx_submitted_urbs--; - ar9170_tx_callback(&aru->common, urb->context); - } - - usb_free_urb(urb); -} - -static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) +static void ar9170_usb_tx_urb_complete_free(struct urb *urb) { struct sk_buff *skb = urb->context; struct ar9170_usb *aru = (struct ar9170_usb *) usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); - if (unlikely(!aru)) { + if (!aru) { dev_kfree_skb_irq(skb); return ; } - aru->tx_submitted_urbs--; - - ar9170_tx_callback(&aru->common, skb); - - ar9170_usb_submit_urb(aru); + ar9170_handle_tx_status(&aru->common, skb, false, + AR9170_TX_STATUS_COMPLETE); } static void ar9170_usb_tx_urb_complete(struct urb *urb) @@ -180,8 +126,8 @@ static void ar9170_usb_irq_completed(struct urb *urb) goto resubmit; } - ar9170_handle_command_response(&aru->common, urb->transfer_buffer, - urb->actual_length); + print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET, + urb->transfer_buffer, urb->actual_length); resubmit: usb_anchor_urb(urb, &aru->rx_submitted); @@ -231,15 +177,16 @@ static void ar9170_usb_rx_completed(struct urb *urb) usb_anchor_urb(urb, &aru->rx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { + if (err) { usb_unanchor_urb(urb); - goto free; + dev_kfree_skb_irq(skb); } return ; free: dev_kfree_skb_irq(skb); + return; } static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru, @@ -335,47 +282,21 @@ static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru) return err; } -static int ar9170_usb_flush(struct ar9170 *ar) +static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) { - struct ar9170_usb *aru = (void *) ar; - struct urb *urb; - int ret, err = 0; + int ret; - if (IS_STARTED(ar)) - aru->common.state = AR9170_IDLE; + aru->common.state = AR9170_UNKNOWN_STATE; - usb_wait_anchor_empty_timeout(&aru->tx_pending, - msecs_to_jiffies(800)); - while ((urb = usb_get_from_anchor(&aru->tx_pending))) { - ar9170_tx_callback(&aru->common, (void *) urb->context); - usb_free_urb(urb); - } + usb_unlink_anchored_urbs(&aru->tx_submitted); - /* lets wait a while until the tx - queues are dried out */ + /* give the LED OFF command and the deauth frame a chance to air. */ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, msecs_to_jiffies(100)); if (ret == 0) - err = -ETIMEDOUT; - - usb_kill_anchored_urbs(&aru->tx_submitted); - - if (IS_ACCEPTING_CMD(ar)) - aru->common.state = AR9170_STARTED; - - return err; -} - -static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) -{ - int err; - - aru->common.state = AR9170_UNKNOWN_STATE; - - err = ar9170_usb_flush(&aru->common); - if (err) - dev_err(&aru->udev->dev, "stuck tx urbs!\n"); - + dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); + usb_poison_anchored_urbs(&aru->rx_submitted); } @@ -416,7 +337,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, usb_anchor_urb(urb, &aru->tx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { + if (err) { usb_unanchor_urb(urb); usb_free_urb(urb); goto err_unbuf; @@ -459,10 +380,12 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, return err; } -static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) +static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, + bool txstatus_needed, unsigned int extra_len) { struct ar9170_usb *aru = (struct ar9170_usb *) ar; struct urb *urb; + int err; if (unlikely(!IS_STARTED(ar))) { /* Seriously, what were you drink... err... thinking!? */ @@ -475,17 +398,18 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) usb_fill_bulk_urb(urb, aru->udev, usb_sndbulkpipe(aru->udev, AR9170_EP_TX), - skb->data, skb->len, - ar9170_usb_tx_urb_complete_frame, skb); + skb->data, skb->len + extra_len, (txstatus_needed ? + ar9170_usb_tx_urb_complete : + ar9170_usb_tx_urb_complete_free), skb); urb->transfer_flags |= URB_ZERO_PACKET; - usb_anchor_urb(urb, &aru->tx_pending); - aru->tx_pending_urbs++; + usb_anchor_urb(urb, &aru->tx_submitted); + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) + usb_unanchor_urb(urb); usb_free_urb(urb); - - ar9170_usb_submit_urb(aru); - return 0; + return err; } static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) @@ -494,7 +418,7 @@ static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) unsigned long flags; u32 in, out; - if (unlikely(!buffer)) + if (!buffer) return ; in = le32_to_cpup((__le32 *)buffer); @@ -580,29 +504,17 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru) { int err = 0; - err = request_firmware(&aru->firmware, "ar9170.fw", - &aru->udev->dev); - if (!err) { - aru->init_values = NULL; - return 0; - } - - if (aru->req_one_stage_fw) { - dev_err(&aru->udev->dev, "ar9170.fw firmware file " - "not found and is required for this device\n"); - return -EINVAL; - } - - dev_err(&aru->udev->dev, "ar9170.fw firmware file " - "not found, trying old firmware...\n"); - err = request_firmware(&aru->init_values, "ar9170-1.fw", &aru->udev->dev); + if (err) { + dev_err(&aru->udev->dev, "file with init values not found.\n"); + return err; + } err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); if (err) { release_firmware(aru->init_values); - dev_err(&aru->udev->dev, "file with init values not found.\n"); + dev_err(&aru->udev->dev, "firmware file not found.\n"); return err; } @@ -636,9 +548,6 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru) { int err; - if (!aru->init_values) - goto upload_fw_start; - /* First, upload initial values to device RAM */ err = ar9170_usb_upload(aru, aru->init_values->data, aru->init_values->size, 0x102800, false); @@ -648,8 +557,6 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru) return err; } -upload_fw_start: - /* Then, upload the firmware itself and start it */ return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size, 0x200000, true); @@ -685,8 +592,10 @@ static void ar9170_usb_stop(struct ar9170 *ar) if (IS_ACCEPTING_CMD(ar)) aru->common.state = AR9170_STOPPED; - ret = ar9170_usb_flush(ar); - if (ret) + /* lets wait a while until the tx - queues are dried out */ + ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, + msecs_to_jiffies(1000)); + if (ret == 0) dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); @@ -747,15 +656,6 @@ static int ar9170_usb_init_device(struct ar9170_usb *aru) return err; } -static bool ar9170_requires_one_stage(const struct usb_device_id *id) -{ - if (!id->driver_info) - return false; - if (id->driver_info == AR9170_REQ_FW1_ONLY) - return true; - return false; -} - static int ar9170_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -776,22 +676,14 @@ static int ar9170_usb_probe(struct usb_interface *intf, aru->intf = intf; ar = &aru->common; - aru->req_one_stage_fw = ar9170_requires_one_stage(id); - usb_set_intfdata(intf, aru); SET_IEEE80211_DEV(ar->hw, &udev->dev); init_usb_anchor(&aru->rx_submitted); - init_usb_anchor(&aru->tx_pending); init_usb_anchor(&aru->tx_submitted); init_completion(&aru->cmd_wait); - spin_lock_init(&aru->tx_urb_lock); - - aru->tx_pending_urbs = 0; - aru->tx_submitted_urbs = 0; aru->common.stop = ar9170_usb_stop; - aru->common.flush = ar9170_usb_flush; aru->common.open = ar9170_usb_open; aru->common.tx = ar9170_usb_tx; aru->common.exec_cmd = ar9170_usb_exec_cmd; @@ -799,7 +691,7 @@ static int ar9170_usb_probe(struct usb_interface *intf, #ifdef CONFIG_PM udev->reset_resume = 1; -#endif /* CONFIG_PM */ +#endif err = ar9170_usb_reset(aru); if (err) goto err_freehw; @@ -884,6 +776,11 @@ static int ar9170_resume(struct usb_interface *intf) usb_unpoison_anchored_urbs(&aru->rx_submitted); usb_unpoison_anchored_urbs(&aru->tx_submitted); + /* + * FIXME: firmware upload will fail on resume. + * but this is better than a hang! + */ + err = ar9170_usb_init_device(aru); if (err) goto err_unrx; diff --git a/trunk/drivers/net/wireless/ath/ar9170/usb.h b/trunk/drivers/net/wireless/ath/ar9170/usb.h index d098f4d5d2f2..ac42586495d8 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/usb.h +++ b/trunk/drivers/net/wireless/ath/ar9170/usb.h @@ -51,7 +51,6 @@ #include "ar9170.h" #define AR9170_NUM_RX_URBS 16 -#define AR9170_NUM_TX_URBS 8 struct firmware; @@ -61,15 +60,9 @@ struct ar9170_usb { struct usb_interface *intf; struct usb_anchor rx_submitted; - struct usb_anchor tx_pending; struct usb_anchor tx_submitted; - bool req_one_stage_fw; - - spinlock_t tx_urb_lock; - unsigned int tx_submitted_urbs; - unsigned int tx_pending_urbs; - + spinlock_t cmdlock; struct completion cmd_wait; int readlen; u8 *readbuf; diff --git a/trunk/drivers/net/wireless/ath/ath5k/Makefile b/trunk/drivers/net/wireless/ath/ath5k/Makefile index 090dc6d268a3..84a74c5248e5 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/Makefile +++ b/trunk/drivers/net/wireless/ath/ath5k/Makefile @@ -11,6 +11,5 @@ ath5k-y += reset.o ath5k-y += attach.o ath5k-y += base.o ath5k-y += led.o -ath5k-y += rfkill.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/trunk/drivers/net/wireless/ath/ath5k/ath5k.h b/trunk/drivers/net/wireless/ath/ath5k/ath5k.h index 6358233bac99..813718210338 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/trunk/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1256,10 +1256,6 @@ extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); -/* rfkill Functions */ -extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); -extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); - /* Misc functions */ int ath5k_hw_set_capabilities(struct ath5k_hw *ah); extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 55f7de09d134..fb5193764afa 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -2070,13 +2070,6 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) return ret; } -static void ath5k_beacon_disable(struct ath5k_softc *sc) -{ - sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); - ath5k_hw_set_imr(sc->ah, sc->imask); - ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq); -} - /* * Transmit a beacon frame at SWBA. Dynamic updates to the * frame contents are done as needed and the slot time is @@ -2360,8 +2353,6 @@ ath5k_init(struct ath5k_softc *sc) if (ret) goto done; - ath5k_rfkill_hw_start(ah); - /* * Reset the key cache since some parts do not reset the * contents on initial power up or resume from suspend. @@ -2470,8 +2461,6 @@ ath5k_stop_hw(struct ath5k_softc *sc) tasklet_kill(&sc->restq); tasklet_kill(&sc->beacontq); - ath5k_rfkill_hw_stop(sc->ah); - return ret; } @@ -2530,9 +2519,6 @@ ath5k_intr(int irq, void *dev_id) */ ath5k_hw_update_mib_counters(ah, &sc->ll_stats); } - if (status & AR5K_INT_GPIO) - tasklet_schedule(&sc->rf_kill.toggleq); - } } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); @@ -2771,7 +2757,6 @@ ath5k_remove_interface(struct ieee80211_hw *hw, goto end; ath5k_hw_set_lladdr(sc->ah, mac); - ath5k_beacon_disable(sc); sc->vif = NULL; end: mutex_unlock(&sc->lock); @@ -2790,9 +2775,11 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&sc->lock); + sc->bintval = conf->beacon_int; + ret = ath5k_chan_set(sc, conf->channel); if (ret < 0) - goto unlock; + return ret; if ((changed & IEEE80211_CONF_CHANGE_POWER) && (sc->power_level != conf->power_level)) { @@ -2821,9 +2808,8 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) */ ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); -unlock: mutex_unlock(&sc->lock); - return ret; + return 0; } #define SUPPORTED_FIF_FLAGS \ @@ -3075,14 +3061,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { int ret; struct ath5k_softc *sc = hw->priv; - struct sk_buff *skb; - - if (WARN_ON(!vif)) { - ret = -EINVAL; - goto out; - } - - skb = ieee80211_beacon_get(hw, vif); + struct sk_buff *skb = ieee80211_beacon_get(hw, vif); if (!skb) { ret = -ENOMEM; diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.h b/trunk/drivers/net/wireless/ath/ath5k/base.h index f9b7f2f819b7..852b2c189fd8 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.h +++ b/trunk/drivers/net/wireless/ath/ath5k/base.h @@ -46,7 +46,6 @@ #include #include #include -#include #include "ath5k.h" #include "debug.h" @@ -92,15 +91,6 @@ struct ath5k_led struct led_classdev led_dev; /* led classdev */ }; -/* Rfkill */ -struct ath5k_rfkill { - /* GPIO PIN for rfkill */ - u16 gpio; - /* polarity of rfkill GPIO PIN */ - bool polarity; - /* RFKILL toggle tasklet */ - struct tasklet_struct toggleq; -}; #if CHAN_DEBUG #define ATH_CHAN_MAX (26+26+26+200+200) @@ -177,8 +167,6 @@ struct ath5k_softc { struct tasklet_struct txtq; /* tx intr tasklet */ struct ath5k_led tx_led; /* tx led */ - struct ath5k_rfkill rf_kill; - spinlock_t block; /* protects beacon */ struct tasklet_struct beacontq; /* beacon intr tasklet */ struct ath5k_buf *bbuf; /* beacon buffer */ diff --git a/trunk/drivers/net/wireless/ath/ath5k/reset.c b/trunk/drivers/net/wireless/ath/ath5k/reset.c index bd0a97a38d34..66067733ddd3 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/reset.c +++ b/trunk/drivers/net/wireless/ath/ath5k/reset.c @@ -1304,6 +1304,23 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, if (ah->ah_version != AR5K_AR5210) ath5k_hw_set_imr(ah, ah->ah_imr); + /* + * Setup RFKill interrupt if rfkill flag is set on eeprom. + * TODO: Use gpio pin and polarity infos from eeprom + * TODO: Handle this in ath5k_intr because it'll result + * a nasty interrupt storm. + */ +#if 0 + if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { + ath5k_hw_set_gpio_input(ah, 0); + ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); + if (ah->ah_gpio[0] == 0) + ath5k_hw_set_gpio_intr(ah, 0, 1); + else + ath5k_hw_set_gpio_intr(ah, 0, 0); + } +#endif + /* Enable 32KHz clock function for AR5212+ chips * Set clocks to 32KHz operation and use an * external 32KHz crystal when sleeping if one diff --git a/trunk/drivers/net/wireless/ath/ath5k/rfkill.c b/trunk/drivers/net/wireless/ath/ath5k/rfkill.c deleted file mode 100644 index 41a877b73fce..000000000000 --- a/trunk/drivers/net/wireless/ath/ath5k/rfkill.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * RFKILL support for ath5k - * - * Copyright (c) 2009 Tobias Doerffel - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - */ - -#include "base.h" - - -static inline void ath5k_rfkill_disable(struct ath5k_softc *sc) -{ - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n", - sc->rf_kill.gpio, sc->rf_kill.polarity); - ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); - ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity); -} - - -static inline void ath5k_rfkill_enable(struct ath5k_softc *sc) -{ - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n", - sc->rf_kill.gpio, sc->rf_kill.polarity); - ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); - ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity); -} - -static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable) -{ - struct ath5k_hw *ah = sc->ah; - u32 curval; - - ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio); - curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio); - ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ? - !!curval : !curval); -} - -static bool -ath5k_is_rfkill_set(struct ath5k_softc *sc) -{ - /* configuring GPIO for input for some reason disables rfkill */ - /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/ - return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) == - sc->rf_kill.polarity; -} - -static void -ath5k_tasklet_rfkill_toggle(unsigned long data) -{ - struct ath5k_softc *sc = (void *)data; - bool blocked; - - blocked = ath5k_is_rfkill_set(sc); - wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked); -} - - -void -ath5k_rfkill_hw_start(struct ath5k_hw *ah) -{ - struct ath5k_softc *sc = ah->ah_sc; - - /* read rfkill GPIO configuration from EEPROM header */ - sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin; - sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol; - - tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle, - (unsigned long)sc); - - ath5k_rfkill_disable(sc); - - /* enable interrupt for rfkill switch */ - if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) - ath5k_rfkill_set_intr(sc, true); -} - - -void -ath5k_rfkill_hw_stop(struct ath5k_hw *ah) -{ - struct ath5k_softc *sc = ah->ah_sc; - - /* disable interrupt for rfkill switch */ - if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) - ath5k_rfkill_set_intr(sc, false); - - tasklet_kill(&sc->rf_kill.toggleq); - - /* enable RFKILL when stopping HW so Wifi LED is turned off */ - ath5k_rfkill_enable(sc); -} - diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 515880aa2116..796a3adffea0 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -460,9 +460,12 @@ struct ath_led { bool registered; }; +/* Rfkill */ +#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */ + struct ath_rfkill { struct rfkill *rfkill; - struct rfkill_ops ops; + struct delayed_work rfkill_poll; char rfkill_name[32]; }; @@ -506,6 +509,8 @@ struct ath_rfkill { #define SC_OP_RXFLUSH BIT(7) #define SC_OP_LED_ASSOCIATED BIT(8) #define SC_OP_RFKILL_REGISTERED BIT(9) +#define SC_OP_RFKILL_SW_BLOCKED BIT(10) +#define SC_OP_RFKILL_HW_BLOCKED BIT(11) #define SC_OP_WAIT_FOR_BEACON BIT(12) #define SC_OP_LED_ON BIT(13) #define SC_OP_SCANNING BIT(14) diff --git a/trunk/drivers/net/wireless/ath/ath9k/beacon.c b/trunk/drivers/net/wireless/ath/ath9k/beacon.c index 3639a2e6987d..a21b21339fbc 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/beacon.c @@ -411,7 +411,6 @@ void ath_beacon_tasklet(unsigned long data) } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { DPRINTF(sc, ATH_DBG_BEACON, "beacon is officially stuck\n"); - sc->sc_flags |= SC_OP_TSF_RESET; ath_reset(sc, false); } @@ -674,14 +673,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; - /* - * It looks like mac80211 may end up using beacon interval of zero in - * some cases (at least for mesh point). Avoid getting into an - * infinite loop by using a bit safer value instead.. - */ - if (intval == 0) - intval = 100; - /* Pull nexttbtt forward to reflect the current TSF */ nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.c b/trunk/drivers/net/wireless/ath/ath9k/debug.c index 6d20725d6451..97df20cbf528 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.c @@ -44,44 +44,6 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file) return 0; } -static ssize_t read_file_debug(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - char buf[32]; - unsigned int len; - - len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_debug(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - unsigned long mask; - char buf[32]; - ssize_t len; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EINVAL; - - buf[len] = '\0'; - if (strict_strtoul(buf, 0, &mask)) - return -EINVAL; - - sc->debug.debug_mask = mask; - return count; -} - -static const struct file_operations fops_debug = { - .read = read_file_debug, - .write = write_file_debug, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE -}; - static ssize_t read_file_dma(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -262,66 +224,111 @@ static const struct file_operations fops_interrupt = { .owner = THIS_MODULE }; -void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) +static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb) +{ + struct ath_tx_info_priv *tx_info_priv = NULL; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *rates = tx_info->status.rates; + int final_ts_idx, idx; + + tx_info_priv = ATH_TX_INFO_PRIV(tx_info); + final_ts_idx = tx_info_priv->tx.ts_rateindex; + idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate; + + sc->debug.stats.n_rcstats[idx].success++; +} + +static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb) { struct ath_tx_info_priv *tx_info_priv = NULL; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_rate *rates = tx_info->status.rates; int final_ts_idx, idx; - struct ath_rc_stats *stats; tx_info_priv = ATH_TX_INFO_PRIV(tx_info); final_ts_idx = tx_info_priv->tx.ts_rateindex; idx = rates[final_ts_idx].idx; - stats = &sc->debug.stats.rcstats[idx]; - stats->success++; + + sc->debug.stats.legacy_rcstats[idx].success++; +} + +void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb) +{ + if (conf_is_ht(&sc->hw->conf)) + ath_debug_stat_11n_rc(sc, skb); + else + ath_debug_stat_legacy_rc(sc, skb); } +/* FIXME: legacy rates, later on .. */ void ath_debug_stat_retries(struct ath_softc *sc, int rix, int xretries, int retries, u8 per) { - struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix]; + if (conf_is_ht(&sc->hw->conf)) { + int idx = sc->cur_rate_table->info[rix].dot11rate; - stats->xretries += xretries; - stats->retries += retries; - stats->per = per; + sc->debug.stats.n_rcstats[idx].xretries += xretries; + sc->debug.stats.n_rcstats[idx].retries += retries; + sc->debug.stats.n_rcstats[idx].per = per; + } } -static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t ath_read_file_stat_11n_rc(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - char *buf; - unsigned int len = 0, max; + char buf[1024]; + unsigned int len = 0; int i = 0; - ssize_t retval; - if (sc->cur_rate_table == NULL) - return 0; + len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success", + "Retries", "XRetries", "PER"); - max = 80 + sc->cur_rate_table->rate_cnt * 64; - buf = kmalloc(max + 1, GFP_KERNEL); - if (buf == NULL) - return 0; - buf[max] = 0; + for (i = 0; i <= 15; i++) { + len += snprintf(buf + len, sizeof(buf) - len, + "%5s%3d: %8u %8u %8u %8u\n", "MCS", i, + sc->debug.stats.n_rcstats[i].success, + sc->debug.stats.n_rcstats[i].retries, + sc->debug.stats.n_rcstats[i].xretries, + sc->debug.stats.n_rcstats[i].per); + } - len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success", - "Retries", "XRetries", "PER"); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t ath_read_file_stat_legacy_rc(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + char buf[512]; + unsigned int len = 0; + int i = 0; + + len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success"); for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { - u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; - struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; - - len += snprintf(buf + len, max - len, - "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000, - (ratekbps % 1000) / 100, stats->success, - stats->retries, stats->xretries, - stats->per); + len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n", + sc->cur_rate_table->info[i].ratekbps / 1000, + sc->debug.stats.legacy_rcstats[i].success); } - retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return retval; + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + + if (sc->cur_rate_table == NULL) + return 0; + + if (conf_is_ht(&sc->hw->conf)) + return ath_read_file_stat_11n_rc(file, user_buf, count, ppos); + else + return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos); } static const struct file_operations fops_rcstat = { @@ -499,11 +506,6 @@ int ath9k_init_debug(struct ath_softc *sc) if (!sc->debug.debugfs_phy) goto err; - sc->debug.debugfs_debug = debugfs_create_file("debug", - S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug); - if (!sc->debug.debugfs_debug) - goto err; - sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO, sc->debug.debugfs_phy, sc, &fops_dma); if (!sc->debug.debugfs_dma) @@ -541,7 +543,6 @@ void ath9k_exit_debug(struct ath_softc *sc) debugfs_remove(sc->debug.debugfs_rcstat); debugfs_remove(sc->debug.debugfs_interrupt); debugfs_remove(sc->debug.debugfs_dma); - debugfs_remove(sc->debug.debugfs_debug); debugfs_remove(sc->debug.debugfs_phy); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.h b/trunk/drivers/net/wireless/ath/ath9k/debug.h index edda15bf2c15..db845cf960c9 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.h +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.h @@ -80,7 +80,11 @@ struct ath_interrupt_stats { u32 dtim; }; -struct ath_rc_stats { +struct ath_legacy_rc_stats { + u32 success; +}; + +struct ath_11n_rc_stats { u32 success; u32 retries; u32 xretries; @@ -89,13 +93,13 @@ struct ath_rc_stats { struct ath_stats { struct ath_interrupt_stats istats; - struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; + struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */ + struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */ }; struct ath9k_debug { int debug_mask; struct dentry *debugfs_phy; - struct dentry *debugfs_debug; struct dentry *debugfs_dma; struct dentry *debugfs_interrupt; struct dentry *debugfs_rcstat; diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index f7baa406918b..61da08a1648c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -1192,69 +1192,120 @@ static bool ath_is_rfkill_set(struct ath_softc *sc) ah->rfkill_polarity; } -/* s/w rfkill handlers */ -static int ath_rfkill_set_block(void *data, bool blocked) +/* h/w rfkill poll function */ +static void ath_rfkill_poll(struct work_struct *work) { - struct ath_softc *sc = data; + struct ath_softc *sc = container_of(work, struct ath_softc, + rf_kill.rfkill_poll.work); + bool radio_on; - if (blocked) - ath_radio_disable(sc); - else - ath_radio_enable(sc); + if (sc->sc_flags & SC_OP_INVALID) + return; - return 0; + radio_on = !ath_is_rfkill_set(sc); + + /* + * enable/disable radio only when there is a + * state change in RF switch + */ + if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) { + enum rfkill_state state; + + if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) { + state = radio_on ? RFKILL_STATE_SOFT_BLOCKED + : RFKILL_STATE_HARD_BLOCKED; + } else if (radio_on) { + ath_radio_enable(sc); + state = RFKILL_STATE_UNBLOCKED; + } else { + ath_radio_disable(sc); + state = RFKILL_STATE_HARD_BLOCKED; + } + + if (state == RFKILL_STATE_HARD_BLOCKED) + sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED; + else + sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED; + + rfkill_force_state(sc->rf_kill.rfkill, state); + } + + queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll, + msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL)); } -static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data) +/* s/w rfkill handler */ +static int ath_sw_toggle_radio(void *data, enum rfkill_state state) { struct ath_softc *sc = data; - bool blocked = !!ath_is_rfkill_set(sc); - if (rfkill_set_hw_state(rfkill, blocked)) - ath_radio_disable(sc); - else - ath_radio_enable(sc); + switch (state) { + case RFKILL_STATE_SOFT_BLOCKED: + if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED | + SC_OP_RFKILL_SW_BLOCKED))) + ath_radio_disable(sc); + sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED; + return 0; + case RFKILL_STATE_UNBLOCKED: + if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) { + sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED; + if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) { + DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the" + "radio as it is disabled by h/w\n"); + return -EPERM; + } + ath_radio_enable(sc); + } + return 0; + default: + return -EINVAL; + } } /* Init s/w rfkill */ static int ath_init_sw_rfkill(struct ath_softc *sc) { - sc->rf_kill.ops.set_block = ath_rfkill_set_block; - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) - sc->rf_kill.ops.poll = ath_rfkill_poll_state; - - snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), - "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy)); - - sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name, - wiphy_dev(sc->hw->wiphy), - RFKILL_TYPE_WLAN, - &sc->rf_kill.ops, sc); + sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy), + RFKILL_TYPE_WLAN); if (!sc->rf_kill.rfkill) { DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n"); return -ENOMEM; } + snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), + "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy)); + sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name; + sc->rf_kill.rfkill->data = sc; + sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio; + sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED; + return 0; } /* Deinitialize rfkill */ static void ath_deinit_rfkill(struct ath_softc *sc) { + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); + if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { rfkill_unregister(sc->rf_kill.rfkill); - rfkill_destroy(sc->rf_kill.rfkill); sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; + sc->rf_kill.rfkill = NULL; } } static int ath_start_rfkill_poll(struct ath_softc *sc) { + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + queue_delayed_work(sc->hw->workqueue, + &sc->rf_kill.rfkill_poll, 0); + if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { if (rfkill_register(sc->rf_kill.rfkill)) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to register rfkill\n"); - rfkill_destroy(sc->rf_kill.rfkill); + rfkill_free(sc->rf_kill.rfkill); /* Deinitialize the device */ ath_cleanup(sc); @@ -1627,6 +1678,10 @@ int ath_attach(u16 devid, struct ath_softc *sc) goto error_attach; #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) + /* Initialze h/w Rfkill */ + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll); + /* Initialize s/w rfkill */ error = ath_init_sw_rfkill(sc); if (error) @@ -2159,8 +2214,10 @@ static void ath9k_stop(struct ieee80211_hw *hw) } else sc->rx.rxlink = NULL; - rfkill_pause_polling(sc->rf_kill.rfkill); - +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); +#endif /* disable HAL and put h/w to sleep */ ath9k_hw_disable(sc->sc_ah); ath9k_hw_configpcipowersave(sc->sc_ah, 1); diff --git a/trunk/drivers/net/wireless/ath/ath9k/pci.c b/trunk/drivers/net/wireless/ath/ath9k/pci.c index ccdf20a2e9be..168411d322a2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/pci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/pci.c @@ -227,6 +227,11 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); +#endif + pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); @@ -251,6 +256,16 @@ static int ath_pci_resume(struct pci_dev *pdev) AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) + /* + * check the h/w rfkill state on resume + * and start the rfkill poll timer + */ + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) + queue_delayed_work(sc->hw->workqueue, + &sc->rf_kill.rfkill_poll, 0); +#endif + return 0; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index b61a071788a5..a8def4fa449c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -711,7 +711,6 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) return 0; if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { - txtid->state &= ~AGGR_ADDBA_PROGRESS; txtid->addba_exchangeattempts = 0; return 0; } diff --git a/trunk/drivers/net/wireless/ath/regd.c b/trunk/drivers/net/wireless/ath/regd.c index eef370bd1211..7a89f9fac7d4 100644 --- a/trunk/drivers/net/wireless/ath/regd.c +++ b/trunk/drivers/net/wireless/ath/regd.c @@ -366,17 +366,11 @@ static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) if (rd & COUNTRY_ERD_FLAG) { /* EEPROM value is a country code */ u16 cc = rd & ~COUNTRY_ERD_FLAG; - printk(KERN_DEBUG - "ath: EEPROM indicates we should expect " - "a country code\n"); for (i = 0; i < ARRAY_SIZE(allCountries); i++) if (allCountries[i].countryCode == cc) return true; } else { /* EEPROM value is a regpair value */ - if (rd != CTRY_DEFAULT) - printk(KERN_DEBUG "ath: EEPROM indicates we " - "should expect a direct regpair map\n"); for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) if (regDomainPairs[i].regDmnEnum == rd) return true; @@ -483,11 +477,6 @@ ath_regd_init(struct ath_regulatory *reg, struct country_code_to_enum_rd *country = NULL; u16 regdmn; - if (!reg) - return -EINVAL; - - printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); - if (!ath_regd_is_eeprom_valid(reg)) { printk(KERN_ERR "ath: Invalid EEPROM contents\n"); return -EINVAL; @@ -497,30 +486,20 @@ ath_regd_init(struct ath_regulatory *reg, reg->country_code = ath_regd_get_default_country(regdmn); if (reg->country_code == CTRY_DEFAULT && - regdmn == CTRY_DEFAULT) { - printk(KERN_DEBUG "ath: EEPROM indicates default " - "country code should be used\n"); + regdmn == CTRY_DEFAULT) reg->country_code = CTRY_UNITED_STATES; - } if (reg->country_code == CTRY_DEFAULT) { country = NULL; } else { - printk(KERN_DEBUG "ath: doing EEPROM country->regdmn " - "map search\n"); country = ath_regd_find_country(reg->country_code); if (country == NULL) { printk(KERN_DEBUG - "ath: no valid country maps found for " - "country code: 0x%0x\n", + "ath: Country is NULL!!!!, cc= %d\n", reg->country_code); return -EINVAL; - } else { + } else regdmn = country->regDmnEnum; - printk(KERN_DEBUG "ath: country maps to " - "regdmn code: 0x%0x\n", - regdmn); - } } reg->regpair = ath_get_regpair(regdmn); @@ -544,7 +523,7 @@ ath_regd_init(struct ath_regulatory *reg, printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", reg->alpha2[0], reg->alpha2[1]); - printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n", + printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", reg->regpair->regDmnEnum); ath_regd_init_wiphy(reg, wiphy, reg_notifier); diff --git a/trunk/drivers/net/wireless/b43/Kconfig b/trunk/drivers/net/wireless/b43/Kconfig index 67f564e37225..21572e40b79d 100644 --- a/trunk/drivers/net/wireless/b43/Kconfig +++ b/trunk/drivers/net/wireless/b43/Kconfig @@ -98,6 +98,13 @@ config B43_LEDS depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43) default y +# This config option automatically enables b43 RFKILL support, +# if it's possible. +config B43_RFKILL + bool + depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43) + default y + # This config option automatically enables b43 HW-RNG support, # if the HW-RNG core is enabled. config B43_HWRNG diff --git a/trunk/drivers/net/wireless/b43/Makefile b/trunk/drivers/net/wireless/b43/Makefile index da379f4b0c3a..281ef8310350 100644 --- a/trunk/drivers/net/wireless/b43/Makefile +++ b/trunk/drivers/net/wireless/b43/Makefile @@ -13,7 +13,7 @@ b43-y += lo.o b43-y += wa.o b43-y += dma.o b43-$(CONFIG_B43_PIO) += pio.o -b43-y += rfkill.o +b43-$(CONFIG_B43_RFKILL) += rfkill.o b43-$(CONFIG_B43_LEDS) += leds.o b43-$(CONFIG_B43_PCMCIA) += pcmcia.o b43-$(CONFIG_B43_DEBUG) += debugfs.o diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h index f580c2812d91..4e8ad841c3c5 100644 --- a/trunk/drivers/net/wireless/b43/b43.h +++ b/trunk/drivers/net/wireless/b43/b43.h @@ -163,7 +163,6 @@ enum { #define B43_SHM_SH_WLCOREREV 0x0016 /* 802.11 core revision */ #define B43_SHM_SH_PCTLWDPOS 0x0008 #define B43_SHM_SH_RXPADOFF 0x0034 /* RX Padding data offset (PIO only) */ -#define B43_SHM_SH_FWCAPA 0x0042 /* Firmware capabilities (Opensource firmware only) */ #define B43_SHM_SH_PHYVER 0x0050 /* PHY version */ #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ @@ -298,10 +297,6 @@ enum { #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ -/* Firmware capabilities field in SHM (Opensource firmware only) */ -#define B43_FWCAPA_HWCRYPTO 0x0001 -#define B43_FWCAPA_QOS 0x0002 - /* MacFilter offsets. */ #define B43_MACFILTER_SELF 0x0000 #define B43_MACFILTER_BSSID 0x0003 @@ -601,13 +596,6 @@ struct b43_wl { /* Pointer to the ieee80211 hardware data structure */ struct ieee80211_hw *hw; - /* The number of queues that were registered with the mac80211 subsystem - * initially. This is a backup copy of hw->queues in case hw->queues has - * to be dynamically lowered at runtime (Firmware does not support QoS). - * hw->queues has to be restored to the original value before unregistering - * from the mac80211 subsystem. */ - u16 mac80211_initially_registered_queues; - struct mutex mutex; spinlock_t irq_lock; /* R/W lock for data transmission. @@ -643,6 +631,9 @@ struct b43_wl { char rng_name[30 + 1]; #endif /* CONFIG_B43_HWRNG */ + /* The RF-kill button */ + struct b43_rfkill rfkill; + /* List of all wireless devices on this chip */ struct list_head devlist; u8 nr_devs; @@ -761,8 +752,6 @@ struct b43_wldev { bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ bool radio_hw_enable; /* saved state of radio hardware enabled state */ bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ - bool qos_enabled; /* TRUE, if QoS is used. */ - bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ /* PHY/Radio device. */ struct b43_phy phy; diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 7964cc32b258..eae680b53052 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1285,7 +1285,7 @@ static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev, { struct b43_dmaring *ring; - if (dev->qos_enabled) { + if (b43_modparam_qos) { /* 0 = highest priority */ switch (queue_prio) { default: diff --git a/trunk/drivers/net/wireless/b43/leds.c b/trunk/drivers/net/wireless/b43/leds.c index c8b317094c31..76f4c7bad8b8 100644 --- a/trunk/drivers/net/wireless/b43/leds.c +++ b/trunk/drivers/net/wireless/b43/leds.c @@ -28,7 +28,6 @@ #include "b43.h" #include "leds.h" -#include "rfkill.h" static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, @@ -88,7 +87,7 @@ static void b43_led_brightness_set(struct led_classdev *led_dev, } static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, - const char *name, const char *default_trigger, + const char *name, char *default_trigger, u8 led_index, bool activelow) { int err; @@ -165,10 +164,10 @@ static void b43_map_led(struct b43_wldev *dev, snprintf(name, sizeof(name), "b43-%s::radio", wiphy_name(hw->wiphy)); b43_register_led(dev, &dev->led_radio, name, - ieee80211_get_radio_led_name(hw), + b43_rfkill_led_name(dev), led_index, activelow); - /* Sync the RF-kill LED state with radio and switch states. */ - if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) + /* Sync the RF-kill LED state with the switch state. */ + if (dev->radio_hw_enable) b43_led_turn_on(dev, led_index, activelow); break; case B43_LED_WEIRD: diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 6456afebdba1..cb4a8712946a 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -80,8 +80,8 @@ static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); -static int modparam_qos = 1; -module_param_named(qos, modparam_qos, int, 0444); +int b43_modparam_qos = 1; +module_param_named(qos, b43_modparam_qos, int, 0444); MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); static int modparam_btcoex = 1; @@ -538,13 +538,6 @@ void b43_hf_write(struct b43_wldev *dev, u64 value) b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); } -/* Read the firmware capabilities bitmask (Opensource firmware only) */ -static u16 b43_fwcapa_read(struct b43_wldev *dev) -{ - B43_WARN_ON(!dev->fw.opensource); - return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA); -} - void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) { u32 low, high; @@ -2314,34 +2307,12 @@ static int b43_upload_microcode(struct b43_wldev *dev) dev->fw.patch = fwpatch; dev->fw.opensource = (fwdate == 0xFFFF); - /* Default to use-all-queues. */ - dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues; - dev->qos_enabled = !!modparam_qos; - /* Default to firmware/hardware crypto acceleration. */ - dev->hwcrypto_enabled = 1; - if (dev->fw.opensource) { - u16 fwcapa; - /* Patchlevel info is encoded in the "time" field. */ dev->fw.patch = fwtime; - b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n", - dev->fw.rev, dev->fw.patch); - - fwcapa = b43_fwcapa_read(dev); - if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) { - b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n"); - /* Disable hardware crypto and fall back to software crypto. */ - dev->hwcrypto_enabled = 0; - } - if (!(fwcapa & B43_FWCAPA_QOS)) { - b43info(dev->wl, "QoS not supported by firmware\n"); - /* Disable QoS. Tweak hw->queues to 1. It will be restored before - * ieee80211_unregister to make sure the networking core can - * properly free possible resources. */ - dev->wl->hw->queues = 1; - dev->qos_enabled = 0; - } + b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n", + dev->fw.rev, dev->fw.patch, + dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : ""); } else { b43info(dev->wl, "Loading firmware version %u.%u " "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", @@ -3499,7 +3470,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) if (!!conf->radio_enabled != phy->radio_on) { if (conf->radio_enabled) { - b43_software_rfkill(dev, false); + b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED); b43info(dev->wl, "Radio turned on by software\n"); if (!dev->radio_hw_enable) { b43info(dev->wl, "The hardware RF-kill button " @@ -3507,7 +3478,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) "Press the button to turn it on.\n"); } } else { - b43_software_rfkill(dev, true); + b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); b43info(dev->wl, "Radio turned off by software\n"); } } @@ -3656,7 +3627,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) goto out_unlock; - if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) { + if (dev->fw.pcm_request_failed) { /* We don't have firmware for the crypto engine. * Must use software-crypto. */ err = -EOPNOTSUPP; @@ -4327,6 +4298,7 @@ static int b43_op_start(struct ieee80211_hw *hw) struct b43_wldev *dev = wl->current_dev; int did_init = 0; int err = 0; + bool do_rfkill_exit = 0; /* Kill all old instance specific information to make sure * the card won't use it in the short timeframe between start @@ -4340,12 +4312,18 @@ static int b43_op_start(struct ieee80211_hw *hw) wl->beacon1_uploaded = 0; wl->beacon_templates_virgin = 1; + /* First register RFkill. + * LEDs that are registered later depend on it. */ + b43_rfkill_init(dev); + mutex_lock(&wl->mutex); if (b43_status(dev) < B43_STAT_INITIALIZED) { err = b43_wireless_core_init(dev); - if (err) + if (err) { + do_rfkill_exit = 1; goto out_mutex_unlock; + } did_init = 1; } @@ -4354,16 +4332,17 @@ static int b43_op_start(struct ieee80211_hw *hw) if (err) { if (did_init) b43_wireless_core_exit(dev); + do_rfkill_exit = 1; goto out_mutex_unlock; } } - /* XXX: only do if device doesn't support rfkill irq */ - wiphy_rfkill_start_polling(hw->wiphy); - out_mutex_unlock: mutex_unlock(&wl->mutex); + if (do_rfkill_exit) + b43_rfkill_exit(dev); + return err; } @@ -4372,6 +4351,7 @@ static void b43_op_stop(struct ieee80211_hw *hw) struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; + b43_rfkill_exit(dev); cancel_work_sync(&(wl->beacon_update_trigger)); mutex_lock(&wl->mutex); @@ -4453,7 +4433,6 @@ static const struct ieee80211_ops b43_hw_ops = { .sta_notify = b43_op_sta_notify, .sw_scan_start = b43_op_sw_scan_start_notifier, .sw_scan_complete = b43_op_sw_scan_complete_notifier, - .rfkill_poll = b43_rfkill_poll, }; /* Hard-reset the chip. Do not call this directly. @@ -4756,7 +4735,6 @@ static int b43_wireless_init(struct ssb_device *dev) b43err(NULL, "Could not allocate ieee80211 device\n"); goto out; } - wl = hw_to_b43_wl(hw); /* fill hw info */ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | @@ -4770,8 +4748,7 @@ static int b43_wireless_init(struct ssb_device *dev) BIT(NL80211_IFTYPE_WDS) | BIT(NL80211_IFTYPE_ADHOC); - hw->queues = modparam_qos ? 4 : 1; - wl->mac80211_initially_registered_queues = hw->queues; + hw->queues = b43_modparam_qos ? 4 : 1; hw->max_rates = 2; SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->et1mac)) @@ -4779,7 +4756,9 @@ static int b43_wireless_init(struct ssb_device *dev) else SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); - /* Initialize struct b43_wl */ + /* Get and initialize struct b43_wl */ + wl = hw_to_b43_wl(hw); + memset(wl, 0, sizeof(*wl)); wl->hw = hw; spin_lock_init(&wl->irq_lock); rwlock_init(&wl->tx_lock); @@ -4845,13 +4824,8 @@ static void b43_remove(struct ssb_device *dev) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (wl->current_dev == wldev) { - /* Restore the queues count before unregistering, because firmware detect - * might have modified it. Restoring is important, so the networking - * stack can properly free resources. */ - wl->hw->queues = wl->mac80211_initially_registered_queues; + if (wl->current_dev == wldev) ieee80211_unregister_hw(wl->hw); - } b43_one_core_detach(dev); @@ -4946,7 +4920,7 @@ static struct ssb_driver b43_ssb_driver = { static void b43_print_driverinfo(void) { const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", - *feat_leds = ""; + *feat_leds = "", *feat_rfkill = ""; #ifdef CONFIG_B43_PCI_AUTOSELECT feat_pci = "P"; @@ -4959,12 +4933,15 @@ static void b43_print_driverinfo(void) #endif #ifdef CONFIG_B43_LEDS feat_leds = "L"; +#endif +#ifdef CONFIG_B43_RFKILL + feat_rfkill = "R"; #endif printk(KERN_INFO "Broadcom 43xx driver loaded " - "[ Features: %s%s%s%s, Firmware-ID: " + "[ Features: %s%s%s%s%s, Firmware-ID: " B43_SUPPORTED_FIRMWARE_ID " ]\n", feat_pci, feat_pcmcia, feat_nphy, - feat_leds); + feat_leds, feat_rfkill); } static int __init b43_init(void) diff --git a/trunk/drivers/net/wireless/b43/main.h b/trunk/drivers/net/wireless/b43/main.h index 950fb1b0546d..40abcf5d1b43 100644 --- a/trunk/drivers/net/wireless/b43/main.h +++ b/trunk/drivers/net/wireless/b43/main.h @@ -39,6 +39,7 @@ #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) +extern int b43_modparam_qos; extern int b43_modparam_verbose; /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if diff --git a/trunk/drivers/net/wireless/b43/phy_a.c b/trunk/drivers/net/wireless/b43/phy_a.c index 816e028a2620..c836c077d51d 100644 --- a/trunk/drivers/net/wireless/b43/phy_a.c +++ b/trunk/drivers/net/wireless/b43/phy_a.c @@ -480,11 +480,11 @@ static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev) } static void b43_aphy_op_software_rfkill(struct b43_wldev *dev, - bool blocked) + enum rfkill_state state) { struct b43_phy *phy = &dev->phy; - if (!blocked) { + if (state == RFKILL_STATE_UNBLOCKED) { if (phy->radio_on) return; b43_radio_write16(dev, 0x0004, 0x00C0); diff --git a/trunk/drivers/net/wireless/b43/phy_common.c b/trunk/drivers/net/wireless/b43/phy_common.c index 6d241622210e..e176b6e0d9cf 100644 --- a/trunk/drivers/net/wireless/b43/phy_common.c +++ b/trunk/drivers/net/wireless/b43/phy_common.c @@ -84,7 +84,7 @@ int b43_phy_init(struct b43_wldev *dev) phy->channel = ops->get_default_chan(dev); - ops->software_rfkill(dev, false); + ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED); err = ops->init(dev); if (err) { b43err(dev->wl, "PHY init failed\n"); @@ -104,7 +104,7 @@ int b43_phy_init(struct b43_wldev *dev) if (ops->exit) ops->exit(dev); err_block_rf: - ops->software_rfkill(dev, true); + ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); return err; } @@ -113,7 +113,7 @@ void b43_phy_exit(struct b43_wldev *dev) { const struct b43_phy_operations *ops = dev->phy.ops; - ops->software_rfkill(dev, true); + ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); if (ops->exit) ops->exit(dev); } @@ -295,13 +295,18 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel) return err; } -void b43_software_rfkill(struct b43_wldev *dev, bool blocked) +void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state) { struct b43_phy *phy = &dev->phy; + if (state == RFKILL_STATE_HARD_BLOCKED) { + /* We cannot hardware-block the device */ + state = RFKILL_STATE_SOFT_BLOCKED; + } + b43_mac_suspend(dev); - phy->ops->software_rfkill(dev, blocked); - phy->radio_on = !blocked; + phy->ops->software_rfkill(dev, state); + phy->radio_on = (state == RFKILL_STATE_UNBLOCKED); b43_mac_enable(dev); } diff --git a/trunk/drivers/net/wireless/b43/phy_common.h b/trunk/drivers/net/wireless/b43/phy_common.h index 44cc918e4fc6..b2d99101947b 100644 --- a/trunk/drivers/net/wireless/b43/phy_common.h +++ b/trunk/drivers/net/wireless/b43/phy_common.h @@ -1,7 +1,7 @@ #ifndef LINUX_B43_PHY_COMMON_H_ #define LINUX_B43_PHY_COMMON_H_ -#include +#include struct b43_wldev; @@ -159,7 +159,7 @@ struct b43_phy_operations { /* Radio */ bool (*supports_hwpctl)(struct b43_wldev *dev); - void (*software_rfkill)(struct b43_wldev *dev, bool blocked); + void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state); void (*switch_analog)(struct b43_wldev *dev, bool on); int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel); unsigned int (*get_default_chan)(struct b43_wldev *dev); @@ -364,7 +364,7 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel); /** * b43_software_rfkill - Turn the radio ON or OFF in software. */ -void b43_software_rfkill(struct b43_wldev *dev, bool blocked); +void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state); /** * b43_phy_txpower_check - Check TX power output. diff --git a/trunk/drivers/net/wireless/b43/phy_g.c b/trunk/drivers/net/wireless/b43/phy_g.c index 5300232449f6..e7b98f013b0f 100644 --- a/trunk/drivers/net/wireless/b43/phy_g.c +++ b/trunk/drivers/net/wireless/b43/phy_g.c @@ -2592,7 +2592,7 @@ static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev) } static void b43_gphy_op_software_rfkill(struct b43_wldev *dev, - bool blocked) + enum rfkill_state state) { struct b43_phy *phy = &dev->phy; struct b43_phy_g *gphy = phy->g; @@ -2600,7 +2600,7 @@ static void b43_gphy_op_software_rfkill(struct b43_wldev *dev, might_sleep(); - if (!blocked) { + if (state == RFKILL_STATE_UNBLOCKED) { /* Turn radio ON */ if (phy->radio_on) return; diff --git a/trunk/drivers/net/wireless/b43/phy_lp.c b/trunk/drivers/net/wireless/b43/phy_lp.c index ea0d3a3a6a64..58e319d6b1ed 100644 --- a/trunk/drivers/net/wireless/b43/phy_lp.c +++ b/trunk/drivers/net/wireless/b43/phy_lp.c @@ -488,7 +488,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) } static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, - bool blocked) + enum rfkill_state state) { //TODO } diff --git a/trunk/drivers/net/wireless/b43/phy_n.c b/trunk/drivers/net/wireless/b43/phy_n.c index be7b5604947b..8bcfda5f3f07 100644 --- a/trunk/drivers/net/wireless/b43/phy_n.c +++ b/trunk/drivers/net/wireless/b43/phy_n.c @@ -579,7 +579,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) } static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, - bool blocked) + enum rfkill_state state) {//TODO } diff --git a/trunk/drivers/net/wireless/b43/pio.c b/trunk/drivers/net/wireless/b43/pio.c index 69138e8c1db6..8cd9776752e6 100644 --- a/trunk/drivers/net/wireless/b43/pio.c +++ b/trunk/drivers/net/wireless/b43/pio.c @@ -313,7 +313,7 @@ static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev, { struct b43_pio_txqueue *q; - if (dev->qos_enabled) { + if (b43_modparam_qos) { /* 0 = highest priority */ switch (queue_prio) { default: diff --git a/trunk/drivers/net/wireless/b43/rfkill.c b/trunk/drivers/net/wireless/b43/rfkill.c index 31e55999893f..9e1d00bc24d3 100644 --- a/trunk/drivers/net/wireless/b43/rfkill.c +++ b/trunk/drivers/net/wireless/b43/rfkill.c @@ -22,11 +22,15 @@ */ +#include "rfkill.h" #include "b43.h" +#include "phy_common.h" + +#include /* Returns TRUE, if the radio is enabled in hardware. */ -bool b43_is_hw_radio_enabled(struct b43_wldev *dev) +static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) { if (dev->phy.rev >= 3) { if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) @@ -41,39 +45,165 @@ bool b43_is_hw_radio_enabled(struct b43_wldev *dev) } /* The poll callback for the hardware button. */ -void b43_rfkill_poll(struct ieee80211_hw *hw) +static void b43_rfkill_poll(struct input_polled_dev *poll_dev) { - struct b43_wl *wl = hw_to_b43_wl(hw); - struct b43_wldev *dev = wl->current_dev; - struct ssb_bus *bus = dev->dev->bus; + struct b43_wldev *dev = poll_dev->private; + struct b43_wl *wl = dev->wl; bool enabled; - bool brought_up = false; + bool report_change = 0; mutex_lock(&wl->mutex); if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { - if (ssb_bus_powerup(bus, 0)) { - mutex_unlock(&wl->mutex); - return; - } - ssb_device_enable(dev->dev, 0); - brought_up = true; + mutex_unlock(&wl->mutex); + return; } - enabled = b43_is_hw_radio_enabled(dev); - if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; + report_change = 1; b43info(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); - wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); - if (enabled != dev->phy.radio_on) - b43_software_rfkill(dev, !enabled); } + mutex_unlock(&wl->mutex); - if (brought_up) { - ssb_device_disable(dev->dev, 0); - ssb_bus_may_powerdown(bus); + /* send the radio switch event to the system - note both a key press + * and a release are required */ + if (unlikely(report_change)) { + input_report_key(poll_dev->input, KEY_WLAN, 1); + input_report_key(poll_dev->input, KEY_WLAN, 0); } +} + +/* Called when the RFKILL toggled in software. */ +static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) +{ + struct b43_wldev *dev = data; + struct b43_wl *wl = dev->wl; + int err = -EBUSY; + if (!wl->rfkill.registered) + return 0; + + mutex_lock(&wl->mutex); + if (b43_status(dev) < B43_STAT_INITIALIZED) + goto out_unlock; + err = 0; + switch (state) { + case RFKILL_STATE_UNBLOCKED: + if (!dev->radio_hw_enable) { + /* No luck. We can't toggle the hardware RF-kill + * button from software. */ + err = -EBUSY; + goto out_unlock; + } + if (!dev->phy.radio_on) + b43_software_rfkill(dev, state); + break; + case RFKILL_STATE_SOFT_BLOCKED: + if (dev->phy.radio_on) + b43_software_rfkill(dev, state); + break; + default: + b43warn(wl, "Received unexpected rfkill state %d.\n", state); + break; + } +out_unlock: mutex_unlock(&wl->mutex); + + return err; +} + +char *b43_rfkill_led_name(struct b43_wldev *dev) +{ + struct b43_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return NULL; + return rfkill_get_led_name(rfk->rfkill); +} + +void b43_rfkill_init(struct b43_wldev *dev) +{ + struct b43_wl *wl = dev->wl; + struct b43_rfkill *rfk = &(wl->rfkill); + int err; + + rfk->registered = 0; + + rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); + if (!rfk->rfkill) + goto out_error; + snprintf(rfk->name, sizeof(rfk->name), + "b43-%s", wiphy_name(wl->hw->wiphy)); + rfk->rfkill->name = rfk->name; + rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; + rfk->rfkill->data = dev; + rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle; + + rfk->poll_dev = input_allocate_polled_device(); + if (!rfk->poll_dev) { + rfkill_free(rfk->rfkill); + goto err_freed_rfk; + } + + rfk->poll_dev->private = dev; + rfk->poll_dev->poll = b43_rfkill_poll; + rfk->poll_dev->poll_interval = 1000; /* msecs */ + + rfk->poll_dev->input->name = rfk->name; + rfk->poll_dev->input->id.bustype = BUS_HOST; + rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; + rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); + + err = rfkill_register(rfk->rfkill); + if (err) + goto err_free_polldev; + +#ifdef CONFIG_RFKILL_INPUT_MODULE + /* B43 RF-kill isn't useful without the rfkill-input subsystem. + * Try to load the module. */ + err = request_module("rfkill-input"); + if (err) + b43warn(wl, "Failed to load the rfkill-input module. " + "The built-in radio LED will not work.\n"); +#endif /* CONFIG_RFKILL_INPUT */ + +#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE) + b43warn(wl, "The rfkill-input subsystem is not available. " + "The built-in radio LED will not work.\n"); +#endif + + err = input_register_polled_device(rfk->poll_dev); + if (err) + goto err_unreg_rfk; + + rfk->registered = 1; + + return; +err_unreg_rfk: + rfkill_unregister(rfk->rfkill); +err_free_polldev: + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; +err_freed_rfk: + rfk->rfkill = NULL; +out_error: + rfk->registered = 0; + b43warn(wl, "RF-kill button init failed\n"); +} + +void b43_rfkill_exit(struct b43_wldev *dev) +{ + struct b43_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return; + rfk->registered = 0; + + input_unregister_polled_device(rfk->poll_dev); + rfkill_unregister(rfk->rfkill); + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; + rfk->rfkill = NULL; } diff --git a/trunk/drivers/net/wireless/b43/rfkill.h b/trunk/drivers/net/wireless/b43/rfkill.h index f046c3ca0519..adacf936d815 100644 --- a/trunk/drivers/net/wireless/b43/rfkill.h +++ b/trunk/drivers/net/wireless/b43/rfkill.h @@ -1,11 +1,52 @@ #ifndef B43_RFKILL_H_ #define B43_RFKILL_H_ -struct ieee80211_hw; struct b43_wldev; -void b43_rfkill_poll(struct ieee80211_hw *hw); -bool b43_is_hw_radio_enabled(struct b43_wldev *dev); +#ifdef CONFIG_B43_RFKILL + +#include +#include + + +struct b43_rfkill { + /* The RFKILL subsystem data structure */ + struct rfkill *rfkill; + /* The poll device for the RFKILL input button */ + struct input_polled_dev *poll_dev; + /* Did initialization succeed? Used for freeing. */ + bool registered; + /* The unique name of this rfkill switch */ + char name[sizeof("b43-phy4294967295")]; +}; + +/* The init function returns void, because we are not interested + * in failing the b43 init process when rfkill init failed. */ +void b43_rfkill_init(struct b43_wldev *dev); +void b43_rfkill_exit(struct b43_wldev *dev); + +char * b43_rfkill_led_name(struct b43_wldev *dev); + + +#else /* CONFIG_B43_RFKILL */ +/* No RFKILL support. */ + +struct b43_rfkill { + /* empty */ +}; + +static inline void b43_rfkill_init(struct b43_wldev *dev) +{ +} +static inline void b43_rfkill_exit(struct b43_wldev *dev) +{ +} +static inline char * b43_rfkill_led_name(struct b43_wldev *dev) +{ + return NULL; +} + +#endif /* CONFIG_B43_RFKILL */ #endif /* B43_RFKILL_H_ */ diff --git a/trunk/drivers/net/wireless/b43/xmit.c b/trunk/drivers/net/wireless/b43/xmit.c index 55f36a7254d9..a63d88841df8 100644 --- a/trunk/drivers/net/wireless/b43/xmit.c +++ b/trunk/drivers/net/wireless/b43/xmit.c @@ -118,6 +118,7 @@ u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate) void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, const u16 octets, const u8 bitrate) { + __le32 *data = &(plcp->data); __u8 *raw = plcp->raw; if (b43_is_ofdm_rate(bitrate)) { @@ -126,7 +127,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, d = b43_plcp_get_ratecode_ofdm(bitrate); B43_WARN_ON(octets & 0xF000); d |= (octets << 5); - plcp->data = cpu_to_le32(d); + *data = cpu_to_le32(d); } else { u32 plen; @@ -140,7 +141,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, raw[1] = 0x04; } else raw[1] = 0x04; - plcp->data |= cpu_to_le32(plen << 16); + *data |= cpu_to_le32(plen << 16); raw[0] = b43_plcp_get_ratecode_cck(bitrate); } } diff --git a/trunk/drivers/net/wireless/b43legacy/Kconfig b/trunk/drivers/net/wireless/b43legacy/Kconfig index 94a463478053..d4f628a74bbd 100644 --- a/trunk/drivers/net/wireless/b43legacy/Kconfig +++ b/trunk/drivers/net/wireless/b43legacy/Kconfig @@ -42,6 +42,14 @@ config B43LEGACY_LEDS depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY) default y +# RFKILL support +# This config option automatically enables b43legacy RFKILL support, +# if it's possible. +config B43LEGACY_RFKILL + bool + depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY) + default y + # This config option automatically enables b43 HW-RNG support, # if the HW-RNG core is enabled. config B43LEGACY_HWRNG diff --git a/trunk/drivers/net/wireless/b43legacy/Makefile b/trunk/drivers/net/wireless/b43legacy/Makefile index 227a77e84362..80cdb73bd140 100644 --- a/trunk/drivers/net/wireless/b43legacy/Makefile +++ b/trunk/drivers/net/wireless/b43legacy/Makefile @@ -6,7 +6,7 @@ b43legacy-y += radio.o b43legacy-y += sysfs.o b43legacy-y += xmit.o # b43 RFKILL button support -b43legacy-y += rfkill.o +b43legacy-$(CONFIG_B43LEGACY_RFKILL) += rfkill.o # b43legacy LED support b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o # b43legacy debugging diff --git a/trunk/drivers/net/wireless/b43legacy/b43legacy.h b/trunk/drivers/net/wireless/b43legacy/b43legacy.h index 77fda148ac46..19a4b0bc0d87 100644 --- a/trunk/drivers/net/wireless/b43legacy/b43legacy.h +++ b/trunk/drivers/net/wireless/b43legacy/b43legacy.h @@ -602,6 +602,9 @@ struct b43legacy_wl { char rng_name[30 + 1]; #endif + /* The RF-kill button */ + struct b43legacy_rfkill rfkill; + /* List of all wireless devices on this chip */ struct list_head devlist; u8 nr_devs; diff --git a/trunk/drivers/net/wireless/b43legacy/leds.c b/trunk/drivers/net/wireless/b43legacy/leds.c index 37e9be893560..3ea55b18c700 100644 --- a/trunk/drivers/net/wireless/b43legacy/leds.c +++ b/trunk/drivers/net/wireless/b43legacy/leds.c @@ -28,7 +28,6 @@ #include "b43legacy.h" #include "leds.h" -#include "rfkill.h" static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, @@ -87,8 +86,7 @@ static void b43legacy_led_brightness_set(struct led_classdev *led_dev, static int b43legacy_register_led(struct b43legacy_wldev *dev, struct b43legacy_led *led, - const char *name, - const char *default_trigger, + const char *name, char *default_trigger, u8 led_index, bool activelow) { int err; @@ -165,10 +163,10 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev, snprintf(name, sizeof(name), "b43legacy-%s::radio", wiphy_name(hw->wiphy)); b43legacy_register_led(dev, &dev->led_radio, name, - ieee80211_get_radio_led_name(hw), + b43legacy_rfkill_led_name(dev), led_index, activelow); - /* Sync the RF-kill LED state with radio and switch states. */ - if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev)) + /* Sync the RF-kill LED state with the switch state. */ + if (dev->radio_hw_enable) b43legacy_led_turn_on(dev, led_index, activelow); break; case B43legacy_LED_WEIRD: diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index e5136fb65ddd..f6f3fbf0a2f4 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -3431,6 +3431,11 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) struct b43legacy_wldev *dev = wl->current_dev; int did_init = 0; int err = 0; + bool do_rfkill_exit = 0; + + /* First register RFkill. + * LEDs that are registered later depend on it. */ + b43legacy_rfkill_init(dev); /* Kill all old instance specific information to make sure * the card won't use it in the short timeframe between start @@ -3446,8 +3451,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { err = b43legacy_wireless_core_init(dev); - if (err) + if (err) { + do_rfkill_exit = 1; goto out_mutex_unlock; + } did_init = 1; } @@ -3456,15 +3463,17 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) if (err) { if (did_init) b43legacy_wireless_core_exit(dev); + do_rfkill_exit = 1; goto out_mutex_unlock; } } - wiphy_rfkill_start_polling(hw->wiphy); - out_mutex_unlock: mutex_unlock(&wl->mutex); + if (do_rfkill_exit) + b43legacy_rfkill_exit(dev); + return err; } @@ -3473,6 +3482,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; + b43legacy_rfkill_exit(dev); cancel_work_sync(&(wl->beacon_update_trigger)); mutex_lock(&wl->mutex); @@ -3508,7 +3518,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = { .start = b43legacy_op_start, .stop = b43legacy_op_stop, .set_tim = b43legacy_op_beacon_set_tim, - .rfkill_poll = b43legacy_rfkill_poll, }; /* Hard-reset the chip. Do not call this directly. diff --git a/trunk/drivers/net/wireless/b43legacy/rfkill.c b/trunk/drivers/net/wireless/b43legacy/rfkill.c index 8783022db11e..4b0c7d27a51f 100644 --- a/trunk/drivers/net/wireless/b43legacy/rfkill.c +++ b/trunk/drivers/net/wireless/b43legacy/rfkill.c @@ -22,12 +22,15 @@ */ +#include "rfkill.h" #include "radio.h" #include "b43legacy.h" +#include + /* Returns TRUE, if the radio is enabled in hardware. */ -bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) +static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) { if (dev->phy.rev >= 3) { if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) @@ -42,43 +45,164 @@ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) } /* The poll callback for the hardware button. */ -void b43legacy_rfkill_poll(struct ieee80211_hw *hw) +static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) { - struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); - struct b43legacy_wldev *dev = wl->current_dev; - struct ssb_bus *bus = dev->dev->bus; + struct b43legacy_wldev *dev = poll_dev->private; + struct b43legacy_wl *wl = dev->wl; bool enabled; - bool brought_up = false; + bool report_change = 0; mutex_lock(&wl->mutex); if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { - if (ssb_bus_powerup(bus, 0)) { - mutex_unlock(&wl->mutex); - return; - } - ssb_device_enable(dev->dev, 0); - brought_up = true; + mutex_unlock(&wl->mutex); + return; } - enabled = b43legacy_is_hw_radio_enabled(dev); - if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; + report_change = 1; b43legacyinfo(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); - wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); - if (enabled != dev->phy.radio_on) { - if (enabled) - b43legacy_radio_turn_on(dev); - else - b43legacy_radio_turn_off(dev, 0); - } } + mutex_unlock(&wl->mutex); + + /* send the radio switch event to the system - note both a key press + * and a release are required */ + if (unlikely(report_change)) { + input_report_key(poll_dev->input, KEY_WLAN, 1); + input_report_key(poll_dev->input, KEY_WLAN, 0); + } +} + +/* Called when the RFKILL toggled in software. + * This is called without locking. */ +static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) +{ + struct b43legacy_wldev *dev = data; + struct b43legacy_wl *wl = dev->wl; + int err = -EBUSY; + + if (!wl->rfkill.registered) + return 0; - if (brought_up) { - ssb_device_disable(dev->dev, 0); - ssb_bus_may_powerdown(bus); + mutex_lock(&wl->mutex); + if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) + goto out_unlock; + err = 0; + switch (state) { + case RFKILL_STATE_UNBLOCKED: + if (!dev->radio_hw_enable) { + /* No luck. We can't toggle the hardware RF-kill + * button from software. */ + err = -EBUSY; + goto out_unlock; + } + if (!dev->phy.radio_on) + b43legacy_radio_turn_on(dev); + break; + case RFKILL_STATE_SOFT_BLOCKED: + if (dev->phy.radio_on) + b43legacy_radio_turn_off(dev, 0); + break; + default: + b43legacywarn(wl, "Received unexpected rfkill state %d.\n", + state); + break; } +out_unlock: mutex_unlock(&wl->mutex); + + return err; } + +char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) +{ + struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return NULL; + return rfkill_get_led_name(rfk->rfkill); +} + +void b43legacy_rfkill_init(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + struct b43legacy_rfkill *rfk = &(wl->rfkill); + int err; + + rfk->registered = 0; + + rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); + if (!rfk->rfkill) + goto out_error; + snprintf(rfk->name, sizeof(rfk->name), + "b43legacy-%s", wiphy_name(wl->hw->wiphy)); + rfk->rfkill->name = rfk->name; + rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; + rfk->rfkill->data = dev; + rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; + + rfk->poll_dev = input_allocate_polled_device(); + if (!rfk->poll_dev) { + rfkill_free(rfk->rfkill); + goto err_freed_rfk; + } + + rfk->poll_dev->private = dev; + rfk->poll_dev->poll = b43legacy_rfkill_poll; + rfk->poll_dev->poll_interval = 1000; /* msecs */ + + rfk->poll_dev->input->name = rfk->name; + rfk->poll_dev->input->id.bustype = BUS_HOST; + rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; + rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); + + err = rfkill_register(rfk->rfkill); + if (err) + goto err_free_polldev; + +#ifdef CONFIG_RFKILL_INPUT_MODULE + /* B43legacy RF-kill isn't useful without the rfkill-input subsystem. + * Try to load the module. */ + err = request_module("rfkill-input"); + if (err) + b43legacywarn(wl, "Failed to load the rfkill-input module." + "The built-in radio LED will not work.\n"); +#endif /* CONFIG_RFKILL_INPUT */ + + err = input_register_polled_device(rfk->poll_dev); + if (err) + goto err_unreg_rfk; + + rfk->registered = 1; + + return; +err_unreg_rfk: + rfkill_unregister(rfk->rfkill); +err_free_polldev: + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; +err_freed_rfk: + rfk->rfkill = NULL; +out_error: + rfk->registered = 0; + b43legacywarn(wl, "RF-kill button init failed\n"); +} + +void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) +{ + struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return; + rfk->registered = 0; + + input_unregister_polled_device(rfk->poll_dev); + rfkill_unregister(rfk->rfkill); + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; + rfk->rfkill = NULL; +} + diff --git a/trunk/drivers/net/wireless/b43legacy/rfkill.h b/trunk/drivers/net/wireless/b43legacy/rfkill.h index 75585571c544..11150a8032f0 100644 --- a/trunk/drivers/net/wireless/b43legacy/rfkill.h +++ b/trunk/drivers/net/wireless/b43legacy/rfkill.h @@ -1,11 +1,59 @@ #ifndef B43legacy_RFKILL_H_ #define B43legacy_RFKILL_H_ -struct ieee80211_hw; struct b43legacy_wldev; -void b43legacy_rfkill_poll(struct ieee80211_hw *hw); +#ifdef CONFIG_B43LEGACY_RFKILL -bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev); +#include +#include +#include + + + +struct b43legacy_rfkill { + /* The RFKILL subsystem data structure */ + struct rfkill *rfkill; + /* The poll device for the RFKILL input button */ + struct input_polled_dev *poll_dev; + /* Did initialization succeed? Used for freeing. */ + bool registered; + /* The unique name of this rfkill switch */ + char name[sizeof("b43legacy-phy4294967295")]; +}; + +/* The init function returns void, because we are not interested + * in failing the b43 init process when rfkill init failed. */ +void b43legacy_rfkill_init(struct b43legacy_wldev *dev); +void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); + +char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); + + +#else /* CONFIG_B43LEGACY_RFKILL */ +/* No RFKILL support. */ + +struct b43legacy_rfkill { + /* empty */ +}; + +static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) +{ +} +static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) +{ + return NULL; +} + +#endif /* CONFIG_B43LEGACY_RFKILL */ #endif /* B43legacy_RFKILL_H_ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/Kconfig b/trunk/drivers/net/wireless/iwlwifi/Kconfig index 029ccb6bdbaa..8304f6406a17 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Kconfig +++ b/trunk/drivers/net/wireless/iwlwifi/Kconfig @@ -5,11 +5,16 @@ config IWLWIFI select FW_LOADER select MAC80211_LEDS if IWLWIFI_LEDS select LEDS_CLASS if IWLWIFI_LEDS + select RFKILL if IWLWIFI_RFKILL config IWLWIFI_LEDS bool "Enable LED support in iwlagn and iwl3945 drivers" depends on IWLWIFI +config IWLWIFI_RFKILL + bool "Enable RF kill support in iwlagn and iwl3945 drivers" + depends on IWLWIFI + config IWLWIFI_SPECTRUM_MEASUREMENT bool "Enable Spectrum Measurement in iwlagn driver" depends on IWLWIFI diff --git a/trunk/drivers/net/wireless/iwlwifi/Makefile b/trunk/drivers/net/wireless/iwlwifi/Makefile index 1d4e0a226fd4..d79d97ad61a5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Makefile +++ b/trunk/drivers/net/wireless/iwlwifi/Makefile @@ -4,6 +4,7 @@ iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o iwlcore-objs += iwl-scan.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o +iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o obj-$(CONFIG_IWLAGN) += iwlagn.o diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/trunk/drivers/net/wireless/iwlwifi/iwl-3945-led.c index 225e5f889346..bd7e520d98c2 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945-led.c @@ -167,6 +167,10 @@ static int iwl3945_led_disassociate(struct iwl_priv *priv, int led_id) IWL_DEBUG_LED(priv, "Disassociated\n"); priv->allow_blinking = 0; + if (iwl_is_rfkill(priv)) + iwl3945_led_off(priv, led_id); + else + iwl3945_led_on(priv, led_id); return 0; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 5eb538d18a80..814afaf6d10b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -38,7 +38,6 @@ #include "iwl-commands.h" #include "iwl-3945.h" -#include "iwl-sta.h" #define RS_NAME "iwl-3945-rs" @@ -715,13 +714,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && !rs_sta->ibss_sta_added) { - u8 sta_id = iwl_find_station(priv, hdr->addr1); + u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n", hdr->addr1); - sta_id = iwl_add_station(priv, hdr->addr1, false, - CMD_ASYNC, NULL); + sta_id = iwl3945_add_station(priv, + hdr->addr1, 0, CMD_ASYNC, NULL); } if (sta_id != IWL_INVALID_STATION) rs_sta->ibss_sta_added = 1; @@ -976,7 +975,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) rcu_read_lock(); - sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr); + sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr); if (!sta) { rcu_read_unlock(); return; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c index 46288e724889..fd65e1c3e055 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -769,6 +769,35 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) return ; } +u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr) +{ + int i, start = IWL_AP_ID; + int ret = IWL_INVALID_STATION; + unsigned long flags; + + if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) || + (priv->iw_mode == NL80211_IFTYPE_AP)) + start = IWL_STA_ID; + + if (is_broadcast_ether_addr(addr)) + return priv->hw_params.bcast_sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + for (i = start; i < priv->hw_params.max_stations; i++) + if ((priv->stations_39[i].used) && + (!compare_ether_addr + (priv->stations_39[i].sta.sta.addr, addr))) { + ret = i; + goto out; + } + + IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n", + addr, priv->num_stations); + out: + spin_unlock_irqrestore(&priv->sta_lock, flags); + return ret; +} + /** * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: * @@ -846,13 +875,13 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) { unsigned long flags_spin; - struct iwl_station_entry *station; + struct iwl3945_station_entry *station; if (sta_id == IWL_INVALID_STATION) return IWL_INVALID_STATION; spin_lock_irqsave(&priv->sta_lock, flags_spin); - station = &priv->stations[sta_id]; + station = &priv->stations_39[sta_id]; station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; station->sta.rate_n_flags = cpu_to_le16(tx_rate); @@ -860,7 +889,8 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - iwl_send_add_sta(priv, &station->sta, flags); + iwl_send_add_sta(priv, + (struct iwl_addsta_cmd *)&station->sta, flags); IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", sta_id, tx_rate); return sta_id; @@ -1999,7 +2029,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ @@ -2010,7 +2040,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) } /* Add the broadcast address so we can send broadcast frames */ - if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) == + if (priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL) == IWL_INVALID_STATION) { IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); return -EIO; @@ -2020,8 +2050,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) * add the IWL_AP_ID to the station rate table */ if (iwl_is_associated(priv) && (priv->iw_mode == NL80211_IFTYPE_STATION)) - if (iwl_add_station(priv, priv->active_rxon.bssid_addr, - true, CMD_SYNC, NULL) == IWL_INVALID_STATION) { + if (priv->cfg->ops->smgmt->add_station(priv, + priv->active_rxon.bssid_addr, 1, 0, NULL) + == IWL_INVALID_STATION) { IWL_ERR(priv, "Error adding AP address for transmit\n"); return -EIO; } @@ -2435,25 +2466,13 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len) } } - static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) { - struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data; - addsta->mode = cmd->mode; - memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); - memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); - addsta->station_flags = cmd->station_flags; - addsta->station_flags_msk = cmd->station_flags_msk; - addsta->tid_disable_tx = cpu_to_le16(0); - addsta->rate_n_flags = cmd->rate_n_flags; - addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; - addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; - addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; - - return (u16)sizeof(struct iwl3945_addsta_cmd); + u16 size = (u16)sizeof(struct iwl3945_addsta_cmd); + memcpy(data, cmd, size); + return size; } - /** * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table */ @@ -2823,6 +2842,15 @@ static struct iwl_lib_ops iwl3945_lib = { .config_ap = iwl3945_config_ap, }; +static struct iwl_station_mgmt_ops iwl3945_station_mgmt = { + .add_station = iwl3945_add_station, +#if 0 + .remove_station = iwl3945_remove_station, +#endif + .find_station = iwl3945_hw_find_station, + .clear_station_table = iwl3945_clear_stations_table, +}; + static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { .get_hcmd_size = iwl3945_get_hcmd_size, .build_addsta_hcmd = iwl3945_build_addsta_hcmd, @@ -2832,6 +2860,7 @@ static struct iwl_ops iwl3945_ops = { .lib = &iwl3945_lib, .hcmd = &iwl3945_hcmd, .utils = &iwl3945_hcmd_utils, + .smgmt = &iwl3945_station_mgmt, }; static struct iwl_cfg iwl3945_bg_cfg = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h index fbb3a573463e..da87528f355f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -36,6 +36,10 @@ #include #include +/*used for rfkill*/ +#include +#include + /* Hardware specific file defines the PCI IDs table for that hardware module */ extern struct pci_device_id iwl3945_hw_card_ids[]; @@ -151,6 +155,7 @@ struct iwl3945_frame { #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ #define STATUS_INT_ENABLED 2 #define STATUS_RF_KILL_HW 3 +#define STATUS_RF_KILL_SW 4 #define STATUS_INIT 5 #define STATUS_ALIVE 6 #define STATUS_READY 7 @@ -197,6 +202,12 @@ struct iwl3945_ibss_seq { * for use by iwl-*.c * *****************************************************************************/ +struct iwl3945_addsta_cmd; +extern int iwl3945_send_add_station(struct iwl_priv *priv, + struct iwl3945_addsta_cmd *sta, u8 flags); +extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid, + int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); +extern void iwl3945_clear_stations_table(struct iwl_priv *priv); extern int iwl3945_power_init_handle(struct iwl_priv *priv); extern int iwl3945_eeprom_init(struct iwl_priv *priv); extern int iwl3945_calc_db_from_ratio(int sig_ratio); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c index 8f3d4bc6a03f..a0b29411a4b3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2221,6 +2221,13 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->txpower_work); } +static struct iwl_station_mgmt_ops iwl4965_station_mgmt = { + .add_station = iwl_add_station_flags, + .remove_station = iwl_remove_station, + .find_station = iwl_find_station, + .clear_station_table = iwl_clear_stations_table, +}; + static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, .commit_rxon = iwl_commit_rxon, @@ -2290,6 +2297,7 @@ static struct iwl_ops iwl4965_ops = { .lib = &iwl4965_lib, .hcmd = &iwl4965_hcmd, .utils = &iwl4965_hcmd_utils, + .smgmt = &iwl4965_station_mgmt, }; struct iwl_cfg iwl4965_agn_cfg = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index b3c648ce8c7b..ab29aab6b2d5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -651,7 +651,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv) goto restart; } - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); ret = priv->cfg->ops->lib->alive_notify(priv); if (ret) { IWL_WARN(priv, @@ -1049,10 +1049,7 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) { u16 size = (u16)sizeof(struct iwl_addsta_cmd); - struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data; - memcpy(addsta, cmd, size); - /* resrved in 5000 */ - addsta->rate_n_flags = cpu_to_le16(0); + memcpy(data, cmd, size); return size; } @@ -1426,6 +1423,13 @@ int iwl5000_calc_rssi(struct iwl_priv *priv, return max_rssi - agc - IWL49_RSSI_OFFSET; } +struct iwl_station_mgmt_ops iwl5000_station_mgmt = { + .add_station = iwl_add_station_flags, + .remove_station = iwl_remove_station, + .find_station = iwl_find_station, + .clear_station_table = iwl_clear_stations_table, +}; + struct iwl_hcmd_ops iwl5000_hcmd = { .rxon_assoc = iwl5000_send_rxon_assoc, .commit_rxon = iwl_commit_rxon, @@ -1545,12 +1549,14 @@ struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, .hcmd = &iwl5000_hcmd, .utils = &iwl5000_hcmd_utils, + .smgmt = &iwl5000_station_mgmt, }; static struct iwl_ops iwl5150_ops = { .lib = &iwl5150_lib, .hcmd = &iwl5000_hcmd, .utils = &iwl5000_hcmd_utils, + .smgmt = &iwl5000_station_mgmt, }; struct iwl_mod_params iwl50_mod_params = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index bd438d8acf55..7236382aeaa6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -72,6 +72,7 @@ static struct iwl_ops iwl6000_ops = { .lib = &iwl5000_lib, .hcmd = &iwl5000_hcmd, .utils = &iwl6000_hcmd_utils, + .smgmt = &iwl5000_station_mgmt, }; struct iwl_cfg iwl6000_2ag_cfg = { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index ff20e5048a55..23a58b00f180 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2502,13 +2502,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && !lq_sta->ibss_sta_added) { - u8 sta_id = iwl_find_station(priv, hdr->addr1); + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, + hdr->addr1); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", hdr->addr1); - sta_id = iwl_add_station(priv, hdr->addr1, - false, CMD_ASYNC, NULL); + sta_id = priv->cfg->ops->smgmt->add_station(priv, + hdr->addr1, 0, + CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { lq_sta->lq.sta_id = sta_id; @@ -2596,7 +2598,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, lq_sta->ibss_sta_added = 0; if (priv->iw_mode == NL80211_IFTYPE_AP) { - u8 sta_id = iwl_find_station(priv, + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, sta->addr); /* for IBSS the call are from tasklet */ @@ -2604,8 +2606,9 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr); - sta_id = iwl_add_station(priv, sta->addr, false, - CMD_ASYNC, NULL); + sta_id = priv->cfg->ops->smgmt->add_station(priv, + sta->addr, 0, + CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { lq_sta->lq.sta_id = sta_id; @@ -2787,10 +2790,9 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv, repeat_rate--; } - lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX; - lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; - lq_cmd->agg_params.agg_time_limit = - cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); + lq_cmd->agg_params.agg_frame_cnt_limit = 64; + lq_cmd->agg_params.agg_dis_start_th = 3; + lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000); } static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index a5637c4aa85d..0a5507cbeb3f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -188,7 +188,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); } - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); priv->start_calib = 0; @@ -737,13 +737,19 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, clear_bit(STATUS_RF_KILL_HW, &priv->status); + if (flags & SW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_SW, &priv->status); + else + clear_bit(STATUS_RF_KILL_SW, &priv->status); + if (!(flags & RXON_CARD_DISABLED)) iwl_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->status))) - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)) || + (test_bit(STATUS_RF_KILL_SW, &status) != + test_bit(STATUS_RF_KILL_SW, &priv->status))) + queue_work(priv->workqueue, &priv->rf_kill); else wake_up_interruptible(&priv->wait_command_queue); } @@ -1039,7 +1045,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) set_bit(STATUS_RF_KILL_HW, &priv->status); else clear_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); + queue_work(priv->workqueue, &priv->rf_kill); } handled |= CSR_INT_BIT_RF_KILL; @@ -1212,7 +1218,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) set_bit(STATUS_RF_KILL_HW, &priv->status); else clear_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); + queue_work(priv->workqueue, &priv->rf_kill); } handled |= CSR_INT_BIT_RF_KILL; @@ -1611,7 +1617,7 @@ static void iwl_alive_start(struct iwl_priv *priv) goto restart; } - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); ret = priv->cfg->ops->lib->alive_notify(priv); if (ret) { IWL_WARN(priv, @@ -1697,7 +1703,7 @@ static void __iwl_down(struct iwl_priv *priv) iwl_leds_unregister(priv); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); @@ -1720,10 +1726,12 @@ static void __iwl_down(struct iwl_priv *priv) ieee80211_stop_queues(priv->hw); /* If we have not previously called iwl_init() then - * clear all bits but the RF Kill bit and return */ + * clear all bits but the RF Kill bits and return */ if (!iwl_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_EXIT_PENDING, &priv->status) << @@ -1732,9 +1740,11 @@ static void __iwl_down(struct iwl_priv *priv) } /* ...otherwise clear out all the status bits but the RF Kill - * bit and continue taking the NIC down. */ + * bits and continue taking the NIC down. */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_FW_ERROR, &priv->status) << @@ -1856,10 +1866,9 @@ static int __iwl_up(struct iwl_priv *priv) set_bit(STATUS_RF_KILL_HW, &priv->status); if (iwl_is_rfkill(priv)) { - wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); - iwl_enable_interrupts(priv); - IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); + IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n", + test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); return 0; } @@ -1878,6 +1887,8 @@ static int __iwl_up(struct iwl_priv *priv) /* clear (again), then enable host interrupts */ iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + /* enable dram interrupt */ + iwl_reset_ict(priv); iwl_enable_interrupts(priv); /* really make sure rfkill handshake bits are cleared */ @@ -1892,7 +1903,7 @@ static int __iwl_up(struct iwl_priv *priv) for (i = 0; i < MAX_HW_RESTARTS; i++) { - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* load bootstrap state machine, * load bootstrap program into processor's memory, @@ -1951,9 +1962,6 @@ static void iwl_bg_alive_start(struct work_struct *data) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - /* enable dram interrupt */ - iwl_reset_ict(priv); - mutex_lock(&priv->mutex); iwl_alive_start(priv); mutex_unlock(&priv->mutex); @@ -1992,6 +2000,7 @@ static void iwl_bg_up(struct work_struct *data) mutex_lock(&priv->mutex); __iwl_up(priv); mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); } static void iwl_bg_restart(struct work_struct *data) @@ -2169,6 +2178,8 @@ static int iwl_mac_start(struct ieee80211_hw *hw) mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); + if (ret) return ret; @@ -2337,7 +2348,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } addr = sta ? sta->addr : iwl_bcast_addr; - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", addr); @@ -2763,6 +2774,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->up, iwl_bg_up); INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); + INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); @@ -3033,8 +3045,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) else set_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + err = iwl_rfkill_init(priv); + if (err) + IWL_ERR(priv, "Unable to initialize RFKILL system. " + "Ignoring error: %d\n", err); + else + iwl_rfkill_set_hw_state(priv); iwl_power_initialize(priv); return 0; @@ -3098,13 +3114,14 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_synchronize_irq(priv); + iwl_rfkill_unregister(priv); iwl_dealloc_ucode_pci(priv); if (priv->rxq.bd) iwl_rx_queue_free(priv, &priv->rxq); iwl_hw_txq_ctx_free(priv); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); iwl_eeprom_free(priv); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h index c87033bf3ad2..e581dc323f0a 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -1067,7 +1067,7 @@ struct iwl_addsta_cmd { * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ __le16 tid_disable_tx; - __le16 rate_n_flags; /* 3945 only */ + __le16 reserved1; /* TID for which to add block-ack support. * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ @@ -1913,18 +1913,6 @@ struct iwl_link_qual_general_params { u8 start_rate_index[LINK_QUAL_AC_NUM]; } __attribute__ ((packed)); -#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ -#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535) -#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0) - -#define LINK_QUAL_AGG_DISABLE_START_DEF (3) -#define LINK_QUAL_AGG_DISABLE_START_MAX (255) -#define LINK_QUAL_AGG_DISABLE_START_MIN (0) - -#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31) -#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (64) -#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) - /** * struct iwl_link_qual_agg_params * diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index f9d16ca5b3d9..e93ddb74457e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -36,6 +36,7 @@ #include "iwl-debug.h" #include "iwl-core.h" #include "iwl-io.h" +#include "iwl-rfkill.h" #include "iwl-power.h" #include "iwl-sta.h" #include "iwl-helpers.h" @@ -1388,7 +1389,7 @@ int iwl_init_drv(struct iwl_priv *priv) mutex_init(&priv->mutex); /* Clear the driver's (not device's) station table */ - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); priv->data_retry_limit = -1; priv->ieee_channels = NULL; @@ -1703,9 +1704,8 @@ static irqreturn_t iwl_isr(int irq, void *data) { struct iwl_priv *priv = data; u32 inta, inta_mask; -#ifdef CONFIG_IWLWIFI_DEBUG u32 inta_fh; -#endif + if (!priv) return IRQ_NONE; @@ -2210,6 +2210,126 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) } EXPORT_SYMBOL(iwl_send_card_state); +void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) +{ + unsigned long flags; + + if (test_bit(STATUS_RF_KILL_SW, &priv->status)) + return; + + IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n"); + + iwl_scan_cancel(priv); + /* FIXME: This is a workaround for AP */ + if (priv->iw_mode != NL80211_IFTYPE_AP) { + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_SW_BIT_RFKILL); + spin_unlock_irqrestore(&priv->lock, flags); + /* call the host command only if no hw rf-kill set */ + if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && + iwl_is_ready(priv)) + iwl_send_card_state(priv, + CARD_STATE_CMD_DISABLE, 0); + set_bit(STATUS_RF_KILL_SW, &priv->status); + /* make sure mac80211 stop sending Tx frame */ + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + } +} +EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio); + +int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) +{ + unsigned long flags; + + if (!test_bit(STATUS_RF_KILL_SW, &priv->status)) + return 0; + + IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n"); + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + + /* If the driver is up it will receive CARD_STATE_NOTIFICATION + * notification where it will clear SW rfkill status. + * Setting it here would break the handler. Only if the + * interface is down we can set here since we don't + * receive any further notification. + */ + if (!priv->is_open) + clear_bit(STATUS_RF_KILL_SW, &priv->status); + spin_unlock_irqrestore(&priv->lock, flags); + + /* wake up ucode */ + msleep(10); + + iwl_read32(priv, CSR_UCODE_DRV_GP1); + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); + + if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { + IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " + "disabled by HW switch\n"); + return 0; + } + + /* when driver is up while rfkill is on, it wont receive + * any CARD_STATE_NOTIFICATION notifications so we have to + * restart it in here + */ + if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) { + clear_bit(STATUS_RF_KILL_SW, &priv->status); + if (!iwl_is_rfkill(priv)) + queue_work(priv->workqueue, &priv->up); + } + + /* If the driver is already loaded, it will receive + * CARD_STATE_NOTIFICATION notifications and the handler will + * call restart to reload the driver. + */ + return 1; +} +EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); + +void iwl_bg_rf_kill(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); + + wake_up_interruptible(&priv->wait_command_queue); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + + if (!iwl_is_rfkill(priv)) { + IWL_DEBUG_RF_KILL(priv, + "HW and/or SW RF Kill no longer active, restarting " + "device\n"); + if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && + priv->is_open) + queue_work(priv->workqueue, &priv->restart); + } else { + /* make sure mac80211 stop sending Tx frame */ + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + + if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) + IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " + "disabled by SW switch\n"); + else + IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n" + "Kill switch must be turned off for " + "wireless networking to work.\n"); + } + mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); +} +EXPORT_SYMBOL(iwl_bg_rf_kill); + void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -2559,12 +2679,19 @@ int iwl_set_mode(struct iwl_priv *priv, int mode) memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* dont commit rxon if rf-kill is on*/ if (!iwl_is_ready_rf(priv)) return -EAGAIN; + cancel_delayed_work(&priv->scan_check); + if (iwl_scan_cancel_timeout(priv, 100)) { + IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); + IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); + return -EAGAIN; + } + iwlcore_commit_rxon(priv); return 0; @@ -2728,6 +2855,23 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv); + if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { + if (conf->radio_enabled && + iwl_radio_kill_sw_enable_radio(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " + "waiting for uCode\n"); + goto out; + } + + if (!conf->radio_enabled) + iwl_radio_kill_sw_disable_radio(priv); + } + + if (!conf->radio_enabled) { + IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); + goto out; + } + if (!iwl_is_ready(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); goto out; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index dabf663e36e5..87df1b767941 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -83,6 +83,15 @@ struct iwl_cmd; #define IWL_SKU_A 0x2 #define IWL_SKU_N 0x8 +struct iwl_station_mgmt_ops { + u8 (*add_station)(struct iwl_priv *priv, const u8 *addr, + int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); + int (*remove_station)(struct iwl_priv *priv, const u8 *addr, + int is_ap); + u8 (*find_station)(struct iwl_priv *priv, const u8 *addr); + void (*clear_station_table)(struct iwl_priv *priv); +}; + struct iwl_hcmd_ops { int (*rxon_assoc)(struct iwl_priv *priv); int (*commit_rxon)(struct iwl_priv *priv); @@ -174,6 +183,7 @@ struct iwl_ops { const struct iwl_lib_ops *lib; const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; + const struct iwl_station_mgmt_ops *smgmt; }; struct iwl_mod_params { @@ -182,7 +192,7 @@ struct iwl_mod_params { int disable_hw_scan; /* def: 0 = use h/w scan */ int num_of_queues; /* def: HW dependent */ int num_of_ampdu_queues;/* def: HW dependent */ - int disable_11n; /* def: 0 = 11n capabilities enabled */ + int disable_11n; /* def: 0 = disable 11n capabilities */ int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ int antenna; /* def: 0 = both antennas (use diversity) */ int restart_fw; /* def: 1 = restart firmware */ @@ -348,6 +358,14 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); ****************************************************/ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); +/***************************************************** + * RF -Kill - here and not in iwl-rfkill.h to be available when + * RF-kill subsystem is not compiled. + ****************************************************/ +void iwl_bg_rf_kill(struct work_struct *work); +void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); +int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); + /******************************************************************************* * Rate ******************************************************************************/ @@ -490,6 +508,7 @@ void iwlcore_free_geos(struct iwl_priv *priv); #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ #define STATUS_INT_ENABLED 2 #define STATUS_RF_KILL_HW 3 +#define STATUS_RF_KILL_SW 4 #define STATUS_INIT 5 #define STATUS_ALIVE 6 #define STATUS_READY 7 @@ -524,6 +543,11 @@ static inline int iwl_is_init(struct iwl_priv *priv) return test_bit(STATUS_INIT, &priv->status); } +static inline int iwl_is_rfkill_sw(struct iwl_priv *priv) +{ + return test_bit(STATUS_RF_KILL_SW, &priv->status); +} + static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) { return test_bit(STATUS_RF_KILL_HW, &priv->status); @@ -531,7 +555,7 @@ static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) static inline int iwl_is_rfkill(struct iwl_priv *priv) { - return iwl_is_rfkill_hw(priv); + return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv); } static inline int iwl_is_ready_rf(struct iwl_priv *priv) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 11e08c068917..af70229144b3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -449,6 +449,8 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, test_bit(STATUS_INT_ENABLED, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", test_bit(STATUS_RF_KILL_HW, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n", + test_bit(STATUS_RF_KILL_SW, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", test_bit(STATUS_INIT, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h index e2d620f0b6e8..2dafc26fb6a8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -41,6 +41,7 @@ #include "iwl-prph.h" #include "iwl-fh.h" #include "iwl-debug.h" +#include "iwl-rfkill.h" #include "iwl-4965-hw.h" #include "iwl-3945-hw.h" #include "iwl-3945-led.h" @@ -69,6 +70,7 @@ extern struct iwl_ops iwl5000_ops; extern struct iwl_lib_ops iwl5000_lib; extern struct iwl_hcmd_ops iwl5000_hcmd; extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils; +extern struct iwl_station_mgmt_ops iwl5000_station_mgmt; /* shared functions from iwl-5000.c */ extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len); @@ -288,11 +290,11 @@ struct iwl_frame { #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) enum { - CMD_SYNC = 0, - CMD_SIZE_NORMAL = 0, - CMD_NO_SKB = 0, + /* CMD_SIZE_NORMAL = 0, */ CMD_SIZE_HUGE = (1 << 0), + /* CMD_SYNC = 0, */ CMD_ASYNC = (1 << 1), + /* CMD_NO_SKB = 0, */ CMD_WANT_SKB = (1 << 2), }; @@ -935,6 +937,9 @@ struct iwl_priv { * 4965's initialize alive response contains some calibration data. */ struct iwl_init_alive_resp card_alive_init; struct iwl_alive_resp card_alive; +#if defined(CONFIG_IWLWIFI_RFKILL) + struct rfkill *rfkill; +#endif #ifdef CONFIG_IWLWIFI_LEDS unsigned long last_blink_time; @@ -1068,6 +1073,7 @@ struct iwl_priv { struct work_struct calibrated_work; struct work_struct scan_completed; struct work_struct rx_replenish; + struct work_struct rf_kill; struct work_struct abort_scan; struct work_struct update_link_led; struct work_struct auth_work; @@ -1113,6 +1119,8 @@ struct iwl_priv { struct iwl3945_notif_statistics statistics_39; + struct iwl3945_station_entry stations_39[IWL_STATION_COUNT]; + u32 sta_supp_rates; }; /*iwl_priv */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 7d7554a2f341..cefa501e5971 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -240,11 +240,13 @@ static int iwl_init_otp_access(struct iwl_priv *priv) if (ret < 0) IWL_ERR(priv, "Time out access OTP\n"); else { - iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_RESET_REQ); - udelay(5); - iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_RESET_REQ); + if (!ret) { + iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_RESET_REQ); + udelay(5); + iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_RESET_REQ); + } } return ret; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-led.c b/trunk/drivers/net/wireless/iwlwifi/iwl-led.c index 5e64252f80f6..19680f72087f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-led.c @@ -176,6 +176,10 @@ static int iwl_led_associate(struct iwl_priv *priv, int led_id) static int iwl_led_disassociate(struct iwl_priv *priv, int led_id) { priv->allow_blinking = 0; + if (iwl_is_rfkill(priv)) + iwl4965_led_off_reg(priv, led_id); + else + iwl4965_led_on_reg(priv, led_id); return 0; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c new file mode 100644 index 000000000000..65605ad44e4b --- /dev/null +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#include +#include +#include + +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" + +/* software rf-kill from user */ +static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) +{ + struct iwl_priv *priv = data; + int err = 0; + + if (!priv->rfkill) + return 0; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return 0; + + IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state); + mutex_lock(&priv->mutex); + + switch (state) { + case RFKILL_STATE_UNBLOCKED: + if (iwl_is_rfkill_hw(priv)) { + err = -EBUSY; + goto out_unlock; + } + iwl_radio_kill_sw_enable_radio(priv); + break; + case RFKILL_STATE_SOFT_BLOCKED: + iwl_radio_kill_sw_disable_radio(priv); + break; + default: + IWL_WARN(priv, "we received unexpected RFKILL state %d\n", + state); + break; + } +out_unlock: + mutex_unlock(&priv->mutex); + + return err; +} + +int iwl_rfkill_init(struct iwl_priv *priv) +{ + struct device *device = wiphy_dev(priv->hw->wiphy); + int ret = 0; + + BUG_ON(device == NULL); + + IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); + priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); + if (!priv->rfkill) { + IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); + ret = -ENOMEM; + goto error; + } + + priv->rfkill->name = priv->cfg->name; + priv->rfkill->data = priv; + priv->rfkill->state = RFKILL_STATE_UNBLOCKED; + priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; + + priv->rfkill->dev.class->suspend = NULL; + priv->rfkill->dev.class->resume = NULL; + + ret = rfkill_register(priv->rfkill); + if (ret) { + IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); + goto free_rfkill; + } + + IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); + return ret; + +free_rfkill: + if (priv->rfkill != NULL) + rfkill_free(priv->rfkill); + priv->rfkill = NULL; + +error: + IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); + return ret; +} +EXPORT_SYMBOL(iwl_rfkill_init); + +void iwl_rfkill_unregister(struct iwl_priv *priv) +{ + + if (priv->rfkill) + rfkill_unregister(priv->rfkill); + + priv->rfkill = NULL; +} +EXPORT_SYMBOL(iwl_rfkill_unregister); + +/* set RFKILL to the right state. */ +void iwl_rfkill_set_hw_state(struct iwl_priv *priv) +{ + if (!priv->rfkill) + return; + + if (iwl_is_rfkill_hw(priv)) { + rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); + return; + } + + if (!iwl_is_rfkill_sw(priv)) + rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED); + else + rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); +} +EXPORT_SYMBOL(iwl_rfkill_set_hw_state); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h new file mode 100644 index 000000000000..633dafb4bf1b --- /dev/null +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#ifndef __iwl_rf_kill_h__ +#define __iwl_rf_kill_h__ + +struct iwl_priv; + +#include + +#ifdef CONFIG_IWLWIFI_RFKILL + +void iwl_rfkill_set_hw_state(struct iwl_priv *priv); +void iwl_rfkill_unregister(struct iwl_priv *priv); +int iwl_rfkill_init(struct iwl_priv *priv); +#else +static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {} +static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {} +static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; } +#endif + + + +#endif /* __iwl_rf_kill_h__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c index 2addf735b193..0eb939c40ac1 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -75,7 +75,7 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) return IWL_AP_ID; } else { u8 *da = ieee80211_get_DA(hdr); - return iwl_find_station(priv, da); + return priv->cfg->ops->smgmt->find_station(priv, da); } } EXPORT_SYMBOL(iwl_get_ra_sta_id); @@ -86,7 +86,8 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) spin_lock_irqsave(&priv->sta_lock, flags); - if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) + if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && + !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE)) IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", sta_id); @@ -227,16 +228,15 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, } /** - * iwl_add_station - Add station to tables in driver and device + * iwl_add_station_flags - Add station to tables in driver and device */ -u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, - struct ieee80211_sta_ht_cap *ht_info) +u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, + u8 flags, struct ieee80211_sta_ht_cap *ht_info) { - struct iwl_station_entry *station; - unsigned long flags_spin; int i; int sta_id = IWL_INVALID_STATION; - u16 rate; + struct iwl_station_entry *station; + unsigned long flags_spin; spin_lock_irqsave(&priv->sta_lock, flags_spin); if (is_ap) @@ -288,12 +288,6 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, priv->iw_mode != NL80211_IFTYPE_ADHOC) iwl_set_ht_add_station(priv, sta_id, ht_info); - /* 3945 only */ - rate = (priv->band == IEEE80211_BAND_5GHZ) ? - IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP; - /* Turn on both antennas for the station... */ - station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); - spin_unlock_irqrestore(&priv->sta_lock, flags_spin); /* Add station to device's station table */ @@ -301,12 +295,12 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, return sta_id; } -EXPORT_SYMBOL(iwl_add_station); +EXPORT_SYMBOL(iwl_add_station_flags); static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) { unsigned long flags; - u8 sta_id = iwl_find_station(priv, addr); + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); BUG_ON(sta_id == IWL_INVALID_STATION); @@ -414,7 +408,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, /** * iwl_remove_station - Remove driver's knowledge of station. */ -int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) +int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) { int sta_id = IWL_INVALID_STATION; int i, ret = -EINVAL; @@ -773,7 +767,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv, unsigned long flags; int i; - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", addr); @@ -952,7 +946,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd); * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, * which requires station table entry to exist). */ -static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap) +static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) { int i, r; struct iwl_link_quality_cmd link_cmd = { @@ -985,9 +979,8 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap) link_cmd.general_params.single_stream_ant_msk = first_antenna(priv->hw_params.valid_tx_ant); link_cmd.general_params.dual_stream_ant_msk = 3; - link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; - link_cmd.agg_params.agg_time_limit = - cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); + link_cmd.agg_params.agg_dis_start_th = 3; + link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000); /* Update the rate scaling for control frame Tx to AP */ link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id; @@ -1002,7 +995,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap) * there is only one AP station with id= IWL_AP_ID * NOTE: mutex must be held before calling this function */ -int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) +int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) { struct ieee80211_sta *sta; struct ieee80211_sta_ht_cap ht_config; @@ -1027,7 +1020,8 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) rcu_read_unlock(); } - sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config); + sta_id = priv->cfg->ops->smgmt->add_station(priv, addr, is_ap, + 0, cur_ht_config); /* Set up default rate scaling table in device's station table */ iwl_sta_init_lq(priv, addr, is_ap); @@ -1060,7 +1054,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* If we are an AP, then find the station, or use BCAST */ case NL80211_IFTYPE_AP: - sta_id = iwl_find_station(priv, hdr->addr1); + sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; return priv->hw_params.bcast_sta_id; @@ -1068,13 +1062,13 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* If this frame is going out to an IBSS network, find the station, * or create a new station table entry */ case NL80211_IFTYPE_ADHOC: - sta_id = iwl_find_station(priv, hdr->addr1); + sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; /* Create new station table entry */ - sta_id = iwl_add_station(priv, hdr->addr1, false, - CMD_ASYNC, NULL); + sta_id = priv->cfg->ops->smgmt->add_station(priv, hdr->addr1, + 0, CMD_ASYNC, NULL); if (sta_id != IWL_INVALID_STATION) return sta_id; @@ -1117,7 +1111,7 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, unsigned long flags; int sta_id; - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) return -ENXIO; @@ -1139,7 +1133,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid) unsigned long flags; int sta_id; - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); return -ENXIO; @@ -1174,7 +1168,7 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) { /* FIXME: need locking over ps_status ??? */ - u8 sta_id = iwl_find_station(priv, addr); + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id != IWL_INVALID_STATION) { u8 sta_awake = priv->stations[sta_id]. diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h index 6deebade6361..59a586b6b56c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -51,15 +51,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf, const u8 *addr, u32 iv32, u16 *phase1key); -int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); -int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); +int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); +int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); void iwl_clear_stations_table(struct iwl_priv *priv); int iwl_get_free_ucode_key_index(struct iwl_priv *priv); int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags); -u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, +u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, + int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); int iwl_sta_rx_agg_start(struct iwl_priv *priv, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index 83d31606dd00..5c10b87d0336 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -95,6 +95,144 @@ struct iwl_mod_params iwl3945_mod_params = { /* the rest are 0 by default */ }; +/*************** STATION TABLE MANAGEMENT **** + * mac80211 should be examined to determine if sta_info is duplicating + * the functionality provided here + */ + +/**************************************************************/ +#if 0 /* temporary disable till we add real remove station */ +/** + * iwl3945_remove_station - Remove driver's knowledge of station. + * + * NOTE: This does not remove station from device's station table. + */ +static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) +{ + int index = IWL_INVALID_STATION; + int i; + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + + if (is_ap) + index = IWL_AP_ID; + else if (is_broadcast_ether_addr(addr)) + index = priv->hw_params.bcast_sta_id; + else + for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) + if (priv->stations_39[i].used && + !compare_ether_addr(priv->stations_39[i].sta.sta.addr, + addr)) { + index = i; + break; + } + + if (unlikely(index == IWL_INVALID_STATION)) + goto out; + + if (priv->stations_39[index].used) { + priv->stations_39[index].used = 0; + priv->num_stations--; + } + + BUG_ON(priv->num_stations < 0); + +out: + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; +} +#endif + +/** + * iwl3945_clear_stations_table - Clear the driver's station table + * + * NOTE: This does not clear or otherwise alter the device's station table. + */ +void iwl3945_clear_stations_table(struct iwl_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->num_stations = 0; + memset(priv->stations_39, 0, sizeof(priv->stations_39)); + + spin_unlock_irqrestore(&priv->sta_lock, flags); +} + +/** + * iwl3945_add_station - Add station to station tables in driver and device + */ +u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info) +{ + int i; + int index = IWL_INVALID_STATION; + struct iwl3945_station_entry *station; + unsigned long flags_spin; + u8 rate; + + spin_lock_irqsave(&priv->sta_lock, flags_spin); + if (is_ap) + index = IWL_AP_ID; + else if (is_broadcast_ether_addr(addr)) + index = priv->hw_params.bcast_sta_id; + else + for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { + if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr, + addr)) { + index = i; + break; + } + + if (!priv->stations_39[i].used && + index == IWL_INVALID_STATION) + index = i; + } + + /* These two conditions has the same outcome but keep them separate + since they have different meaning */ + if (unlikely(index == IWL_INVALID_STATION)) { + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + return index; + } + + if (priv->stations_39[index].used && + !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) { + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + return index; + } + + IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr); + station = &priv->stations_39[index]; + station->used = 1; + priv->num_stations++; + + /* Set up the REPLY_ADD_STA command to send to device */ + memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd)); + memcpy(station->sta.sta.addr, addr, ETH_ALEN); + station->sta.mode = 0; + station->sta.sta.sta_id = index; + station->sta.station_flags = 0; + + if (priv->band == IEEE80211_BAND_5GHZ) + rate = IWL_RATE_6M_PLCP; + else + rate = IWL_RATE_1M_PLCP; + + /* Turn on both antennas for the station... */ + station->sta.rate_n_flags = + iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK); + + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + + /* Add station to device's station table */ + iwl_send_add_sta(priv, + (struct iwl_addsta_cmd *)&station->sta, flags); + return index; + +} + /** * iwl3945_get_antenna_flags - Get antenna flags for RXON command * @priv: eeprom and antenna fields are used to determine antenna flags @@ -151,31 +289,32 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, key_flags &= ~STA_KEY_FLG_INVALID; spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, + priv->stations_39[sta_id].keyinfo.alg = keyconf->alg; + priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen; + memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key, keyconf->keylen); - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, + memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key, keyconf->keylen); - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = + priv->stations_39[sta_id].sta.key.key_offset = iwl_get_free_ucode_key_index(priv); /* else, we are overriding an existing key => no need to allocated room * in uCode. */ - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, "no space for a new key"); - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + priv->stations_39[sta_id].sta.key.key_flags = key_flags; + priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); - ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + ret = iwl_send_add_sta(priv, + (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -201,16 +340,17 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) unsigned long flags; spin_lock_irqsave(&priv->sta_lock, flags); - memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, + memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); + memset(&priv->stations_39[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); - priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; + priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); + iwl_send_add_sta(priv, + (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0); return 0; } @@ -438,7 +578,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, int sta_id) { struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; - struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; + struct iwl_hw_key *keyinfo = &priv->stations_39[sta_id].keyinfo; switch (keyinfo->alg) { case ALG_CCMP: @@ -613,7 +753,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (ieee80211_is_data_qos(fc)) { qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; - seq_number = priv->stations[sta_id].tid[tid].seq_number & + seq_number = priv->stations_39[sta_id].tid[tid].seq_number & IEEE80211_SCTL_SEQ; hdr->seq_ctrl = cpu_to_le16(seq_number) | (hdr->seq_ctrl & @@ -673,7 +813,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; if (qc) - priv->stations[sta_id].tid[tid].seq_number = seq_number; + priv->stations_39[sta_id].tid[tid].seq_number = seq_number; } else { wait_write_ptr = 1; txq->need_update = 0; @@ -1009,12 +1149,18 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, clear_bit(STATUS_RF_KILL_HW, &priv->status); + if (flags & SW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_SW, &priv->status); + else + clear_bit(STATUS_RF_KILL_SW, &priv->status); + iwl_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->status))) - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)) || + (test_bit(STATUS_RF_KILL_SW, &status) != + test_bit(STATUS_RF_KILL_SW, &priv->status))) + queue_work(priv->workqueue, &priv->rf_kill); else wake_up_interruptible(&priv->wait_command_queue); } @@ -1170,7 +1316,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) /* If we've added more space for the firmware to place data, tell it. * Increment device's write pointer in multiples of 8. */ - if ((rxq->write_actual != (rxq->write & ~0x7)) + if ((write != (rxq->write & ~0x7)) || (abs(rxq->write - rxq->read) > 7)) { spin_lock_irqsave(&rxq->lock, flags); rxq->need_update = 1; @@ -1191,7 +1337,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) * Also restock the Rx queue via iwl3945_rx_queue_restock. * This is called as a scheduled work item (except for during initialization) */ -static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) +static void iwl3945_rx_allocate(struct iwl_priv *priv) { struct iwl_rx_queue *rxq = &priv->rxq; struct list_head *element; @@ -1214,7 +1360,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) /* Alloc a new receive buffer */ rxb->skb = alloc_skb(priv->hw_params.rx_buf_size, - priority); + GFP_KERNEL); if (!rxb->skb) { if (net_ratelimit()) IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); @@ -1273,7 +1419,6 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; rxq->free_count = 0; - rxq->write_actual = 0; spin_unlock_irqrestore(&rxq->lock, flags); } @@ -1282,21 +1427,13 @@ void iwl3945_rx_replenish(void *data) struct iwl_priv *priv = data; unsigned long flags; - iwl3945_rx_allocate(priv, GFP_KERNEL); + iwl3945_rx_allocate(priv); spin_lock_irqsave(&priv->lock, flags); iwl3945_rx_queue_restock(priv); spin_unlock_irqrestore(&priv->lock, flags); } -static void iwl3945_rx_replenish_now(struct iwl_priv *priv) -{ - iwl3945_rx_allocate(priv, GFP_ATOMIC); - - iwl3945_rx_queue_restock(priv); -} - - /* Assumes that the skb field of the buffers in 'pool' is kept accurate. * If an SKB has been detached, the POOL needs to have its SKB set to NULL * This free routine walks the list of POOL entries and if SKB is set to @@ -1419,19 +1556,13 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) unsigned long flags; u8 fill_rx = 0; u32 count = 8; - int total_empty = 0; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; i = rxq->read; - /* calculate total frames need to be restock after handling RX */ - total_empty = r - priv->rxq.write_actual; - if (total_empty < 0) - total_empty += RX_QUEUE_SIZE; - - if (total_empty > (RX_QUEUE_SIZE / 2)) + if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) fill_rx = 1; /* Rx interrupt, but nothing sent from uCode */ if (i == r) @@ -1508,7 +1639,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) count++; if (count >= 8) { priv->rxq.read = i; - iwl3945_rx_replenish_now(priv); + iwl3945_rx_queue_restock(priv); count = 0; } } @@ -1516,10 +1647,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) /* Backtrack one entry */ priv->rxq.read = i; - if (fill_rx) - iwl3945_rx_replenish_now(priv); - else - iwl3945_rx_queue_restock(priv); + iwl3945_rx_queue_restock(priv); } /* call this function to flush any scheduled tasklet */ @@ -2461,7 +2589,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) goto restart; } - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); @@ -2553,7 +2681,7 @@ static void __iwl3945_down(struct iwl_priv *priv) set_bit(STATUS_EXIT_PENDING, &priv->status); iwl3945_led_unregister(priv); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); @@ -2580,6 +2708,8 @@ static void __iwl3945_down(struct iwl_priv *priv) if (!iwl_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_EXIT_PENDING, &priv->status) << @@ -2588,9 +2718,11 @@ static void __iwl3945_down(struct iwl_priv *priv) } /* ...otherwise clear out all the status bits but the RF Kill - * bit and continue taking the NIC down. */ + * bits and continue taking the NIC down. */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_FW_ERROR, &priv->status) << @@ -2647,6 +2779,12 @@ static int __iwl3945_up(struct iwl_priv *priv) return -EIO; } + if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { + IWL_WARN(priv, "Radio disabled by SW RF kill (module " + "parameter)\n"); + return -ENODEV; + } + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { IWL_ERR(priv, "ucode not available for device bring up\n"); return -EIO; @@ -2695,7 +2833,7 @@ static int __iwl3945_up(struct iwl_priv *priv) for (i = 0; i < MAX_HW_RESTARTS; i++) { - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* load bootstrap state machine, * load bootstrap program into processor's memory, @@ -2763,14 +2901,15 @@ static void iwl3945_rfkill_poll(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, rfkill_poll.work); + unsigned long status = priv->status; if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &priv->status); else set_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) + queue_work(priv->workqueue, &priv->rf_kill); queue_delayed_work(priv->workqueue, &priv->rfkill_poll, round_jiffies_relative(2 * HZ)); @@ -3002,6 +3141,7 @@ static void iwl3945_bg_up(struct work_struct *data) mutex_lock(&priv->mutex); __iwl3945_up(priv); mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); } static void iwl3945_bg_restart(struct work_struct *data) @@ -3107,7 +3247,7 @@ void iwl3945_post_associate(struct iwl_priv *priv) case NL80211_IFTYPE_ADHOC: priv->assoc_id = 1; - iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL); + priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL); iwl3945_sync_sta(priv, IWL_STA_ID, (priv->band == IEEE80211_BAND_5GHZ) ? IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, @@ -3164,6 +3304,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); + if (ret) goto out_release_irq; @@ -3296,7 +3438,7 @@ void iwl3945_config_ap(struct iwl_priv *priv) /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv); - iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL); + priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL); } iwl3945_send_beacon_cmd(priv); @@ -3327,7 +3469,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static_key = !iwl_is_associated(priv); if (!static_key) { - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", addr); @@ -3816,6 +3958,7 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->up, iwl3945_bg_up); INIT_WORK(&priv->restart, iwl3945_bg_restart); INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); + INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); @@ -3901,7 +4044,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) mutex_init(&priv->mutex); /* Clear the driver's (not device's) station table */ - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); priv->data_retry_limit = -1; priv->ieee_channels = NULL; @@ -4182,6 +4325,13 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e if (err) IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + err = iwl_rfkill_init(priv); + if (err) + IWL_ERR(priv, "Unable to initialize RFKILL system. " + "Ignoring error: %d\n", err); + else + iwl_rfkill_set_hw_state(priv); + /* Start monitoring the killswitch */ queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 2 * HZ); @@ -4247,6 +4397,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); + iwl_rfkill_unregister(priv); cancel_delayed_work_sync(&priv->rfkill_poll); iwl3945_dealloc_ucode_pci(priv); @@ -4256,7 +4407,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) iwl3945_hw_txq_ctx_free(priv); iwl3945_unset_hw_params(priv); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /*netif_stop_queue(dev); */ flush_workqueue(priv->workqueue); diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/Kconfig b/trunk/drivers/net/wireless/iwmc3200wifi/Kconfig index 1eccb6df46dd..41bd4b2b5411 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/Kconfig +++ b/trunk/drivers/net/wireless/iwmc3200wifi/Kconfig @@ -1,9 +1,10 @@ config IWM tristate "Intel Wireless Multicomm 3200 WiFi driver" depends on MMC && WLAN_80211 && EXPERIMENTAL - depends on CFG80211 select WIRELESS_EXT + select CFG80211 select FW_LOADER + select RFKILL config IWM_DEBUG bool "Enable full debugging output in iwmc3200wifi" diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/Makefile b/trunk/drivers/net/wireless/iwmc3200wifi/Makefile index 927f022545c1..7cb415e5c11b 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/Makefile +++ b/trunk/drivers/net/wireless/iwmc3200wifi/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_IWM) := iwmc3200wifi.o iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o -iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o +iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o rfkill.o iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/trunk/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 96f714e6e12b..3256ad2c96ce 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -268,7 +268,7 @@ static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) iwm->conf.frag_threshold = wiphy->frag_threshold; - ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX, + ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, CFG_FRAG_THRESHOLD, iwm->conf.frag_threshold); if (ret < 0) diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/fw.c b/trunk/drivers/net/wireless/iwmc3200wifi/fw.c index ec1a15a5a0e4..db4ba0864730 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/fw.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/fw.c @@ -72,7 +72,7 @@ static int iwm_fw_op_offset(struct iwm_priv *iwm, const struct firmware *fw, } if (fw->size < IWM_HDR_LEN) { - IWM_ERR(iwm, "FW is too small (%zu)\n", fw->size); + IWM_ERR(iwm, "FW is too small (%d)\n", fw->size); return -EINVAL; } diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/iwm.h b/trunk/drivers/net/wireless/iwmc3200wifi/iwm.h index 635c16ee6186..3b29681792bb 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/trunk/drivers/net/wireless/iwmc3200wifi/iwm.h @@ -343,4 +343,8 @@ int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size, struct iwm_wifi_cmd *cmd); void iwm_rx_free(struct iwm_priv *iwm); +/* RF Kill API */ +int iwm_rfkill_init(struct iwm_priv *iwm); +void iwm_rfkill_exit(struct iwm_priv *iwm); + #endif diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/netdev.c b/trunk/drivers/net/wireless/iwmc3200wifi/netdev.c index 68e2c3b6c7a1..eec7201e91a8 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -136,8 +136,17 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev, wdev->netdev = ndev; + ret = iwm_rfkill_init(iwm); + if (ret) { + dev_err(dev, "Failed to init rfkill\n"); + goto out_rfkill; + } + return iwm; + out_rfkill: + unregister_netdev(ndev); + out_ndev: free_netdev(ndev); @@ -153,6 +162,7 @@ void iwm_if_free(struct iwm_priv *iwm) if (!iwm_to_ndev(iwm)) return; + iwm_rfkill_exit(iwm); unregister_netdev(iwm_to_ndev(iwm)); free_netdev(iwm_to_ndev(iwm)); iwm_wdev_free(iwm); diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/rfkill.c b/trunk/drivers/net/wireless/iwmc3200wifi/rfkill.c new file mode 100644 index 000000000000..4ca8b495f82d --- /dev/null +++ b/trunk/drivers/net/wireless/iwmc3200wifi/rfkill.c @@ -0,0 +1,88 @@ +/* + * Intel Wireless Multicomm 3200 WiFi driver + * + * Copyright (C) 2009 Intel Corporation + * Samuel Ortiz + * Zhu Yi + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#include + +#include "iwm.h" + +static int iwm_rfkill_soft_toggle(void *data, enum rfkill_state state) +{ + struct iwm_priv *iwm = data; + + switch (state) { + case RFKILL_STATE_UNBLOCKED: + if (test_bit(IWM_RADIO_RFKILL_HW, &iwm->radio)) + return -EBUSY; + + if (test_and_clear_bit(IWM_RADIO_RFKILL_SW, &iwm->radio) && + (iwm_to_ndev(iwm)->flags & IFF_UP)) + iwm_up(iwm); + + break; + case RFKILL_STATE_SOFT_BLOCKED: + if (!test_and_set_bit(IWM_RADIO_RFKILL_SW, &iwm->radio)) + iwm_down(iwm); + + break; + default: + break; + } + + return 0; +} + +int iwm_rfkill_init(struct iwm_priv *iwm) +{ + int ret; + + iwm->rfkill = rfkill_allocate(iwm_to_dev(iwm), RFKILL_TYPE_WLAN); + if (!iwm->rfkill) { + IWM_ERR(iwm, "Unable to allocate rfkill device\n"); + return -ENOMEM; + } + + iwm->rfkill->name = KBUILD_MODNAME; + iwm->rfkill->data = iwm; + iwm->rfkill->state = RFKILL_STATE_UNBLOCKED; + iwm->rfkill->toggle_radio = iwm_rfkill_soft_toggle; + + ret = rfkill_register(iwm->rfkill); + if (ret) { + IWM_ERR(iwm, "Failed to register rfkill device\n"); + goto fail; + } + + return 0; + fail: + rfkill_free(iwm->rfkill); + return ret; +} + +void iwm_rfkill_exit(struct iwm_priv *iwm) +{ + if (iwm->rfkill) + rfkill_unregister(iwm->rfkill); + + rfkill_free(iwm->rfkill); + iwm->rfkill = NULL; +} diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c b/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c index b54da677b371..edc0a0091058 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c @@ -395,7 +395,7 @@ static struct iwm_if_ops if_sdio_ops = { .debugfs_init = if_sdio_debugfs_init, .debugfs_exit = if_sdio_debugfs_exit, .umac_name = "iwmc3200wifi-umac-sdio.bin", - .calib_lmac_name = "iwmc3200wifi-calib-sdio.bin", + .calib_lmac_name = "iwmc3200wifi-lmac-calib-sdio.bin", .lmac_name = "iwmc3200wifi-lmac-sdio.bin", }; diff --git a/trunk/drivers/net/wireless/libertas/11d.c b/trunk/drivers/net/wireless/libertas/11d.c index 9a5408e7d94a..4bc46a60ae2f 100644 --- a/trunk/drivers/net/wireless/libertas/11d.c +++ b/trunk/drivers/net/wireless/libertas/11d.c @@ -207,7 +207,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband); lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo, COUNTRY_CODE_LEN + 1 + - sizeof(struct ieee_subbandset) * nr_subband); + sizeof(struct ieeetypes_subbandset) * nr_subband); return 0; } @@ -302,9 +302,11 @@ static u8 lbs_region_chan_supported_11d(u8 region, u8 chan) * @param parsed_region_chan pointer to parsed_region_chan_11d * @return 0 */ -static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryinfo, +static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* + countryinfo, u8 band, - struct parsed_region_chan_11d *parsed_region_chan) + struct parsed_region_chan_11d * + parsed_region_chan) { u8 nr_subband, nrchan; u8 lastchan, firstchan; @@ -329,7 +331,7 @@ static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryin lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30); if ((*(countryinfo->countrycode)) == 0 - || (countryinfo->header.len <= COUNTRY_CODE_LEN)) { + || (countryinfo->len <= COUNTRY_CODE_LEN)) { /* No region Info or Wrong region info: treat as No 11D info */ goto done; } @@ -347,8 +349,8 @@ static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryin memcpy(parsed_region_chan->countrycode, countryinfo->countrycode, COUNTRY_CODE_LEN); - nr_subband = (countryinfo->header.len - COUNTRY_CODE_LEN) / - sizeof(struct ieee_subbandset); + nr_subband = (countryinfo->len - COUNTRY_CODE_LEN) / + sizeof(struct ieeetypes_subbandset); for (j = 0, lastchan = 0; j < nr_subband; j++) { @@ -500,7 +502,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, { struct cmd_ds_802_11d_domain_info *pdomaininfo = &cmd->params.domaininfo; - struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain; + struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain; u8 nr_subband = priv->domainreg.nr_subband; lbs_deb_enter(LBS_DEB_11D); @@ -522,16 +524,16 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, sizeof(domain->countrycode)); domain->header.len = - cpu_to_le16(nr_subband * sizeof(struct ieee_subbandset) + + cpu_to_le16(nr_subband * sizeof(struct ieeetypes_subbandset) + sizeof(domain->countrycode)); if (nr_subband) { memcpy(domain->subband, priv->domainreg.subband, - nr_subband * sizeof(struct ieee_subbandset)); + nr_subband * sizeof(struct ieeetypes_subbandset)); cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + le16_to_cpu(domain->header.len) + - sizeof(struct mrvl_ie_header) + + sizeof(struct mrvlietypesheader) + S_DS_GEN); } else { cmd->size = @@ -554,7 +556,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) { struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp; - struct mrvl_ie_domain_param_set *domain = &domaininfo->domain; + struct mrvlietypes_domainparamset *domain = &domaininfo->domain; u16 action = le16_to_cpu(domaininfo->action); s16 ret = 0; u8 nr_subband = 0; @@ -565,7 +567,7 @@ int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) (int)le16_to_cpu(resp->size)); nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / - sizeof(struct ieee_subbandset); + sizeof(struct ieeetypes_subbandset); lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband); diff --git a/trunk/drivers/net/wireless/libertas/11d.h b/trunk/drivers/net/wireless/libertas/11d.h index fb75d3e321a0..4f4f47f0f878 100644 --- a/trunk/drivers/net/wireless/libertas/11d.h +++ b/trunk/drivers/net/wireless/libertas/11d.h @@ -20,36 +20,35 @@ struct cmd_ds_command; /** Data structure for Country IE*/ -struct ieee_subbandset { +struct ieeetypes_subbandset { u8 firstchan; u8 nrchan; u8 maxtxpwr; } __attribute__ ((packed)); -struct ieee_ie_country_info_set { - struct ieee_ie_header header; - +struct ieeetypes_countryinfoset { + u8 element_id; + u8 len; u8 countrycode[COUNTRY_CODE_LEN]; - struct ieee_subbandset subband[1]; + struct ieeetypes_subbandset subband[1]; }; -struct ieee_ie_country_info_full_set { - struct ieee_ie_header header; - +struct ieeetypes_countryinfofullset { + u8 element_id; + u8 len; u8 countrycode[COUNTRY_CODE_LEN]; - struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; + struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; } __attribute__ ((packed)); -struct mrvl_ie_domain_param_set { - struct mrvl_ie_header header; - +struct mrvlietypes_domainparamset { + struct mrvlietypesheader header; u8 countrycode[COUNTRY_CODE_LEN]; - struct ieee_subbandset subband[1]; + struct ieeetypes_subbandset subband[1]; } __attribute__ ((packed)); struct cmd_ds_802_11d_domain_info { __le16 action; - struct mrvl_ie_domain_param_set domain; + struct mrvlietypes_domainparamset domain; } __attribute__ ((packed)); /** domain regulatory information */ @@ -58,7 +57,7 @@ struct lbs_802_11d_domain_reg { u8 countrycode[COUNTRY_CODE_LEN]; /** No. of subband*/ u8 nr_subband; - struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; + struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; }; struct chan_power_11d { diff --git a/trunk/drivers/net/wireless/libertas/assoc.c b/trunk/drivers/net/wireless/libertas/assoc.c index b9b374119033..a0e440cd8967 100644 --- a/trunk/drivers/net/wireless/libertas/assoc.c +++ b/trunk/drivers/net/wireless/libertas/assoc.c @@ -12,14 +12,15 @@ #include "scan.h" #include "cmd.h" +static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp); + static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -/* The firmware needs the following bits masked out of the beacon-derived - * capability field when associating/joining to a BSS: - * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) +/* The firmware needs certain bits masked out of the beacon-derviced capability + * field when associating/joining to BSSs. */ #define CAPINFO_MASK (~(0xda00)) @@ -101,295 +102,6 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len) } -static u8 iw_auth_to_ieee_auth(u8 auth) -{ - if (auth == IW_AUTH_ALG_OPEN_SYSTEM) - return 0x00; - else if (auth == IW_AUTH_ALG_SHARED_KEY) - return 0x01; - else if (auth == IW_AUTH_ALG_LEAP) - return 0x80; - - lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth); - return 0; -} - -/** - * @brief This function prepares the authenticate command. AUTHENTICATE only - * sets the authentication suite for future associations, as the firmware - * handles authentication internally during the ASSOCIATE command. - * - * @param priv A pointer to struct lbs_private structure - * @param bssid The peer BSSID with which to authenticate - * @param auth The authentication mode to use (from wireless.h) - * - * @return 0 or -1 - */ -static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth) -{ - struct cmd_ds_802_11_authenticate cmd; - int ret = -1; - DECLARE_MAC_BUF(mac); - - lbs_deb_enter(LBS_DEB_JOIN); - - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - memcpy(cmd.bssid, bssid, ETH_ALEN); - - cmd.authtype = iw_auth_to_ieee_auth(auth); - - lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n", - print_mac(mac, bssid), cmd.authtype); - - ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd); - - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); - return ret; -} - - -static int lbs_assoc_post(struct lbs_private *priv, - struct cmd_ds_802_11_associate_response *resp) -{ - int ret = 0; - union iwreq_data wrqu; - struct bss_descriptor *bss; - u16 status_code; - - lbs_deb_enter(LBS_DEB_ASSOC); - - if (!priv->in_progress_assoc_req) { - lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n"); - ret = -1; - goto done; - } - bss = &priv->in_progress_assoc_req->bss; - - /* - * Older FW versions map the IEEE 802.11 Status Code in the association - * response to the following values returned in resp->statuscode: - * - * IEEE Status Code Marvell Status Code - * 0 -> 0x0000 ASSOC_RESULT_SUCCESS - * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED - * others -> 0x0003 ASSOC_RESULT_REFUSED - * - * Other response codes: - * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) - * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for - * association response from the AP) - */ - - status_code = le16_to_cpu(resp->statuscode); - if (priv->fwrelease < 0x09000000) { - switch (status_code) { - case 0x00: - break; - case 0x01: - lbs_deb_assoc("ASSOC_RESP: invalid parameters\n"); - break; - case 0x02: - lbs_deb_assoc("ASSOC_RESP: internal timer " - "expired while waiting for the AP\n"); - break; - case 0x03: - lbs_deb_assoc("ASSOC_RESP: association " - "refused by AP\n"); - break; - case 0x04: - lbs_deb_assoc("ASSOC_RESP: authentication " - "refused by AP\n"); - break; - default: - lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x " - " unknown\n", status_code); - break; - } - } else { - /* v9+ returns the AP's association response */ - lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code); - } - - if (status_code) { - lbs_mac_event_disconnected(priv); - ret = -1; - goto done; - } - - lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", - (void *) (resp + sizeof (resp->hdr)), - le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr)); - - /* Send a Media Connected event, according to the Spec */ - priv->connect_status = LBS_CONNECTED; - - /* Update current SSID and BSSID */ - memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); - priv->curbssparams.ssid_len = bss->ssid_len; - memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); - - priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; - priv->NF[TYPE_RXPD][TYPE_AVG] = 0; - - memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR)); - memset(priv->rawNF, 0x00, sizeof(priv->rawNF)); - priv->nextSNRNF = 0; - priv->numSNRNF = 0; - - netif_carrier_on(priv->dev); - if (!priv->tx_pending_len) - netif_wake_queue(priv->dev); - - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - -done: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - -/** - * @brief This function prepares an association-class command. - * - * @param priv A pointer to struct lbs_private structure - * @param assoc_req The association request describing the BSS to associate - * or reassociate with - * @param command The actual command, either CMD_802_11_ASSOCIATE or - * CMD_802_11_REASSOCIATE - * - * @return 0 or -1 - */ -static int lbs_associate(struct lbs_private *priv, - struct assoc_request *assoc_req, - u16 command) -{ - struct cmd_ds_802_11_associate cmd; - int ret = 0; - struct bss_descriptor *bss = &assoc_req->bss; - u8 *pos = &(cmd.iebuf[0]); - u16 tmpcap, tmplen, tmpauth; - struct mrvl_ie_ssid_param_set *ssid; - struct mrvl_ie_ds_param_set *ds; - struct mrvl_ie_cf_param_set *cf; - struct mrvl_ie_rates_param_set *rates; - struct mrvl_ie_rsn_param_set *rsn; - struct mrvl_ie_auth_type *auth; - - lbs_deb_enter(LBS_DEB_ASSOC); - - BUG_ON((command != CMD_802_11_ASSOCIATE) && - (command != CMD_802_11_REASSOCIATE)); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.command = cpu_to_le16(command); - - /* Fill in static fields */ - memcpy(cmd.bssid, bss->bssid, ETH_ALEN); - cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); - - /* Capability info */ - tmpcap = (bss->capability & CAPINFO_MASK); - if (bss->mode == IW_MODE_INFRA) - tmpcap |= WLAN_CAPABILITY_ESS; - cmd.capability = cpu_to_le16(tmpcap); - lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap); - - /* SSID */ - ssid = (struct mrvl_ie_ssid_param_set *) pos; - ssid->header.type = cpu_to_le16(TLV_TYPE_SSID); - tmplen = bss->ssid_len; - ssid->header.len = cpu_to_le16(tmplen); - memcpy(ssid->ssid, bss->ssid, tmplen); - pos += sizeof(ssid->header) + tmplen; - - ds = (struct mrvl_ie_ds_param_set *) pos; - ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); - ds->header.len = cpu_to_le16(1); - ds->channel = bss->phy.ds.channel; - pos += sizeof(ds->header) + 1; - - cf = (struct mrvl_ie_cf_param_set *) pos; - cf->header.type = cpu_to_le16(TLV_TYPE_CF); - tmplen = sizeof(*cf) - sizeof (cf->header); - cf->header.len = cpu_to_le16(tmplen); - /* IE payload should be zeroed, firmware fills it in for us */ - pos += sizeof(*cf); - - rates = (struct mrvl_ie_rates_param_set *) pos; - rates->header.type = cpu_to_le16(TLV_TYPE_RATES); - memcpy(&rates->rates, &bss->rates, MAX_RATES); - tmplen = MAX_RATES; - if (get_common_rates(priv, rates->rates, &tmplen)) { - ret = -1; - goto done; - } - pos += sizeof(rates->header) + tmplen; - rates->header.len = cpu_to_le16(tmplen); - lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen); - - /* Copy the infra. association rates into Current BSS state structure */ - memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); - memcpy(&priv->curbssparams.rates, &rates->rates, tmplen); - - /* Set MSB on basic rates as the firmware requires, but _after_ - * copying to current bss rates. - */ - lbs_set_basic_rate_flags(rates->rates, tmplen); - - /* Firmware v9+ indicate authentication suites as a TLV */ - if (priv->fwrelease >= 0x09000000) { - DECLARE_MAC_BUF(mac); - - auth = (struct mrvl_ie_auth_type *) pos; - auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); - auth->header.len = cpu_to_le16(2); - tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode); - auth->auth = cpu_to_le16(tmpauth); - pos += sizeof(auth->header) + 2; - - lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n", - print_mac(mac, bss->bssid), priv->secinfo.auth_mode); - } - - /* WPA/WPA2 IEs */ - if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { - rsn = (struct mrvl_ie_rsn_param_set *) pos; - /* WPA_IE or WPA2_IE */ - rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]); - tmplen = (u16) assoc_req->wpa_ie[1]; - rsn->header.len = cpu_to_le16(tmplen); - memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen); - lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn, - sizeof(rsn->header) + tmplen); - pos += sizeof(rsn->header) + tmplen; - } - - cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) + - (u16)(pos - (u8 *) &cmd.iebuf)); - - /* update curbssparams */ - priv->curbssparams.channel = bss->phy.ds.channel; - - if (lbs_parse_dnld_countryinfo_11d(priv, bss)) { - ret = -1; - goto done; - } - - ret = lbs_cmd_with_response(priv, command, &cmd); - if (ret == 0) { - ret = lbs_assoc_post(priv, - (struct cmd_ds_802_11_associate_response *) &cmd); - } - -done: - lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); - return ret; -} - /** * @brief Associate to a specific BSS discovered in a scan * @@ -398,7 +110,7 @@ static int lbs_associate(struct lbs_private *priv, * * @return 0-success, otherwise fail */ -static int lbs_try_associate(struct lbs_private *priv, +static int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req) { int ret; @@ -406,15 +118,11 @@ static int lbs_try_associate(struct lbs_private *priv, lbs_deb_enter(LBS_DEB_ASSOC); - /* FW v9 and higher indicate authentication suites as a TLV in the - * association command, not as a separate authentication command. - */ - if (priv->fwrelease < 0x09000000) { - ret = lbs_set_authentication(priv, assoc_req->bss.bssid, - priv->secinfo.auth_mode); - if (ret) - goto out; - } + ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, + 0, CMD_OPTION_WAITFORRSP, + 0, assoc_req->bss.bssid); + if (ret) + goto out; /* Use short preamble only when both the BSS and firmware support it */ if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && @@ -425,78 +133,14 @@ static int lbs_try_associate(struct lbs_private *priv, if (ret) goto out; - ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE); + ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, + 0, CMD_OPTION_WAITFORRSP, 0, assoc_req); out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } -static int lbs_adhoc_post(struct lbs_private *priv, - struct cmd_ds_802_11_ad_hoc_result *resp) -{ - int ret = 0; - u16 command = le16_to_cpu(resp->hdr.command); - u16 result = le16_to_cpu(resp->hdr.result); - union iwreq_data wrqu; - struct bss_descriptor *bss; - DECLARE_SSID_BUF(ssid); - - lbs_deb_enter(LBS_DEB_JOIN); - - if (!priv->in_progress_assoc_req) { - lbs_deb_join("ADHOC_RESP: no in-progress association " - "request\n"); - ret = -1; - goto done; - } - bss = &priv->in_progress_assoc_req->bss; - - /* - * Join result code 0 --> SUCCESS - */ - if (result) { - lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result); - if (priv->connect_status == LBS_CONNECTED) - lbs_mac_event_disconnected(priv); - ret = -1; - goto done; - } - - /* Send a Media Connected event, according to the Spec */ - priv->connect_status = LBS_CONNECTED; - - if (command == CMD_RET(CMD_802_11_AD_HOC_START)) { - /* Update the created network descriptor with the new BSSID */ - memcpy(bss->bssid, resp->bssid, ETH_ALEN); - } - - /* Set the BSSID from the joined/started descriptor */ - memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); - - /* Set the new SSID to current SSID */ - memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); - priv->curbssparams.ssid_len = bss->ssid_len; - - netif_carrier_on(priv->dev); - if (!priv->tx_pending_len) - netif_wake_queue(priv->dev); - - memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); - - lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", - print_ssid(ssid, bss->ssid, bss->ssid_len), - priv->curbssparams.bssid, - priv->curbssparams.channel); - -done: - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); - return ret; -} - /** * @brief Join an adhoc network found in a previous scan * @@ -575,10 +219,11 @@ static int lbs_adhoc_join(struct lbs_private *priv, memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN); memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len); - memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set)); + memcpy(&cmd.bss.phyparamset, &bss->phyparamset, + sizeof(union ieeetypes_phyparamset)); - memcpy(&cmd.bss.ibss, &bss->ss.ibss, - sizeof(struct ieee_ie_ibss_param_set)); + memcpy(&cmd.bss.ssparamset, &bss->ssparamset, + sizeof(union IEEEtypes_ssparamset)); cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", @@ -615,7 +260,7 @@ static int lbs_adhoc_join(struct lbs_private *priv, */ lbs_set_basic_rate_flags(cmd.bss.rates, ratesize); - cmd.bss.ibss.atimwindow = bss->atimwindow; + cmd.bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow); if (assoc_req->secinfo.wep_enabled) { u16 tmp = le16_to_cpu(cmd.bss.capability); @@ -642,10 +287,8 @@ static int lbs_adhoc_join(struct lbs_private *priv, } ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); - if (ret == 0) { - ret = lbs_adhoc_post(priv, - (struct cmd_ds_802_11_ad_hoc_result *)&cmd); - } + if (ret == 0) + ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); @@ -700,24 +343,22 @@ static int lbs_adhoc_start(struct lbs_private *priv, WARN_ON(!assoc_req->channel); /* set Physical parameter set */ - cmd.ds.header.id = WLAN_EID_DS_PARAMS; - cmd.ds.header.len = 1; - cmd.ds.channel = assoc_req->channel; + cmd.phyparamset.dsparamset.elementid = WLAN_EID_DS_PARAMS; + cmd.phyparamset.dsparamset.len = 1; + cmd.phyparamset.dsparamset.currentchan = assoc_req->channel; /* set IBSS parameter set */ - cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS; - cmd.ibss.header.len = 2; - cmd.ibss.atimwindow = cpu_to_le16(0); + cmd.ssparamset.ibssparamset.elementid = WLAN_EID_IBSS_PARAMS; + cmd.ssparamset.ibssparamset.len = 2; + cmd.ssparamset.ibssparamset.atimwindow = 0; /* set capability info */ tmpcap = WLAN_CAPABILITY_IBSS; - if (assoc_req->secinfo.wep_enabled || - assoc_req->secinfo.WPAenabled || - assoc_req->secinfo.WPA2enabled) { - lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n"); + if (assoc_req->secinfo.wep_enabled) { + lbs_deb_join("ADHOC_START: WEP enabled, setting privacy on\n"); tmpcap |= WLAN_CAPABILITY_PRIVACY; } else - lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n"); + lbs_deb_join("ADHOC_START: WEP disabled, setting privacy off\n"); cmd.capability = cpu_to_le16(tmpcap); @@ -754,8 +395,7 @@ static int lbs_adhoc_start(struct lbs_private *priv, ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); if (ret == 0) - ret = lbs_adhoc_post(priv, - (struct cmd_ds_802_11_ad_hoc_result *)&cmd); + ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); @@ -1080,7 +720,7 @@ static int assoc_helper_essid(struct lbs_private *priv, assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); if (bss != NULL) { memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); - ret = lbs_try_associate(priv, assoc_req); + ret = lbs_associate(priv, assoc_req); } else { lbs_deb_assoc("SSID not found; cannot associate\n"); } @@ -1132,9 +772,8 @@ static int assoc_helper_bssid(struct lbs_private *priv, memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); if (assoc_req->mode == IW_MODE_INFRA) { - ret = lbs_try_associate(priv, assoc_req); - lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n", - ret); + ret = lbs_associate(priv, assoc_req); + lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret); } else if (assoc_req->mode == IW_MODE_ADHOC) { lbs_adhoc_join(priv, assoc_req); } @@ -1827,6 +1466,57 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv) } +/** + * @brief This function prepares command of authenticate. + * + * @param priv A pointer to struct lbs_private structure + * @param cmd A pointer to cmd_ds_command structure + * @param pdata_buf Void cast of pointer to a BSSID to authenticate with + * + * @return 0 or -1 + */ +int lbs_cmd_80211_authenticate(struct lbs_private *priv, + struct cmd_ds_command *cmd, + void *pdata_buf) +{ + struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth; + int ret = -1; + u8 *bssid = pdata_buf; + + lbs_deb_enter(LBS_DEB_JOIN); + + cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE); + cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate) + + S_DS_GEN); + + /* translate auth mode to 802.11 defined wire value */ + switch (priv->secinfo.auth_mode) { + case IW_AUTH_ALG_OPEN_SYSTEM: + pauthenticate->authtype = 0x00; + break; + case IW_AUTH_ALG_SHARED_KEY: + pauthenticate->authtype = 0x01; + break; + case IW_AUTH_ALG_LEAP: + pauthenticate->authtype = 0x80; + break; + default: + lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n", + priv->secinfo.auth_mode); + goto out; + } + + memcpy(pauthenticate->macaddr, bssid, ETH_ALEN); + + lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", + bssid, pauthenticate->authtype); + ret = 0; + +out: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); + return ret; +} + /** * @brief Deauthenticate from a specific BSS * @@ -1860,3 +1550,285 @@ int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN], return ret; } +int lbs_cmd_80211_associate(struct lbs_private *priv, + struct cmd_ds_command *cmd, void *pdata_buf) +{ + struct cmd_ds_802_11_associate *passo = &cmd->params.associate; + int ret = 0; + struct assoc_request *assoc_req = pdata_buf; + struct bss_descriptor *bss = &assoc_req->bss; + u8 *pos; + u16 tmpcap, tmplen; + struct mrvlietypes_ssidparamset *ssid; + struct mrvlietypes_phyparamset *phy; + struct mrvlietypes_ssparamset *ss; + struct mrvlietypes_ratesparamset *rates; + struct mrvlietypes_rsnparamset *rsn; + + lbs_deb_enter(LBS_DEB_ASSOC); + + pos = (u8 *) passo; + + if (!priv) { + ret = -1; + goto done; + } + + cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE); + + memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr)); + pos += sizeof(passo->peerstaaddr); + + /* set the listen interval */ + passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL); + + pos += sizeof(passo->capability); + pos += sizeof(passo->listeninterval); + pos += sizeof(passo->bcnperiod); + pos += sizeof(passo->dtimperiod); + + ssid = (struct mrvlietypes_ssidparamset *) pos; + ssid->header.type = cpu_to_le16(TLV_TYPE_SSID); + tmplen = bss->ssid_len; + ssid->header.len = cpu_to_le16(tmplen); + memcpy(ssid->ssid, bss->ssid, tmplen); + pos += sizeof(ssid->header) + tmplen; + + phy = (struct mrvlietypes_phyparamset *) pos; + phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS); + tmplen = sizeof(phy->fh_ds.dsparamset); + phy->header.len = cpu_to_le16(tmplen); + memcpy(&phy->fh_ds.dsparamset, + &bss->phyparamset.dsparamset.currentchan, + tmplen); + pos += sizeof(phy->header) + tmplen; + + ss = (struct mrvlietypes_ssparamset *) pos; + ss->header.type = cpu_to_le16(TLV_TYPE_CF); + tmplen = sizeof(ss->cf_ibss.cfparamset); + ss->header.len = cpu_to_le16(tmplen); + pos += sizeof(ss->header) + tmplen; + + rates = (struct mrvlietypes_ratesparamset *) pos; + rates->header.type = cpu_to_le16(TLV_TYPE_RATES); + memcpy(&rates->rates, &bss->rates, MAX_RATES); + tmplen = MAX_RATES; + if (get_common_rates(priv, rates->rates, &tmplen)) { + ret = -1; + goto done; + } + pos += sizeof(rates->header) + tmplen; + rates->header.len = cpu_to_le16(tmplen); + lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen); + + /* Copy the infra. association rates into Current BSS state structure */ + memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates)); + memcpy(&priv->curbssparams.rates, &rates->rates, tmplen); + + /* Set MSB on basic rates as the firmware requires, but _after_ + * copying to current bss rates. + */ + lbs_set_basic_rate_flags(rates->rates, tmplen); + + if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { + rsn = (struct mrvlietypes_rsnparamset *) pos; + /* WPA_IE or WPA2_IE */ + rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]); + tmplen = (u16) assoc_req->wpa_ie[1]; + rsn->header.len = cpu_to_le16(tmplen); + memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen); + lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn, + sizeof(rsn->header) + tmplen); + pos += sizeof(rsn->header) + tmplen; + } + + /* update curbssparams */ + priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan; + + if (lbs_parse_dnld_countryinfo_11d(priv, bss)) { + ret = -1; + goto done; + } + + cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN); + + /* set the capability info */ + tmpcap = (bss->capability & CAPINFO_MASK); + if (bss->mode == IW_MODE_INFRA) + tmpcap |= WLAN_CAPABILITY_ESS; + passo->capability = cpu_to_le16(tmpcap); + lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap); + +done: + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); + return ret; +} + +int lbs_ret_80211_associate(struct lbs_private *priv, + struct cmd_ds_command *resp) +{ + int ret = 0; + union iwreq_data wrqu; + struct ieeetypes_assocrsp *passocrsp; + struct bss_descriptor *bss; + u16 status_code; + + lbs_deb_enter(LBS_DEB_ASSOC); + + if (!priv->in_progress_assoc_req) { + lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n"); + ret = -1; + goto done; + } + bss = &priv->in_progress_assoc_req->bss; + + passocrsp = (struct ieeetypes_assocrsp *) &resp->params; + + /* + * Older FW versions map the IEEE 802.11 Status Code in the association + * response to the following values returned in passocrsp->statuscode: + * + * IEEE Status Code Marvell Status Code + * 0 -> 0x0000 ASSOC_RESULT_SUCCESS + * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * others -> 0x0003 ASSOC_RESULT_REFUSED + * + * Other response codes: + * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) + * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for + * association response from the AP) + */ + + status_code = le16_to_cpu(passocrsp->statuscode); + switch (status_code) { + case 0x00: + break; + case 0x01: + lbs_deb_assoc("ASSOC_RESP: invalid parameters\n"); + break; + case 0x02: + lbs_deb_assoc("ASSOC_RESP: internal timer " + "expired while waiting for the AP\n"); + break; + case 0x03: + lbs_deb_assoc("ASSOC_RESP: association " + "refused by AP\n"); + break; + case 0x04: + lbs_deb_assoc("ASSOC_RESP: authentication " + "refused by AP\n"); + break; + default: + lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x " + " unknown\n", status_code); + break; + } + + if (status_code) { + lbs_mac_event_disconnected(priv); + ret = -1; + goto done; + } + + lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params, + le16_to_cpu(resp->size) - S_DS_GEN); + + /* Send a Media Connected event, according to the Spec */ + priv->connect_status = LBS_CONNECTED; + + /* Update current SSID and BSSID */ + memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); + priv->curbssparams.ssid_len = bss->ssid_len; + memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); + + priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; + priv->NF[TYPE_RXPD][TYPE_AVG] = 0; + + memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR)); + memset(priv->rawNF, 0x00, sizeof(priv->rawNF)); + priv->nextSNRNF = 0; + priv->numSNRNF = 0; + + netif_carrier_on(priv->dev); + if (!priv->tx_pending_len) + netif_wake_queue(priv->dev); + + memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); + +done: + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); + return ret; +} + +static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp) +{ + int ret = 0; + u16 command = le16_to_cpu(resp->command); + u16 result = le16_to_cpu(resp->result); + struct cmd_ds_802_11_ad_hoc_result *adhoc_resp; + union iwreq_data wrqu; + struct bss_descriptor *bss; + DECLARE_SSID_BUF(ssid); + + lbs_deb_enter(LBS_DEB_JOIN); + + adhoc_resp = (struct cmd_ds_802_11_ad_hoc_result *) resp; + + if (!priv->in_progress_assoc_req) { + lbs_deb_join("ADHOC_RESP: no in-progress association " + "request\n"); + ret = -1; + goto done; + } + bss = &priv->in_progress_assoc_req->bss; + + /* + * Join result code 0 --> SUCCESS + */ + if (result) { + lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result); + if (priv->connect_status == LBS_CONNECTED) + lbs_mac_event_disconnected(priv); + ret = -1; + goto done; + } + + /* Send a Media Connected event, according to the Spec */ + priv->connect_status = LBS_CONNECTED; + + if (command == CMD_RET(CMD_802_11_AD_HOC_START)) { + /* Update the created network descriptor with the new BSSID */ + memcpy(bss->bssid, adhoc_resp->bssid, ETH_ALEN); + } + + /* Set the BSSID from the joined/started descriptor */ + memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN); + + /* Set the new SSID to current SSID */ + memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); + priv->curbssparams.ssid_len = bss->ssid_len; + + netif_carrier_on(priv->dev); + if (!priv->tx_pending_len) + netif_wake_queue(priv->dev); + + memset(&wrqu, 0, sizeof(wrqu)); + memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); + + lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n", + print_ssid(ssid, bss->ssid, bss->ssid_len), + priv->curbssparams.bssid, + priv->curbssparams.channel); + +done: + lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); + return ret; +} + diff --git a/trunk/drivers/net/wireless/libertas/assoc.h b/trunk/drivers/net/wireless/libertas/assoc.h index 6e765e9f91a3..8b7336dd02a3 100644 --- a/trunk/drivers/net/wireless/libertas/assoc.h +++ b/trunk/drivers/net/wireless/libertas/assoc.h @@ -8,9 +8,22 @@ void lbs_association_worker(struct work_struct *work); struct assoc_request *lbs_get_association_request(struct lbs_private *priv); +struct cmd_ds_command; +int lbs_cmd_80211_authenticate(struct lbs_private *priv, + struct cmd_ds_command *cmd, + void *pdata_buf); + int lbs_adhoc_stop(struct lbs_private *priv); int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN], u16 reason); +int lbs_cmd_80211_associate(struct lbs_private *priv, + struct cmd_ds_command *cmd, + void *pdata_buf); + +int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv, + struct cmd_ds_command *resp); +int lbs_ret_80211_associate(struct lbs_private *priv, + struct cmd_ds_command *resp); #endif /* _LBS_ASSOC_H */ diff --git a/trunk/drivers/net/wireless/libertas/cmd.c b/trunk/drivers/net/wireless/libertas/cmd.c index 01db705a38ec..c455b9abbfc0 100644 --- a/trunk/drivers/net/wireless/libertas/cmd.c +++ b/trunk/drivers/net/wireless/libertas/cmd.c @@ -1220,7 +1220,8 @@ static void lbs_submit_command(struct lbs_private *priv, command = le16_to_cpu(cmd->command); /* These commands take longer */ - if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE) + if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE || + command == CMD_802_11_AUTHENTICATE) timeo = 5 * HZ; lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", @@ -1414,6 +1415,15 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); break; + case CMD_802_11_ASSOCIATE: + case CMD_802_11_REASSOCIATE: + ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf); + break; + + case CMD_802_11_AUTHENTICATE: + ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf); + break; + case CMD_MAC_REG_ACCESS: case CMD_BBP_REG_ACCESS: case CMD_RF_REG_ACCESS: @@ -1460,8 +1470,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, break; case CMD_802_11_LED_GPIO_CTRL: { - struct mrvl_ie_ledgpio *gpio = - (struct mrvl_ie_ledgpio*) + struct mrvlietypes_ledgpio *gpio = + (struct mrvlietypes_ledgpio*) cmdptr->params.ledgpio.data; memmove(&cmdptr->params.ledgpio, diff --git a/trunk/drivers/net/wireless/libertas/cmdresp.c b/trunk/drivers/net/wireless/libertas/cmdresp.c index c42d3faa2660..bcf2a9756fb6 100644 --- a/trunk/drivers/net/wireless/libertas/cmdresp.c +++ b/trunk/drivers/net/wireless/libertas/cmdresp.c @@ -5,7 +5,7 @@ #include #include #include -#include + #include #include "host.h" @@ -154,11 +154,11 @@ static int lbs_ret_802_11_rssi(struct lbs_private *priv, lbs_deb_enter(LBS_DEB_CMD); /* store the non average value */ - priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR); - priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor); + priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR); + priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor); - priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR); - priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor); + priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR); + priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor); priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], @@ -210,6 +210,12 @@ static inline int handle_cmd_response(struct lbs_private *priv, ret = lbs_ret_reg_access(priv, respcmd, resp); break; + case CMD_RET_802_11_ASSOCIATE: + case CMD_RET(CMD_802_11_ASSOCIATE): + case CMD_RET(CMD_802_11_REASSOCIATE): + ret = lbs_ret_80211_associate(priv, resp); + break; + case CMD_RET(CMD_802_11_SET_AFC): case CMD_RET(CMD_802_11_GET_AFC): spin_lock_irqsave(&priv->driver_lock, flags); @@ -219,6 +225,7 @@ static inline int handle_cmd_response(struct lbs_private *priv, break; + case CMD_RET(CMD_802_11_AUTHENTICATE): case CMD_RET(CMD_802_11_BEACON_STOP): break; diff --git a/trunk/drivers/net/wireless/libertas/debugfs.c b/trunk/drivers/net/wireless/libertas/debugfs.c index 811ffc3ef414..50e28a0cdfee 100644 --- a/trunk/drivers/net/wireless/libertas/debugfs.c +++ b/trunk/drivers/net/wireless/libertas/debugfs.c @@ -183,12 +183,12 @@ static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf, */ static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size) { - struct mrvl_ie_header *tlv_h; + struct mrvlietypesheader *tlv_h; uint16_t length; ssize_t pos = 0; while (pos < size) { - tlv_h = (struct mrvl_ie_header *) tlv; + tlv_h = (struct mrvlietypesheader *) tlv; if (!tlv_h->len) return NULL; if (tlv_h->type == cpu_to_le16(tlv_type)) @@ -206,7 +206,7 @@ static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask, size_t count, loff_t *ppos) { struct cmd_ds_802_11_subscribe_event *subscribed; - struct mrvl_ie_thresholds *got; + struct mrvlietypes_thresholds *got; struct lbs_private *priv = file->private_data; ssize_t ret = 0; size_t pos = 0; @@ -259,7 +259,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, loff_t *ppos) { struct cmd_ds_802_11_subscribe_event *events; - struct mrvl_ie_thresholds *tlv; + struct mrvlietypes_thresholds *tlv; struct lbs_private *priv = file->private_data; ssize_t buf_size; int value, freq, new_mask; diff --git a/trunk/drivers/net/wireless/libertas/dev.h b/trunk/drivers/net/wireless/libertas/dev.h index f9ec69e04734..a4455ec7c354 100644 --- a/trunk/drivers/net/wireless/libertas/dev.h +++ b/trunk/drivers/net/wireless/libertas/dev.h @@ -321,6 +321,8 @@ struct lbs_private { u32 monitormode; u8 fw_ready; + u8 fn_init_required; + u8 fn_shutdown_required; }; extern struct cmd_confirm_sleep confirm_sleep; @@ -338,7 +340,7 @@ struct bss_descriptor { u32 rssi; u32 channel; u16 beaconperiod; - __le16 atimwindow; + u32 atimwindow; /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */ u8 mode; @@ -348,10 +350,10 @@ struct bss_descriptor { unsigned long last_scanned; - union ieee_phy_param_set phy; - union ieee_ss_param_set ss; + union ieeetypes_phyparamset phyparamset; + union IEEEtypes_ssparamset ssparamset; - struct ieee_ie_country_info_full_set countryinfo; + struct ieeetypes_countryinfofullset countryinfo; u8 wpa_ie[MAX_WPA_IE_LEN]; size_t wpa_ie_len; diff --git a/trunk/drivers/net/wireless/libertas/hostcmd.h b/trunk/drivers/net/wireless/libertas/hostcmd.h index 0a2e29140add..391c54ab2b09 100644 --- a/trunk/drivers/net/wireless/libertas/hostcmd.h +++ b/trunk/drivers/net/wireless/libertas/hostcmd.h @@ -250,9 +250,7 @@ struct cmd_ds_gspi_bus_config { } __attribute__ ((packed)); struct cmd_ds_802_11_authenticate { - struct cmd_header hdr; - - u8 bssid[ETH_ALEN]; + u8 macaddr[ETH_ALEN]; u8 authtype; u8 reserved[10]; } __attribute__ ((packed)); @@ -265,23 +263,22 @@ struct cmd_ds_802_11_deauthenticate { } __attribute__ ((packed)); struct cmd_ds_802_11_associate { - struct cmd_header hdr; - - u8 bssid[6]; + u8 peerstaaddr[6]; __le16 capability; __le16 listeninterval; __le16 bcnperiod; u8 dtimperiod; - u8 iebuf[512]; /* Enough for required and most optional IEs */ -} __attribute__ ((packed)); -struct cmd_ds_802_11_associate_response { - struct cmd_header hdr; +#if 0 + mrvlietypes_ssidparamset_t ssidParamSet; + mrvlietypes_phyparamset_t phyparamset; + mrvlietypes_ssparamset_t ssparamset; + mrvlietypes_ratesparamset_t ratesParamSet; +#endif +} __attribute__ ((packed)); - __le16 capability; - __le16 statuscode; - __le16 aid; - u8 iebuf[512]; +struct cmd_ds_802_11_associate_rsp { + struct ieeetypes_assocrsp assocRsp; } __attribute__ ((packed)); struct cmd_ds_802_11_set_wep { @@ -538,11 +535,9 @@ struct cmd_ds_802_11_ad_hoc_start { u8 bsstype; __le16 beaconperiod; u8 dtimperiod; /* Reserved on v9 and later */ - struct ieee_ie_ibss_param_set ibss; - u8 reserved1[4]; - struct ieee_ie_ds_param_set ds; - u8 reserved2[4]; - __le16 probedelay; /* Reserved on v9 and later */ + union IEEEtypes_ssparamset ssparamset; + union ieeetypes_phyparamset phyparamset; + __le16 probedelay; __le16 capability; u8 rates[MAX_RATES]; u8 tlv_memory_size_pad[100]; @@ -563,10 +558,8 @@ struct adhoc_bssdesc { u8 dtimperiod; __le64 timestamp; __le64 localtime; - struct ieee_ie_ds_param_set ds; - u8 reserved1[4]; - struct ieee_ie_ibss_param_set ibss; - u8 reserved2[4]; + union ieeetypes_phyparamset phyparamset; + union IEEEtypes_ssparamset ssparamset; __le16 capability; u8 rates[MAX_RATES]; @@ -772,6 +765,8 @@ struct cmd_ds_command { /* command Body */ union { struct cmd_ds_802_11_ps_mode psmode; + struct cmd_ds_802_11_associate associate; + struct cmd_ds_802_11_authenticate auth; struct cmd_ds_802_11_get_stat gstat; struct cmd_ds_802_3_get_stat gstat_8023; struct cmd_ds_802_11_rf_antenna rant; diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c index 8cdb88c6ca28..a7e3fc119b70 100644 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ b/trunk/drivers/net/wireless/libertas/if_sdio.c @@ -39,24 +39,8 @@ #include "decl.h" #include "defs.h" #include "dev.h" -#include "cmd.h" #include "if_sdio.h" -/* The if_sdio_remove() callback function is called when - * user removes this module from kernel space or ejects - * the card from the slot. The driver handles these 2 cases - * differently for SD8688 combo chip. - * If the user is removing the module, the FUNC_SHUTDOWN - * command for SD8688 is sent to the firmware. - * If the card is removed, there is no need to send this command. - * - * The variable 'user_rmmod' is used to distinguish these two - * scenarios. This flag is initialized as FALSE in case the card - * is removed, and will be set to TRUE for module removal when - * module_exit function is called. - */ -static u8 user_rmmod; - static char *lbs_helper_name = NULL; module_param_named(helper_name, lbs_helper_name, charp, 0644); @@ -77,6 +61,7 @@ struct if_sdio_model { int model; const char *helper; const char *firmware; + struct if_sdio_card *card; }; static struct if_sdio_model if_sdio_models[] = { @@ -85,18 +70,21 @@ static struct if_sdio_model if_sdio_models[] = { .model = IF_SDIO_MODEL_8385, .helper = "sd8385_helper.bin", .firmware = "sd8385.bin", + .card = NULL, }, { /* 8686 */ .model = IF_SDIO_MODEL_8686, .helper = "sd8686_helper.bin", .firmware = "sd8686.bin", + .card = NULL, }, { /* 8688 */ .model = IF_SDIO_MODEL_8688, .helper = "sd8688_helper.bin", .firmware = "sd8688.bin", + .card = NULL, }, }; @@ -939,6 +927,8 @@ static int if_sdio_probe(struct sdio_func *func, goto free; } + if_sdio_models[i].card = card; + card->helper = if_sdio_models[i].helper; card->firmware = if_sdio_models[i].firmware; @@ -1024,16 +1014,8 @@ static int if_sdio_probe(struct sdio_func *func, /* * FUNC_INIT is required for SD8688 WLAN/BT multiple functions */ - if (card->model == IF_SDIO_MODEL_8688) { - struct cmd_header cmd; - - memset(&cmd, 0, sizeof(cmd)); - - lbs_deb_sdio("send function INIT command\n"); - if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd), - lbs_cmd_copyback, (unsigned long) &cmd)) - lbs_pr_alert("CMD_FUNC_INIT cmd failed\n"); - } + priv->fn_init_required = + (card->model == IF_SDIO_MODEL_8688) ? 1 : 0; ret = lbs_start_card(priv); if (ret) @@ -1075,39 +1057,30 @@ static void if_sdio_remove(struct sdio_func *func) { struct if_sdio_card *card; struct if_sdio_packet *packet; + int ret; lbs_deb_enter(LBS_DEB_SDIO); card = sdio_get_drvdata(func); - if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) { - /* - * FUNC_SHUTDOWN is required for SD8688 WLAN/BT - * multiple functions - */ - struct cmd_header cmd; - - memset(&cmd, 0, sizeof(cmd)); - - lbs_deb_sdio("send function SHUTDOWN command\n"); - if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN, - &cmd, sizeof(cmd), lbs_cmd_copyback, - (unsigned long) &cmd)) - lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n"); - } + lbs_stop_card(card->priv); card->priv->surpriseremoved = 1; lbs_deb_sdio("call remove card\n"); - lbs_stop_card(card->priv); lbs_remove_card(card->priv); flush_workqueue(card->workqueue); destroy_workqueue(card->workqueue); sdio_claim_host(func); + + /* Disable interrupts */ + sdio_writeb(func, 0x00, IF_SDIO_H_INT_MASK, &ret); + sdio_release_irq(func); sdio_disable_func(func); + sdio_release_host(func); while (card->packets) { @@ -1143,9 +1116,6 @@ static int __init if_sdio_init_module(void) ret = sdio_register_driver(&if_sdio_driver); - /* Clear the flag in case user removes the card. */ - user_rmmod = 0; - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); return ret; @@ -1153,10 +1123,22 @@ static int __init if_sdio_init_module(void) static void __exit if_sdio_exit_module(void) { + int i; + struct if_sdio_card *card; + lbs_deb_enter(LBS_DEB_SDIO); - /* Set the flag as user is removing this module. */ - user_rmmod = 1; + for (i = 0; i < ARRAY_SIZE(if_sdio_models); i++) { + card = if_sdio_models[i].card; + + /* + * FUNC_SHUTDOWN is required for SD8688 WLAN/BT + * multiple functions + */ + if (card && card->priv) + card->priv->fn_shutdown_required = + (card->model == IF_SDIO_MODEL_8688) ? 1 : 0; + } sdio_unregister_driver(&if_sdio_driver); diff --git a/trunk/drivers/net/wireless/libertas/if_spi.c b/trunk/drivers/net/wireless/libertas/if_spi.c index f8c2898d82b0..5fa55fe1f860 100644 --- a/trunk/drivers/net/wireless/libertas/if_spi.c +++ b/trunk/drivers/net/wireless/libertas/if_spi.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -50,6 +51,13 @@ struct if_spi_card { u16 card_id; u8 card_rev; + /* Pin number for our GPIO chip-select. */ + /* TODO: Once the generic SPI layer has some additional features, we + * should take this out and use the normal chip select here. + * We need support for chip select delays, and not dropping chipselect + * after each word. */ + int gpio_cs; + /* The last time that we initiated an SPU operation */ unsigned long prev_xfer_time; @@ -111,6 +119,9 @@ static struct chip_ident chip_id_to_device_name[] = { * First we have to put a SPU register name on the bus. Then we can * either read from or write to that register. * + * For 16-bit transactions, byte order on the bus is big-endian. + * We don't have to worry about that here, though. + * The translation takes place in the SPI routines. */ static void spu_transaction_init(struct if_spi_card *card) @@ -122,10 +133,12 @@ static void spu_transaction_init(struct if_spi_card *card) * If not, we have to busy-wait to be on the safe side. */ ndelay(400); } + gpio_set_value(card->gpio_cs, 0); /* assert CS */ } static void spu_transaction_finish(struct if_spi_card *card) { + gpio_set_value(card->gpio_cs, 1); /* drop CS */ card->prev_xfer_time = jiffies; } @@ -134,14 +147,7 @@ static void spu_transaction_finish(struct if_spi_card *card) static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) { int err = 0; - u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); - struct spi_message m; - struct spi_transfer reg_trans; - struct spi_transfer data_trans; - - spi_message_init(&m); - memset(®_trans, 0, sizeof(reg_trans)); - memset(&data_trans, 0, sizeof(data_trans)); + u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK; /* You must give an even number of bytes to the SPU, even if it * doesn't care about the last one. */ @@ -150,26 +156,29 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) spu_transaction_init(card); /* write SPU register index */ - reg_trans.tx_buf = ®_out; - reg_trans.len = sizeof(reg_out); - - data_trans.tx_buf = buf; - data_trans.len = len; + err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); + if (err) + goto out; - spi_message_add_tail(®_trans, &m); - spi_message_add_tail(&data_trans, &m); + err = spi_write(card->spi, buf, len); - err = spi_sync(card->spi, &m); +out: spu_transaction_finish(card); return err; } static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) { - u16 buff; + return spu_write(card, reg, (u8 *)&val, sizeof(u16)); +} - buff = cpu_to_le16(val); - return spu_write(card, reg, (u8 *)&buff, sizeof(u16)); +static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val) +{ + /* The lower 16 bits are written first. */ + u16 out[2]; + out[0] = val & 0xffff; + out[1] = (val & 0xffff0000) >> 16; + return spu_write(card, reg, (u8 *)&out, sizeof(u32)); } static inline int spu_reg_is_port_reg(u16 reg) @@ -186,13 +195,10 @@ static inline int spu_reg_is_port_reg(u16 reg) static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) { - unsigned int delay; + unsigned int i, delay; int err = 0; - u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); - struct spi_message m; - struct spi_transfer reg_trans; - struct spi_transfer dummy_trans; - struct spi_transfer data_trans; + u16 zero = 0; + u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK; /* You must take an even number of bytes from the SPU, even if you * don't care about the last one. */ @@ -200,34 +206,29 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) spu_transaction_init(card); - spi_message_init(&m); - memset(®_trans, 0, sizeof(reg_trans)); - memset(&dummy_trans, 0, sizeof(dummy_trans)); - memset(&data_trans, 0, sizeof(data_trans)); - /* write SPU register index */ - reg_trans.tx_buf = ®_out; - reg_trans.len = sizeof(reg_out); - spi_message_add_tail(®_trans, &m); + err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); + if (err) + goto out; delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : card->spu_reg_delay; if (card->use_dummy_writes) { /* Clock in dummy cycles while the SPU fills the FIFO */ - dummy_trans.len = delay / 8; - spi_message_add_tail(&dummy_trans, &m); + for (i = 0; i < delay / 16; ++i) { + err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); + if (err) + return err; + } } else { /* Busy-wait while the SPU fills the FIFO */ - reg_trans.delay_usecs = - DIV_ROUND_UP((100 + (delay * 10)), 1000); + ndelay(100 + (delay * 10)); } /* read in data */ - data_trans.rx_buf = buf; - data_trans.len = len; - spi_message_add_tail(&data_trans, &m); + err = spi_read(card->spi, buf, len); - err = spi_sync(card->spi, &m); +out: spu_transaction_finish(card); return err; } @@ -235,25 +236,18 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) /* Read 16 bits from an SPI register */ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) { - u16 buf; - int ret; - - ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); - if (ret == 0) - *val = le16_to_cpup(&buf); - return ret; + return spu_read(card, reg, (u8 *)val, sizeof(u16)); } /* Read 32 bits from an SPI register. * The low 16 bits are read first. */ static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) { - u32 buf; + u16 buf[2]; int err; - - err = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); + err = spu_read(card, reg, (u8 *)buf, sizeof(u32)); if (!err) - *val = le32_to_cpup(&buf); + *val = buf[0] | (buf[1] << 16); return err; } @@ -1057,6 +1051,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) spi_set_drvdata(spi, card); card->pdata = pdata; card->spi = spi; + card->gpio_cs = pdata->gpio_cs; card->prev_xfer_time = jiffies; sema_init(&card->spi_ready, 0); @@ -1065,18 +1060,26 @@ static int __devinit if_spi_probe(struct spi_device *spi) INIT_LIST_HEAD(&card->data_packet_list); spin_lock_init(&card->buffer_lock); + /* set up GPIO CS line. TODO: use regular CS line */ + err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); + if (err) + goto free_card; + err = gpio_direction_output(card->gpio_cs, 1); + if (err) + goto free_gpio; + /* Initialize the SPI Interface Unit */ err = spu_init(card, pdata->use_dummy_writes); if (err) - goto free_card; + goto free_gpio; err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); if (err) - goto free_card; + goto free_gpio; /* Firmware load */ err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); if (err) - goto free_card; + goto free_gpio; if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) lbs_deb_spi("Firmware is already loaded for " "Marvell WLAN 802.11 adapter\n"); @@ -1084,7 +1087,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) err = if_spi_calculate_fw_names(card->card_id, card->helper_fw_name, card->main_fw_name); if (err) - goto free_card; + goto free_gpio; lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " "(chip_id = 0x%04x, chip_rev = 0x%02x) " @@ -1095,23 +1098,23 @@ static int __devinit if_spi_probe(struct spi_device *spi) spi->max_speed_hz); err = if_spi_prog_helper_firmware(card); if (err) - goto free_card; + goto free_gpio; err = if_spi_prog_main_firmware(card); if (err) - goto free_card; + goto free_gpio; lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); } err = spu_set_interrupt_mode(card, 0, 1); if (err) - goto free_card; + goto free_gpio; /* Register our card with libertas. * This will call alloc_etherdev */ priv = lbs_add_card(card, &spi->dev); if (!priv) { err = -ENOMEM; - goto free_card; + goto free_gpio; } card->priv = priv; priv->card = card; @@ -1156,6 +1159,8 @@ static int __devinit if_spi_probe(struct spi_device *spi) if_spi_terminate_spi_thread(card); remove_card: lbs_remove_card(priv); /* will call free_netdev */ +free_gpio: + gpio_free(card->gpio_cs); free_card: free_if_spi_card(card); out: @@ -1176,6 +1181,7 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) free_irq(spi->irq, card); if_spi_terminate_spi_thread(card); lbs_remove_card(priv); /* will call free_netdev */ + gpio_free(card->gpio_cs); if (card->pdata->teardown) card->pdata->teardown(spi); free_if_spi_card(card); diff --git a/trunk/drivers/net/wireless/libertas/main.c b/trunk/drivers/net/wireless/libertas/main.c index 89575e448015..a58a12352672 100644 --- a/trunk/drivers/net/wireless/libertas/main.c +++ b/trunk/drivers/net/wireless/libertas/main.c @@ -1002,9 +1002,17 @@ static int lbs_setup_firmware(struct lbs_private *priv) { int ret = -1; s16 curlevel = 0, minlevel = 0, maxlevel = 0; + struct cmd_header cmd; lbs_deb_enter(LBS_DEB_FW); + if (priv->fn_init_required) { + memset(&cmd, 0, sizeof(cmd)); + if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd), + lbs_cmd_copyback, (unsigned long) &cmd)) + lbs_pr_alert("CMD_FUNC_INIT command failed\n"); + } + /* Read MAC address from firmware */ memset(priv->current_addr, 0xff, ETH_ALEN); ret = lbs_update_hw_spec(priv); @@ -1192,6 +1200,9 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) priv->mesh_open = 0; priv->infra_open = 0; + priv->fn_init_required = 0; + priv->fn_shutdown_required = 0; + /* Setup the OS Interface to our functions */ dev->netdev_ops = &lbs_netdev_ops; dev->watchdog_timeo = 5 * HZ; @@ -1373,11 +1384,20 @@ void lbs_stop_card(struct lbs_private *priv) struct net_device *dev; struct cmd_ctrl_node *cmdnode; unsigned long flags; + struct cmd_header cmd; lbs_deb_enter(LBS_DEB_MAIN); if (!priv) goto out; + + if (priv->fn_shutdown_required) { + memset(&cmd, 0, sizeof(cmd)); + if (__lbs_cmd(priv, CMD_FUNC_SHUTDOWN, &cmd, sizeof(cmd), + lbs_cmd_copyback, (unsigned long) &cmd)) + lbs_pr_alert("CMD_FUNC_SHUTDOWN command failed\n"); + } + dev = priv->dev; netif_stop_queue(dev); diff --git a/trunk/drivers/net/wireless/libertas/scan.c b/trunk/drivers/net/wireless/libertas/scan.c index 601b54249677..8124db36aaff 100644 --- a/trunk/drivers/net/wireless/libertas/scan.c +++ b/trunk/drivers/net/wireless/libertas/scan.c @@ -27,12 +27,12 @@ + 40) /* 40 for WPAIE */ //! Memory needed to store a max sized channel List TLV for a firmware scan -#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvl_ie_header) \ +#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvlietypesheader) \ + (MRVDRV_MAX_CHANNELS_PER_SCAN \ * sizeof(struct chanscanparamset))) //! Memory needed to store a max number/size SSID TLV for a firmware scan -#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvl_ie_ssid_param_set)) +#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset)) //! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max #define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \ @@ -211,7 +211,7 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv, */ static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) { - struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv; + struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv; ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len); @@ -249,7 +249,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv, int chan_count) { size_t size = sizeof(struct chanscanparamset) *chan_count; - struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv; + struct mrvlietypes_chanlistparamset *chan_tlv = (void *)tlv; chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); memcpy(chan_tlv->chanscanparam, chan_list, size); @@ -270,7 +270,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv, static int lbs_scan_add_rates_tlv(uint8_t *tlv) { int i; - struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; + struct mrvlietypes_ratesparamset *rate_tlv = (void *)tlv; rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); tlv += sizeof(rate_tlv->header); @@ -513,12 +513,12 @@ void lbs_scan_worker(struct work_struct *work) static int lbs_process_bss(struct bss_descriptor *bss, uint8_t **pbeaconinfo, int *bytesleft) { - struct ieee_ie_fh_param_set *fh; - struct ieee_ie_ds_param_set *ds; - struct ieee_ie_cf_param_set *cf; - struct ieee_ie_ibss_param_set *ibss; + struct ieeetypes_fhparamset *pFH; + struct ieeetypes_dsparamset *pDS; + struct ieeetypes_cfparamset *pCF; + struct ieeetypes_ibssparamset *pibss; DECLARE_SSID_BUF(ssid); - struct ieee_ie_country_info_set *pcountryinfo; + struct ieeetypes_countryinfoset *pcountryinfo; uint8_t *pos, *end, *p; uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; uint16_t beaconsize = 0; @@ -616,49 +616,50 @@ static int lbs_process_bss(struct bss_descriptor *bss, break; case WLAN_EID_FH_PARAMS: - fh = (struct ieee_ie_fh_param_set *) pos; - memcpy(&bss->phy.fh, fh, sizeof(*fh)); + pFH = (struct ieeetypes_fhparamset *) pos; + memmove(&bss->phyparamset.fhparamset, pFH, + sizeof(struct ieeetypes_fhparamset)); lbs_deb_scan("got FH IE\n"); break; case WLAN_EID_DS_PARAMS: - ds = (struct ieee_ie_ds_param_set *) pos; - bss->channel = ds->channel; - memcpy(&bss->phy.ds, ds, sizeof(*ds)); + pDS = (struct ieeetypes_dsparamset *) pos; + bss->channel = pDS->currentchan; + memcpy(&bss->phyparamset.dsparamset, pDS, + sizeof(struct ieeetypes_dsparamset)); lbs_deb_scan("got DS IE, channel %d\n", bss->channel); break; case WLAN_EID_CF_PARAMS: - cf = (struct ieee_ie_cf_param_set *) pos; - memcpy(&bss->ss.cf, cf, sizeof(*cf)); + pCF = (struct ieeetypes_cfparamset *) pos; + memcpy(&bss->ssparamset.cfparamset, pCF, + sizeof(struct ieeetypes_cfparamset)); lbs_deb_scan("got CF IE\n"); break; case WLAN_EID_IBSS_PARAMS: - ibss = (struct ieee_ie_ibss_param_set *) pos; - bss->atimwindow = ibss->atimwindow; - memcpy(&bss->ss.ibss, ibss, sizeof(*ibss)); + pibss = (struct ieeetypes_ibssparamset *) pos; + bss->atimwindow = le16_to_cpu(pibss->atimwindow); + memmove(&bss->ssparamset.ibssparamset, pibss, + sizeof(struct ieeetypes_ibssparamset)); lbs_deb_scan("got IBSS IE\n"); break; case WLAN_EID_COUNTRY: - pcountryinfo = (struct ieee_ie_country_info_set *) pos; + pcountryinfo = (struct ieeetypes_countryinfoset *) pos; lbs_deb_scan("got COUNTRY IE\n"); - if (pcountryinfo->header.len < sizeof(pcountryinfo->countrycode) - || pcountryinfo->header.len > 254) { - lbs_deb_scan("%s: 11D- Err CountryInfo len %d, min %zd, max 254\n", - __func__, - pcountryinfo->header.len, - sizeof(pcountryinfo->countrycode)); + if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) + || pcountryinfo->len > 254) { + lbs_deb_scan("process_bss: 11D- Err CountryInfo len %d, min %zd, max 254\n", + pcountryinfo->len, sizeof(pcountryinfo->countrycode)); ret = -1; goto done; } - memcpy(&bss->countryinfo, pcountryinfo, - pcountryinfo->header.len + 2); + memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2); lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo", (uint8_t *) pcountryinfo, - (int) (pcountryinfo->header.len + 2)); + (int) (pcountryinfo->len + 2)); break; case WLAN_EID_EXT_SUPP_RATES: @@ -1129,7 +1130,7 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy, goto done; } - bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize); + bytesleft = le16_to_cpu(scanresp->bssdescriptsize); lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); scanrespsize = le16_to_cpu(resp->size); diff --git a/trunk/drivers/net/wireless/libertas/types.h b/trunk/drivers/net/wireless/libertas/types.h index 99905df65b25..de03b9c9c204 100644 --- a/trunk/drivers/net/wireless/libertas/types.h +++ b/trunk/drivers/net/wireless/libertas/types.h @@ -8,14 +8,9 @@ #include #include -struct ieee_ie_header { - u8 id; +struct ieeetypes_cfparamset { + u8 elementid; u8 len; -} __attribute__ ((packed)); - -struct ieee_ie_cf_param_set { - struct ieee_ie_header header; - u8 cfpcnt; u8 cfpperiod; __le16 cfpmaxduration; @@ -23,35 +18,42 @@ struct ieee_ie_cf_param_set { } __attribute__ ((packed)); -struct ieee_ie_ibss_param_set { - struct ieee_ie_header header; - +struct ieeetypes_ibssparamset { + u8 elementid; + u8 len; __le16 atimwindow; } __attribute__ ((packed)); -union ieee_ss_param_set { - struct ieee_ie_cf_param_set cf; - struct ieee_ie_ibss_param_set ibss; +union IEEEtypes_ssparamset { + struct ieeetypes_cfparamset cfparamset; + struct ieeetypes_ibssparamset ibssparamset; } __attribute__ ((packed)); -struct ieee_ie_fh_param_set { - struct ieee_ie_header header; - +struct ieeetypes_fhparamset { + u8 elementid; + u8 len; __le16 dwelltime; u8 hopset; u8 hoppattern; u8 hopindex; } __attribute__ ((packed)); -struct ieee_ie_ds_param_set { - struct ieee_ie_header header; +struct ieeetypes_dsparamset { + u8 elementid; + u8 len; + u8 currentchan; +} __attribute__ ((packed)); - u8 channel; +union ieeetypes_phyparamset { + struct ieeetypes_fhparamset fhparamset; + struct ieeetypes_dsparamset dsparamset; } __attribute__ ((packed)); -union ieee_phy_param_set { - struct ieee_ie_fh_param_set fh; - struct ieee_ie_ds_param_set ds; +struct ieeetypes_assocrsp { + __le16 capability; + __le16 statuscode; + __le16 aid; + u8 iebuffer[1]; } __attribute__ ((packed)); /** TLV type ID definition */ @@ -92,33 +94,32 @@ union ieee_phy_param_set { #define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) #define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) #define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23) -#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) #define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37) #define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291) /** TLV related data structures*/ -struct mrvl_ie_header { +struct mrvlietypesheader { __le16 type; __le16 len; } __attribute__ ((packed)); -struct mrvl_ie_data { - struct mrvl_ie_header header; +struct mrvlietypes_data { + struct mrvlietypesheader header; u8 Data[1]; } __attribute__ ((packed)); -struct mrvl_ie_rates_param_set { - struct mrvl_ie_header header; +struct mrvlietypes_ratesparamset { + struct mrvlietypesheader header; u8 rates[1]; } __attribute__ ((packed)); -struct mrvl_ie_ssid_param_set { - struct mrvl_ie_header header; +struct mrvlietypes_ssidparamset { + struct mrvlietypesheader header; u8 ssid[1]; } __attribute__ ((packed)); -struct mrvl_ie_wildcard_ssid_param_set { - struct mrvl_ie_header header; +struct mrvlietypes_wildcardssidparamset { + struct mrvlietypesheader header; u8 MaxSsidlength; u8 ssid[1]; } __attribute__ ((packed)); @@ -143,72 +144,91 @@ struct chanscanparamset { __le16 maxscantime; } __attribute__ ((packed)); -struct mrvl_ie_chanlist_param_set { - struct mrvl_ie_header header; +struct mrvlietypes_chanlistparamset { + struct mrvlietypesheader header; struct chanscanparamset chanscanparam[1]; } __attribute__ ((packed)); -struct mrvl_ie_cf_param_set { - struct mrvl_ie_header header; +struct cfparamset { u8 cfpcnt; u8 cfpperiod; __le16 cfpmaxduration; __le16 cfpdurationremaining; } __attribute__ ((packed)); -struct mrvl_ie_ds_param_set { - struct mrvl_ie_header header; - u8 channel; +struct ibssparamset { + __le16 atimwindow; } __attribute__ ((packed)); -struct mrvl_ie_rsn_param_set { - struct mrvl_ie_header header; - u8 rsnie[1]; +struct mrvlietypes_ssparamset { + struct mrvlietypesheader header; + union { + struct cfparamset cfparamset[1]; + struct ibssparamset ibssparamset[1]; + } cf_ibss; } __attribute__ ((packed)); -struct mrvl_ie_tsf_timestamp { - struct mrvl_ie_header header; - __le64 tsftable[1]; +struct fhparamset { + __le16 dwelltime; + u8 hopset; + u8 hoppattern; + u8 hopindex; +} __attribute__ ((packed)); + +struct dsparamset { + u8 currentchan; } __attribute__ ((packed)); -/* v9 and later firmware only */ -struct mrvl_ie_auth_type { - struct mrvl_ie_header header; - __le16 auth; +struct mrvlietypes_phyparamset { + struct mrvlietypesheader header; + union { + struct fhparamset fhparamset[1]; + struct dsparamset dsparamset[1]; + } fh_ds; +} __attribute__ ((packed)); + +struct mrvlietypes_rsnparamset { + struct mrvlietypesheader header; + u8 rsnie[1]; +} __attribute__ ((packed)); + +struct mrvlietypes_tsftimestamp { + struct mrvlietypesheader header; + __le64 tsftable[1]; } __attribute__ ((packed)); /** Local Power capability */ -struct mrvl_ie_power_capability { - struct mrvl_ie_header header; +struct mrvlietypes_powercapability { + struct mrvlietypesheader header; s8 minpower; s8 maxpower; } __attribute__ ((packed)); /* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */ -struct mrvl_ie_thresholds { - struct mrvl_ie_header header; +struct mrvlietypes_thresholds { + struct mrvlietypesheader header; u8 value; u8 freq; } __attribute__ ((packed)); -struct mrvl_ie_beacons_missed { - struct mrvl_ie_header header; +struct mrvlietypes_beaconsmissed { + struct mrvlietypesheader header; u8 beaconmissed; u8 reserved; } __attribute__ ((packed)); -struct mrvl_ie_num_probes { - struct mrvl_ie_header header; +struct mrvlietypes_numprobes { + struct mrvlietypesheader header; __le16 numprobes; } __attribute__ ((packed)); -struct mrvl_ie_bcast_probe { - struct mrvl_ie_header header; +struct mrvlietypes_bcastprobe { + struct mrvlietypesheader header; __le16 bcastprobe; } __attribute__ ((packed)); -struct mrvl_ie_num_ssid_probe { - struct mrvl_ie_header header; +struct mrvlietypes_numssidprobe { + struct mrvlietypesheader header; __le16 numssidprobe; } __attribute__ ((packed)); @@ -217,8 +237,8 @@ struct led_pin { u8 pin; } __attribute__ ((packed)); -struct mrvl_ie_ledgpio { - struct mrvl_ie_header header; +struct mrvlietypes_ledgpio { + struct mrvlietypesheader header; struct led_pin ledpin[1]; } __attribute__ ((packed)); @@ -230,8 +250,8 @@ struct led_bhv { } __attribute__ ((packed)); -struct mrvl_ie_ledbhv { - struct mrvl_ie_header header; +struct mrvlietypes_ledbhv { + struct mrvlietypesheader header; struct led_bhv ledbhv[1]; } __attribute__ ((packed)); diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index e789c6e9938c..574b8bb121e1 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -280,6 +280,7 @@ struct mac80211_hwsim_data { struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; struct ieee80211_channel *channel; + int radio_enabled; unsigned long beacon_int; /* in jiffies unit */ unsigned int rx_filter; int started; @@ -417,7 +418,8 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, if (data == data2) continue; - if (!data2->started || !hwsim_ps_rx_ok(data2, skb) || + if (!data2->started || !data2->radio_enabled || + !hwsim_ps_rx_ok(data2, skb) || data->channel->center_freq != data2->channel->center_freq || !(data->group & data2->group)) continue; @@ -439,6 +441,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { + struct mac80211_hwsim_data *data = hw->priv; bool ack; struct ieee80211_tx_info *txi; @@ -450,6 +453,13 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } + if (!data->radio_enabled) { + printk(KERN_DEBUG "%s: dropped TX frame since radio " + "disabled\n", wiphy_name(hw->wiphy)); + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + ack = mac80211_hwsim_tx_frame(hw, skb); txi = IEEE80211_SKB_CB(skb); @@ -536,7 +546,7 @@ static void mac80211_hwsim_beacon(unsigned long arg) struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; struct mac80211_hwsim_data *data = hw->priv; - if (!data->started) + if (!data->started || !data->radio_enabled) return; ieee80211_iterate_active_interfaces_atomic( @@ -552,14 +562,15 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) struct mac80211_hwsim_data *data = hw->priv; struct ieee80211_conf *conf = &hw->conf; - printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n", + printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d idle=%d ps=%d)\n", wiphy_name(hw->wiphy), __func__, - conf->channel->center_freq, + conf->channel->center_freq, conf->radio_enabled, !!(conf->flags & IEEE80211_CONF_IDLE), !!(conf->flags & IEEE80211_CONF_PS)); data->channel = conf->channel; - if (!data->started || !data->beacon_int) + data->radio_enabled = conf->radio_enabled; + if (!data->started || !data->radio_enabled || !data->beacon_int) del_timer(&data->beacon_timer); else mod_timer(&data->beacon_timer, jiffies + data->beacon_int); @@ -776,7 +787,8 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) pspoll->aid = cpu_to_le16(0xc000 | vp->aid); memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); memcpy(pspoll->ta, mac, ETH_ALEN); - if (!mac80211_hwsim_tx_frame(data->hw, skb)) + if (data->radio_enabled && + !mac80211_hwsim_tx_frame(data->hw, skb)) printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__); dev_kfree_skb(skb); } @@ -807,7 +819,8 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, memcpy(hdr->addr1, vp->bssid, ETH_ALEN); memcpy(hdr->addr2, mac, ETH_ALEN); memcpy(hdr->addr3, vp->bssid, ETH_ALEN); - if (!mac80211_hwsim_tx_frame(data->hw, skb)) + if (data->radio_enabled && + !mac80211_hwsim_tx_frame(data->hw, skb)) printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); dev_kfree_skb(skb); } diff --git a/trunk/drivers/net/wireless/p54/p54common.c b/trunk/drivers/net/wireless/p54/p54common.c index b618bd14583f..48d81d98e12d 100644 --- a/trunk/drivers/net/wireless/p54/p54common.c +++ b/trunk/drivers/net/wireless/p54/p54common.c @@ -823,30 +823,30 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb) struct p54_tx_info *range; unsigned long flags; - if (unlikely(!skb || !dev || skb_queue_empty(&priv->tx_queue))) + if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue))) return; - /* There used to be a check here to see if the SKB was on the - * TX queue or not. This can never happen because all SKBs we - * see here successfully went through p54_assign_address() - * which means the SKB is on the ->tx_queue. + /* + * don't try to free an already unlinked skb */ + if (unlikely((!skb->next) || (!skb->prev))) + return; spin_lock_irqsave(&priv->tx_queue.lock, flags); info = IEEE80211_SKB_CB(skb); range = (void *)info->rate_driver_data; - if (!skb_queue_is_first(&priv->tx_queue, skb)) { + if (skb->prev != (struct sk_buff *)&priv->tx_queue) { struct ieee80211_tx_info *ni; struct p54_tx_info *mr; - ni = IEEE80211_SKB_CB(skb_queue_prev(&priv->tx_queue, skb)); + ni = IEEE80211_SKB_CB(skb->prev); mr = (struct p54_tx_info *)ni->rate_driver_data; } - if (!skb_queue_is_last(&priv->tx_queue, skb)) { + if (skb->next != (struct sk_buff *)&priv->tx_queue) { struct ieee80211_tx_info *ni; struct p54_tx_info *mr; - ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, skb)); + ni = IEEE80211_SKB_CB(skb->next); mr = (struct p54_tx_info *)ni->rate_driver_data; } __skb_unlink(skb, &priv->tx_queue); @@ -864,13 +864,15 @@ static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev, unsigned long flags; spin_lock_irqsave(&priv->tx_queue.lock, flags); - skb_queue_walk(&priv->tx_queue, entry) { + entry = priv->tx_queue.next; + while (entry != (struct sk_buff *)&priv->tx_queue) { struct p54_hdr *hdr = (struct p54_hdr *) entry->data; if (hdr->req_id == req_id) { spin_unlock_irqrestore(&priv->tx_queue.lock, flags); return entry; } + entry = entry->next; } spin_unlock_irqrestore(&priv->tx_queue.lock, flags); return NULL; @@ -888,22 +890,24 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) int count, idx; spin_lock_irqsave(&priv->tx_queue.lock, flags); - skb_queue_walk(&priv->tx_queue, entry) { + entry = (struct sk_buff *) priv->tx_queue.next; + while (entry != (struct sk_buff *)&priv->tx_queue) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); struct p54_hdr *entry_hdr; struct p54_tx_data *entry_data; unsigned int pad = 0, frame_len; range = (void *)info->rate_driver_data; - if (range->start_addr != addr) + if (range->start_addr != addr) { + entry = entry->next; continue; + } - if (!skb_queue_is_last(&priv->tx_queue, entry)) { + if (entry->next != (struct sk_buff *)&priv->tx_queue) { struct ieee80211_tx_info *ni; struct p54_tx_info *mr; - ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, - entry)); + ni = IEEE80211_SKB_CB(entry->next); mr = (struct p54_tx_info *)ni->rate_driver_data; } @@ -1164,21 +1168,23 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, } } - skb_queue_walk(&priv->tx_queue, entry) { + entry = priv->tx_queue.next; + while (left--) { u32 hole_size; info = IEEE80211_SKB_CB(entry); range = (void *)info->rate_driver_data; hole_size = range->start_addr - last_addr; if (!target_skb && hole_size >= len) { - target_skb = skb_queue_prev(&priv->tx_queue, entry); + target_skb = entry->prev; hole_size -= len; target_addr = last_addr; } largest_hole = max(largest_hole, hole_size); last_addr = range->end_addr; + entry = entry->next; } if (!target_skb && priv->rx_end - last_addr >= len) { - target_skb = skb_peek_tail(&priv->tx_queue); + target_skb = priv->tx_queue.prev; largest_hole = max(largest_hole, priv->rx_end - last_addr - len); if (!skb_queue_empty(&priv->tx_queue)) { info = IEEE80211_SKB_CB(target_skb); @@ -2084,6 +2090,7 @@ static int p54_start(struct ieee80211_hw *dev) static void p54_stop(struct ieee80211_hw *dev) { struct p54_common *priv = dev->priv; + struct sk_buff *skb; mutex_lock(&priv->conf_mutex); priv->mode = NL80211_IFTYPE_UNSPECIFIED; @@ -2098,7 +2105,8 @@ static void p54_stop(struct ieee80211_hw *dev) p54_tx_cancel(dev, priv->cached_beacon); priv->stop(dev); - skb_queue_purge(&priv->tx_queue); + while ((skb = skb_dequeue(&priv->tx_queue))) + kfree_skb(skb); priv->cached_beacon = NULL; priv->tsf_high32 = priv->tsf_low32 = 0; mutex_unlock(&priv->conf_mutex); diff --git a/trunk/drivers/net/wireless/p54/p54usb.c b/trunk/drivers/net/wireless/p54/p54usb.c index 0e877a104a89..f40c0f468b27 100644 --- a/trunk/drivers/net/wireless/p54/p54usb.c +++ b/trunk/drivers/net/wireless/p54/p54usb.c @@ -84,8 +84,8 @@ MODULE_DEVICE_TABLE(usb, p54u_table); static const struct { u32 intf; enum p54u_hw_type type; - const char *fw; - const char *fw_legacy; + char fw[FIRMWARE_NAME_MAX]; + char fw_legacy[FIRMWARE_NAME_MAX]; char hw[20]; } p54u_fwlist[__NUM_P54U_HWTYPES] = { { diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index 7441d5585110..c254fdf446fd 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -157,55 +157,55 @@ MODULE_PARM_DESC(workaround_interval, #define NDIS_802_11_LENGTH_RATES_EX 16 enum ndis_80211_net_type { - NDIS_80211_TYPE_FREQ_HOP, - NDIS_80211_TYPE_DIRECT_SEQ, - NDIS_80211_TYPE_OFDM_A, - NDIS_80211_TYPE_OFDM_G + ndis_80211_type_freq_hop, + ndis_80211_type_direct_seq, + ndis_80211_type_ofdm_a, + ndis_80211_type_ofdm_g }; enum ndis_80211_net_infra { - NDIS_80211_INFRA_ADHOC, - NDIS_80211_INFRA_INFRA, - NDIS_80211_INFRA_AUTO_UNKNOWN + ndis_80211_infra_adhoc, + ndis_80211_infra_infra, + ndis_80211_infra_auto_unknown }; enum ndis_80211_auth_mode { - NDIS_80211_AUTH_OPEN, - NDIS_80211_AUTH_SHARED, - NDIS_80211_AUTH_AUTO_SWITCH, - NDIS_80211_AUTH_WPA, - NDIS_80211_AUTH_WPA_PSK, - NDIS_80211_AUTH_WPA_NONE, - NDIS_80211_AUTH_WPA2, - NDIS_80211_AUTH_WPA2_PSK + ndis_80211_auth_open, + ndis_80211_auth_shared, + ndis_80211_auth_auto_switch, + ndis_80211_auth_wpa, + ndis_80211_auth_wpa_psk, + ndis_80211_auth_wpa_none, + ndis_80211_auth_wpa2, + ndis_80211_auth_wpa2_psk }; enum ndis_80211_encr_status { - NDIS_80211_ENCR_WEP_ENABLED, - NDIS_80211_ENCR_DISABLED, - NDIS_80211_ENCR_WEP_KEY_ABSENT, - NDIS_80211_ENCR_NOT_SUPPORTED, - NDIS_80211_ENCR_TKIP_ENABLED, - NDIS_80211_ENCR_TKIP_KEY_ABSENT, - NDIS_80211_ENCR_CCMP_ENABLED, - NDIS_80211_ENCR_CCMP_KEY_ABSENT + ndis_80211_encr_wep_enabled, + ndis_80211_encr_disabled, + ndis_80211_encr_wep_key_absent, + ndis_80211_encr_not_supported, + ndis_80211_encr_tkip_enabled, + ndis_80211_encr_tkip_key_absent, + ndis_80211_encr_ccmp_enabled, + ndis_80211_encr_ccmp_key_absent }; enum ndis_80211_priv_filter { - NDIS_80211_PRIV_ACCEPT_ALL, - NDIS_80211_PRIV_8021X_WEP + ndis_80211_priv_accept_all, + ndis_80211_priv_8021x_wep }; enum ndis_80211_addkey_bits { - NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28), - NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29), - NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30), - NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31) + ndis_80211_addkey_8021x_auth = cpu_to_le32(1 << 28), + ndis_80211_addkey_set_init_recv_seq = cpu_to_le32(1 << 29), + ndis_80211_addkey_pairwise_key = cpu_to_le32(1 << 30), + ndis_80211_addkey_transmit_key = cpu_to_le32(1 << 31), }; enum ndis_80211_addwep_bits { - NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30), - NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31) + ndis_80211_addwep_perclient_key = cpu_to_le32(1 << 30), + ndis_80211_addwep_transmit_key = cpu_to_le32(1 << 31), }; struct ndis_80211_ssid { @@ -361,7 +361,7 @@ static const struct ieee80211_rate rndis_rates[] = { }; /* RNDIS device private data */ -struct rndis_wlan_private { +struct rndis_wext_private { struct usbnet *usbdev; struct wireless_dev wdev; @@ -441,13 +441,13 @@ static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev) +static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev) { - return (struct rndis_wlan_private *)dev->driver_priv; + return (struct rndis_wext_private *)dev->driver_priv; } -static u32 get_bcm4320_power(struct rndis_wlan_private *priv) +static u32 get_bcm4320_power(struct rndis_wext_private *priv) { return BCM4320_DEFAULT_TXPOWER * bcm4320_power_output[priv->param_power_output] / 100; @@ -480,7 +480,7 @@ static int rndis_error_status(__le32 rndis_status) static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); union { void *buf; struct rndis_msg_hdr *header; @@ -526,7 +526,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); union { void *buf; struct rndis_msg_hdr *header; @@ -747,7 +747,7 @@ static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret; ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); @@ -794,7 +794,7 @@ static int is_associated(struct usbnet *usbdev) static int disassociate(struct usbnet *usbdev, int reset_ssid) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_ssid ssid; int i, ret = 0; @@ -826,7 +826,7 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid) static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; int auth_mode, ret; @@ -835,23 +835,23 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) - auth_mode = NDIS_80211_AUTH_WPA2; + auth_mode = ndis_80211_auth_wpa2; else - auth_mode = NDIS_80211_AUTH_WPA2_PSK; + auth_mode = ndis_80211_auth_wpa2_psk; } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) - auth_mode = NDIS_80211_AUTH_WPA; + auth_mode = ndis_80211_auth_wpa; else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) - auth_mode = NDIS_80211_AUTH_WPA_PSK; + auth_mode = ndis_80211_auth_wpa_psk; else - auth_mode = NDIS_80211_AUTH_WPA_NONE; + auth_mode = ndis_80211_auth_wpa_none; } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) - auth_mode = NDIS_80211_AUTH_AUTO_SWITCH; + auth_mode = ndis_80211_auth_auto_switch; else - auth_mode = NDIS_80211_AUTH_SHARED; + auth_mode = ndis_80211_auth_shared; } else - auth_mode = NDIS_80211_AUTH_OPEN; + auth_mode = ndis_80211_auth_open; tmp = cpu_to_le32(auth_mode); ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, @@ -869,16 +869,16 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) static int set_priv_filter(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) - tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP); + tmp = cpu_to_le32(ndis_80211_priv_8021x_wep); else - tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL); + tmp = cpu_to_le32(ndis_80211_priv_accept_all); return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, sizeof(tmp)); @@ -887,7 +887,7 @@ static int set_priv_filter(struct usbnet *usbdev) static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; int encr_mode, ret; @@ -896,18 +896,18 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) groupwise); if (pairwise & IW_AUTH_CIPHER_CCMP) - encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; + encr_mode = ndis_80211_encr_ccmp_enabled; else if (pairwise & IW_AUTH_CIPHER_TKIP) - encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; + encr_mode = ndis_80211_encr_tkip_enabled; else if (pairwise & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - encr_mode = NDIS_80211_ENCR_WEP_ENABLED; + encr_mode = ndis_80211_encr_wep_enabled; else if (groupwise & IW_AUTH_CIPHER_CCMP) - encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; + encr_mode = ndis_80211_encr_ccmp_enabled; else if (groupwise & IW_AUTH_CIPHER_TKIP) - encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; + encr_mode = ndis_80211_encr_tkip_enabled; else - encr_mode = NDIS_80211_ENCR_DISABLED; + encr_mode = ndis_80211_encr_disabled; tmp = cpu_to_le32(encr_mode); ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, @@ -925,7 +925,7 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) static int set_assoc_params(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg); set_priv_filter(usbdev); @@ -937,7 +937,7 @@ static int set_assoc_params(struct usbnet *usbdev) static int set_infra_mode(struct usbnet *usbdev, int mode) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; int ret, i; @@ -970,12 +970,12 @@ static int set_infra_mode(struct usbnet *usbdev, int mode) static void set_default_iw_params(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); priv->wpa_keymgmt = 0; priv->wpa_version = 0; - set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA); + set_infra_mode(usbdev, ndis_80211_infra_infra); set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, IW_AUTH_ALG_OPEN_SYSTEM); set_priv_filter(usbdev); @@ -996,7 +996,7 @@ static int deauthenticate(struct usbnet *usbdev) /* index must be 0 - N, as per NDIS */ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_wep_key ndis_key; int ret; @@ -1011,7 +1011,7 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) memcpy(&ndis_key.material, key, key_len); if (index == priv->encr_tx_key_index) { - ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY; + ndis_key.index |= ndis_80211_addwep_transmit_key; ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, IW_AUTH_CIPHER_NONE); if (ret) @@ -1039,7 +1039,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, int index, const struct sockaddr *addr, const u8 *rx_seq, int alg, int flags) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_key ndis_key; int ret; @@ -1047,15 +1047,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, return -EINVAL; if (key_len > sizeof(ndis_key.material) || key_len < 0) return -EINVAL; - if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) + if ((flags & ndis_80211_addkey_set_init_recv_seq) && !rx_seq) return -EINVAL; - if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr) + if ((flags & ndis_80211_addkey_pairwise_key) && !addr) return -EINVAL; devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, - !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY), - !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY), - !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)); + !!(flags & ndis_80211_addkey_transmit_key), + !!(flags & ndis_80211_addkey_pairwise_key), + !!(flags & ndis_80211_addkey_set_init_recv_seq)); memset(&ndis_key, 0, sizeof(ndis_key)); @@ -1073,15 +1073,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, } else memcpy(ndis_key.material, key, key_len); - if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) + if (flags & ndis_80211_addkey_set_init_recv_seq) memcpy(ndis_key.rsc, rx_seq, 6); - if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { + if (flags & ndis_80211_addkey_pairwise_key) { /* pairwise key */ memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); } else { /* group key */ - if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) + if (priv->infra_mode == ndis_80211_infra_adhoc) memset(ndis_key.bssid, 0xff, ETH_ALEN); else get_bssid(usbdev, ndis_key.bssid); @@ -1096,7 +1096,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, priv->encr_key_len[index] = key_len; priv->encr_key_wpa[index] = 1; - if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY) + if (flags & ndis_80211_addkey_transmit_key) priv->encr_tx_key_index = index; return 0; @@ -1106,7 +1106,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, /* remove_key is for both wep and wpa */ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_remove_key remove_key; __le32 keyindex; int ret; @@ -1128,7 +1128,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) /* pairwise key */ if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0) remove_key.index |= - NDIS_80211_ADDKEY_PAIRWISE_KEY; + ndis_80211_addkey_pairwise_key; memcpy(remove_key.bssid, bssid, sizeof(remove_key.bssid)); } else @@ -1161,7 +1161,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) static void set_multicast_list(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct dev_mc_list *mclist; __le32 filter; int ret, i, size; @@ -1238,10 +1238,10 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, switch (type) { case NL80211_IFTYPE_ADHOC: - mode = NDIS_80211_INFRA_ADHOC; + mode = ndis_80211_infra_adhoc; break; case NL80211_IFTYPE_STATION: - mode = NDIS_80211_INFRA_INFRA; + mode = ndis_80211_infra_infra; break; default: return -EINVAL; @@ -1256,7 +1256,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret; __le32 tmp; @@ -1286,7 +1286,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, struct ndis_80211_bssid_ex *bssid) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ieee80211_channel *channel; s32 signal; u64 timestamp; @@ -1371,8 +1371,8 @@ static int rndis_check_bssid_list(struct usbnet *usbdev) static void rndis_get_scan_results(struct work_struct *work) { - struct rndis_wlan_private *priv = - container_of(work, struct rndis_wlan_private, scan_work.work); + struct rndis_wext_private *priv = + container_of(work, struct rndis_wext_private, scan_work.work); struct usbnet *usbdev = priv->usbdev; int ret; @@ -1497,7 +1497,7 @@ static int rndis_iw_set_auth(struct net_device *dev, { struct iw_param *p = &wrqu->param; struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret = -ENOTSUPP; switch (p->flags & IW_AUTH_INDEX) { @@ -1578,7 +1578,7 @@ static int rndis_iw_get_auth(struct net_device *dev, { struct iw_param *p = &wrqu->param; struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); switch (p->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: @@ -1609,7 +1609,7 @@ static int rndis_iw_set_encode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret, index, key_len; u8 *key; @@ -1672,7 +1672,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, { struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int keyidx, flags; keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; @@ -1698,11 +1698,11 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, flags = 0; if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) - flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ; + flags |= ndis_80211_addkey_set_init_recv_seq; if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) - flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY; + flags |= ndis_80211_addkey_pairwise_key; if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY; + flags |= ndis_80211_addkey_transmit_key; return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, ext->rx_seq, ext->alg, flags); @@ -1713,7 +1713,7 @@ static int rndis_iw_set_genie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret = 0; #ifdef DEBUG @@ -1747,7 +1747,7 @@ static int rndis_iw_get_genie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); devdbg(usbdev, "SIOCGIWGENIE"); @@ -1886,7 +1886,7 @@ static int rndis_iw_get_txpower(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tx_power; if (priv->radio_on) { @@ -1912,7 +1912,7 @@ static int rndis_iw_set_txpower(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tx_power = 0; if (!wrqu->txpower.disabled) { @@ -1969,7 +1969,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct iw_mlme *mlme = (struct iw_mlme *)extra; unsigned char bssid[ETH_ALEN]; @@ -1994,7 +1994,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); unsigned long flags; spin_lock_irqsave(&priv->stats_lock, flags); @@ -2037,28 +2037,28 @@ static const iw_handler rndis_iw_handler[] = IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme, }; -static const iw_handler rndis_wlan_private_handler[] = { +static const iw_handler rndis_wext_private_handler[] = { }; -static const struct iw_priv_args rndis_wlan_private_args[] = { +static const struct iw_priv_args rndis_wext_private_args[] = { }; static const struct iw_handler_def rndis_iw_handlers = { .num_standard = ARRAY_SIZE(rndis_iw_handler), - .num_private = ARRAY_SIZE(rndis_wlan_private_handler), - .num_private_args = ARRAY_SIZE(rndis_wlan_private_args), + .num_private = ARRAY_SIZE(rndis_wext_private_handler), + .num_private_args = ARRAY_SIZE(rndis_wext_private_args), .standard = (iw_handler *)rndis_iw_handler, - .private = (iw_handler *)rndis_wlan_private_handler, - .private_args = (struct iw_priv_args *)rndis_wlan_private_args, + .private = (iw_handler *)rndis_wext_private_handler, + .private_args = (struct iw_priv_args *)rndis_wext_private_args, .get_wireless_stats = rndis_get_wireless_stats, }; -static void rndis_wlan_worker(struct work_struct *work) +static void rndis_wext_worker(struct work_struct *work) { - struct rndis_wlan_private *priv = - container_of(work, struct rndis_wlan_private, work); + struct rndis_wext_private *priv = + container_of(work, struct rndis_wext_private, work); struct usbnet *usbdev = priv->usbdev; union iwreq_data evt; unsigned char bssid[ETH_ALEN]; @@ -2119,10 +2119,10 @@ static void rndis_wlan_worker(struct work_struct *work) set_multicast_list(usbdev); } -static void rndis_wlan_set_multicast_list(struct net_device *dev) +static void rndis_wext_set_multicast_list(struct net_device *dev) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) return; @@ -2131,9 +2131,9 @@ static void rndis_wlan_set_multicast_list(struct net_device *dev) queue_work(priv->workqueue, &priv->work); } -static void rndis_wlan_link_change(struct usbnet *usbdev, int state) +static void rndis_wext_link_change(struct usbnet *usbdev, int state) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* queue work to avoid recursive calls into rndis_command */ set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); @@ -2141,14 +2141,14 @@ static void rndis_wlan_link_change(struct usbnet *usbdev, int state) } -static int rndis_wlan_get_caps(struct usbnet *usbdev) +static int rndis_wext_get_caps(struct usbnet *usbdev) { struct { __le32 num_items; __le32 items[8]; } networks_supported; int len, retval, i, n; - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* determine supported modes */ len = sizeof(networks_supported); @@ -2160,14 +2160,14 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev) n = 8; for (i = 0; i < n; i++) { switch (le32_to_cpu(networks_supported.items[i])) { - case NDIS_80211_TYPE_FREQ_HOP: - case NDIS_80211_TYPE_DIRECT_SEQ: + case ndis_80211_type_freq_hop: + case ndis_80211_type_direct_seq: priv->caps |= CAP_MODE_80211B; break; - case NDIS_80211_TYPE_OFDM_A: + case ndis_80211_type_ofdm_a: priv->caps |= CAP_MODE_80211A; break; - case NDIS_80211_TYPE_OFDM_G: + case ndis_80211_type_ofdm_g: priv->caps |= CAP_MODE_80211G; break; } @@ -2181,8 +2181,8 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev) #define STATS_UPDATE_JIFFIES (HZ) static void rndis_update_wireless_stats(struct work_struct *work) { - struct rndis_wlan_private *priv = - container_of(work, struct rndis_wlan_private, stats_work.work); + struct rndis_wext_private *priv = + container_of(work, struct rndis_wext_private, stats_work.work); struct usbnet *usbdev = priv->usbdev; struct iw_statistics iwstats; __le32 rssi, tmp; @@ -2297,7 +2297,7 @@ static int bcm4320a_early_init(struct usbnet *usbdev) static int bcm4320b_early_init(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); char buf[8]; /* Early initialization settings, setting these won't have effect @@ -2363,21 +2363,21 @@ static int bcm4320b_early_init(struct usbnet *usbdev) } /* same as rndis_netdev_ops but with local multicast handler */ -static const struct net_device_ops rndis_wlan_netdev_ops = { +static const struct net_device_ops rndis_wext_netdev_ops = { .ndo_open = usbnet_open, .ndo_stop = usbnet_stop, .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = rndis_wlan_set_multicast_list, + .ndo_set_multicast_list = rndis_wext_set_multicast_list, }; -static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) +static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) { struct wiphy *wiphy; - struct rndis_wlan_private *priv; + struct rndis_wext_private *priv; int retval, len; __le32 tmp; @@ -2385,7 +2385,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) * NOTE: We only support a single virtual interface, so wiphy * and wireless_dev are somewhat synonymous for this device. */ - wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wlan_private)); + wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wext_private)); if (!wiphy) return -ENOMEM; @@ -2395,7 +2395,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) priv->wdev.iftype = NL80211_IFTYPE_STATION; /* These have to be initialized before calling generic_rndis_bind(). - * Otherwise we'll be in big trouble in rndis_wlan_early_init(). + * Otherwise we'll be in big trouble in rndis_wext_early_init(). */ usbdev->driver_priv = priv; usbdev->net->wireless_handlers = &rndis_iw_handlers; @@ -2406,7 +2406,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) /* because rndis_command() sleeps we need to use workqueue */ priv->workqueue = create_singlethread_workqueue("rndis_wlan"); - INIT_WORK(&priv->work, rndis_wlan_worker); + INIT_WORK(&priv->work, rndis_wext_worker); INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); @@ -2420,9 +2420,9 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) * picks up rssi to closest station instead of to access point). * * rndis_host wants to avoid all OID as much as possible - * so do promisc/multicast handling in rndis_wlan. + * so do promisc/multicast handling in rndis_wext. */ - usbdev->net->netdev_ops = &rndis_wlan_netdev_ops; + usbdev->net->netdev_ops = &rndis_wext_netdev_ops; tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, @@ -2455,7 +2455,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) wiphy->max_scan_ssids = 1; /* TODO: fill-out band information based on priv->caps */ - rndis_wlan_get_caps(usbdev); + rndis_wext_get_caps(usbdev); memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); @@ -2497,9 +2497,9 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) } -static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) +static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* turn radio off */ disassociate(usbdev, 0); @@ -2520,7 +2520,7 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) } -static int rndis_wlan_reset(struct usbnet *usbdev) +static int rndis_wext_reset(struct usbnet *usbdev) { return deauthenticate(usbdev); } @@ -2529,40 +2529,40 @@ static int rndis_wlan_reset(struct usbnet *usbdev) static const struct driver_info bcm4320b_info = { .description = "Wireless RNDIS device, BCM4320b based", .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .bind = rndis_wlan_bind, - .unbind = rndis_wlan_unbind, + .bind = rndis_wext_bind, + .unbind = rndis_wext_unbind, .status = rndis_status, .rx_fixup = rndis_rx_fixup, .tx_fixup = rndis_tx_fixup, - .reset = rndis_wlan_reset, + .reset = rndis_wext_reset, .early_init = bcm4320b_early_init, - .link_change = rndis_wlan_link_change, + .link_change = rndis_wext_link_change, }; static const struct driver_info bcm4320a_info = { .description = "Wireless RNDIS device, BCM4320a based", .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .bind = rndis_wlan_bind, - .unbind = rndis_wlan_unbind, + .bind = rndis_wext_bind, + .unbind = rndis_wext_unbind, .status = rndis_status, .rx_fixup = rndis_rx_fixup, .tx_fixup = rndis_tx_fixup, - .reset = rndis_wlan_reset, + .reset = rndis_wext_reset, .early_init = bcm4320a_early_init, - .link_change = rndis_wlan_link_change, + .link_change = rndis_wext_link_change, }; -static const struct driver_info rndis_wlan_info = { +static const struct driver_info rndis_wext_info = { .description = "Wireless RNDIS device", .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .bind = rndis_wlan_bind, - .unbind = rndis_wlan_unbind, + .bind = rndis_wext_bind, + .unbind = rndis_wext_unbind, .status = rndis_status, .rx_fixup = rndis_rx_fixup, .tx_fixup = rndis_tx_fixup, - .reset = rndis_wlan_reset, + .reset = rndis_wext_reset, .early_init = bcm4320a_early_init, - .link_change = rndis_wlan_link_change, + .link_change = rndis_wext_link_change, }; /*-------------------------------------------------------------------------*/ @@ -2672,11 +2672,11 @@ static const struct usb_device_id products [] = { { /* RNDIS is MSFT's un-official variant of CDC ACM */ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), - .driver_info = (unsigned long) &rndis_wlan_info, + .driver_info = (unsigned long) &rndis_wext_info, }, { /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), - .driver_info = (unsigned long) &rndis_wlan_info, + .driver_info = (unsigned long) &rndis_wext_info, }, { }, // END }; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c index 435f945fe64d..0197531bd88c 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c @@ -520,7 +520,7 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, if (state == STATE_SLEEP) { rt2x00pci_register_read(rt2x00dev, CSR20, ®); rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, - (rt2x00dev->beacon_int - 20) * 16); + (libconf->conf->beacon_int - 20) * 16); rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, libconf->conf->listen_interval - 1); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c index 08b30d01e67d..f95cb646f85a 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c @@ -569,7 +569,7 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, if (state == STATE_SLEEP) { rt2x00pci_register_read(rt2x00dev, CSR20, ®); rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, - (rt2x00dev->beacon_int - 20) * 16); + (libconf->conf->beacon_int - 20) * 16); rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, libconf->conf->listen_interval - 1); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 66daf68ff0ee..69f966f1ce54 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -647,7 +647,7 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev, if (state == STATE_SLEEP) { rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); rt2x00_set_field16(®, MAC_CSR18_DELAY_AFTER_BEACON, - rt2x00dev->beacon_int - 20); + libconf->conf->beacon_int - 20); rt2x00_set_field16(®, MAC_CSR18_BEACONS_BEFORE_WAKEUP, libconf->conf->listen_interval - 1); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 37561667925b..142ad34fdc49 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -2927,17 +2927,12 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Edimax */ { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Encore */ - { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) }, /* EnGenius */ { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -2956,8 +2951,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* I-O DATA */ - { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) }, /* LevelOne */ { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -2977,7 +2970,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Pegatron */ { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Philips */ { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Planex */ @@ -2989,7 +2981,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Quanta */ { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Ralink */ - { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -3014,7 +3005,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) }, /* SMC */ { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -3039,8 +3029,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Zinwell */ { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zyxel */ { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00.h b/trunk/drivers/net/wireless/rt2x00/rt2x00.h index a498dde024e1..2b64a6198698 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00.h @@ -801,11 +801,6 @@ struct rt2x00_dev { */ u8 calibration[2]; - /* - * Beacon interval. - */ - u16 beacon_int; - /* * Low level statistics which will have * to be kept up to date while device is running. diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00config.c b/trunk/drivers/net/wireless/rt2x00/rt2x00config.c index 3e019a12df2e..c5bbf0b6e207 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00config.c @@ -108,9 +108,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, erp.basic_rates = bss_conf->basic_rates; erp.beacon_int = bss_conf->beacon_int; - /* Update global beacon interval time, this is needed for PS support */ - rt2x00dev->beacon_int = bss_conf->beacon_int; - rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index 49b29ff90c47..a8bf5c432858 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -956,7 +956,7 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, if (state == STATE_SLEEP) { rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, - rt2x00dev->beacon_int - 10); + libconf->conf->beacon_int - 10); rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, libconf->conf->listen_interval - 1); rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5); diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index c18848836f2d..211a3d6bc054 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -852,7 +852,7 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev, if (state == STATE_SLEEP) { rt2x00usb_register_read(rt2x00dev, MAC_CSR11, ®); rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, - rt2x00dev->beacon_int - 10); + libconf->conf->beacon_int - 10); rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, libconf->conf->listen_interval - 1); rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5); diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c index 294250e294dd..6499ccc34c94 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -74,8 +74,6 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, /* AirLive */ {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, - /* Linksys */ - {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B}, {} }; @@ -323,7 +321,12 @@ static void rtl8187_rx_cb(struct urb *urb) unsigned long f; spin_lock_irqsave(&priv->rx_queue.lock, f); - __skb_unlink(skb, &priv->rx_queue); + if (skb->next) + __skb_unlink(skb, &priv->rx_queue); + else { + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + return; + } spin_unlock_irqrestore(&priv->rx_queue.lock, f); skb_put(skb, urb->actual_length); diff --git a/trunk/drivers/net/wireless/wavelan.c b/trunk/drivers/net/wireless/wavelan.c index 25d27b64f528..3ab3eb957189 100644 --- a/trunk/drivers/net/wireless/wavelan.c +++ b/trunk/drivers/net/wireless/wavelan.c @@ -2869,6 +2869,10 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev) if (lp->tx_n_in_use == (NTXBLOCKS - 1)) return 1; } +#ifdef DEBUG_TX_ERROR + if (skb->next) + printk(KERN_INFO "skb has next\n"); +#endif /* Do we need some padding? */ /* Note : on wireless the propagation time is in the order of 1us, diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index 1a90d69f18a9..e55b33961aeb 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -3107,6 +3107,11 @@ wavelan_packet_xmit(struct sk_buff * skb, * so the Tx buffer is now free */ } +#ifdef DEBUG_TX_ERROR + if (skb->next) + printk(KERN_INFO "skb has next\n"); +#endif + /* Check if we need some padding */ /* Note : on wireless the propagation time is in the order of 1us, * and we don't have the Ethernet specific requirement of beeing diff --git a/trunk/drivers/net/yellowfin.c b/trunk/drivers/net/yellowfin.c index 3c7a5053f1da..7477ffdcddb4 100644 --- a/trunk/drivers/net/yellowfin.c +++ b/trunk/drivers/net/yellowfin.c @@ -717,7 +717,7 @@ static void yellowfin_tx_timeout(struct net_device *dev) if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE) netif_wake_queue (dev); /* Typical path */ - dev->trans_start = jiffies; /* prevent tx timeout */ + dev->trans_start = jiffies; dev->stats.tx_errors++; } @@ -876,6 +876,7 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_start_queue (dev); /* Typical path */ else yp->tx_full = 1; + dev->trans_start = jiffies; if (yellowfin_debug > 4) { printk(KERN_DEBUG "%s: Yellowfin transmit frame #%d queued in slot %d.\n", diff --git a/trunk/drivers/platform/x86/Kconfig b/trunk/drivers/platform/x86/Kconfig index c682ac536415..284ebaca6e45 100644 --- a/trunk/drivers/platform/x86/Kconfig +++ b/trunk/drivers/platform/x86/Kconfig @@ -21,7 +21,7 @@ config ACER_WMI depends on NEW_LEDS depends on BACKLIGHT_CLASS_DEVICE depends on SERIO_I8042 - depends on RFKILL || RFKILL = n + depends on RFKILL select ACPI_WMI ---help--- This is a driver for newer Acer (and Wistron) laptops. It adds @@ -60,7 +60,7 @@ config DELL_LAPTOP depends on DCDBAS depends on EXPERIMENTAL depends on BACKLIGHT_CLASS_DEVICE - depends on RFKILL || RFKILL = n + depends on RFKILL depends on POWER_SUPPLY default n ---help--- @@ -117,7 +117,7 @@ config HP_WMI tristate "HP WMI extras" depends on ACPI_WMI depends on INPUT - depends on RFKILL || RFKILL = n + depends on RFKILL help Say Y here if you want to support WMI-based hotkeys on HP laptops and to read data from WMI such as docking or ambient light sensor state. @@ -196,13 +196,14 @@ config THINKPAD_ACPI tristate "ThinkPad ACPI Laptop Extras" depends on ACPI depends on INPUT - depends on RFKILL || RFKILL = n select BACKLIGHT_LCD_SUPPORT select BACKLIGHT_CLASS_DEVICE select HWMON select NVRAM select NEW_LEDS select LEDS_CLASS + select NET + select RFKILL ---help--- This is a driver for the IBM and Lenovo ThinkPad laptops. It adds support for Fn-Fx key combinations, Bluetooth control, video @@ -337,9 +338,9 @@ config EEEPC_LAPTOP depends on ACPI depends on INPUT depends on EXPERIMENTAL - depends on RFKILL || RFKILL = n select BACKLIGHT_CLASS_DEVICE select HWMON + select RFKILL ---help--- This driver supports the Fn-Fx keys on Eee PC laptops. It also adds the ability to switch camera/wlan on/off. @@ -404,8 +405,9 @@ config ACPI_TOSHIBA tristate "Toshiba Laptop Extras" depends on ACPI depends on INPUT - depends on RFKILL || RFKILL = n select INPUT_POLLDEV + select NET + select RFKILL select BACKLIGHT_CLASS_DEVICE ---help--- This driver adds support for access to certain system settings diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index 09a503e5da6a..62d02b3c998e 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -958,47 +958,58 @@ static void acer_rfkill_update(struct work_struct *ignored) status = get_u32(&state, ACER_CAP_WIRELESS); if (ACPI_SUCCESS(status)) - rfkill_set_sw_state(wireless_rfkill, !!state); + rfkill_force_state(wireless_rfkill, state ? + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED); if (has_cap(ACER_CAP_BLUETOOTH)) { status = get_u32(&state, ACER_CAP_BLUETOOTH); if (ACPI_SUCCESS(status)) - rfkill_set_sw_state(bluetooth_rfkill, !!state); + rfkill_force_state(bluetooth_rfkill, state ? + RFKILL_STATE_UNBLOCKED : + RFKILL_STATE_SOFT_BLOCKED); } schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); } -static int acer_rfkill_set(void *data, bool blocked) +static int acer_rfkill_set(void *data, enum rfkill_state state) { acpi_status status; - u32 cap = (unsigned long)data; - status = set_u32(!!blocked, cap); + u32 *cap = data; + status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap); if (ACPI_FAILURE(status)) return -ENODEV; return 0; } -static const struct rfkill_ops acer_rfkill_ops = { - .set_block = acer_rfkill_set, -}; - -static struct rfkill *acer_rfkill_register(struct device *dev, - enum rfkill_type type, - char *name, u32 cap) +static struct rfkill * acer_rfkill_register(struct device *dev, +enum rfkill_type type, char *name, u32 cap) { int err; + u32 state; + u32 *data; struct rfkill *rfkill_dev; - rfkill_dev = rfkill_alloc(name, dev, type, - &acer_rfkill_ops, - (void *)(unsigned long)cap); + rfkill_dev = rfkill_allocate(dev, type); if (!rfkill_dev) return ERR_PTR(-ENOMEM); + rfkill_dev->name = name; + get_u32(&state, cap); + rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED : + RFKILL_STATE_SOFT_BLOCKED; + data = kzalloc(sizeof(u32), GFP_KERNEL); + if (!data) { + rfkill_free(rfkill_dev); + return ERR_PTR(-ENOMEM); + } + *data = cap; + rfkill_dev->data = data; + rfkill_dev->toggle_radio = acer_rfkill_set; err = rfkill_register(rfkill_dev); if (err) { - rfkill_destroy(rfkill_dev); + kfree(rfkill_dev->data); + rfkill_free(rfkill_dev); return ERR_PTR(err); } return rfkill_dev; @@ -1016,8 +1027,8 @@ static int acer_rfkill_init(struct device *dev) RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", ACER_CAP_BLUETOOTH); if (IS_ERR(bluetooth_rfkill)) { + kfree(wireless_rfkill->data); rfkill_unregister(wireless_rfkill); - rfkill_destroy(wireless_rfkill); return PTR_ERR(bluetooth_rfkill); } } @@ -1030,13 +1041,11 @@ static int acer_rfkill_init(struct device *dev) static void acer_rfkill_exit(void) { cancel_delayed_work_sync(&acer_rfkill_work); - + kfree(wireless_rfkill->data); rfkill_unregister(wireless_rfkill); - rfkill_destroy(wireless_rfkill); - if (has_cap(ACER_CAP_BLUETOOTH)) { + kfree(bluetooth_rfkill->data); rfkill_unregister(bluetooth_rfkill); - rfkill_destroy(bluetooth_rfkill); } return; } diff --git a/trunk/drivers/platform/x86/dell-laptop.c b/trunk/drivers/platform/x86/dell-laptop.c index 2faf0e14f05a..af9f43021172 100644 --- a/trunk/drivers/platform/x86/dell-laptop.c +++ b/trunk/drivers/platform/x86/dell-laptop.c @@ -174,11 +174,10 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, result[3]: NVRAM format version number */ -static int dell_rfkill_set(void *data, bool blocked) +static int dell_rfkill_set(int radio, enum rfkill_state state) { struct calling_interface_buffer buffer; - int disable = blocked ? 0 : 1; - unsigned long radio = (unsigned long)data; + int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1; memset(&buffer, 0, sizeof(struct calling_interface_buffer)); buffer.input[0] = (1 | (radio<<8) | (disable << 16)); @@ -187,24 +186,56 @@ static int dell_rfkill_set(void *data, bool blocked) return 0; } -static void dell_rfkill_query(struct rfkill *rfkill, void *data) +static int dell_wifi_set(void *data, enum rfkill_state state) +{ + return dell_rfkill_set(1, state); +} + +static int dell_bluetooth_set(void *data, enum rfkill_state state) +{ + return dell_rfkill_set(2, state); +} + +static int dell_wwan_set(void *data, enum rfkill_state state) +{ + return dell_rfkill_set(3, state); +} + +static int dell_rfkill_get(int bit, enum rfkill_state *state) { struct calling_interface_buffer buffer; int status; - int bit = (unsigned long)data + 16; + int new_state = RFKILL_STATE_HARD_BLOCKED; memset(&buffer, 0, sizeof(struct calling_interface_buffer)); dell_send_request(&buffer, 17, 11); status = buffer.output[1]; - if (status & BIT(bit)) - rfkill_set_hw_state(rfkill, !!(status & BIT(16))); + if (status & (1<<16)) + new_state = RFKILL_STATE_SOFT_BLOCKED; + + if (status & (1<name = "dell-wifi"; + wifi_rfkill->toggle_radio = dell_wifi_set; + wifi_rfkill->get_state = dell_wifi_get; ret = rfkill_register(wifi_rfkill); if (ret) goto err_wifi; } if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { - bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL, - RFKILL_TYPE_BLUETOOTH, - &dell_rfkill_ops, (void *) 2); - if (!bluetooth_rfkill) { - ret = -ENOMEM; + bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH); + if (!bluetooth_rfkill) goto err_bluetooth; - } + bluetooth_rfkill->name = "dell-bluetooth"; + bluetooth_rfkill->toggle_radio = dell_bluetooth_set; + bluetooth_rfkill->get_state = dell_bluetooth_get; ret = rfkill_register(bluetooth_rfkill); if (ret) goto err_bluetooth; } if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { - wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN, - &dell_rfkill_ops, (void *) 3); - if (!wwan_rfkill) { - ret = -ENOMEM; + wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN); + if (!wwan_rfkill) goto err_wwan; - } + wwan_rfkill->name = "dell-wwan"; + wwan_rfkill->toggle_radio = dell_wwan_set; + wwan_rfkill->get_state = dell_wwan_get; ret = rfkill_register(wwan_rfkill); if (ret) goto err_wwan; @@ -255,15 +285,22 @@ static int dell_setup_rfkill(void) return 0; err_wwan: - rfkill_destroy(wwan_rfkill); - if (bluetooth_rfkill) + if (wwan_rfkill) + rfkill_free(wwan_rfkill); + if (bluetooth_rfkill) { rfkill_unregister(bluetooth_rfkill); + bluetooth_rfkill = NULL; + } err_bluetooth: - rfkill_destroy(bluetooth_rfkill); - if (wifi_rfkill) + if (bluetooth_rfkill) + rfkill_free(bluetooth_rfkill); + if (wifi_rfkill) { rfkill_unregister(wifi_rfkill); + wifi_rfkill = NULL; + } err_wifi: - rfkill_destroy(wifi_rfkill); + if (wifi_rfkill) + rfkill_free(wifi_rfkill); return ret; } diff --git a/trunk/drivers/platform/x86/eeepc-laptop.c b/trunk/drivers/platform/x86/eeepc-laptop.c index 03bf522bd7ab..353a898c3693 100644 --- a/trunk/drivers/platform/x86/eeepc-laptop.c +++ b/trunk/drivers/platform/x86/eeepc-laptop.c @@ -299,22 +299,39 @@ static int update_bl_status(struct backlight_device *bd) * Rfkill helpers */ -static bool eeepc_wlan_rfkill_blocked(void) +static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state) +{ + if (state == RFKILL_STATE_SOFT_BLOCKED) + return set_acpi(CM_ASL_WLAN, 0); + else + return set_acpi(CM_ASL_WLAN, 1); +} + +static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state) { if (get_acpi(CM_ASL_WLAN) == 1) - return false; - return true; + *state = RFKILL_STATE_UNBLOCKED; + else + *state = RFKILL_STATE_SOFT_BLOCKED; + return 0; } -static int eeepc_rfkill_set(void *data, bool blocked) +static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state) { - unsigned long asl = (unsigned long)data; - return set_acpi(asl, !blocked); + if (state == RFKILL_STATE_SOFT_BLOCKED) + return set_acpi(CM_ASL_BLUETOOTH, 0); + else + return set_acpi(CM_ASL_BLUETOOTH, 1); } -static const struct rfkill_ops eeepc_rfkill_ops = { - .set_block = eeepc_rfkill_set, -}; +static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state) +{ + if (get_acpi(CM_ASL_BLUETOOTH) == 1) + *state = RFKILL_STATE_UNBLOCKED; + else + *state = RFKILL_STATE_SOFT_BLOCKED; + return 0; +} /* * Sys helpers @@ -514,9 +531,9 @@ static int notify_brn(void) static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) { + enum rfkill_state state; struct pci_dev *dev; struct pci_bus *bus = pci_find_bus(0, 1); - bool blocked; if (event != ACPI_NOTIFY_BUS_CHECK) return; @@ -526,8 +543,9 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) return; } - blocked = eeepc_wlan_rfkill_blocked(); - if (!blocked) { + eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); + + if (state == RFKILL_STATE_UNBLOCKED) { dev = pci_get_slot(bus, 0); if (dev) { /* Device already present */ @@ -548,7 +566,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) } } - rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); + rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); } static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) @@ -666,17 +684,26 @@ static int eeepc_hotk_add(struct acpi_device *device) eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); if (get_acpi(CM_ASL_WLAN) != -1) { - ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan", - &device->dev, - RFKILL_TYPE_WLAN, - &eeepc_rfkill_ops, - (void *)CM_ASL_WLAN); + ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, + RFKILL_TYPE_WLAN); if (!ehotk->eeepc_wlan_rfkill) goto wlan_fail; - rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, - get_acpi(CM_ASL_WLAN) != 1); + ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; + ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; + ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; + if (get_acpi(CM_ASL_WLAN) == 1) { + ehotk->eeepc_wlan_rfkill->state = + RFKILL_STATE_UNBLOCKED; + rfkill_set_default(RFKILL_TYPE_WLAN, + RFKILL_STATE_UNBLOCKED); + } else { + ehotk->eeepc_wlan_rfkill->state = + RFKILL_STATE_SOFT_BLOCKED; + rfkill_set_default(RFKILL_TYPE_WLAN, + RFKILL_STATE_SOFT_BLOCKED); + } result = rfkill_register(ehotk->eeepc_wlan_rfkill); if (result) goto wlan_fail; @@ -684,17 +711,28 @@ static int eeepc_hotk_add(struct acpi_device *device) if (get_acpi(CM_ASL_BLUETOOTH) != -1) { ehotk->eeepc_bluetooth_rfkill = - rfkill_alloc("eeepc-bluetooth", - &device->dev, - RFKILL_TYPE_BLUETOOTH, - &eeepc_rfkill_ops, - (void *)CM_ASL_BLUETOOTH); + rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); if (!ehotk->eeepc_bluetooth_rfkill) goto bluetooth_fail; - rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, - get_acpi(CM_ASL_BLUETOOTH) != 1); + ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; + ehotk->eeepc_bluetooth_rfkill->toggle_radio = + eeepc_bluetooth_rfkill_set; + ehotk->eeepc_bluetooth_rfkill->get_state = + eeepc_bluetooth_rfkill_state; + if (get_acpi(CM_ASL_BLUETOOTH) == 1) { + ehotk->eeepc_bluetooth_rfkill->state = + RFKILL_STATE_UNBLOCKED; + rfkill_set_default(RFKILL_TYPE_BLUETOOTH, + RFKILL_STATE_UNBLOCKED); + } else { + ehotk->eeepc_bluetooth_rfkill->state = + RFKILL_STATE_SOFT_BLOCKED; + rfkill_set_default(RFKILL_TYPE_BLUETOOTH, + RFKILL_STATE_SOFT_BLOCKED); + } + result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); if (result) goto bluetooth_fail; @@ -703,10 +741,13 @@ static int eeepc_hotk_add(struct acpi_device *device) return 0; bluetooth_fail: - rfkill_destroy(ehotk->eeepc_bluetooth_rfkill); + if (ehotk->eeepc_bluetooth_rfkill) + rfkill_free(ehotk->eeepc_bluetooth_rfkill); rfkill_unregister(ehotk->eeepc_wlan_rfkill); + ehotk->eeepc_wlan_rfkill = NULL; wlan_fail: - rfkill_destroy(ehotk->eeepc_wlan_rfkill); + if (ehotk->eeepc_wlan_rfkill) + rfkill_free(ehotk->eeepc_wlan_rfkill); eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); ehotk_fail: diff --git a/trunk/drivers/platform/x86/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c index 16fffe44e333..fe171fad12cf 100644 --- a/trunk/drivers/platform/x86/hp-wmi.c +++ b/trunk/drivers/platform/x86/hp-wmi.c @@ -154,46 +154,58 @@ static int hp_wmi_dock_state(void) return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0); } -static int hp_wmi_set_block(void *data, bool blocked) +static int hp_wmi_wifi_set(void *data, enum rfkill_state state) { - unsigned long b = (unsigned long) data; - int query = BIT(b + 8) | ((!!blocked) << b); + if (state) + return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x101); + else + return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x100); +} - return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query); +static int hp_wmi_bluetooth_set(void *data, enum rfkill_state state) +{ + if (state) + return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x202); + else + return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x200); } -static const struct rfkill_ops hp_wmi_rfkill_ops = { - .set_block = hp_wmi_set_block, -}; +static int hp_wmi_wwan_set(void *data, enum rfkill_state state) +{ + if (state) + return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x404); + else + return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x400); +} -static bool hp_wmi_wifi_state(void) +static int hp_wmi_wifi_state(void) { int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); if (wireless & 0x100) - return false; + return RFKILL_STATE_UNBLOCKED; else - return true; + return RFKILL_STATE_SOFT_BLOCKED; } -static bool hp_wmi_bluetooth_state(void) +static int hp_wmi_bluetooth_state(void) { int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); if (wireless & 0x10000) - return false; + return RFKILL_STATE_UNBLOCKED; else - return true; + return RFKILL_STATE_SOFT_BLOCKED; } -static bool hp_wmi_wwan_state(void) +static int hp_wmi_wwan_state(void) { int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); if (wireless & 0x1000000) - return false; + return RFKILL_STATE_UNBLOCKED; else - return true; + return RFKILL_STATE_SOFT_BLOCKED; } static ssize_t show_display(struct device *dev, struct device_attribute *attr, @@ -335,14 +347,14 @@ static void hp_wmi_notify(u32 value, void *context) } } else if (eventcode == 0x5) { if (wifi_rfkill) - rfkill_set_sw_state(wifi_rfkill, - hp_wmi_wifi_state()); + rfkill_force_state(wifi_rfkill, + hp_wmi_wifi_state()); if (bluetooth_rfkill) - rfkill_set_sw_state(bluetooth_rfkill, - hp_wmi_bluetooth_state()); + rfkill_force_state(bluetooth_rfkill, + hp_wmi_bluetooth_state()); if (wwan_rfkill) - rfkill_set_sw_state(wwan_rfkill, - hp_wmi_wwan_state()); + rfkill_force_state(wwan_rfkill, + hp_wmi_wwan_state()); } else printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", eventcode); @@ -418,30 +430,31 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) goto add_sysfs_error; if (wireless & 0x1) { - wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev, - RFKILL_TYPE_WLAN, - &hp_wmi_rfkill_ops, - (void *) 0); + wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); + wifi_rfkill->name = "hp-wifi"; + wifi_rfkill->state = hp_wmi_wifi_state(); + wifi_rfkill->toggle_radio = hp_wmi_wifi_set; err = rfkill_register(wifi_rfkill); if (err) - goto register_wifi_error; + goto add_sysfs_error; } if (wireless & 0x2) { - bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev, - RFKILL_TYPE_BLUETOOTH, - &hp_wmi_rfkill_ops, - (void *) 1); + bluetooth_rfkill = rfkill_allocate(&device->dev, + RFKILL_TYPE_BLUETOOTH); + bluetooth_rfkill->name = "hp-bluetooth"; + bluetooth_rfkill->state = hp_wmi_bluetooth_state(); + bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set; err = rfkill_register(bluetooth_rfkill); if (err) goto register_bluetooth_error; } if (wireless & 0x4) { - wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev, - RFKILL_TYPE_WWAN, - &hp_wmi_rfkill_ops, - (void *) 2); + wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); + wwan_rfkill->name = "hp-wwan"; + wwan_rfkill->state = hp_wmi_wwan_state(); + wwan_rfkill->toggle_radio = hp_wmi_wwan_set; err = rfkill_register(wwan_rfkill); if (err) goto register_wwan_err; @@ -449,15 +462,11 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) return 0; register_wwan_err: - rfkill_destroy(wwan_rfkill); if (bluetooth_rfkill) rfkill_unregister(bluetooth_rfkill); register_bluetooth_error: - rfkill_destroy(bluetooth_rfkill); if (wifi_rfkill) rfkill_unregister(wifi_rfkill); -register_wifi_error: - rfkill_destroy(wifi_rfkill); add_sysfs_error: cleanup_sysfs(device); return err; @@ -467,18 +476,12 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device) { cleanup_sysfs(device); - if (wifi_rfkill) { + if (wifi_rfkill) rfkill_unregister(wifi_rfkill); - rfkill_destroy(wifi_rfkill); - } - if (bluetooth_rfkill) { + if (bluetooth_rfkill) rfkill_unregister(bluetooth_rfkill); - rfkill_destroy(wifi_rfkill); - } - if (wwan_rfkill) { + if (wwan_rfkill) rfkill_unregister(wwan_rfkill); - rfkill_destroy(wwan_rfkill); - } return 0; } diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index e48d9a4506ff..f1963b05175b 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -128,11 +128,11 @@ enum sony_nc_rfkill { SONY_BLUETOOTH, SONY_WWAN, SONY_WIMAX, - N_SONY_RFKILL, + SONY_RFKILL_MAX, }; -static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL]; -static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900}; +static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX]; +static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900}; static void sony_nc_rfkill_update(void); /*********** Input Devices ***********/ @@ -1051,96 +1051,147 @@ static void sony_nc_rfkill_cleanup(void) { int i; - for (i = 0; i < N_SONY_RFKILL; i++) { - if (sony_rfkill_devices[i]) { + for (i = 0; i < SONY_RFKILL_MAX; i++) { + if (sony_rfkill_devices[i]) rfkill_unregister(sony_rfkill_devices[i]); - rfkill_destroy(sony_rfkill_devices[i]); - } } } -static int sony_nc_rfkill_set(void *data, bool blocked) +static int sony_nc_rfkill_get(void *data, enum rfkill_state *state) +{ + int result; + int argument = sony_rfkill_address[(long) data]; + + sony_call_snc_handle(0x124, 0x200, &result); + if (result & 0x1) { + sony_call_snc_handle(0x124, argument, &result); + if (result & 0xf) + *state = RFKILL_STATE_UNBLOCKED; + else + *state = RFKILL_STATE_SOFT_BLOCKED; + } else { + *state = RFKILL_STATE_HARD_BLOCKED; + } + + return 0; +} + +static int sony_nc_rfkill_set(void *data, enum rfkill_state state) { int result; int argument = sony_rfkill_address[(long) data] + 0x100; - if (!blocked) + if (state == RFKILL_STATE_UNBLOCKED) argument |= 0xff0000; return sony_call_snc_handle(0x124, argument, &result); } -static const struct rfkill_ops sony_rfkill_ops = { - .set_block = sony_nc_rfkill_set, -}; - -static int sony_nc_setup_rfkill(struct acpi_device *device, - enum sony_nc_rfkill nc_type) +static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) { int err = 0; - struct rfkill *rfk; - enum rfkill_type type; - const char *name; - - switch (nc_type) { - case SONY_WIFI: - type = RFKILL_TYPE_WLAN; - name = "sony-wifi"; - break; - case SONY_BLUETOOTH: - type = RFKILL_TYPE_BLUETOOTH; - name = "sony-bluetooth"; - break; - case SONY_WWAN: - type = RFKILL_TYPE_WWAN; - name = "sony-wwan"; - break; - case SONY_WIMAX: - type = RFKILL_TYPE_WIMAX; - name = "sony-wimax"; - break; - default: - return -EINVAL; + struct rfkill *sony_wifi_rfkill; + + sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); + if (!sony_wifi_rfkill) + return -1; + sony_wifi_rfkill->name = "sony-wifi"; + sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set; + sony_wifi_rfkill->get_state = sony_nc_rfkill_get; + sony_wifi_rfkill->data = (void *)SONY_WIFI; + err = rfkill_register(sony_wifi_rfkill); + if (err) + rfkill_free(sony_wifi_rfkill); + else { + sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill; + sony_nc_rfkill_set(sony_wifi_rfkill->data, + RFKILL_STATE_UNBLOCKED); } + return err; +} - rfk = rfkill_alloc(name, &device->dev, type, - &sony_rfkill_ops, (void *)nc_type); - if (!rfk) - return -ENOMEM; +static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) +{ + int err = 0; + struct rfkill *sony_bluetooth_rfkill; - err = rfkill_register(rfk); - if (err) { - rfkill_destroy(rfk); - return err; + sony_bluetooth_rfkill = rfkill_allocate(&device->dev, + RFKILL_TYPE_BLUETOOTH); + if (!sony_bluetooth_rfkill) + return -1; + sony_bluetooth_rfkill->name = "sony-bluetooth"; + sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set; + sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get; + sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH; + err = rfkill_register(sony_bluetooth_rfkill); + if (err) + rfkill_free(sony_bluetooth_rfkill); + else { + sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill; + sony_nc_rfkill_set(sony_bluetooth_rfkill->data, + RFKILL_STATE_UNBLOCKED); } - sony_rfkill_devices[nc_type] = rfk; return err; } -static void sony_nc_rfkill_update() +static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) { - enum sony_nc_rfkill i; - int result; - bool hwblock; + int err = 0; + struct rfkill *sony_wwan_rfkill; - sony_call_snc_handle(0x124, 0x200, &result); - hwblock = !(result & 0x1); + sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); + if (!sony_wwan_rfkill) + return -1; + sony_wwan_rfkill->name = "sony-wwan"; + sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set; + sony_wwan_rfkill->get_state = sony_nc_rfkill_get; + sony_wwan_rfkill->data = (void *)SONY_WWAN; + err = rfkill_register(sony_wwan_rfkill); + if (err) + rfkill_free(sony_wwan_rfkill); + else { + sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill; + sony_nc_rfkill_set(sony_wwan_rfkill->data, + RFKILL_STATE_UNBLOCKED); + } + return err; +} + +static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) +{ + int err = 0; + struct rfkill *sony_wimax_rfkill; - for (i = 0; i < N_SONY_RFKILL; i++) { - int argument = sony_rfkill_address[i]; + sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX); + if (!sony_wimax_rfkill) + return -1; + sony_wimax_rfkill->name = "sony-wimax"; + sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set; + sony_wimax_rfkill->get_state = sony_nc_rfkill_get; + sony_wimax_rfkill->data = (void *)SONY_WIMAX; + err = rfkill_register(sony_wimax_rfkill); + if (err) + rfkill_free(sony_wimax_rfkill); + else { + sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill; + sony_nc_rfkill_set(sony_wimax_rfkill->data, + RFKILL_STATE_UNBLOCKED); + } + return err; +} - if (!sony_rfkill_devices[i]) - continue; +static void sony_nc_rfkill_update() +{ + int i; + enum rfkill_state state; - if (hwblock) { - if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) - sony_nc_rfkill_set((void *)i, true); - continue; + for (i = 0; i < SONY_RFKILL_MAX; i++) { + if (sony_rfkill_devices[i]) { + sony_rfkill_devices[i]-> + get_state(sony_rfkill_devices[i]->data, + &state); + rfkill_force_state(sony_rfkill_devices[i], state); } - - sony_call_snc_handle(0x124, argument, &result); - rfkill_set_states(sony_rfkill_devices[i], - !(result & 0xf), false); } } @@ -1159,13 +1210,13 @@ static int sony_nc_rfkill_setup(struct acpi_device *device) } if (result & 0x1) - sony_nc_setup_rfkill(device, SONY_WIFI); + sony_nc_setup_wifi_rfkill(device); if (result & 0x2) - sony_nc_setup_rfkill(device, SONY_BLUETOOTH); + sony_nc_setup_bluetooth_rfkill(device); if (result & 0x1c) - sony_nc_setup_rfkill(device, SONY_WWAN); + sony_nc_setup_wwan_rfkill(device); if (result & 0x20) - sony_nc_setup_rfkill(device, SONY_WIMAX); + sony_nc_setup_wimax_rfkill(device); return 0; } diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index 86e958539f46..912be65b6261 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -166,6 +166,13 @@ enum { #define TPACPI_MAX_ACPI_ARGS 3 +/* rfkill switches */ +enum { + TPACPI_RFK_BLUETOOTH_SW_ID = 0, + TPACPI_RFK_WWAN_SW_ID, + TPACPI_RFK_UWB_SW_ID, +}; + /* printk headers */ #define TPACPI_LOG TPACPI_FILE ": " #define TPACPI_EMERG KERN_EMERG TPACPI_LOG @@ -998,234 +1005,67 @@ static int __init tpacpi_check_std_acpi_brightness_support(void) return 0; } -static void printk_deprecated_attribute(const char * const what, - const char * const details) -{ - tpacpi_log_usertask("deprecated sysfs attribute"); - printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " - "will be removed. %s\n", - what, details); -} - -/************************************************************************* - * rfkill and radio control support helpers - */ - -/* - * ThinkPad-ACPI firmware handling model: - * - * WLSW (master wireless switch) is event-driven, and is common to all - * firmware-controlled radios. It cannot be controlled, just monitored, - * as expected. It overrides all radio state in firmware - * - * The kernel, a masked-off hotkey, and WLSW can change the radio state - * (TODO: verify how WLSW interacts with the returned radio state). - * - * The only time there are shadow radio state changes, is when - * masked-off hotkeys are used. - */ - -/* - * Internal driver API for radio state: - * - * int: < 0 = error, otherwise enum tpacpi_rfkill_state - * bool: true means radio blocked (off) - */ -enum tpacpi_rfkill_state { - TPACPI_RFK_RADIO_OFF = 0, - TPACPI_RFK_RADIO_ON -}; - -/* rfkill switches */ -enum tpacpi_rfk_id { - TPACPI_RFK_BLUETOOTH_SW_ID = 0, - TPACPI_RFK_WWAN_SW_ID, - TPACPI_RFK_UWB_SW_ID, - TPACPI_RFK_SW_MAX -}; - -static const char *tpacpi_rfkill_names[] = { - [TPACPI_RFK_BLUETOOTH_SW_ID] = "bluetooth", - [TPACPI_RFK_WWAN_SW_ID] = "wwan", - [TPACPI_RFK_UWB_SW_ID] = "uwb", - [TPACPI_RFK_SW_MAX] = NULL -}; - -/* ThinkPad-ACPI rfkill subdriver */ -struct tpacpi_rfk { - struct rfkill *rfkill; - enum tpacpi_rfk_id id; - const struct tpacpi_rfk_ops *ops; -}; - -struct tpacpi_rfk_ops { - /* firmware interface */ - int (*get_status)(void); - int (*set_status)(const enum tpacpi_rfkill_state); -}; - -static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX]; - -/* Query FW and update rfkill sw state for a given rfkill switch */ -static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk) -{ - int status; - - if (!tp_rfk) - return -ENODEV; - - status = (tp_rfk->ops->get_status)(); - if (status < 0) - return status; - - rfkill_set_sw_state(tp_rfk->rfkill, - (status == TPACPI_RFK_RADIO_OFF)); - - return status; -} - -/* Query FW and update rfkill sw state for all rfkill switches */ -static void tpacpi_rfk_update_swstate_all(void) -{ - unsigned int i; - - for (i = 0; i < TPACPI_RFK_SW_MAX; i++) - tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]); -} - -/* - * Sync the HW-blocking state of all rfkill switches, - * do notice it causes the rfkill core to schedule uevents - */ -static void tpacpi_rfk_update_hwblock_state(bool blocked) -{ - unsigned int i; - struct tpacpi_rfk *tp_rfk; - - for (i = 0; i < TPACPI_RFK_SW_MAX; i++) { - tp_rfk = tpacpi_rfkill_switches[i]; - if (tp_rfk) { - if (rfkill_set_hw_state(tp_rfk->rfkill, - blocked)) { - /* ignore -- we track sw block */ - } - } - } -} - -/* Call to get the WLSW state from the firmware */ -static int hotkey_get_wlsw(void); - -/* Call to query WLSW state and update all rfkill switches */ -static bool tpacpi_rfk_check_hwblock_state(void) -{ - int res = hotkey_get_wlsw(); - int hw_blocked; - - /* When unknown or unsupported, we have to assume it is unblocked */ - if (res < 0) - return false; - - hw_blocked = (res == TPACPI_RFK_RADIO_OFF); - tpacpi_rfk_update_hwblock_state(hw_blocked); - - return hw_blocked; -} - -static int tpacpi_rfk_hook_set_block(void *data, bool blocked) -{ - struct tpacpi_rfk *tp_rfk = data; - int res; - - dbg_printk(TPACPI_DBG_RFKILL, - "request to change radio state to %s\n", - blocked ? "blocked" : "unblocked"); - - /* try to set radio state */ - res = (tp_rfk->ops->set_status)(blocked ? - TPACPI_RFK_RADIO_OFF : TPACPI_RFK_RADIO_ON); - - /* and update the rfkill core with whatever the FW really did */ - tpacpi_rfk_update_swstate(tp_rfk); - - return (res < 0) ? res : 0; -} - -static const struct rfkill_ops tpacpi_rfk_rfkill_ops = { - .set_block = tpacpi_rfk_hook_set_block, -}; - -static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, - const struct tpacpi_rfk_ops *tp_rfkops, +static int __init tpacpi_new_rfkill(const unsigned int id, + struct rfkill **rfk, const enum rfkill_type rfktype, const char *name, - const bool set_default) + const bool set_default, + int (*toggle_radio)(void *, enum rfkill_state), + int (*get_state)(void *, enum rfkill_state *)) { - struct tpacpi_rfk *atp_rfk; int res; - bool initial_sw_state = false; - int initial_sw_status; - - BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); - - atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL); - if (atp_rfk) - atp_rfk->rfkill = rfkill_alloc(name, - &tpacpi_pdev->dev, - rfktype, - &tpacpi_rfk_rfkill_ops, - atp_rfk); - if (!atp_rfk || !atp_rfk->rfkill) { + enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED; + + res = get_state(NULL, &initial_state); + if (res < 0) { + printk(TPACPI_ERR + "failed to read initial state for %s, error %d; " + "will turn radio off\n", name, res); + } else if (set_default) { + /* try to set the initial state as the default for the rfkill + * type, since we ask the firmware to preserve it across S5 in + * NVRAM */ + if (rfkill_set_default(rfktype, + (initial_state == RFKILL_STATE_UNBLOCKED) ? + RFKILL_STATE_UNBLOCKED : + RFKILL_STATE_SOFT_BLOCKED) == -EPERM) + vdbg_printk(TPACPI_DBG_RFKILL, + "Default state for %s cannot be changed\n", + name); + } + + *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); + if (!*rfk) { printk(TPACPI_ERR "failed to allocate memory for rfkill class\n"); - kfree(atp_rfk); return -ENOMEM; } - atp_rfk->id = id; - atp_rfk->ops = tp_rfkops; - - initial_sw_status = (tp_rfkops->get_status)(); - if (initial_sw_status < 0) { - printk(TPACPI_ERR - "failed to read initial state for %s, error %d\n", - name, initial_sw_status); - } else { - initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF); - if (set_default) { - /* try to keep the initial state, since we ask the - * firmware to preserve it across S5 in NVRAM */ - rfkill_set_sw_state(atp_rfk->rfkill, initial_sw_state); - } - } - rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state()); + (*rfk)->name = name; + (*rfk)->get_state = get_state; + (*rfk)->toggle_radio = toggle_radio; + (*rfk)->state = initial_state; - res = rfkill_register(atp_rfk->rfkill); + res = rfkill_register(*rfk); if (res < 0) { printk(TPACPI_ERR "failed to register %s rfkill switch: %d\n", name, res); - rfkill_destroy(atp_rfk->rfkill); - kfree(atp_rfk); + rfkill_free(*rfk); + *rfk = NULL; return res; } - tpacpi_rfkill_switches[id] = atp_rfk; return 0; } -static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id) +static void printk_deprecated_attribute(const char * const what, + const char * const details) { - struct tpacpi_rfk *tp_rfk; - - BUG_ON(id >= TPACPI_RFK_SW_MAX); - - tp_rfk = tpacpi_rfkill_switches[id]; - if (tp_rfk) { - rfkill_unregister(tp_rfk->rfkill); - tpacpi_rfkill_switches[id] = NULL; - kfree(tp_rfk); - } + tpacpi_log_usertask("deprecated sysfs attribute"); + printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " + "will be removed. %s\n", + what, details); } static void printk_deprecated_rfkill_attribute(const char * const what) @@ -1234,112 +1074,6 @@ static void printk_deprecated_rfkill_attribute(const char * const what) "Please switch to generic rfkill before year 2010"); } -/* sysfs enable ------------------------------------------------ */ -static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id, - struct device_attribute *attr, - char *buf) -{ - int status; - - printk_deprecated_rfkill_attribute(attr->attr.name); - - /* This is in the ABI... */ - if (tpacpi_rfk_check_hwblock_state()) { - status = TPACPI_RFK_RADIO_OFF; - } else { - status = tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]); - if (status < 0) - return status; - } - - return snprintf(buf, PAGE_SIZE, "%d\n", - (status == TPACPI_RFK_RADIO_ON) ? 1 : 0); -} - -static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long t; - int res; - - printk_deprecated_rfkill_attribute(attr->attr.name); - - if (parse_strtoul(buf, 1, &t)) - return -EINVAL; - - tpacpi_disclose_usertask(attr->attr.name, "set to %ld\n", t); - - /* This is in the ABI... */ - if (tpacpi_rfk_check_hwblock_state() && !!t) - return -EPERM; - - res = tpacpi_rfkill_switches[id]->ops->set_status((!!t) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF); - tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]); - - return (res < 0) ? res : count; -} - -/* procfs -------------------------------------------------------------- */ -static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p) -{ - int len = 0; - - if (id >= TPACPI_RFK_SW_MAX) - len += sprintf(p + len, "status:\t\tnot supported\n"); - else { - int status; - - /* This is in the ABI... */ - if (tpacpi_rfk_check_hwblock_state()) { - status = TPACPI_RFK_RADIO_OFF; - } else { - status = tpacpi_rfk_update_swstate( - tpacpi_rfkill_switches[id]); - if (status < 0) - return status; - } - - len += sprintf(p + len, "status:\t\t%s\n", - (status == TPACPI_RFK_RADIO_ON) ? - "enabled" : "disabled"); - len += sprintf(p + len, "commands:\tenable, disable\n"); - } - - return len; -} - -static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf) -{ - char *cmd; - int status = -1; - int res = 0; - - if (id >= TPACPI_RFK_SW_MAX) - return -ENODEV; - - while ((cmd = next_cmd(&buf))) { - if (strlencmp(cmd, "enable") == 0) - status = TPACPI_RFK_RADIO_ON; - else if (strlencmp(cmd, "disable") == 0) - status = TPACPI_RFK_RADIO_OFF; - else - return -EINVAL; - } - - if (status != -1) { - tpacpi_disclose_usertask("procfs", "attempt to %s %s\n", - (status == TPACPI_RFK_RADIO_ON) ? - "enable" : "disable", - tpacpi_rfkill_names[id]); - res = (tpacpi_rfkill_switches[id]->ops->set_status)(status); - tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]); - } - - return res; -} - /************************************************************************* * thinkpad-acpi driver attributes */ @@ -1393,6 +1127,8 @@ static DRIVER_ATTR(version, S_IRUGO, #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES +static void tpacpi_send_radiosw_update(void); + /* wlsw_emulstate ------------------------------------------------------ */ static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv, char *buf) @@ -1408,10 +1144,11 @@ static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv, if (parse_strtoul(buf, 1, &t)) return -EINVAL; - if (tpacpi_wlsw_emulstate != !!t) { + if (tpacpi_wlsw_emulstate != t) { + tpacpi_wlsw_emulstate = !!t; + tpacpi_send_radiosw_update(); + } else tpacpi_wlsw_emulstate = !!t; - tpacpi_rfk_update_hwblock_state(!t); /* negative logic */ - } return count; } @@ -1726,23 +1463,17 @@ static struct attribute_set *hotkey_dev_attributes; /* HKEY.MHKG() return bits */ #define TP_HOTKEY_TABLET_MASK (1 << 3) -static int hotkey_get_wlsw(void) +static int hotkey_get_wlsw(int *status) { - int status; - - if (!tp_features.hotkey_wlsw) - return -ENODEV; - #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES - if (dbg_wlswemul) - return (tpacpi_wlsw_emulstate) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + if (dbg_wlswemul) { + *status = !!tpacpi_wlsw_emulstate; + return 0; + } #endif - - if (!acpi_evalf(hkey_handle, &status, "WLSW", "d")) + if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) return -EIO; - - return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + return 0; } static int hotkey_get_tablet_mode(int *status) @@ -2376,16 +2107,12 @@ static ssize_t hotkey_radio_sw_show(struct device *dev, struct device_attribute *attr, char *buf) { - int res; - res = hotkey_get_wlsw(); + int res, s; + res = hotkey_get_wlsw(&s); if (res < 0) return res; - /* Opportunistic update */ - tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF)); - - return snprintf(buf, PAGE_SIZE, "%d\n", - (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1); + return snprintf(buf, PAGE_SIZE, "%d\n", !!s); } static struct device_attribute dev_attr_hotkey_radio_sw = @@ -2496,52 +2223,30 @@ static struct attribute *hotkey_mask_attributes[] __initdata = { &dev_attr_hotkey_wakeup_hotunplug_complete.attr, }; -/* - * Sync both the hw and sw blocking state of all switches - */ +static void bluetooth_update_rfk(void); +static void wan_update_rfk(void); +static void uwb_update_rfk(void); static void tpacpi_send_radiosw_update(void) { int wlsw; - /* - * We must sync all rfkill controllers *before* issuing any - * rfkill input events, or we will race the rfkill core input - * handler. - * - * tpacpi_inputdev_send_mutex works as a syncronization point - * for the above. - * - * We optimize to avoid numerous calls to hotkey_get_wlsw. - */ - - wlsw = hotkey_get_wlsw(); - - /* Sync hw blocking state first if it is hw-blocked */ - if (wlsw == TPACPI_RFK_RADIO_OFF) - tpacpi_rfk_update_hwblock_state(true); + /* Sync these BEFORE sending any rfkill events */ + if (tp_features.bluetooth) + bluetooth_update_rfk(); + if (tp_features.wan) + wan_update_rfk(); + if (tp_features.uwb) + uwb_update_rfk(); - /* Sync sw blocking state */ - tpacpi_rfk_update_swstate_all(); - - /* Sync hw blocking state last if it is hw-unblocked */ - if (wlsw == TPACPI_RFK_RADIO_ON) - tpacpi_rfk_update_hwblock_state(false); - - /* Issue rfkill input event for WLSW switch */ - if (!(wlsw < 0)) { + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { mutex_lock(&tpacpi_inputdev_send_mutex); input_report_switch(tpacpi_inputdev, - SW_RFKILL_ALL, (wlsw > 0)); + SW_RFKILL_ALL, !!wlsw); input_sync(tpacpi_inputdev); mutex_unlock(&tpacpi_inputdev_send_mutex); } - - /* - * this can be unconditional, as we will poll state again - * if userspace uses the notify to read data - */ hotkey_radio_sw_notify_change(); } @@ -3351,6 +3056,8 @@ enum { #define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" +static struct rfkill *tpacpi_bluetooth_rfkill; + static void bluetooth_suspend(pm_message_t state) { /* Try to make sure radio will resume powered off */ @@ -3360,47 +3067,83 @@ static void bluetooth_suspend(pm_message_t state) "bluetooth power down on resume request failed\n"); } -static int bluetooth_get_status(void) +static int bluetooth_get_radiosw(void) { int status; + if (!tp_features.bluetooth) + return -ENODEV; + + /* WLSW overrides bluetooth in firmware/hardware, reflect that */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) + return RFKILL_STATE_HARD_BLOCKED; + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_bluetoothemul) return (tpacpi_bluetooth_emulstate) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; #endif if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) return -EIO; return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; +} + +static void bluetooth_update_rfk(void) +{ + int status; + + if (!tpacpi_bluetooth_rfkill) + return; + + status = bluetooth_get_radiosw(); + if (status < 0) + return; + rfkill_force_state(tpacpi_bluetooth_rfkill, status); + + vdbg_printk(TPACPI_DBG_RFKILL, + "forced rfkill state to %d\n", + status); } -static int bluetooth_set_status(enum tpacpi_rfkill_state state) +static int bluetooth_set_radiosw(int radio_on, int update_rfk) { int status; + if (!tp_features.bluetooth) + return -ENODEV; + + /* WLSW overrides bluetooth in firmware/hardware, but there is no + * reason to risk weird behaviour. */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status + && radio_on) + return -EPERM; + vdbg_printk(TPACPI_DBG_RFKILL, - "will attempt to %s bluetooth\n", - (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable"); + "will %s bluetooth\n", radio_on ? "enable" : "disable"); #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_bluetoothemul) { - tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON); + tpacpi_bluetooth_emulstate = !!radio_on; + if (update_rfk) + bluetooth_update_rfk(); return 0; } #endif /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ - if (state == TPACPI_RFK_RADIO_ON) + if (radio_on) status = TP_ACPI_BLUETOOTH_RADIOSSW; else status = 0; - if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) return -EIO; + if (update_rfk) + bluetooth_update_rfk(); + return 0; } @@ -3409,16 +3152,35 @@ static ssize_t bluetooth_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { - return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID, - attr, buf); + int status; + + printk_deprecated_rfkill_attribute("bluetooth_enable"); + + status = bluetooth_get_radiosw(); + if (status < 0) + return status; + + return snprintf(buf, PAGE_SIZE, "%d\n", + (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0); } static ssize_t bluetooth_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID, - attr, buf, count); + unsigned long t; + int res; + + printk_deprecated_rfkill_attribute("bluetooth_enable"); + + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + + tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t); + + res = bluetooth_set_radiosw(t, 1); + + return (res) ? res : count; } static struct device_attribute dev_attr_bluetooth_enable = @@ -3436,10 +3198,23 @@ static const struct attribute_group bluetooth_attr_group = { .attrs = bluetooth_attributes, }; -static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = { - .get_status = bluetooth_get_status, - .set_status = bluetooth_set_status, -}; +static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) +{ + int bts = bluetooth_get_radiosw(); + + if (bts < 0) + return bts; + + *state = bts; + return 0; +} + +static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) +{ + dbg_printk(TPACPI_DBG_RFKILL, + "request to change radio state to %d\n", state); + return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); +} static void bluetooth_shutdown(void) { @@ -3455,12 +3230,13 @@ static void bluetooth_shutdown(void) static void bluetooth_exit(void) { - sysfs_remove_group(&tpacpi_pdev->dev.kobj, - &bluetooth_attr_group); + bluetooth_shutdown(); - tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID); + if (tpacpi_bluetooth_rfkill) + rfkill_unregister(tpacpi_bluetooth_rfkill); - bluetooth_shutdown(); + sysfs_remove_group(&tpacpi_pdev->dev.kobj, + &bluetooth_attr_group); } static int __init bluetooth_init(struct ibm_init_struct *iibm) @@ -3501,18 +3277,20 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) if (!tp_features.bluetooth) return 1; - res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, - &bluetooth_tprfk_ops, - RFKILL_TYPE_BLUETOOTH, - TPACPI_RFK_BLUETOOTH_SW_NAME, - true); + res = sysfs_create_group(&tpacpi_pdev->dev.kobj, + &bluetooth_attr_group); if (res) return res; - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, - &bluetooth_attr_group); + res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, + &tpacpi_bluetooth_rfkill, + RFKILL_TYPE_BLUETOOTH, + TPACPI_RFK_BLUETOOTH_SW_NAME, + true, + tpacpi_bluetooth_rfk_set, + tpacpi_bluetooth_rfk_get); if (res) { - tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID); + bluetooth_exit(); return res; } @@ -3522,12 +3300,46 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) /* procfs -------------------------------------------------------------- */ static int bluetooth_read(char *p) { - return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p); + int len = 0; + int status = bluetooth_get_radiosw(); + + if (!tp_features.bluetooth) + len += sprintf(p + len, "status:\t\tnot supported\n"); + else { + len += sprintf(p + len, "status:\t\t%s\n", + (status == RFKILL_STATE_UNBLOCKED) ? + "enabled" : "disabled"); + len += sprintf(p + len, "commands:\tenable, disable\n"); + } + + return len; } static int bluetooth_write(char *buf) { - return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf); + char *cmd; + int state = -1; + + if (!tp_features.bluetooth) + return -ENODEV; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "enable") == 0) { + state = 1; + } else if (strlencmp(cmd, "disable") == 0) { + state = 0; + } else + return -EINVAL; + } + + if (state != -1) { + tpacpi_disclose_usertask("procfs bluetooth", + "attempt to %s\n", + state ? "enable" : "disable"); + bluetooth_set_radiosw(state, 1); + } + + return 0; } static struct ibm_struct bluetooth_driver_data = { @@ -3553,6 +3365,8 @@ enum { #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" +static struct rfkill *tpacpi_wan_rfkill; + static void wan_suspend(pm_message_t state) { /* Try to make sure radio will resume powered off */ @@ -3562,47 +3376,83 @@ static void wan_suspend(pm_message_t state) "WWAN power down on resume request failed\n"); } -static int wan_get_status(void) +static int wan_get_radiosw(void) { int status; + if (!tp_features.wan) + return -ENODEV; + + /* WLSW overrides WWAN in firmware/hardware, reflect that */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) + return RFKILL_STATE_HARD_BLOCKED; + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_wwanemul) return (tpacpi_wwan_emulstate) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; #endif if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) return -EIO; return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; +} + +static void wan_update_rfk(void) +{ + int status; + + if (!tpacpi_wan_rfkill) + return; + + status = wan_get_radiosw(); + if (status < 0) + return; + rfkill_force_state(tpacpi_wan_rfkill, status); + + vdbg_printk(TPACPI_DBG_RFKILL, + "forced rfkill state to %d\n", + status); } -static int wan_set_status(enum tpacpi_rfkill_state state) +static int wan_set_radiosw(int radio_on, int update_rfk) { int status; + if (!tp_features.wan) + return -ENODEV; + + /* WLSW overrides bluetooth in firmware/hardware, but there is no + * reason to risk weird behaviour. */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status + && radio_on) + return -EPERM; + vdbg_printk(TPACPI_DBG_RFKILL, - "will attempt to %s wwan\n", - (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable"); + "will %s WWAN\n", radio_on ? "enable" : "disable"); #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_wwanemul) { - tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON); + tpacpi_wwan_emulstate = !!radio_on; + if (update_rfk) + wan_update_rfk(); return 0; } #endif /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ - if (state == TPACPI_RFK_RADIO_ON) + if (radio_on) status = TP_ACPI_WANCARD_RADIOSSW; else status = 0; - if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) return -EIO; + if (update_rfk) + wan_update_rfk(); + return 0; } @@ -3611,16 +3461,35 @@ static ssize_t wan_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { - return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID, - attr, buf); + int status; + + printk_deprecated_rfkill_attribute("wwan_enable"); + + status = wan_get_radiosw(); + if (status < 0) + return status; + + return snprintf(buf, PAGE_SIZE, "%d\n", + (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0); } static ssize_t wan_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID, - attr, buf, count); + unsigned long t; + int res; + + printk_deprecated_rfkill_attribute("wwan_enable"); + + if (parse_strtoul(buf, 1, &t)) + return -EINVAL; + + tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t); + + res = wan_set_radiosw(t, 1); + + return (res) ? res : count; } static struct device_attribute dev_attr_wan_enable = @@ -3638,10 +3507,23 @@ static const struct attribute_group wan_attr_group = { .attrs = wan_attributes, }; -static const struct tpacpi_rfk_ops wan_tprfk_ops = { - .get_status = wan_get_status, - .set_status = wan_set_status, -}; +static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) +{ + int wans = wan_get_radiosw(); + + if (wans < 0) + return wans; + + *state = wans; + return 0; +} + +static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) +{ + dbg_printk(TPACPI_DBG_RFKILL, + "request to change radio state to %d\n", state); + return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); +} static void wan_shutdown(void) { @@ -3657,12 +3539,13 @@ static void wan_shutdown(void) static void wan_exit(void) { - sysfs_remove_group(&tpacpi_pdev->dev.kobj, - &wan_attr_group); + wan_shutdown(); - tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID); + if (tpacpi_wan_rfkill) + rfkill_unregister(tpacpi_wan_rfkill); - wan_shutdown(); + sysfs_remove_group(&tpacpi_pdev->dev.kobj, + &wan_attr_group); } static int __init wan_init(struct ibm_init_struct *iibm) @@ -3701,19 +3584,20 @@ static int __init wan_init(struct ibm_init_struct *iibm) if (!tp_features.wan) return 1; - res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, - &wan_tprfk_ops, - RFKILL_TYPE_WWAN, - TPACPI_RFK_WWAN_SW_NAME, - true); - if (res) - return res; - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, &wan_attr_group); + if (res) + return res; + res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, + &tpacpi_wan_rfkill, + RFKILL_TYPE_WWAN, + TPACPI_RFK_WWAN_SW_NAME, + true, + tpacpi_wan_rfk_set, + tpacpi_wan_rfk_get); if (res) { - tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID); + wan_exit(); return res; } @@ -3723,12 +3607,48 @@ static int __init wan_init(struct ibm_init_struct *iibm) /* procfs -------------------------------------------------------------- */ static int wan_read(char *p) { - return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p); + int len = 0; + int status = wan_get_radiosw(); + + tpacpi_disclose_usertask("procfs wan", "read"); + + if (!tp_features.wan) + len += sprintf(p + len, "status:\t\tnot supported\n"); + else { + len += sprintf(p + len, "status:\t\t%s\n", + (status == RFKILL_STATE_UNBLOCKED) ? + "enabled" : "disabled"); + len += sprintf(p + len, "commands:\tenable, disable\n"); + } + + return len; } static int wan_write(char *buf) { - return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf); + char *cmd; + int state = -1; + + if (!tp_features.wan) + return -ENODEV; + + while ((cmd = next_cmd(&buf))) { + if (strlencmp(cmd, "enable") == 0) { + state = 1; + } else if (strlencmp(cmd, "disable") == 0) { + state = 0; + } else + return -EINVAL; + } + + if (state != -1) { + tpacpi_disclose_usertask("procfs wan", + "attempt to %s\n", + state ? "enable" : "disable"); + wan_set_radiosw(state, 1); + } + + return 0; } static struct ibm_struct wan_driver_data = { @@ -3752,59 +3672,108 @@ enum { #define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw" -static int uwb_get_status(void) +static struct rfkill *tpacpi_uwb_rfkill; + +static int uwb_get_radiosw(void) { int status; + if (!tp_features.uwb) + return -ENODEV; + + /* WLSW overrides UWB in firmware/hardware, reflect that */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status) + return RFKILL_STATE_HARD_BLOCKED; + #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_uwbemul) return (tpacpi_uwb_emulstate) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; #endif if (!acpi_evalf(hkey_handle, &status, "GUWB", "d")) return -EIO; return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ? - TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF; + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; } -static int uwb_set_status(enum tpacpi_rfkill_state state) +static void uwb_update_rfk(void) { int status; + if (!tpacpi_uwb_rfkill) + return; + + status = uwb_get_radiosw(); + if (status < 0) + return; + rfkill_force_state(tpacpi_uwb_rfkill, status); + vdbg_printk(TPACPI_DBG_RFKILL, - "will attempt to %s UWB\n", - (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable"); + "forced rfkill state to %d\n", + status); +} + +static int uwb_set_radiosw(int radio_on, int update_rfk) +{ + int status; + + if (!tp_features.uwb) + return -ENODEV; + + /* WLSW overrides UWB in firmware/hardware, but there is no + * reason to risk weird behaviour. */ + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status + && radio_on) + return -EPERM; + + vdbg_printk(TPACPI_DBG_RFKILL, + "will %s UWB\n", radio_on ? "enable" : "disable"); #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_uwbemul) { - tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON); + tpacpi_uwb_emulstate = !!radio_on; + if (update_rfk) + uwb_update_rfk(); return 0; } #endif - if (state == TPACPI_RFK_RADIO_ON) - status = TP_ACPI_UWB_RADIOSSW; - else - status = 0; - + status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0; if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status)) return -EIO; + if (update_rfk) + uwb_update_rfk(); + return 0; } /* --------------------------------------------------------------------- */ -static const struct tpacpi_rfk_ops uwb_tprfk_ops = { - .get_status = uwb_get_status, - .set_status = uwb_set_status, -}; +static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) +{ + int uwbs = uwb_get_radiosw(); + + if (uwbs < 0) + return uwbs; + + *state = uwbs; + return 0; +} + +static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state) +{ + dbg_printk(TPACPI_DBG_RFKILL, + "request to change radio state to %d\n", state); + return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); +} static void uwb_exit(void) { - tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID); + if (tpacpi_uwb_rfkill) + rfkill_unregister(tpacpi_uwb_rfkill); } static int __init uwb_init(struct ibm_init_struct *iibm) @@ -3844,10 +3813,13 @@ static int __init uwb_init(struct ibm_init_struct *iibm) return 1; res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, - &uwb_tprfk_ops, + &tpacpi_uwb_rfkill, RFKILL_TYPE_UWB, TPACPI_RFK_UWB_SW_NAME, - false); + false, + tpacpi_uwb_rfk_set, + tpacpi_uwb_rfk_get); + return res; } diff --git a/trunk/drivers/platform/x86/toshiba_acpi.c b/trunk/drivers/platform/x86/toshiba_acpi.c index 81d31ea507d1..4345089f5171 100644 --- a/trunk/drivers/platform/x86/toshiba_acpi.c +++ b/trunk/drivers/platform/x86/toshiba_acpi.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -249,15 +250,21 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result) struct toshiba_acpi_dev { struct platform_device *p_dev; - struct rfkill *bt_rfk; + struct rfkill *rfk_dev; + struct input_polled_dev *poll_dev; const char *bt_name; + const char *rfk_name; + + bool last_rfk_state; struct mutex mutex; }; static struct toshiba_acpi_dev toshiba_acpi = { .bt_name = "Toshiba Bluetooth", + .rfk_name = "Toshiba RFKill Switch", + .last_rfk_state = false, }; /* Bluetooth rfkill handlers */ @@ -276,6 +283,21 @@ static u32 hci_get_bt_present(bool *present) return hci_result; } +static u32 hci_get_bt_on(bool *on) +{ + u32 hci_result; + u32 value, value2; + + value = 0; + value2 = 0x0001; + hci_read2(HCI_WIRELESS, &value, &value2, &hci_result); + if (hci_result == HCI_SUCCESS) + *on = (value & HCI_WIRELESS_BT_POWER) && + (value & HCI_WIRELESS_BT_ATTACH); + + return hci_result; +} + static u32 hci_get_radio_state(bool *radio_state) { u32 hci_result; @@ -289,67 +311,70 @@ static u32 hci_get_radio_state(bool *radio_state) return hci_result; } -static int bt_rfkill_set_block(void *data, bool blocked) +static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state) { - struct toshiba_acpi_dev *dev = data; u32 result1, result2; u32 value; - int err; bool radio_state; + struct toshiba_acpi_dev *dev = data; - value = (blocked == false); + value = (state == RFKILL_STATE_UNBLOCKED); - mutex_lock(&dev->mutex); - if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) { - err = -EBUSY; - goto out; - } + if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) + return -EFAULT; - if (!radio_state) { - err = 0; - goto out; + switch (state) { + case RFKILL_STATE_UNBLOCKED: + if (!radio_state) + return -EPERM; + break; + case RFKILL_STATE_SOFT_BLOCKED: + break; + default: + return -EINVAL; } + mutex_lock(&dev->mutex); hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1); hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2); + mutex_unlock(&dev->mutex); if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS) - err = -EBUSY; - else - err = 0; - out: - mutex_unlock(&dev->mutex); - return err; + return -EFAULT; + + return 0; } -static void bt_rfkill_poll(struct rfkill *rfkill, void *data) +static void bt_poll_rfkill(struct input_polled_dev *poll_dev) { + bool state_changed; bool new_rfk_state; bool value; u32 hci_result; - struct toshiba_acpi_dev *dev = data; - - mutex_lock(&dev->mutex); + struct toshiba_acpi_dev *dev = poll_dev->private; hci_result = hci_get_radio_state(&value); - if (hci_result != HCI_SUCCESS) { - /* Can't do anything useful */ - mutex_unlock(&dev->mutex); - } + if (hci_result != HCI_SUCCESS) + return; /* Can't do anything useful */ new_rfk_state = value; + mutex_lock(&dev->mutex); + state_changed = new_rfk_state != dev->last_rfk_state; + dev->last_rfk_state = new_rfk_state; mutex_unlock(&dev->mutex); - if (rfkill_set_hw_state(rfkill, !new_rfk_state)) - bt_rfkill_set_block(data, true); + if (unlikely(state_changed)) { + rfkill_force_state(dev->rfk_dev, + new_rfk_state ? + RFKILL_STATE_SOFT_BLOCKED : + RFKILL_STATE_HARD_BLOCKED); + input_report_switch(poll_dev->input, SW_RFKILL_ALL, + new_rfk_state); + input_sync(poll_dev->input); + } } -static const struct rfkill_ops toshiba_rfk_ops = { - .set_block = bt_rfkill_set_block, - .poll = bt_rfkill_poll, -}; - static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; static struct backlight_device *toshiba_backlight_device; static int force_fan; @@ -677,11 +702,14 @@ static struct backlight_ops toshiba_backlight_data = { static void toshiba_acpi_exit(void) { - if (toshiba_acpi.bt_rfk) { - rfkill_unregister(toshiba_acpi.bt_rfk); - rfkill_destroy(toshiba_acpi.bt_rfk); + if (toshiba_acpi.poll_dev) { + input_unregister_polled_device(toshiba_acpi.poll_dev); + input_free_polled_device(toshiba_acpi.poll_dev); } + if (toshiba_acpi.rfk_dev) + rfkill_unregister(toshiba_acpi.rfk_dev); + if (toshiba_backlight_device) backlight_device_unregister(toshiba_backlight_device); @@ -700,6 +728,8 @@ static int __init toshiba_acpi_init(void) acpi_status status = AE_OK; u32 hci_result; bool bt_present; + bool bt_on; + bool radio_on; int ret = 0; if (acpi_disabled) @@ -763,21 +793,60 @@ static int __init toshiba_acpi_init(void) /* Register rfkill switch for Bluetooth */ if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { - toshiba_acpi.bt_rfk = rfkill_alloc(toshiba_acpi.bt_name, - &toshiba_acpi.p_dev->dev, - RFKILL_TYPE_BLUETOOTH, - &toshiba_rfk_ops, - &toshiba_acpi); - if (!toshiba_acpi.bt_rfk) { + toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev, + RFKILL_TYPE_BLUETOOTH); + if (!toshiba_acpi.rfk_dev) { printk(MY_ERR "unable to allocate rfkill device\n"); toshiba_acpi_exit(); return -ENOMEM; } - ret = rfkill_register(toshiba_acpi.bt_rfk); + toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name; + toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio; + toshiba_acpi.rfk_dev->data = &toshiba_acpi; + + if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) { + toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED; + } else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS && + radio_on) { + toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED; + } else { + toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED; + } + + ret = rfkill_register(toshiba_acpi.rfk_dev); if (ret) { printk(MY_ERR "unable to register rfkill device\n"); - rfkill_destroy(toshiba_acpi.bt_rfk); + toshiba_acpi_exit(); + return -ENOMEM; + } + + /* Register input device for kill switch */ + toshiba_acpi.poll_dev = input_allocate_polled_device(); + if (!toshiba_acpi.poll_dev) { + printk(MY_ERR + "unable to allocate kill-switch input device\n"); + toshiba_acpi_exit(); + return -ENOMEM; + } + toshiba_acpi.poll_dev->private = &toshiba_acpi; + toshiba_acpi.poll_dev->poll = bt_poll_rfkill; + toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */ + + toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name; + toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST; + /* Toshiba USB ID */ + toshiba_acpi.poll_dev->input->id.vendor = 0x0930; + set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit); + set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit); + input_report_switch(toshiba_acpi.poll_dev->input, + SW_RFKILL_ALL, TRUE); + input_sync(toshiba_acpi.poll_dev->input); + + ret = input_register_polled_device(toshiba_acpi.poll_dev); + if (ret) { + printk(MY_ERR + "unable to register kill-switch input device\n"); toshiba_acpi_exit(); return ret; } diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 74c49d9a8dba..2994aa1ed466 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -2937,8 +2937,8 @@ int qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb) if (card->info.type == QETH_CARD_TYPE_OSN) return cast_type; - if (skb_dst(skb) && skb_dst(skb)->neighbour) { - cast_type = skb_dst(skb)->neighbour->type; + if (skb->dst && skb->dst->neighbour) { + cast_type = skb->dst->neighbour->type; if ((cast_type == RTN_BROADCAST) || (cast_type == RTN_MULTICAST) || (cast_type == RTN_ANYCAST)) diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index ecd3d06c0d5c..9ca6bab7c9ba 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "qeth_core.h" @@ -641,7 +640,6 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; struct dev_addr_list *dm; - struct netdev_hw_addr *ha; if (card->info.type == QETH_CARD_TYPE_OSN) return ; @@ -655,8 +653,8 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) for (dm = dev->mc_list; dm; dm = dm->next) qeth_l2_add_mc(card, dm->da_addr, 0); - list_for_each_entry(ha, &dev->uc_list, list) - qeth_l2_add_mc(card, ha->addr, 1); + for (dm = dev->uc_list; dm; dm = dm->next) + qeth_l2_add_mc(card, dm->da_addr, 1); spin_unlock_bh(&card->mclock); if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index 6f2386e9d6e2..b36b5cdf9000 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -2549,9 +2549,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, /* IPv4 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); memset(hdr->hdr.l3.dest_addr, 0, 12); - if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) { + if ((skb->dst) && (skb->dst->neighbour)) { *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - *((u32 *) skb_dst(skb)->neighbour->primary_key); + *((u32 *) skb->dst->neighbour->primary_key); } else { /* fill in destination address used in ip header */ *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = @@ -2562,9 +2562,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); if (card->info.type == QETH_CARD_TYPE_IQD) hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; - if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) { + if ((skb->dst) && (skb->dst->neighbour)) { memcpy(hdr->hdr.l3.dest_addr, - skb_dst(skb)->neighbour->primary_key, 16); + skb->dst->neighbour->primary_key, 16); } else { /* fill in destination address used in ip header */ memcpy(hdr->hdr.l3.dest_addr, @@ -3012,7 +3012,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) card->dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - card->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; SET_NETDEV_DEV(card->dev, &card->gdev->dev); return register_netdev(card->dev); diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index f791348871fc..ce33f107b0a0 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -182,8 +182,8 @@ static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) fc = fcoe_from_ctlr(fip); rtnl_lock(); if (!is_zero_ether_addr(old)) - dev_unicast_delete(fc->real_dev, old); - dev_unicast_add(fc->real_dev, new); + dev_unicast_delete(fc->real_dev, old, ETH_ALEN); + dev_unicast_add(fc->real_dev, new, ETH_ALEN); rtnl_unlock(); } @@ -233,11 +233,13 @@ void fcoe_netdev_cleanup(struct fcoe_softc *fc) /* Delete secondary MAC addresses */ rtnl_lock(); memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); - dev_unicast_delete(fc->real_dev, flogi_maddr); + dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN); if (!is_zero_ether_addr(fc->ctlr.data_src_addr)) - dev_unicast_delete(fc->real_dev, fc->ctlr.data_src_addr); + dev_unicast_delete(fc->real_dev, + fc->ctlr.data_src_addr, ETH_ALEN); if (fc->ctlr.spma) - dev_unicast_delete(fc->real_dev, fc->ctlr.ctl_src_addr); + dev_unicast_delete(fc->real_dev, + fc->ctlr.ctl_src_addr, ETH_ALEN); dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); rtnl_unlock(); } @@ -345,9 +347,9 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) */ rtnl_lock(); memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); - dev_unicast_add(fc->real_dev, flogi_maddr); + dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN); if (fc->ctlr.spma) - dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr); + dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr, ETH_ALEN); dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); rtnl_unlock(); diff --git a/trunk/drivers/usb/gadget/f_phonet.c b/trunk/drivers/usb/gadget/f_phonet.c index 96fb118355b0..c1abeb89b413 100644 --- a/trunk/drivers/usb/gadget/f_phonet.c +++ b/trunk/drivers/usb/gadget/f_phonet.c @@ -188,7 +188,8 @@ static struct usb_descriptor_header *hs_pn_function[] = { static int pn_net_open(struct net_device *dev) { - netif_wake_queue(dev); + if (netif_carrier_ok(dev)) + netif_wake_queue(dev); return 0; } @@ -218,7 +219,8 @@ static void pn_tx_complete(struct usb_ep *ep, struct usb_request *req) } dev_kfree_skb_any(skb); - netif_wake_queue(dev); + if (netif_carrier_ok(dev)) + netif_wake_queue(dev); } static int pn_net_xmit(struct sk_buff *skb, struct net_device *dev) @@ -253,7 +255,7 @@ static int pn_net_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&port->lock, flags); out: if (unlikely(skb)) { - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); dev->stats.tx_dropped++; } return 0; @@ -381,6 +383,7 @@ static void __pn_reset(struct usb_function *f) struct phonet_port *port = netdev_priv(dev); netif_carrier_off(dev); + netif_stop_queue(dev); port->usb = NULL; usb_ep_disable(fp->out_ep); @@ -424,6 +427,8 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) fp->in_ep->driver_data = fp; netif_carrier_on(dev); + if (netif_running(dev)) + netif_wake_queue(dev); for (i = 0; i < phonet_rxq_size; i++) pn_rx_submit(fp, fp->out_reqv[i], GFP_ATOMIC); } @@ -569,10 +574,9 @@ static struct net_device *dev; int __init phonet_bind_config(struct usb_configuration *c) { struct f_phonet *fp; - int err, size; + int err; - size = sizeof(*fp) + (phonet_rxq_size * sizeof(struct usb_request *)); - fp = kzalloc(size, GFP_KERNEL); + fp = kzalloc(sizeof(*fp), GFP_KERNEL); if (!fp) return -ENOMEM; @@ -597,13 +601,16 @@ int __init gphonet_setup(struct usb_gadget *gadget) /* Create net device */ BUG_ON(dev); - dev = alloc_netdev(sizeof(*port), "upnlink%d", pn_net_setup); + dev = alloc_netdev(sizeof(*port) + + (phonet_rxq_size * sizeof(struct usb_request *)), + "upnlink%d", pn_net_setup); if (!dev) return -ENOMEM; port = netdev_priv(dev); spin_lock_init(&port->lock); netif_carrier_off(dev); + netif_stop_queue(dev); SET_NETDEV_DEV(dev, &gadget->dev); err = register_netdev(dev); diff --git a/trunk/firmware/Makefile b/trunk/firmware/Makefile index 621de8e952f7..96c3dd8cc683 100644 --- a/trunk/firmware/Makefile +++ b/trunk/firmware/Makefile @@ -41,7 +41,7 @@ fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ cxgb3/t3c_psram-1.1.0.bin \ - cxgb3/t3fw-7.4.0.bin + cxgb3/t3fw-7.1.0.bin fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ diff --git a/trunk/firmware/WHENCE b/trunk/firmware/WHENCE index 0f5649a08c0c..bb8fda8f06b8 100644 --- a/trunk/firmware/WHENCE +++ b/trunk/firmware/WHENCE @@ -412,7 +412,7 @@ Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter File: cxgb3/t3b_psram-1.1.0.bin.ihex File: cxgb3/t3c_psram-1.1.0.bin.ihex -file: cxgb3/t3fw-7.4.0.bin.ihex +file: cxgb3/t3fw-7.1.0.bin.ihex License: GPLv2 or OpenIB.org BSD license, no source visible diff --git a/trunk/firmware/cis/.gitignore b/trunk/firmware/cis/.gitignore deleted file mode 100644 index 1de39847f261..000000000000 --- a/trunk/firmware/cis/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.cis diff --git a/trunk/firmware/cxgb3/t3fw-7.1.0.bin.ihex b/trunk/firmware/cxgb3/t3fw-7.1.0.bin.ihex new file mode 100644 index 000000000000..1042f755f68f --- /dev/null +++ b/trunk/firmware/cxgb3/t3fw-7.1.0.bin.ihex @@ -0,0 +1,1885 @@ +:1000000060007400200380002003700000001000D6 +:1000100000002000E100028400070000E1000288E7 +:1000200000010000E0000000E00000A0010000006E +:1000300044444440E3000183200200002001E0002A +:100040002001FF101FFFD0001FFFC000E300043C91 +:1000500002000000200069881FFFC290200069D0C4 +:100060001FFFC29420006A101FFFC29820006A84FC +:100070001FFFC29C200003C0C00000E43100EA3131 +:1000800000A13100A03103020002ED306E2A05000C +:10009000ED3100020002160012FFDBC03014FFDA5F +:1000A000D30FD30FD30F03431F244C107249F0D347 +:1000B0000FD30FD30F12FFD5230A00240A00D30F4A +:1000C000D30FD30F03431F244C107249F0D30FD327 +:1000D0000FD30F14FFCE03421F14FFCB03421F1296 +:1000E000FFCCC0302D37302D37342D37382D373CED +:1000F000233D017233ED00020012FFC4C0302F37E0 +:10010000002F37102F37202F3730233D017233ED6A +:1001100000020012FFBEC0302737002737102737F4 +:1001200020273730233D017233ED03020012FFB95F +:1001300013FFBA0C0200932012FFB913FFB90C028F +:1001400000932012FFB8C0319320822012FFB71312 +:10015000FFB7932012FFB715FFB316FFB6C030D715 +:100160002005660160001B00000000000000000088 +:10017000043605000200D30FD30F05330C6E3B1479 +:100180000747140704437631E604360505330C6F40 +:100190003BED00020012FFA615FFA3230A00D720A3 +:1001A000070443043E0505330C0747146F3BF00377 +:1001B000020012FFA1C03014FFA1D30FD30FD30F41 +:1001C0009340B4447249F2D30FD30FD30F14FF9B63 +:1001D000834014FF9B834012FF9B230A0014FF9A65 +:1001E000D30FD30FD30F9340B4447249F2D30FD33C +:1001F0000FD30F14FF95834012FF95C92F832084DE +:10020000218522BC22743B0F8650B4559630B433FE +:100210007433F463FFE60000653FE1655FDE12FFC3 +:100220007C230A0028374028374428374828374C91 +:10023000233D017233ED03020000020012FF7AC079 +:1002400032032E0503020012FF7813FF819320C0B2 +:1002500011014931004831010200C00014FF7E0441 +:10026000D23115FF7D945014FF7D04D33115FF7CEE +:10027000945014FF7C04D43115FF7C24560014FFE5 +:100280007B04D53115FF7B24560010FF7A03000054 +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200063FFFC000000000000000000000000006E +:100430000000000000000000000000001FFC0000A1 +:100440001FFC0000E30005C81FFC00001FFC0000AB +:10045000E30005C81FFC00001FFC0000E30005C806 +:100460001FFFC0001FFFC000E30005C81FFFC00042 +:100470001FFFC018E30005C81FFFC0181FFFC018EA +:10048000E30005E01FFFC0181FFFC28CE30005E07A +:100490001FFFC28C1FFFC28CE30008541FFFC290D5 +:1004A0001FFFC58CE3000854200000002000016AF3 +:1004B000E3000B502000018020000180E3000CBC11 +:1004C0002000020020000203E3000CBC2000021CFC +:1004D00020000220E3000CC02000022020000226A1 +:1004E000E3000CC42000023C20000240E3000CCCDE +:1004F0002000024020000249E3000CD02000024C02 +:1005000020000250E3000CDC2000025020000259C1 +:10051000E3000CE02000025C20000260E3000CEC31 +:100520002000026020000269E3000CF02000026C51 +:1005300020000270E3000CFC200002702000027911 +:10054000E3000D002000028C2000028CE3000D0C63 +:100550002000029020000293E3000D0C200002AC6A +:10056000200002B0E3000D10200002D0200002F2B3 +:10057000E3000D14200003B0200003B0E3000D38A9 +:10058000200003B0200003B0E3000D38200003B0CA +:10059000200003B0E3000D38200003B0200003B0BA +:1005A000E3000D38200003B020006BA8E3000D38F5 +:1005B00020006BA820006BA8E3007530000000004D +:1005C00000000000000000001FFC00001FFC0000F5 +:1005D0001FFFC5901FFFC67020006BA820006BA8EE +:1005E000DEFFFE000000080CDEADBEEF1FFFC2A064 +:1005F0001FFCFE001FFFC0941FFFC5C0300000009D +:10060000003FFFFF8040000010000000080FFFFFC8 +:100610001FFFC26D000FFFFF804FFFFF8000000033 +:1006200000000880B000000560500000600000007D +:1006300040000011350000004100000010000001E2 +:1006400020000000000010007FFFFFFF40000000BE +:1006500005000000800000190400000000000800F0 +:1006600010000005806000007000000020000009FC +:10067000001FF8008000001EA0000000F80000002D +:1006800007FFFFFF080000001800000001008001C4 +:10069000420000001FFFC21D1FFFC0DC00010080E0 +:1006A000604000001A0000000C0000000000300054 +:1006B000600008008000001C000100008000001A9B +:1006C00080000018FC0000008000000100004000D5 +:1006D000030000008000040050000003FFFFBFFF84 +:1006E0001FFFC3D400000FFFFFFFF000000016D073 +:1006F0000000FFF7A50000001FFFC4B01FFFC4618A +:100700000001000800000B20202FFF801FFFC455B0 +:1007100000002C00FFFEFFF800FFFFFF1FFFC57861 +:1007200000002000FFFFDFFF0000FFEF01001100CD +:100730001FFFC3D21FFFC590FFFFEFFF0000FFFBAD +:100740001FFFC6301FFFBEA0FFFFF7FF1FFFC064E3 +:100750000000FFFD1FFFC6200001FBD01FFFC5B03A +:100760001FFFC6601FFFC591E0FFFE001FFFC5A071 +:10077000000080001FFFC53C1FFFC5B41FFFC068FD +:100780001FFFC4D01FFCFFD800010081E10006005C +:10079000000027101FFCFE301FFCFE70E10002006D +:1007A0001FFFC5381FFFC5500003D0901FFFC56451 +:1007B0002B5063802B5079802B5090802B50A6803B +:1007C0001FFFC4690100110F202FFE0020300080A0 +:1007D000202FFF000000FFFF0001FFF82B50B200A8 +:1007E0002B50B208000100102B50B1802B50B2806A +:1007F0002B50BA00000100112B50BD282B50BC809B +:100800002B50BDA020300000DFFFFE005000000292 +:1008100000C0000002000000FFFFF7F41FFFC06CE3 +:10082000000FF80004400000001000000C40000021 +:100830001C400000E00000A01FFFC5401FFD000895 +:100840001FFFC5541FFFC5681FFFC57CE100069050 +:10085000E10006EC000000000000000000000000C5 +:100860000000000001000000000000000000000087 +:100870000000000020100040201000402010004028 +:1008800020140080200C0000200C0000200C000030 +:1008900020100040201400802014008020140080CC +:1008A000201800C0201C0100201C0100201C010099 +:1008B00020200140201800C0201800C0201800C0CF +:1008C000201C0100201800C0201800C0201800C003 +:1008D000201C010020200140202001402020014058 +:1008E00020200940202009402020094020200940E4 +:1008F00020240980FFFFFFFFFFFFFFFFFFFFFFFF37 +:1009000000000000000000000000000000000000E7 +:1009100000000000200052FC200051CC200052FCBE +:10092000200052FC200051082000510820005108EE +:1009300020004F4820004F4820004F4020004EAC80 +:1009400020004D5420004B342000490800000000D6 +:1009500000000000200052CC200051982000523CA2 +:100960002000523C20004FF020004FF020004FF0BC +:1009700020004FF020004FF020004F3820004FF0B3 +:1009800020004C7420004AE4200048B4000000001D +:100990000000000020000BE0200038BC200004C054 +:1009A000200044A820000BD820003FB4200003F012 +:1009B000200044682000489020003CC420003BE018 +:1009C00020003838200036C42000343420002F9412 +:1009D00020003A3C20002BF4200028282000653419 +:1009E000200023B4200020942000204020001D2C53 +:1009F000200018402000157020000DEC20000C2471 +:100A00002000113420001320200041AC20003C784D +:100A100020000BE8200004C00000000000000000DF +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A900000000000000000003264000000000000C0 +:100AA0003264000064006400640064006400640058 +:100AB000640064000000000000000000000000006E +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000001000E6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000010000000000000000000C5 +:100B200000000000000000000043238000000000DF +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B5000005C94015D94025E94035F940043000086 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B9000005C90015D90025E90035F900053000046 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD000009C94001D90019D94029E94039F940498 +:100BE0000894050994060A94070B9400430000003A +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C1000009C90019D90029E90071D90039F900460 +:100C20007890057990067A90077B90005300000039 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C500000DC94001D9001DD9402DE9403DF940417 +:100C60000494050594060694070794080894090956 +:100C7000940A0A940B0B940043000000000000004B +:100C80000000000000000000000000000000000064 +:100C900000DC9001DD9002DE900B1D9003DF9004DC +:100CA000B49005B59006B69007B79008B89009B90A +:100CB000900ABA900BBB90005300000063FFFC0049 +:100CC0002000696410FFFF0A00000000200069880E +:100CD00000D23110FFFE0A0000000000200069D0A1 +:100CE00000D33110FFFE0A000000000020006A104F +:100CF00000D43110FFFE0A000000000020006A84CA +:100D000000D53110FFFE0A000000000063FFFC0068 +:100D1000E00000A012FFF78220028257C82163FF83 +:100D2000FC12FFF303E83004EE3005C0309320944A +:100D300021952263FFFC00001FFFD000000400206B +:100D40001FFFC5901FFFC670200A0011FFFB13FF95 +:100D5000FB03E63101020016FFFA17FFFAD30F7703 +:100D60006B069060B4667763F85415505419E60F1B +:100D7000140063FFF90000006C1004C020D10F00C4 +:100D80006C1004C0C71AEF06D830BC2BD720857270 +:100D90000D4211837105450B957202330C237601C8 +:100DA0007B3B04233D089371A32D12EEFE19EEFE4A +:100DB000A2767D632C2E0A00088202280A01038E87 +:100DC000380E0E42C8EE29A67E6D4A050020880026 +:100DD000308C8271D10FC0F0028F387FC0EA63FF80 +:100DE000E400C0F1C050037E0CA2EE0E3D1208825A +:100DF0000203F538050542CB5729A67E2FDC100FDC +:100E00004F366DFA0500208800308CBC75C0300864 +:100E1000E208280A01058338030342C93E29A67E59 +:100E20000D480CD30F6D8A0500208800B08C8271AC +:100E3000D10FC05008F53875C0C163FFBBC0600258 +:100E4000863876C0DA63FFD46C101216EED8C1F87B +:100E5000C1E72B221E2C221DC0D07BC12F292006CA +:100E6000D7B0299CFACC57282070288CFF282470F2 +:100E700064915C2AB0000EA80C6481670FA90C6411 +:100E800092B3C1E97EA13969AC2F600036292006F2 +:100E9000D7D0299CFACC57282070288CFF282470A2 +:100EA0006491352AD0000EA80C6481640FA90C64EB +:100EB000931BC1E97EA10968AC09C020D10F0000D5 +:100EC000002D25028A32C0900A6F5065F5AD2924A5 +:100ED000670908476585A92F200C18EEB50CFE118F +:100EE000A8EE28E286B44978930260057A19EEB13B +:100EF00009F90A2992A3689007882009880C65855A +:100F00006627E28564756065558E7BC104D9B06043 +:100F10000001C0908B941CEEA80B88148CC40B0BA2 +:100F200047A8CC18EEA609BB1008CC029C7018EE9E +:100F3000A41CEEA508A8010B88020C4C021BEEA114 +:100F40009C710B880298722C90232B902204C8105D +:100F500006BB100C4C1208BB0228902107CC100CC9 +:100F600088100C88020B88021CEE998B330CBB0195 +:100F70008C340B880298739C999C748B958C399B4C +:100F80007588968B38987688979C799B7898771C8B +:100F9000EE9028E2850CFC082DC4CF08480B28E60B +:100FA0008565550B2B221E2D221D7BD9022B0A0095 +:100FB00064BF062CB00728B000DA2006880A288211 +:100FC0004CC0D10B8000DBA065AFE763FEEB0000F7 +:100FD000292070659E9C6004E42A207065AEC36081 +:100FE00004DB00002EB0032C2067D4E065C1058A25 +:100FF000328C330AFF500C4554BC5564F4E619EEAC +:1010000075882A09A90109880C64821BC0926000B6 +:10101000DD2ED0032A2067D4E065A0D88A328B3336 +:101020000AFC500B4554BC5564C4B919EE6A882AB1 +:1010300009A9017989D50BEA5064A4DD0CEE11C031 +:10104000F02F16132E16168AE78CE82A16128EE950 +:10105000DFC0AAEA7EAB01B1CF0BA85065834288FE +:1010600037DBC0AE89991E789B022BCC012B161B57 +:1010700029120E2B0A0029161A7FC3077FC9027E88 +:10108000AB01C0B165B4988B352F0A002A0A007AEB +:10109000C30564C3C72F0A0165F4842B12162B16EF +:1010A00019005104C0C100CC1A2CCCFF2C16170C0F +:1010B000FC132C16182B121A2A121BDC505818FA83 +:1010C000C0D0C0902E5CF42C12172812182F121BBF +:1010D0002A121A08FF010CAA018834074C0AAB8BAC +:1010E0002812192BC6162F86082A86092E74102955 +:1010F00024672E70038975B1EA2A7403B0990949EF +:101100000C659DB52B20672D250265B3F42B221E9F +:101110002C221D7BC901C0B064BD9E2CB00728B035 +:1011200000DA2006880A28824CC0D10B8000DBA0A0 +:1011300065AFE763FD8389BAB19965909788341CE0 +:10114000EE2698BA8F331EEE1F0F4F542FB42C8DFE +:101150002A8A320EDD020CAC017DC9660A49516F44 +:1011600092608A3375A65B2CB0130AED510DCD0148 +:101170000D0D410C0C417DC9492EB012B0EE65E356 +:10118000C2C0D08E378CB88A368FB97CA3077AC993 +:10119000027EFB01C0D1CED988350AAD020E8E0881 +:1011A00078EB022DAC0189B7DAC0AF9B79BB01B1F6 +:1011B000CADCB0C0B07DA3077AD9027CEB01C0B114 +:1011C00064B15DC091292467C020D10F00008ADA84 +:1011D000B1AA64A0BC2E20672D250265E30B1FED8C +:1011E000F98A3218EDFE0FAF0108FF0C65F2860A8E +:1011F00048516F820260027DC090292467090A4726 +:1012000065A2F27BC901C0B064BCAE2CB00728B0A7 +:1012100000DA2006880A28824CC0D10B8000DBA0AF +:1012200065AFE763FC9300000CE9506492EB0CEFB0 +:1012300011C080281611AFBF2F16198EF88BF7DA60 +:10124000E08FF92B1610ABFB7FBB01B1EA0CA85065 +:101250006580D68837DCE0AF89991C789B022CEC3E +:10126000012C161B29120C2C0A0029161A7AE307E6 +:101270007AE9027FBB01C0C165C2A48B352C0A008C +:101280002A0A007AE30564E1CA2C0A0164CE1160DF +:10129000028D88341BEDD198DA8F331EEDCA0F4FC3 +:1012A000542FD42C8C2A8A320ECC020BAB010CBBEF +:1012B0000C65BF0E0A49516E920263FF058A330A1C +:1012C000AB5064BEFD2CD0130AEE510ECE010E0EB3 +:1012D000410C0C410ECC0C65CEE82FD012B0FF654E +:1012E000F26EC0B08E378CD88A362FD2097CA30715 +:1012F0007AC9027EFB01C0B165BEC78835DBA0AEEE +:101300008E78EB01B1AB89D7DAC0AF9D79DB01B143 +:10131000CAC0C07BA3077AB9027DEB01C0C165CE0C +:10132000A1C090292467C020D10F88378C3698142B +:101330000CE90C29161408F80C981D78FB072812E4 +:1013400014B088281614891D9F159B16C0F02B1207 +:101350001429161A2B161B8B147AE30B7AE90688CC +:10136000158E1678EB01C0F165F1B929121A2F120A +:10137000118A352E121B9A1AAFEE2F1210C0A0AF91 +:101380009F79FB01B1EE9F11881AC0F098107AE3A3 +:101390000A7EA9052A12017A8B01C0F164F08160EE +:1013A000018289368B3799170BE80C981F09C90CF5 +:1013B00029161578EB07281215B088281615D9C0FC +:1013C0009A199E188A1F2E12152A161A2E161BDA23 +:1013D000C0C0E08C177F930B7FA90688188F1978FF +:1013E000FB01C0E165E13D29121A2F12138A352E47 +:1013F000121B9A1BAFEE2F1212C0A0AF9F79FB01F8 +:10140000B1EE9F13881BC0F098127AE30A7EA905FB +:101410002A12037A8B01C0F165F1092E12162E16DD +:10142000192A121B005104C0E100EE1AB0EE2E166C +:10143000170EFF132F16180FCC01ACAA2F121A0E7D +:10144000BC01ACFC7FCB01B1AA2A161B2C161A6377 +:10145000FC6200007FB30263FE3163FE2B7EB302A9 +:1014600063FC3463FC2E00006450C0DA20DBF058CB +:1014700015DEC020D10FC09163FD7E00C09163FADC +:101480004CDA20DB70C0D12E0A80C09A2924682C47 +:1014900070075814CED2A0D10F034C0B18ED51DBBE +:1014A000C0A82878C3022BCDF8D9B063FA65000034 +:1014B0002A2C74DB40580E5063FAE80000002D25FA +:1014C000027BC901C0B064B0172CB00728B000DAA5 +:1014D0002006880A28824CC0D10B8000DBA065AFB3 +:1014E000E7C020D10FC09163FC04022A02580250C9 +:1014F0000AA202060000022A0258024D0AA20206AF +:101500000000DB70DA20C0D12E0A80C09E2924683A +:101510002C70075814AEC020D10FC09463FBCF00CD +:10152000C09663FBC9C09663FBC400002A2C74DB21 +:1015300030DC405BFE13DBA0C2A02AB4002F200CDD +:1015400063FF27008D358CB77DCB0263FDD263FC32 +:10155000718F358ED77FEB0263FDC563FC6400009D +:101560006C1004C020D10F006C1004C020D10F00FB +:101570006C10042B221E28221DC0A0C09429240612 +:101580002A25027B8901DBA0C9B913ED08DA2028DE +:10159000B0002CB00703880A28824CC0D10B800011 +:1015A000DBA065AFE7C020D10F0000006C1004295C +:1015B00020062A2102689805289CF965811A0A0AE2 +:1015C0004C65A0F016ECFB2B629E1AECF86FB8028B +:1015D0006000F12AA22668A0078B200ABB0C65B028 +:1015E000E32A629D64A0DD2B200C0CBC11A6CC2D3F +:1015F000C2866FD9026000D71DECEF0DBD0A2DD257 +:10160000A368D0078E200DEE0C65E0C327C285C00D +:10161000E06470BB1DECF468434D1CECF38A2B0CAA +:10162000AA029A7089200899110D99029971882A45 +:1016300098748F329F75282104088811987718ECC8 +:10164000E40CBF11A6FF2DF285A8B82E84CF2DDCA7 +:10165000282DF685C85A2A2C74DB40580DE7D2A0F5 +:10166000D10FC020D10F00002C9CF964C08D2C201C +:10167000668931B1CC0C0C472C24666FC669709E0C +:101680006618ECDA89308F2B0989400B991009FF15 +:101690000208FF029F708C2008CC110DCC029C71B7 +:1016A0008A339A7389329972882A98748F349F7515 +:1016B00063FF820000CC57DA20DB30DC405814B8DE +:1016C000C020D10F00DA20C0B658154763FFE500EF +:1016D000DA2058154563FFDC00DA20DB30DC40DD22 +:1016E000505815C7D2A0D10F2B21045813DA1DEC86 +:1016F000BD2B200CC0E02E246663FF842F2123C065 +:10170000C87FC30263FF792C20662B2104B1CC0C67 +:101710000C472C24665813CF1DECB32B200CC0E0D3 +:101720002E246663FF5A00006C1004C0B7C0A116D7 +:10173000ECB015ECA2D720D840B822C04005350245 +:101740009671957002A438040442C94B1AEC95199D +:10175000EC9629A67EC140D30F6D4A050080880013 +:10176000208C220A88A272D10FC05008A53875B00B +:10177000E363FFD76C100893149412292006655276 +:1017800088C0716898052A9CF965A29816EC892989 +:1017900021028A1409094C6590C78AA00A6A512A55 +:1017A000ACFD65A0BCCC5FDB30DA208C1258147C19 +:1017B000C0519A14C7BF9BA98E142EE20968E0603D +:1017C0002F629E1DEC7A6FF8026000812DD2266890 +:1017D000D0052F22007DF9752C629DC79064C06DE5 +:1017E0009C118A142B200C2AA0200CBD11A6DD0A06 +:1017F0004F14BFA809880129D286AF88288C09799F +:101800008B551FEC6C0FBF0A2FF2A368F00528223E +:10181000007F894329D285D49065907760003D0090 +:10182000002B200C1FEC640CBD11A6DD29D2860F05 +:10183000BF0A6E96102FF2A368F00488207F8905F6 +:1018400029D285659165DA205814E7600013DA2003 +:10185000C0B65814E5600009C09063FFB9DA20589B +:1018600014E28914899109FE506551E48C128D149B +:10187000DA20DBD08DD09E100D6D515813549A1480 +:1018800064A208C75F8FA195A9C0510F0F479F128F +:1018900063FEFB00C091C0F12820062C2066288C36 +:1018A000F9A7CC0C0C472C24666FC6088D148DD17B +:1018B00070DE01C090DD90648159C9D32A12012BDA +:1018C00021045813648A14C0B02B24668EA92AA060 +:1018D000200E28141CEC438D1415EC37C1700A77C8 +:1018E0003685562DDC28AC2C9C13DED0A8557CD335 +:1018F000022EDDF8D3E0DA40055B02DC305BFF8AC4 +:10190000D4A028200CB455C0D02B0A882F0A800CF4 +:101910008C11A6CC29C285AF3FAB9929C6851CEC9A +:101920002CDEF0AC882D84CF28120329120478F322 +:10193000022EFDF8289020D3E007880CC17008081B +:1019400047289420087736657FAB891413EC2A89E1 +:1019500090C0F47797491BEC28C1CA28210485144C +:10196000099E4006EE11875304881185520E8802A5 +:101970000C88029BA09FA18F2B9DA598A497A7954B +:10198000A603FF029FA22C200C1EEC11AECE0CCCA5 +:101990001106CC082BC2852DE4CF2BBC202BC6858D +:1019A0002A2C748B12580D14D2A0D10F28203DC0C0 +:1019B000E07C877F2E24670E0A4765A07B1AEC0F18 +:1019C00088201EEBFD8F148EE48FF40888110A889E +:1019D000020F8F14AFEE1FEC0A98910FEE029E904B +:1019E0001EEC09C0801AEBFA2CD285AABAB8CC2812 +:1019F000A4CF2CD6852C21022F20700ECC02B1FF53 +:101A00002F24702C2502C020D10F87148770070760 +:101A10004763FD6E282123C099798B0263FE9ADD0E +:101A2000F063FE9500DA20DB308C12DD505814F4A0 +:101A3000D2A0D10FC0E163FF7A8B148C12DD50C0AD +:101A4000AA2E0A802A2468DA20581360D2A0D10F67 +:101A5000007096552B629E6EB8531DEBD42DD22686 +:101A600068D0048E207DE9452A629DCBAF2B2104EE +:101A70002C20665812F8C090292466821418EBE2D4 +:101A80008F2108FF019F21C020D10F008B10C9B802 +:101A90008CA00C6C51CCCC8E241FEBD08DE19E140D +:101AA0000FDD029DE18810658FA9C020D10FDA20DB +:101AB000C0B658144DC020D10F0000006C1006298C +:101AC0002102C0D07597102A32047FA70A8B357F78 +:101AD000BF052D25020DD902090C4C65C18216EBFC +:101AE000B41EEBB228629EC0FA78F3026001882926 +:101AF000E2266890078A2009AA0C65A17A2A629DCD +:101B0000DFA064A1772B200C0CBC11A6CC29C286C7 +:101B1000C08C79830260015719EBA709B90A299291 +:101B2000A3689007882009880C65814327C2851C1B +:101B3000EBA964713A8931098B140CBB016FB11D9B +:101B40002C20669F10B1CC0C0C472C24666EC6026C +:101B500060014009FF5065F13A8A102AAC188934B7 +:101B6000C0C47F973C18EBAA1BEBA98F359C719BD7 +:101B7000708B209D7408BB029B72C08298751BEB12 +:101B8000A50F08409B730F881198777FF70B2F21C3 +:101B900002284A0008FF022F2502C0B4600004009A +:101BA0000000C0B07E97048F362F25227D970488D1 +:101BB000372825217C9736C0F1C0900AF9382F3C90 +:101BC0002009094264908619EB7618EB7728967EF7 +:101BD00000F08800A08C00F08800A08C00F0880045 +:101BE000A08C2A629D2DE4A22AAC182A669D893019 +:101BF0007797388F338A3218EB8007BE0B2C21047D +:101C0000B4BB04CC1198E0C08498E1882B9DE59A80 +:101C1000E69FE71AEB78099F4006FF110FCC020AF6 +:101C2000880298E2C1FC0FCC022CE604C9B82C2033 +:101C30000C1EEB670CCA11AECC06AA0829A2852D92 +:101C4000C4CF09B90B29A685CF5CC020D10FC081B4 +:101C5000C0900F8938C08779880263FF7263FF667E +:101C600000CC57DA20DB30DC4058134DC020D10FB8 +:101C7000DA205813DD63FFE8C0A063FE82DA20C0DB +:101C8000B65813D963FFD900DB402A2C74580C5A7C +:101C9000D2A0D10F8A102B210458126E1EEB44C023 +:101CA000D02D246663FEB1006C1006D62019EB3FE0 +:101CB0001EEB4128610217EB3E08084C65805F8AE5 +:101CC000300A6A5169A3572B729E6EB83F2A92263A +:101CD00068A0048C607AC9342A729D2C4CFECAAB71 +:101CE0002B600CB64F0CBD11A7DD28D2860EBE0AA4 +:101CF00078FB269C112EE2A32C160068E0052F62CB +:101D0000007EF91522D285CF2560000D00DA60C073 +:101D1000B65813B5C85A60010F00DA605813B2659F +:101D20005106DC40DB308D30DA600D6D51581227E2 +:101D3000D3A064A0F384A1C05104044763FF6D00E5 +:101D4000C0B02C60668931B1CC0C0C472C64666F36 +:101D5000C60270960A2B610458123EC0B02B64660E +:101D60006550B42A3C10C0E7DC20C0D1C0F002DFCF +:101D7000380F0F4264F09019EB0A18EB0B28967E8F +:101D80008D106DDA0500A08800C08CC0A089301DC0 +:101D9000EB1A77975388328C108F3302CE0BC02406 +:101DA00092E12261049DE00422118D6B9BE59FE787 +:101DB00098E61FEB100998400688110822020FDDF3 +:101DC00002C18D9DE208220292E4B4C22E600C1F73 +:101DD000EB000CE811A7882C8285AFEE0C220B2BB0 +:101DE000E4CF228685D2A0D10F28600CD2A08C111E +:101DF00019EAF80C8D11A988A7DD2ED2852B84CF86 +:101E00000ECC0B2CD685D10FC0F00ADF387FE8024C +:101E100063FF6C63FF6000002A6C74C0B2DC20DDDD +:101E20004058121CC0B063FF63C020D10F000000F7 +:101E30006C10042C221D2A221EC049D320293006F2 +:101E4000243468C0407AC105DDA060000200C0D023 +:101E50006E9738C08F2E0A802B3014C09629340616 +:101E60000EBB022E31022B34147E8004243502DE98 +:101E7000407AC10EC8ABDBD0DA302C0A00580A76A3 +:101E80002E31020E0F4CC8FEC020D10F6895F828E5 +:101E9000310208084C658FEF1AEAC61CEAC42BA26F +:101EA0009EC09A7B9B462BC22668B0048D307BD99E +:101EB0003B29A29DC0E3CB9394901BEAD72D31041C +:101EC0009B9608DD110EDD029D979D9112EAD4C00C +:101ED000E524C4A22E34062F310228A29D02FF025F +:101EE000288C3028A69D2F3502C020D10FDA30C0B3 +:101EF000B658133DC020D10F6C10062920066898F3 +:101F000005289CF965825D29210209094C6592101A +:101F1000CD51DB30DA20044C025812A1C051D3A0BD +:101F2000C7AF2A360AC0E019EAA31DEAA91FEAA230 +:101F30008A3A16EA9FB1AC64C13528629E6F880266 +:101F40006001F129DC332992266890078B2009BBB8 +:101F50000C65B1E027629DC08E6471D82B200C0CFB +:101F6000BC11A6CC29C2867983026001D219EA91FC +:101F700009B90A2992A397106890082822000988B5 +:101F80000C6581BB27C2856471B5292006299CF99F +:101F90006491EC2C20668931B1CC0C0C472C246662 +:101FA0006EC6026001A109F85065819B883689F4EC +:101FB000088C14AC991CEA810C99022C21049970AC +:101FC00019EA980808479971892A0988100899021E +:101FD00018EA95089902997228301329301204885A +:101FE0001006991008990228302C9A740C88100851 +:101FF000C802098802987389379975883898768A53 +:1020000039C0819A771AEA888935987B9978098945 +:10201000140A9902997A8A30893277A73618EA76B3 +:102020008F33987CC084987D882B2E761129761268 +:102030002F761319EA700A9F4006FF1104CA11098E +:1020400088020FAA02987EC1F90FAA022A7610C050 +:10205000AA600001C0A6ADBF0CBC11A6CC29C285E8 +:102060002EF4CF09A90B29C685655107C020D10FD1 +:102070002B200C0CBC1106CC0828C28609B90A6FAB +:10208000890260012E2992A36890082A220009AAD9 +:102090000C65A11F2AC28564A11928203D0828408B +:1020A00064808C843504841464408485F574537F83 +:1020B0008436048414644077745374293013C08CBC +:1020C00079886CC0902924670908476580ED8820CD +:1020D00089F484351FEA4B048414A4940F440294B9 +:1020E000A014EA4608881104880298A1843698A3AF +:1020F000048414A4990F990299A219EA42ADB42854 +:10210000C2852E44CF288C1028C6852821022F2076 +:1021100070098802B2FF2F2470282502C020D10F39 +:1021200000CC57DA20DB30DC4058121DC020D10F24 +:10213000C09163FF8FDA20C0B65812AB63FFE10095 +:10214000DA205812A963FFD88A102B2104581141B4 +:102150001DEA201FEA192B200CC0E02E24668A3AC3 +:1021600063FE480000DA20DB30DC40DD50581324E9 +:10217000D2A0D10F2A2C74DB40580B1FD2A0D10F54 +:10218000292123C08879830263FE202A12002C2093 +:10219000662B21042CCC010C0C472C246658112DE5 +:1021A0001DEA0C1FEA052B200CC0E02E24668A3A9B +:1021B00063FDF800DA2058128C63FF64DA205BFFBD +:1021C0001CD2A0D10F0000006C10089515C061C191 +:1021D000B0D9402A203DC0400BAA010A64382A2009 +:1021E0000629160668A8052CACF965C33B1DE9F263 +:1021F0006440052F120564F29C2621021EE9EE06BA +:10220000064C6562E315E9EA6440D98A3529300352 +:102210009A140A990C6490CC2C200C8B149C110CF1 +:10222000CC11A5CC9C122CC286B4BB7CB30260023C +:10223000D38F110EFE0A2EE2A368E0098620D30F89 +:102240000E660C6562BE88122882856482B6891487 +:1022500064905EDA80D9308C201EE9E81FE9E91D20 +:10226000E9D68B148DD4D4B07FB718B88A293C1026 +:10227000853608C6110E66029681058514A5D50F10 +:10228000550295800418146D8927889608CB11088B +:1022900088140EBB02A8D8299C200F88029BA19805 +:1022A000A088929BA3088814A8D80F880298A22A15 +:1022B000AC1019E9D4C0C08F141EE9C586128D1167 +:1022C000286285AEDD08FF0B2CD4CF2821022F66B3 +:1022D000858B352A2070098802ABAA2825022A247A +:1022E00070C020D10F29529E18E9B16F9802600288 +:1022F0000828822668800829220008990C6591F92F +:102300002A529DC1CA9A1364A1EF2B200C262006E5 +:102310000CB811A5882D82860EBE0A7DC30260020C +:10232000022EE2A368E0082F22000EFF0C65F1F3F5 +:10233000288285DE806481FF9810266CF96461FF35 +:102340002C20668831B1CC0C0C472C24666EC6025A +:102350006001BC08FD5065D1B617E9B419E9981AB7 +:10236000E99F2C21048B2D2830102F211D0C881063 +:102370000BFB090C88020A880209BB0264415289DE +:1023800010C04D9B90979198928D35D9E064D06C98 +:10239000D730DBD0D8307FD713273C10BCE92632AA +:1023A000168C3996E69CE78A37B4389AE80B1314F2 +:1023B0006430492A821686799A9696978C778A7D18 +:1023C0009C982B82172C7C209A9A2A9C189B998681 +:1023D0007BB03BB8896DB9218BC996A52692162A88 +:1023E000AC18B8999BA196A08BC786CD9BA22B92C7 +:1023F0001596A49BA386CB2CCC2026A605C0346BB7 +:10240000D4200D3B0C0DD8090E880A7FB705C0906B +:102410009988BC88C0900B1A126DAA069988998B6E +:10242000288C18C0D01BE9831CE98216E978B1FF1B +:102430002A211C23E6130F0F4F26E6122F251D7F9E +:10244000A906C0F0C08028251D05F6111AE9718F74 +:10245000202BE6152CE6162DE61726E6180AFA02BA +:102460002AE614292006299CF96490FF29200C8D66 +:1024700015C0801AE9570C9C11AA99A5CCDA202B1B +:10248000C2852894CF0B4B0B2BC685C0B08C165839 +:102490001114D2A0D10F8A356FA548D8308BD56DD5 +:1024A000A90C8A860A8A14CBA97AB337288C10C063 +:1024B00080282467080B4765B112DA20DB302C1224 +:1024C00006581137D3A0C0C1C0D02DA4039C1563FA +:1024D000FD26863664610C8910C04D9B90979198BB +:1024E0009263FEA4C08163FFC78A15CCA7DA20DB04 +:1024F000308C1658112BC020D10FDA20C0B65811DD +:10250000BA63FFE400DA208B115811B763FFD900DA +:102510009E178A132B210458104F8E17C0B02B24FE +:102520006663FE34C08063FE09DA20DB308C16DD82 +:1025300050581233D2A0D10FDA205811AB63FFA844 +:102540002D2123C0C87DC30263FE0D8A132B2104F5 +:102550002C20669817B1CC0C0C472C246658103DE3 +:102560008E17C0D02D246663FDEE0000262123B017 +:102570006606064F262523656EF128206A7F8705AB +:102580000829416490A5C0D01BE91C19E92B26201D +:102590000723E61BB16609FA022BE61A28200A2D4A +:1025A000E61D2AE61E09880228E61C88260606473C +:1025B00028E6202B220826E53E2BE6212D24072C99 +:1025C00020062A206468C347B44463FE9EDB30DAE9 +:1025D000208D15C0CE2E0A802C24688C1658107BB6 +:1025E000D2A0D10F8E102A321616E8F30A2A1486CA +:1025F000662BE61297E127E61328E614AA66096619 +:102600000296E02EEC4869ED50C14663FD7A000069 +:1026100064AFB419E8E928201689920A880C009161 +:102620000400881AA8B8982963FF9C002B21046E27 +:10263000B81E2C2066B8CC0C0C472C2466C9C09E52 +:10264000178A135810048E17C0348F20C0D02D2441 +:1026500066C06826240663FF2C008D35C08064D0D8 +:102660004AD9E0DC30DBE0DF301AE8F4B188B4FFAF +:1026700017E8F486C9249DFF8DC82CCC102D463058 +:102680000767012D46320A66011DE8EE264631AD88 +:102690006D2D463326F21597B796B684C3BCBB940E +:1026A000B58D35299C107D83C22F211DC14663FD48 +:1026B0004B0000006C1006292006289CF86582C398 +:1026C0002921022B200C09094C6590E116E8B90C70 +:1026D000BA11A6AA2DA2862C0A127DC3026002900E +:1026E00019E8B509B90A2992A36890078C2009CC8A +:1026F0000C65C27C29A2856492762D629E1AE8AB95 +:102700006FD8026002722AA22629160168A0082B3F +:1027100022000ABB0C65B26029629DC18C6492588C +:102720002A21200A806099102C203CC7EF000F3E20 +:10273000010B3EB1BD0FDB390BBB098F260DBD115F +:102740002DDC1C0D0D410EDD038E27B1DD0D0D417D +:102750000FEE0C0DBB0B2BBC1C0BB7027EC71C2C49 +:1027600021257BCB162D1AFC0CBA0C0DA16000099B +:102770003E01073EB1780987390B770A77EB026093 +:10278000020A2C2123282121B1CC0C0C4F2C25230B +:102790007C8B29B0CD2D2523C855DA20DB30580F8E +:1027A000FA292102CC96C0E80E9E022E2502CC57B3 +:1027B000DA20DB30DC4058107AC020D10F2C2066A4 +:1027C0008931B1CC0C0C472C24666EC6026001D353 +:1027D00009FD5065D1CD2F0A012E30112922146434 +:1027E000E01128221B090C4400C10400FA1A0A88CF +:1027F0000228261B2E3010C0A0C0B088301CE86E06 +:1028000094129513C04125203C2CC022088D1477CA +:1028100087052F0A010CFA38C0F2C0840858010F4E +:102820005F010F4B3805354007BB10C0F0084F382B +:1028300008FF100FBB0228ECFEC0F0084F38842BB5 +:102840000BA8100AFF102A21200F88020B8802080B +:10285000440218E87D8F110844022821250A2A1411 +:102860000828140488110A88022A210494F08B2075 +:1028700004E41008BB1104BB02C04A04BB029BF174 +:10288000842A08AB110BEB0294F40A54110B440296 +:102890000555100D1B4094F707BB100B550208554A +:1028A00002C08195F68433C05094F3B1948B329575 +:1028B000F898F99BF2C080C1BC24261498FB9BF5C4 +:1028C00099FA853895FC843A94FD8B3B9BFE8839B8 +:1028D00098FF853525F6108436851324F6118B373D +:1028E00084122BF612C0B064C08189307797468D70 +:1028F0003288332E30108F111CE840099940069918 +:10290000112CF614C0C42CF6158C2B2DF61A28F6B3 +:102910001B2BF61904A81109880208EE0219E835E4 +:10292000C18008EE0209C90229F6162EF618C09ECB +:10293000600004000000C09A2F200C18E8250CFE4F +:1029400011A8FFA6EE2DE2852BF4CF0D9D0B2DE6F1 +:1029500085C87F8A268929A7AA9A260A990C090977 +:102960004829252565504CC020D10F00C09A63FF2F +:10297000C6DA2058109D63FE34DA20C0B658109A8B +:1029800063FE2A00689738C020D10F0000DA20DBF0 +:1029900070581057C0B0C0C10ACA390ACB3865BDDB +:1029A000E063FE098A102B2104580F2AC0B02B24A3 +:1029B0006663FE21DB402A2C7458090FD2A0D10F88 +:1029C000DA20580F2F63FCF76C1004C020D10F00E1 +:1029D0006C1004290A801EE81D1FE81D1CE7F50C79 +:1029E0002B11ACBB2C2CFC2DB2850FCC029ED19CA4 +:1029F000D0C051C07013E81914E81818E8162AB2AC +:102A000085A82804240A234691A986B8AA2AB6854F +:102A1000A98827849F25649FD10F00006C100AD6D7 +:102A200030283010292006288CF964829B68980B86 +:102A30002A9CF965A1B2022A02580F1189371BE7B7 +:102A4000DEC89164520E2A21020A0C4C65C2588DD0 +:102A50003019E7D774D7052E212365E29E2F929E69 +:102A60001AE7D36FF8026002532AA22668A0082C46 +:102A700022000ACC0C65C2442A929D64A23E9A159B +:102A80001FE7CD8D67C1E664D00E2B620618E7CA3A +:102A900064B0052880217B8B422B200C18E7C50CE5 +:102AA000BC11A8CC29C28679EB450FBE0A2EE2A341 +:102AB00068E0048F207EF9372CC2859C1864C233ED +:102AC0002B212F87660B7B360B790C6F9D266ED2E0 +:102AD000462C203D7BC740CE5560001E2A200CC1ED +:102AE000B28C205810759A1864A2458D6763FFCF89 +:102AF000C0C063FFC5D7B063FFD300C0E060000271 +:102B00002E60030EDB0C6EB20EDC700CEA11AA6AAA +:102B10002AAC20580199D7A0DA20DB70C1C82D213A +:102B20002058101B8C268B279A160CBB0C7AB334BA +:102B30008F18896399F3886298F28E659EF82D60EC +:102B4000108A189D1768D729C0D09DA92C22182B50 +:102B500022139CAB9BAA97A58E667E73026000979A +:102B6000CF5860001FDA208B16580FE165A138633B +:102B7000FFBDC081C0908F18C0A29AF999FB98FA46 +:102B800097F563FFD2DB30DA20DC40580F85C05167 +:102B9000D6A0C0C02BA0102CA4039B172C12080297 +:102BA0002A02066B02DF702D60038E179D149E10A3 +:102BB0000CDD11C0E0AD6D2DDC205801188C148B9C +:102BC00016ACAC2C64038A268929ABAA0A990C9A04 +:102BD00026886609094829252507880C98662F222A +:102BE00018A7FF2F261863FE96DA20DB30DC40DDC5 +:102BF00050581083D2A0D10FC0302C20668961B10B +:102C0000CC0C0C472C24666EC6026000D2C0300982 +:102C1000FD5065D0CA8E6764E069647066DB608CC5 +:102C200018DF70DA202D60038E170CDD119E10ADB9 +:102C30006D2DDC201EE7845800F9232618DA208B3E +:102C400016DC402F2213DD50B1FF2F2613580F241E +:102C5000D2A0D10F0028203D084840658DE76F9530 +:102C60003EDA308DB56D990C8CA80C8C14CACF7CD3 +:102C7000D32D2AAC10C090292467090D4764DDC507 +:102C8000600092002C1208066B022D6C20077F0258 +:102C90008E17DA209E101EE76B58007D63FF9A00A6 +:102CA000C09163FFD1000000655081DA20DB60DC59 +:102CB00040580F3BC020C0F02FA403D10FDA20C032 +:102CC000B6580FC963FFE000006F950263FD6CDA30 +:102CD00020DB30DC40DD50C4E0580EBCD2A0D10F68 +:102CE0008A152B2104580E5B232466286010981740 +:102CF00063FF2100DA20580FBC63FFABC858DB30FC +:102D0000DA20580EA12A210265AF9CC09409A902BD +:102D100029250263FF91DB30DC40DD50C0A32E0A81 +:102D2000802A2468DA20580EA9D2A0D10FC020D161 +:102D30000FDA202B200C580FC563FF6B6C10042892 +:102D40002006C062288CF8658125C050C7DF2B2281 +:102D50001BC0E12A206B29212300A104B099292559 +:102D600023B1AA00EC1A0BC4010A0A442A246B04FA +:102D7000E4390DCC030CBB012B261B6440692920D0 +:102D80000C1BE70B0C9A110BAA082FA2861BE70954 +:102D90006FF9026000B60B9B0A2BB2A368B0082C37 +:102DA00022000BCC0C65C0A42BA2851DE72D64B0BE +:102DB0009B8C2B2421040DCC029CB08820C0C5081C +:102DC00088110C880298B1882A08441198B48F346D +:102DD00094B79FB5C0401EE6FE2DA2850E9E082525 +:102DE000E4CF2DDC282DA68529210209094C689401 +:102DF0001A689820C9402A210265A00B2A221E2B9E +:102E0000221D7AB10265A079C020D10F2C21236543 +:102E1000CFDE6000082E21212D21237EDBD52B2241 +:102E20001E2F221D2525027BF901C0B064BFC413EB +:102E3000E6DF2CB00728B000DA2003880A28824C8D +:102E4000C0D10B8000DBA065AFE763FFA62A2C741E +:102E5000C0B02C0A02580D951CE7039CA08B2008DB +:102E6000BB1106BB029BA1893499A263FF790000C4 +:102E7000262468DA20DB30DC40DD50580FE1D2A098 +:102E8000D10FDA202B200C580F58C020D10F000092 +:102E90006C1006073D14C080DC30DB40DA20C047F0 +:102EA000C02123BC30032838080842774001B1DD37 +:102EB00064815A1EE6BB19E6BC29E67ED30F6DDAA3 +:102EC0000500508800308CC0E0C02025A03C14E6EE +:102ED000BAB6D38FC0C0D00F87142440220F8940C8 +:102EE000941077F704C081048238C0F10B2810C019 +:102EF00044C02204540104FD3802520102FE380885 +:102F0000DD10821C07EE100E6E020EDD02242CFE78 +:102F1000C0E004FE380AEE100E88020D88028DAB68 +:102F20001EE6AA08D8020E880298B0C0E80428104D +:102F30000E5E0184A025A125084411084402052540 +:102F400014045511043402C0810E8E3994B18FAA35 +:102F500084109FB475660C26A11FC0F2062614606B +:102F60000009000026A120C0F20626140565020F04 +:102F7000770107873905E6100778100866020655BD +:102F80000295B625A1040AE611085811082802087E +:102F9000660296B7C060644056649053067E11C0C6 +:102FA000F489C288C30B340B96459847994618E6B6 +:102FB000919F410459110E99021FE68F020E470896 +:102FC000D80298420E99029F40C1E00E990299449E +:102FD0002FA00CB4380CF91114E67E1EE675A4FF80 +:102FE000AE992E928526F4CF0E880B289685D10FA8 +:102FF0002BA00C1FE66F1CE6760CBE11ACBBAFEE2F +:103000002DE28526B4CF0D3D0B2DE685D10FC08076 +:1030100005283878480263FEA263FE966C1006C04D +:10302000C06570F18830C030088714778712C0B04F +:10303000C0A619E661299022C030CC97C03160004B +:1030400003C0B0C0A6C0E0C091C0D4C08225203C5F +:103050000B3F109712831CC0700858010D5D0108CA +:103060009738C0800B9838077710048810086802DA +:10307000087702C0800D98382D3CFE0888100D9E00 +:10308000388D2B0AEE1008EE0207EE020CB8100F76 +:10309000DD02053B400EDD029D408920043D100805 +:1030A00099110D99022D210409A90208DD119941F8 +:1030B000872A05B9100D3D020ABB110DBB02087726 +:1030C0000297442821258712082814048811071E16 +:1030D0004007EE100E990275660926211F06261478 +:1030E000600006002621200626140868029B470976 +:1030F0008802984629200CD2C0C0800C9E111BE685 +:10310000341FE62BAB99AFEE2DE2852894CF0DADA1 +:103110000B2DE685D10FDD40C0A6C0B08E51CAE0B0 +:10312000B2AAB1BB2DDC108F500E783698100877FC +:103130000C9FD898D989538F52991199DB9FDA7EC9 +:103140008309B1CC255C10C97763FFCF88108D113E +:1031500008E70C9751AD8DD7F078DB01B1F79D539F +:1031600097528830C030088714088840648ED5652F +:10317000BEC963FEBC0000006C1004D720B03A88C2 +:1031800020C0308221CAA0742B1E2972046D080F42 +:10319000C980C9918575B133A2527A3B0B742B0853 +:1031A00063FFE900649FECD10FD240D10F00000013 +:1031B0006C1008D630C0709515DA408E3914E5FED3 +:1031C0009A1464E0026451FC2920062A9CF865A246 +:1031D0005F2A21020A0B4C65B21F2C320015E5F460 +:1031E00074C7052D212365D3242E529E1AE5F06F56 +:1031F000E80260021B2AA22668A0082B22000ABB54 +:103200000C65B20C2E529D1DE5EB64E2038B386415 +:10321000B22D9E16C8BC8D691EE5E864D0052EE06F +:10322000217BEB492E200C18E5E20CEF11A8FF29B9 +:10323000F286C186798B4A17E5DF07E70A2772A372 +:10324000687004882077893925F2856452A2272185 +:103250002E07B73607B90C6F9D01D7B089696E92FA +:103260004228203D7B873C8A15CDAF600018C1B253 +:103270008C202A200C580E90D5A064A2AC8B6863D9 +:10328000FFCBC05063FFC3C0E06000022E60030E9E +:103290009B0C6EB20EDC700CEA11AA6A2AAC285B99 +:1032A000FFB6D7A0DA20DB70C1C42D211F580E381D +:1032B0008C268B27D4A00CBB0C7AB3258A63C090D4 +:1032C0009A538862995898528F659F598E679E5B72 +:1032D0008D6697559D5A8B687B7B748B15CEB3603A +:1032E000000DDA20DB40580E0265A10D63FFCC0013 +:1032F000DA20DB308C14580DAAD6A0C0C0C0D19DF6 +:10330000152CA403DA20DB60DF70DC50C0E0256000 +:10331000039E101EE5C10C5D11AD6D2DDC285BFF19 +:103320003F8E66A5A88F67286403AF7F77FB01B146 +:10333000EE9E669F678D268C29A4DD0DCC0C9D2604 +:103340008B680C0C482C252507BB0C9B6863FEC3BF +:103350002C20668961B1CC0C0C472C24666EC60209 +:103360006000B809FD5065D0B2CBBF8E69CBEBDBF6 +:1033700060DC50DF70DA201EE5BC2D6003C0809851 +:10338000100CDD11AD6D2DDC285BFF248B15C942BF +:103390008A2629220904AA082A26060A990C09095C +:1033A0004829252565B13CC020D10F00DB602D6C7C +:1033B00028DF70DA20C0C01EE5AC9C10DC505BFE3C +:1033C000B463FFC7002D203D0D4D4065DDF96FE56D +:1033D00022DA308F456DE90C8EAA0E8E14C9E37E79 +:1033E000F3112AAC10C090292467090F4764FDD758 +:1033F00060014100C09163FFED00881565814CDAE2 +:1034000020DB608C14580D66C020C09029A403D125 +:103410000FDA20C0B6580DF463FFDE008A162B21A8 +:1034200004580C8CC0A02A24668B6863FF3A000005 +:10343000002B9CF965B0C5DA20580C9163FD910012 +:103440002B200C0CBA11A5AA2FA286C1C27FC302E1 +:103450006000FC0DB90A2992A36890078C2009CC62 +:103460000C65C0EB26A2856460E52C20668931B12D +:10347000CC0C0C472C24666FC60270960ADAE02B3F +:103480002104580C74272466893077974B18E55926 +:103490001DE55A8A328B33C0F42C2104099E400664 +:1034A000EE1104CC110ECC029F61C1E00ECC029D46 +:1034B000608F2B9A669B679C64976508FF029F62EA +:1034C0002F200C18E5430CFE11A5EE2DE285A8FF78 +:1034D00027F4CF2DDC202DE6858F1565F091C020D7 +:1034E000D10F00002A2C748B14580643D2A0D10FA0 +:1034F00000DA20DBE0580DBC63FEFE0000DA20DBC2 +:10350000308C148D15580E3ED2A0D10F00008815B6 +:10351000C888DA20DB30580C9C2A210265AEDAC05C +:103520009409A90229250263FECFDA202B200C582A +:103530000DC763FEC4272468DA20DB302C12042D6B +:1035400012052E0A80580CA163FC7C00C020D10F0C +:10355000DA20580DA58A15CDA1DA20033B022C12E2 +:1035600004580D0F27A403C020D10F00C020D10F95 +:103570002A2C748B14580620D2A0D10F6C100C2862 +:103580002102941008084C6583621FE50929F29E08 +:103590006F98026003661DE50529D2266890082A07 +:1035A000220009AA0C65A3542CF29D64C34E2B2063 +:1035B0000C0CB611AF66286286C1EC78E30260039A +:1035C0004619E4FC09B90A2992A36890078A2009E0 +:1035D000AA0C65A33224628564432CC0E12A310918 +:1035E000C07027246689359A11992A8836991298CD +:1035F0002B89379813992C883899140858149815E2 +:10360000982D89392A25042E251D29251C28302886 +:10361000C09228243C2A30290808479816098901B5 +:103620002A243D2A311599170A094109A90C299C18 +:10363000EC29251F7E87192D2A000DA06000083E69 +:10364000010A3EB1AD08DA390EAA110A990C2925F2 +:103650001F2A211F18E5060A8160C1D0941A951B04 +:1036600001083E00053EB184054839843C259CFC98 +:103670000D883629201408AA1C8D3D2726182E26D1 +:10368000132E26142E261527261B2E246B2724677F +:1036900027246808581C0909432924142932112AAF +:1036A000252E28252F27252427252527252C2725A6 +:1036B000232525202425212D2522841A2D211C8512 +:1036C0001B6FD202600209C0A099186D080AB1AA46 +:1036D00000A10400E91A7D9B0263FFEE8918C080F7 +:1036E000C0E1C070C0D29B1D951B961C9C1E16E4A9 +:1036F000D12C203D15E4E00C0B400DCC010BE7383C +:103700001DE4C30A77100CE8380B8810C0C49C4134 +:103710000877029D40B0A80988118B209C499D48DC +:10372000954B9643087702861418E4D115E4B9083E +:10373000770205BB029B4A9B429746881287110875 +:10374000DA149A4E0D88100D77110877021AE4AC3E +:1037500006D8140D6610087702974FC78F984D98BA +:103760004C9845871598440715140D55110A5502B4 +:10377000954715E4C18A262D46102D46182D462062 +:103780002C46112C46192C46212B46122B461A2862 +:1037900046142846152B46228816254624254626FB +:1037A0008B170A0C48090D4885130EDD1105CC1145 +:1037B0000839400BEB390299101EE4B00DCC020D14 +:1037C0005511082D400655022E461316E47B0FDDD9 +:1037D00011254616080840851B0188100DBB02867E +:1037E000671DE4A70988020CBB0219E4771CE4A555 +:1037F0002B46172D461BA7661BE4A4C0702C461C45 +:103800000988028C1E28461E2B4623C0908B1D293A +:10381000461D29461F18E49D29462728462529319B +:10382000162E200629246A243117962D2425238656 +:103830001CCCE1272407C0D7090E4064E0829A29F6 +:1038400009284164809164409B2D2406C098094951 +:1038500036280AA024628501C404A844282104242F +:1038600066850888118E3F8A3E2D32100EA41800FE +:10387000C4040EAE1800EE110ACA530EDD02C0E3F6 +:103880000E880298C11EE48209084E9EC08E2094C4 +:10389000C398C59DC418E44E1DE47F05EE110EAA21 +:1038A000020DAA02A8B82784CF9AC21EE44024F2CF +:1038B0009D27E4A2244C1824F69D655052C020D1C7 +:1038C0000F2D2406C0A0C09809493604A93863FF0B +:1038D0007FC0A063FE070000654F6DC098C0A82A96 +:1038E000240663FF6B2D2406C09063FF63CC57DA78 +:1038F00020DB308C10580C2AC020D10F00DA20C0F9 +:10390000B6580CB963FFE500DA20580CB763FFDC4A +:103910002A2C748B10580538D2A0D10F6C100628B1 +:1039200020068A336F8202600161C05013E42029AF +:10393000210216E41F699204252502D9502C201576 +:103940009A2814E41D8F2627200B0AFE0C04770901 +:103950002B711C64E1398E428D436FBC0260016F94 +:1039600000E104B0C800881A08A80808D8029827FF +:103970002B200668B32ECE972B221E2C221D011160 +:10398000027BC901C0B064B0172CB00728B000DAC0 +:103990002003880A28824CC0D10B8000DBA065AFD1 +:1039A000E7C020D10F2D206464DFCA8B29C0F10B42 +:1039B000AB0C66BFC02B200C0CBC11A6CC28C28659 +:1039C0002E0A0878EB611EE3FB0EBE0A2EE2A36806 +:1039D000E0052822007E894F29C2851EE4076490F5 +:1039E000461FE4159E90C084989128200A95930F55 +:1039F000880298928E200FEE029E942F2007882630 +:103A00002F950A98969A972E200625240768E34357 +:103A10002921022AC2851DE3EE2AAC20ADBD25D4A2 +:103A2000CF2AC68563FF4E002E2065CBEDC08228CD +:103A30002465C9F605E4310002002A62821BE3F71F +:103A40002941020BAA022A668209E4312921026374 +:103A5000FF23000064DFB88F422E201600F1040D12 +:103A6000EE0C00EE1AAEAE9E2963FFA38A202B3225 +:103A700021B1AA9AB0293221283223B499293621BA +:103A80007989A92B32222B362163FFA0C020D10FC8 +:103A90009F27252415ACB828751C2B2006C0C12EE5 +:103AA000BCFE64E0AB68B7772DBCFD65DEC72D209A +:103AB00064C0F064D0868E290EAE0C66E089C0F139 +:103AC00028205A288CFE08CF3865FEE863FF58008E +:103AD00000E0049310C0810AF30C038339C78F08F8 +:103AE000D80308A80108F80C080819A83303C80C63 +:103AF000A8B828751C030B472B24158310CBB700DF +:103B0000E104B0BC00CC1AACAC0CDC029C27659E76 +:103B10005EC0B20B990209094F29250263FE5000CD +:103B20002D206A0D2D4165DF7EDA20C0B0580C755E +:103B300064AF18C0F163FEEF9F2763FFD02E221FF2 +:103B400065EE3263FF79000028221F658E2763FF30 +:103B50006E252406252502C09063FE196C100665AB +:103B600071332B4C18C0C7293C18C0A1C08009A8CC +:103B7000380808426481101CE38A1AE38B2AC67E47 +:103B80002A5CFDD30F6DAA0500B08800908C894097 +:103B9000C0A00988471FE3B4080B47094C50090D22 +:103BA0005304DD10B4CC04CC100D5D029D310CBB70 +:103BB000029B3088438E2098350FEE029E328D2670 +:103BC000D850A6DD9D268E40C0900E5E5064E097D2 +:103BD0001CE39A1EE389038B0BC0F49FB19EB02DAA +:103BE000200A99B30CDD029DB28F200CFF029FB416 +:103BF0008E262D20079EB68C282DB50A9CB7292429 +:103C0000072F20062B206469F339CBB61DE36B2305 +:103C100020168DD20B330C00D10400331AB48DA3BF +:103C2000C3932922200C13E36A1FE3610C2E11AF0A +:103C3000EEA3222924CF2FE285D2A00FDD0B2DE6A3 +:103C400085D10F002E200CB48C0CEB111FE3611DED +:103C5000E358AFEEADBB22B28529E4CF02C20B22FE +:103C6000B685D2A0D10F00002E200C1CE3511FE31B +:103C7000580CEB11AFEEACBB22B28529E4CF028227 +:103C80000B22B685D2A0D10FC0D00BAD387DC802B3 +:103C900063FEEC63FEE08E40272C747BEE12DA703C +:103CA000C0B32C3C18DD50580A7B8940C08063FEAD +:103CB000E3DE60DA20DB30DC40DD505800059A108E +:103CC000DB50077A0258044C881063FEF8000000AD +:103CD0006C100692121EE3428C40AE2D0C8C472EC7 +:103CE0003C1804CA0BD9A07DA30229ADF875C30204 +:103CF000600084C0B0C023C0A09D106D0844B89F70 +:103D00000EB80A8D900EB70BB8770D6D36ADAA9D23 +:103D1000800D660CD8F000808800708C879068B1A8 +:103D200024B22277D3278891C0D0CB879890279C44 +:103D30001000708800F08C9D91CB6FC08108BB0390 +:103D400075CB3663FFB4B1222EEC1863FFD4859295 +:103D50000D770C86939790A6D67D6B01B1559693FF +:103D60009592600016B3CC2D9C188810D9D078D3CA +:103D7000C729DDF863FFC100C0238A421BE3470067 +:103D8000CD322D44029B3092318942854379A10581 +:103D90001EE3430E550187121BE334897095350BE2 +:103DA0009902993288420A880C98428676A6A6968D +:103DB000768F44AFAF9F44D10F0000006C10089382 +:103DC00011D6308830C091086351080847059838EB +:103DD0009812282102293CFD08084C6581656591EF +:103DE000628A630A2B5065B18B0A6F142E0AFF7C1E +:103DF000A60A2C205ACCC42D0A022D245A7FE00298 +:103E0000600215892888261FE32609880C65820F21 +:103E10002E200B0FEE0B2DE0FE2EE0FF08DD110E25 +:103E2000DD021EE320AEDD1EE3201CE3200EDD01DB +:103E30000DCC37C180084837B88DB4889810896098 +:103E40001AE2DE7B96218B622AA0219C147BA317A9 +:103E50009D132A200C8B108C20580B978C148D13DB +:103E6000DBA0CEAC6001C4002E200C1BE2D10CEA1A +:103E7000110BAA082BA2861FE2CF7BDB3B0FEF0AB8 +:103E80002FF2A368F0052822007F892C2BA28564DD +:103E9000B0AA87628826DE700C7936097A0C6FAD7D +:103EA0001C8F279B1508FF0C77F3197E7B729D13DF +:103EB0009C149B15CF56600025C0B063FFD0D790EF +:103EC00063FFDD00009D139C14DA20DB70580B08A3 +:103ED0008B158C148D1365A06A8E6263FFCC00DA9B +:103EE000208B11DC40580AAED6A08B15C051DE7075 +:103EF000DA20DC60DD405BFF768D138C14D9A02EB8 +:103F0000200C1BE2AB1FE2B20CEA11AFEFC0E0AB3A +:103F1000AA2BA2852EF4CF0B990B29A68563FF1D32 +:103F200000DA20DC60DD40DE708912282007DF50D7 +:103F3000A9882824075BFF09D2A0D10F00DBE0DAB3 +:103F400020580B296550EF2A20140A3A4065A0EB4F +:103F5000DB60DC40DD30022A0258099CD6A064A058 +:103F6000D584A183A0040447030547951203635138 +:103F7000C05163FE5C2C2006D30F28CCFD6480A5C5 +:103F800068C704C0932924062C2006C0B18D641F85 +:103F9000E28A9D279D289D298FF29D2600F104002D +:103FA000BB1A00F004B0BE0EDD01C0F0ADBB8D65E4 +:103FB0002F24070D0E5E01EE11AEBB2E0AFEB0BB24 +:103FC0000B0B190EBB36C0E20B0B470EBB372B2475 +:103FD0001618E2820A09450D0B422B240B29240AEC +:103FE000B4BE2E240C7D88572920162FCCFDB09D01 +:103FF0000A5C520DCC362C246465FDEC0C0C476435 +:10400000CDE618E26D8E2888820C9F0C008104009A +:10401000FF1AAFEE9E2963FDCF1CE29C63FE1300E6 +:104020001CE29363FE0C8D6563FFA500DA202B2054 +:104030000C580B06645F0FC020D10F00C020D10FB9 +:10404000C093292416C09363FFA000006C1004C025 +:104050006017E2561DE259C3812931012A3008292F +:10406000240A78A108C3B27BA172D260D10FC0C16B +:104070006550512625022AD0202F200B290AFB2B20 +:1040800020142E201526241509BB010DFF0928F147 +:104090001C2B2414A8EE2EF51C64A0B52B221E2880 +:1040A000221D0111027B8901DB6064B0172CB0076F +:1040B00028B000DA2007880A28824CC0D10B800083 +:1040C000DBA065AFE7DB30DC40DD50DA205800D8FC +:1040D000292102090B4CCAB2D2A0D10F00CC5A2C14 +:1040E00030087BC1372ED02064E02D022A02033B2A +:1040F00002DC40DD505800CED2A0D10F2B2014B0EE +:10410000BB2B24140B0F4164F0827CB7CAC0C10CD6 +:104110009C022C2502D2A0D10FC020D10F2E200648 +:1041200069E2C12F21020F0F4C69F1B8262406263F +:1041300025022B221E28221D2A200B2920150DAA1C +:10414000092CA11C262415AC9929A51C7B814A6049 +:104150000049B0BB2B24140B0D41CBD67CB7022CED +:1041600025022B221E2E221D7BE9022B0A0064B0A1 +:10417000172CB00728B000DA2007880A28824CC024 +:10418000D10B8000DBA065AFE7C020D10F2624064D +:10419000D2A0D10F26240663FFC7DB601DE20764AF +:1041A000BF422CB00728B000DA2007880A28824CCA +:1041B000C0D10B8000DBA065AFE71DE1FF63FF24EA +:1041C0006C1004282006C0646F8564CA5B29201423 +:1041D0007D9726DA20DB30DC40055D025800192986 +:1041E0002102090A4CC8A3C020D10F00C0B10B9B0B +:1041F000022B2502C020D10F0000022A02033B023D +:104200002C0A015800CAC9AADA20DB30DC40580960 +:10421000E429A011D3A07E97082C0AFD0C9C012C48 +:10422000A411C0512D201406DD022D241463FFA219 +:10423000DA20DB30DC40DD50C0E0580964D2A0D188 +:104240000F0000006C100616E1DA1CE1DA65513B44 +:10425000C0E117E1D62821028B2008084C65807B3D +:104260002932000969516993722A629E6EA8482A10 +:10427000722668A0027AB93F2A629DB44FCBA72B61 +:10428000200C0CBD1106DD0828D28678FB150CBF6A +:104290000A2FF2A368F00488207F89072DD285D3E6 +:1042A0000F65D0602A210419E202D30F7A9B1DDA30 +:1042B00020580864600024002C21041BE1FD7CBB15 +:1042C00013DA20C0B658085FC9536000EFDA2058EF +:1042D0000A46600006DA20C0B6580A436550DDDCA5 +:1042E00040DB308D30DA200D6D515808B8D3A06412 +:1042F000A0CA1CE1B0C05184A18EA00404470E0ED8 +:104300004763FF50002B2104C08C8931C070DF70DF +:1043100009F950098F386EB8172C2066AECC0C0CFA +:10432000472C24667CFB099D105808CA8D10272451 +:104330006694D11EE1B6B8DC9ED0655056C0D7B8A1 +:104340003AC0B1C0F00CBF380F0F42CBF119E19465 +:1043500018E19628967EB04BD30F6DBA0500A08861 +:1043600000C08C2C200CC0201DE19A0CCF11A6FFA0 +:104370002EF285ADCC27C4CF0E4E0B2EF685D10F75 +:10438000C0800AB83878D0CD63FFC1008E300E0EE1 +:104390004763FEBD2A2C742B0A01044D025808BD48 +:1043A0002F200C12E18B0CF911A699A2FF27F4CF54 +:1043B000289285D2A008480B289685D10FC020D11D +:1043C0000F0000006C1004C060CB55DB30DC4005F2 +:1043D0005D02022A025BFF9B29210209084CC88268 +:1043E000D2A0D10F2B2014B0BB2B24140B0C41CB2B +:1043F000C57DB7EBC0C10C9C022C2502D2A0D10F09 +:104400000000022A02033B02066C02C0D0C7F72E4E +:10441000201428310126250228240A0FEE012E241B +:104420001458010D63FFA300262406D2A0D10F006B +:104430006C1006282102D62008084C65809D2B2090 +:104440000C12E15B0CB811A2882A8286B5497A93D6 +:104450000260009719E15809B90A2992A3689008E7 +:104460002A620009AA0C65A0822882851CE1636487 +:1044700080799C80B887B14B9B819B10655074C03C +:10448000A7D970280A01C0D0078D380D0D42CBDEA8 +:104490001FE1441EE1452EF67ED830D30F6D4A054C +:1044A00000808800908C2E3008C0A000EE322E7460 +:1044B0000028600C19E1470C8D11A2DDA988C020ED +:1044C0002CD2852284CFD2A00CBC0B2CD685D10F48 +:1044D000C0F0038F387FA0C063FFB400CC582A6CB3 +:1044E00074DB30DC405807F1C020D10FDA60580986 +:1044F000BE63FFE7DD402A6C74C0B0DC705808650D +:104500002E30088B1000EE322E740028600C19E15A +:10451000300C8D11A2DDA988C0202CD2852284CF39 +:10452000D2A00CBC0B2CD685D10F00006C10042936 +:104530002014282006B199292414688124C0AF2CA6 +:104540000A012B21022C24067BA004C0D02D2502B9 +:10455000022A02033B02044C02C0D05800BFD2A082 +:10456000D10FC020D10F00006C1004293101C2B45A +:1045700029240A2A3011C28378A16C7BA169645076 +:10458000472C2006C0686FC562CA572D20147CD7FF +:1045900022DA20DB30DC40DD505BFFA52921020957 +:1045A0000E4CC8E2C020D10FC0F10F9F022F250290 +:1045B000C020D10FDA20DB30C0C05BFFDC28201424 +:1045C00006880228241463FFC72920151BE0FB2A54 +:1045D000200BC0C09C240BAA092BA11C2C2415ABBA +:1045E0009929A51C63FF9900C020D10FDA20DB3088 +:1045F000DC40DD50C0E0580875D2A0D10F000000AB +:104600006C1004CB5513E0F625221F0D46110655FC +:104610000CA32326221E25261F06440B24261E73C8 +:104620004B1DC852D240D10F280A80C04024261FFB +:10463000A82828261E28261DD240D10FC020D10F21 +:10464000244DF824261E63FFD80000006C100428B7 +:104650002006D6206E85026000DE17E0D51DE0DC66 +:1046600019E0D5C0C1C0202A8CFC64A1322B6102A4 +:10467000B44E0B0B4C65B0A82B600C2A62000CB832 +:10468000110788082F828609B90A7FE30260009F1C +:104690002992A368900509AA0C65A09328828564D5 +:1046A000808DB8891BE0DA94819B8065514DC0B73D +:1046B000B838C0A1C0E009AE380E0E4264E0481A16 +:1046C000E0B81FE0B92FA67EB04A6DAA0500808829 +:1046D00000908CC0A02E600C0CE811A7882F82855A +:1046E000ADEE0F4F0B2F86852B600622E4CF68B10D +:1046F0002A296015C0B2C99AD2A02D61022B640686 +:104700000CDD022D6502D10FC0E008AE387EB0B7D7 +:1047100063FFAB00226406D2A0D10F00D2A0D10F5C +:1047200000CC57DA60DB30DC4058089DC020D10F48 +:10473000DA6058092D63FFE80028221E29221D781F +:104740009902280A00C176C1C1C1D21BE0A5C124CB +:10475000AB6B6480437891402A80000CAF0C64F00E +:10476000AE0DAE0C64E0A802AF0C64F0A207AE0C74 +:1047700064E09C2FACE864F0962EACE764E0902FE8 +:10478000ACE664F08A2A800708A80B088A027B83BB +:10479000022A8DF8D8A065AFBBC0906000730000FE +:1047A0002B600C0CB811A7882E82866EE87909BAA6 +:1047B0000A2AA2A368A0048E607AE96B2A82856423 +:1047C000A0651FE08DC0E32E64069EA19FA01FE0A0 +:1047D000B92E600A92A30FEE029EA28E600FEE0227 +:1047E0009EA42F60147AFF4722A417ADBE2F8285A6 +:1047F00022E4CF2FFC182F868563FE702A6C74C0CC +:10480000B1DC90DD405807A31DE072C0C163FEC457 +:10481000D9A0DA60DB30DC40DD50C2F0C1E009FE37 +:10482000395807EAD2A0D10FDA605808EF63FEF0DA +:104830002CA4170DBE0829828522E4CF299C1829B3 +:10484000868564500C2A6C74044B0258016BD2A00C +:10485000D10FC020D10F00006C10062B221E282281 +:104860001D93107B8901C0B0C0C9C03BC1F20406D2 +:10487000401DE05BC0E2C0740747010E4E01AD2D44 +:104880009E11C0402E0A1464B06E6D084428221D8B +:104890007B81652AB0007EA13B7FA1477B51207CB4 +:1048A000A14968A91768AA1473A111C09F79A10C26 +:1048B000C18B78A107C1AE290A1E29B4007CA12BA7 +:1048C0002AB0070BAB0BDAB07DB3022ABDF8DBA030 +:1048D000CAA563FFB428B01089116987BB649FB86B +:1048E00063FFDC00647FB463FFD50000646FD0C059 +:1048F00041C1AE2AB40063FFC62B2102CEBE2A22DC +:104900001D2B221E7AB12A8C107CB1217AB901C0EC +:10491000B0C9B913E026DA2028B0002CB00703880C +:104920000A28824CC0D10B8000DBA065AFE7D240E3 +:10493000D10F8910659FD463FFF300006C1008C08D +:10494000D0C8598C302921020C0C4760000C8E30E5 +:104950000E1E5065E19E292102C0C116E015090B0B +:104960004C65B0908A300A6E5168E3026000852F72 +:10497000629E1BE00E6EF8532BB22668B0052E2205 +:10498000007BE94727629DB748CB7F97102B200C0F +:10499000B04E0CBF11A6FF29F2869E12798B4117EB +:1049A000E00507B70A2772A368700488207789306A +:1049B00029F285DF90D7906590652A210419E03CA3 +:1049C0007A9B22DA2058069F600029002C21041BC4 +:1049D000E0387CBB18DA20C0B658069AC958600186 +:1049E0004CC09063FFCCDA2058087F600006DA20C4 +:1049F000C0B658087D655135DC40DB308D30DA209B +:104A00000D6D515806F2C0D0D3A064A12029210217 +:104A1000C05184A18CA00404470C0C4763FF3E00E6 +:104A2000C09C8831DBD008F850089B3828210498B6 +:104A3000116E8823282066AC8C0C0C472C24667CD5 +:104A4000BB159F139E148A108B115807028E148F6A +:104A500013C0D02D24668A30C092C1C81BDFEC7F02 +:104A6000A6099BF099F12CF40827FC106550A4B816 +:104A70003ADF70C051C08007583808084264806728 +:104A800018DFC819DFC929867E6A420AD30F6DE98B +:104A90000500A08800F08CC0A08930B4E37F962880 +:104AA000C0F207E90B2C94089B909F912F200C12C9 +:104AB000DFC80CF811A688298285A2FF2DF4CFD279 +:104AC000A009330B238685D10F22200C891218DF11 +:104AD000C00C2B11A6BBA8222D24CF2CB285D2A0AE +:104AE0000C990B29B685D10FC087C0900A59387927 +:104AF000809663FF8ADB30DA20C0C1C0D05BFF56EE +:104B0000292102C0D02A9CFE65AE4D2D2502C09001 +:104B100063FE45009E142A2C74C0B1DC70DD405841 +:104B200006DD8E14C0D01BDFB9C1C863FF6AC02088 +:104B3000D10F00006C100628210216DF9D08084CDA +:104B400065821929629E6F980260022019DF9829F8 +:104B500092266890078A2009AA0C65A20F27629DF9 +:104B6000C0CC6472072B21048E31C0A0DDA00EFEE4 +:104B7000500ECD386EB8102C2066B1CC0C0C472CE2 +:104B800024667CDB026001EFC0C12930081BDF8A8C +:104B900064909C2F0AFFC0D3B09E64E10268921318 +:104BA0006450882A2C74044B025800930AA202060F +:104BB000000000002B200C2721040CBC11A6CC29DE +:104BC000C286280A087983026001B919DF7A09B917 +:104BD0000A2992A36890082E220009EE0C65E1A430 +:104BE0002EC28564E19E26200713DF836E7B026060 +:104BF000019A17DF7A1FDF8319DFB0C0D228200A9D +:104C000093E09DE1A9690F880298E22F90802A9491 +:104C100080B1FF07FF029FE32EC2851FDF6D0EDE0E +:104C20000BAFBF2AF4CF2EC685655F76C020D10FAB +:104C30002830102930112E301300993200ED3264E3 +:104C400080EE2A30141FDF9D00AA3278EF050F9EF8 +:104C5000092DE47F1EDF9B66A0050F98092A84803A +:104C6000B4A718DF98C76F009104AE9EDDE000AFD7 +:104C70001A00C31A6EE1052DB2000DED0C1EDF9275 +:104C800008D81C063303AE882A848B2EB02E2784C6 +:104C90008C03EE010FEE022EB42E58018F63FEFF3F +:104CA0002931082925042830142E3109B088648060 +:104CB000A32E240AC0812E30162CB4232E240BB42C +:104CC000EF2F240C8C378B36292504DEB0DFC00C87 +:104CD0008F390B8E390FEE0264EEC4089F1101C4A8 +:104CE000048D380CB81800C4040CBE1800EE110E68 +:104CF000DD02C0E30EFF021EDF669F719E701EDFA5 +:104D0000658F2098739D7405FF110BCD53C180985A +:104D1000750FDD020EDD029D721EDF242A24662F30 +:104D2000629D2AE4A22FFC182F669D63FE7100008D +:104D3000002F30121BDF6600FA3278FF050B980B4C +:104D40002A847F66D0050B9A0B2DA4802A3011008F +:104D5000AA3263FF442F240A9E2B63FF56CC57DAF6 +:104D600020DB30DC4058070EC020D10F00DA20C015 +:104D7000B658079D63FFE500DA70580636C0A02AD2 +:104D8000246663FE02DA2058079863FFCFB16928D2 +:104D9000200A8620090947991129240798107F8144 +:104DA0002693E027E50A9AE388109DE119DF428DFA +:104DB00011096F029FE42DE416098802C0D398E21E +:104DC0002A240763FE5100001DDF0B0868118F11B4 +:104DD000892B93E008FF02C08F9FE50D990299E2AD +:104DE000047F11C0D49DE108FF029FE463FFD0005F +:104DF0006C1004C020D10F006C100485210D3811F7 +:104E000014DEE98622A42408660C962205330B934F +:104E100021743B13C862D230D10FC030BC29992114 +:104E200099209322D230D10F233DF8932163FFE3E1 +:104E30006C100AD620941817DEDED930B8389819CD +:104E40009914655252C0E1D2E02E61021DDEDB0EE4 +:104E50000E4C65E1628F308E190F6F512FFCFD658E +:104E6000F1558EE129D0230E8F5077E66B8F181EF7 +:104E7000DF18B0FF0FF4110F1F146590CE18DF1567 +:104E80008C60A8CCC0B119DEC928600B09CC0B0D11 +:104E9000880929811C28811A2A0A0009880C08BA65 +:104EA000381BDF0B0CA90A2992947B9B0260008CB3 +:104EB0002B600C94160CBD11A7DD29D286B8487959 +:104EC00083026000D219DEBB09B80A2882A39817B2 +:104ED0006880026000A36000A51ADEFF84180AEE55 +:104EE00001CA981BDEB28C192BB0008CC06EB313B4 +:104EF0001DDEAF0C1C520DCC0B2DC295C0A17EDB6C +:104F0000AE6000380C0C5360000900000018DEF1A0 +:104F10008C60A8CCC0B119DEA528600B09CC0B0DA4 +:104F2000880929811C28811A2A0A0009880C08BAD4 +:104F3000380CA90A2992947E930263FF72DA60C04A +:104F4000BA58072964507360026600001ADE988C14 +:104F5000192AA0008CC06EA31A18DE940C1C5208EB +:104F6000CC0B18DEDB2BC295C0A178B30263FF3FE8 +:104F700063FFC9000C0C5363FF09896078991829F5 +:104F8000D285C9922B729E1DDE896EB8232DD22642 +:104F9000991369D00B60000DDA6058071360001791 +:104FA0000088607D890A9A1A29729D9C129915CFF2 +:104FB00095DA60C0B658070C6551F58D148C18DB76 +:104FC000D08DD0066A020D6D51580580D3A09A1479 +:104FD00064A1DD82A085A1B8AF9F19050547020233 +:104FE000479518C05163FE602B6104C08C8931C0A5 +:104FF000A009F950098A386EB81F2C6066A2CC0C43 +:105000000C472C64667CAB119F119E1B8A155805BA +:10501000918E1B8F11C0A02A64669F1164F0E12954 +:1050200012032812096DF9172F810300908DAEFE2F +:105030000080889F9200908C008088B89900908CA6 +:1050400065514E8A10851A8B301FDE6B88122960DD +:105050000708580A2C82942D61040ECC0C2C8694DF +:105060006FDB3C1CDE95AC9C29C0800B5D50A29987 +:1050700009094729C48065D0DA2E600CC0D01FDE34 +:10508000540CE811AFEEA7882282852DE4CF0242AE +:105090000B228685D2A0D10F8E300E0E4763FDA65F +:1050A000A29C0C0C472C64077AB6CD8B602E600A4C +:1050B000280AFF08E80C64810E18DE7E831682132E +:1050C000B33902330B2C34162D350AC02392319F8D +:1050D00030C020923308B20208E80292349832C0FD +:1050E000802864072B600CD2A01CDE390CBE11A7EF +:1050F000EE2DE285ACBB28B4CF0D9D0B2DE685D1FE +:105100000F8B1888138D30B88C0D8F470D4950B414 +:10511000990499100D0D5F04DD1009FF029F800DA9 +:10512000BB029B8165508D851AB83AC0F1C0800CD6 +:10513000F83808084264806B1BDE1A19DE1B29B69A +:105140007E8D18B0DD6DDA0500A08800C08CC0A08F +:1051500063FEF30082138B161DDE2B28600AC0E06D +:105160002EC4800D880202B20B99239F20C0D298D2 +:10517000229D2122600CB2BB0C2D11A7DD28D28507 +:1051800008BB0B18DE132BD685A8222E24CFD2A065 +:10519000D10F9E1B851A2A6C748B185BFF178E1B10 +:1051A00063FEA300C087C0900AF93879809263FF3C +:1051B00086C020D10F9E1B2A6C74C0B18D18580573 +:1051C000358E1B851A63FE7E886B8213891608BE96 +:1051D000110ECE0202920B9E25B4991EDE069F2070 +:1051E0000E88029822C0EF04D8110E88029824C0BD +:1051F000E49E21C080D2A02B600C2864071CDDF443 +:105200000CBE11A7EE2DE285ACBB28B4CF0D9D0BD3 +:105210002DE685D10F0000006C1004C020D10F00D6 +:105220006C10048633C071C030600001B1330031AE +:105230000400741A0462017460F1D10F6C1004024E +:105240002A02033B025BFFF61CDDDC1BDE24C79F4A +:1052500088B009A903098A019AB079801EC0F00FAD +:10526000E4311DDDD30002002BD2821EDE1D2AC1D7 +:10527000020EBB022BD6820AE431D10F28C102C133 +:105280009009880208084F28C50208E431D10F00B0 +:105290006C1004C0C00CE43112DDC81ADDC5000278 +:1052A0000029A28218DE111BDE0F2621020B9901B4 +:1052B00008660129A68226250206E43114DE0C15B3 +:1052C000DE07236A902326128550242611252613F3 +:1052D000222C40D10F0000006C1008D6102B0A645D +:1052E000291AB41ADDB20D23111CDDB30F2511B834 +:1052F0001898130E551118DDFEAC55A838AA332C9A +:1053000080FF2A80FEA933288D0129800108AA1177 +:105310002880000CAA0208881109880208AA1C2803 +:105320008C0828160458084C14DDA40AA70224414E +:10533000162A30802B120407AA28580847B1338B4D +:1053400013B4559A6004AC28B4662C56277B69E0E8 +:1053500016DDDB9412C050C0D017DD979D15D370B9 +:10536000D4102F60802E60829F169E178816728937 +:105370001A8D128C402A607F0DCC282B3A200CAA63 +:1053800028580835C0B10ABE372E35408F1772F93C +:105390001A8D128C402A60810DCC282B3A200CAA41 +:1053A0002858082DC0B10ABE372E3542B233B44456 +:1053B000B1556952B6B466C0508F15B877D370B284 +:1053C000FF9F156EF899D10F6C1004C021D10F000A +:1053D0006C1004270A001CDD761FDD871EDD8A1D88 +:1053E000DD731ADDB51BDDC3C02824B0006D2A753E +:1053F000AA48288080C09164806100410415DD6E58 +:10540000C03125502E00361A0655010595390C5627 +:10541000110C66082962966E974D0D590A2992243F +:1054200068900812DDA702420872993B2362951228 +:10543000DD6BCB349F300282020E4402C092993160 +:1054400094329233AD52246295C090244C1024665D +:105450009524B0002924A0AA42292480B177B14420 +:1054600004044224B400D10FD10FD10F6C10041AE0 +:10547000DD4F2AA00058021C5BFFD5022A02033B25 +:10548000025BFFD11BDD4DC9A12CB102C0D40DCCF4 +:10549000020C0C4F2CB5020CE431D10FC0A00AE471 +:1054A0003118DD430002002F828219DD562EB10231 +:1054B00009FF022F86820EE431D10F006C1004C068 +:1054C0002002E43114DD3D16DD3A00020022628242 +:1054D000234102732F0603E431C020D10F19DD8769 +:1054E0001ADD862841020A2A010988012A668228D3 +:1054F000450208E43115DD7D12DD8225461DD10F00 +:105500006C1004292006289CF96480A02A9CFD6563 +:10551000A0968A288D262F0A087AD9042B221FC824 +:10552000BD2C206464C0812E22090EAE0C66E0788A +:105530002B200C1EDD1F0CBC11AECC28C28619DD41 +:105540001D78F3026000AD09B90A2992A36890089A +:105550002E220009EE0C65E09B29C2851FDD276421 +:1055600090929F90C0E41FDD349E9128200AC0E0F5 +:105570009E930F8802989288200F880298942F207B +:10558000079A979D962F950A2E24072820062920F2 +:105590006468833328C28512DD0E288C20A2B22EC7 +:1055A00024CF28C685C020D10FC020D10F2A206A61 +:1055B0000111020A2A4165AF52DA20C0B05805D164 +:1055C00064AFE5C021D10F00649FC81FDCFB2D2014 +:1055D000168FF209DD0C00F10400DD1AADAD9D2936 +:1055E00012DCFC28C285A2B22E24CF288C2028C62B +:1055F00085C020D10FC021D10F0000006C100426FF +:105600000A001BDD4015DCEC28206517DCE9288C3E +:10561000FE6480940C4D110DBD082CD2F52BD2F4F4 +:105620002ED2F77CB13DB4BB2BD6F47BE9052BD24F +:10563000F62BD6F47CB92C2AD2F62AD6F52AD6F443 +:1056400006E4310002002872822AFAFF0041042990 +:105650000A012F510200991A0A9903098801287634 +:10566000820FE4312624652BD2F48E5A2CD2F5B069 +:10567000EE9E5A7BCB1629D2F62FD2F70CB80C0926 +:10568000FF0C08FF0C0F2F14C8F96000320BCA0C76 +:105690000A2A14CEA92B5102C0C20CBB020B0B4F1D +:1056A0002B55020BE431D10F00DB30DA205BFF9485 +:1056B0001BDD1564AF5D0C4D11ADBD63FFA800008F +:1056C00006E4310002002F728218DCD42E51020849 +:1056D000FF022F76820EE431D10F00006C1004C05F +:1056E0003003E43116DCB315DCB40002002462821E +:1056F00074472118DD05875A084801286682CD7352 +:1057000019DD030C2A11AA9922928329928472919D +:10571000038220CC292B51020BE431C020D10F0091 +:105720001FDCFC2E51020FEE012E55020EE431B0AB +:105730002DB17C9C5A12DCF708DD112D5619D10FC2 +:105740006C10061BDC9A1EDC9C22B0001ADCF36F86 +:1057500023721DDCDAC04818DCF21FDCF0DC10D547 +:10576000C083F000808600508A6D4A4F0F35110DBE +:1057700034092440800B560A296294B1330E55092E +:105780002251400F44110C440A874009A80C02889A +:105790003622514107883608770CA89929669497D4 +:1057A00040296295874109A80C0288360788360887 +:1057B000770CA8992966959741030342B1380808E8 +:1057C0004298F0D10F1CDCD713DCD827B00023326D +:1057D000B5647057C091C0D016DCD615DCD4C0407B +:1057E0002AC00003884328C4006D793C004104B1FD +:1057F0004400971A7780148E502FB2952DB695AF2E +:10580000EE2EED2006EE369E5060001877A009833C +:10581000509D5023B69560000223B295223D20068C +:10582000223622B695B455B8BBD10F000388432861 +:10583000C400D10F6C1004C04004E43115DCBE007C +:105840000200885013DCBDCB815BFFBD1CDCBC0CAF +:105850002D11ADCC2BC2822AC28394507BAB142E67 +:10586000C28429C2850ABD0C0E990C0D990C092918 +:10587000146000050BA90C092914993015DC4F2A76 +:1058800051020AE4312A2CFC58004B2B32000AA2A8 +:10589000022BBCFF9B30CCB6C8A4D2A0D10F000015 +:1058A00004E4311EDC430002002DE2822FBAFF2CFB +:1058B00051020FDD012DE6820CE431D10F00000012 +:1058C0006C1004D10F0000006C1004C020D10F0038 +:1058D0006C100413DC9BC0D103230923318DC0A0BD +:1058E0006F340260008D19DC321BDC3317DC940C42 +:1058F0002811A8772672832572822CFAFF765147E9 +:1059000088502E7285255C0425768275E9052572FE +:10591000842576827659292E72842E76822E76837D +:105920000AE4310002002392820021042FB1020018 +:10593000D61A0C66030633012396820FE4312672D1 +:105940008325728260000200D8A07659220AE431D1 +:1059500000020023928200210400D21A2FB1020C0F +:1059600022030232012296820FE431D280D10F004D +:10597000D280D10FC020D10F6C1004DB30862015EF +:10598000DC0B280A00282502DA2028B0002CB007FA +:1059900005880A28824C2D0A010B8000DBA065AF28 +:1059A000E61ADC040A4A0A29A2A3C7BF769101D1EC +:1059B0000F2BA6A3D10F00006C1004C0D1C7CF1BC2 +:1059C000DBFE19DBFB17DBF90C2811A87786758540 +:1059D00074C0A076516288508E77B455957475E97D +:1059E00003857695747659278F769F759F740AE4A0 +:1059F00031000200239282B42E2FB10200E1040094 +:105A0000D61A0C66030633012396820FE43186759D +:105A100083747639280AE4310002002E9282B4227F +:105A200000210424B10200DF1A0CFF030FEE012E47 +:105A3000968204E431D280D10FD8A07651D6D2809C +:105A4000D10F00006C1004290A801EDC001FDC004E +:105A50001CDBD80C2B11ACBB2C2CFC2DB2850FCC35 +:105A6000029ED19CD0C051C07013DBFC14DBFB182C +:105A7000DBF92AB285A82804240A234691A986B80E +:105A8000AA2AB685A98827849F25649FD10F000084 +:105A90006C100419DC2C0C2A11A9A98990C48479F2 +:105AA0008B761BDC1AABAC2AC2832CC2847AC16809 +:105AB0008AA02BBC30D3A064A05E0B2B0A2CB2A30F +:105AC00019DBE568C0071DDC20D30F7DC94AA92971 +:105AD000299D0129901F68913270A603D3A0CA9E08 +:105AE000689210C7AF2AB6A32A2CFC5BFFB3D23052 +:105AF000D10F000013DBC503A3018C311DDBB60CF5 +:105B00008C140DCC012CB6A363FFDC00C020D10F98 +:105B1000DA205BFFCCC020D10FC020D10F000000E5 +:105B20006C1004DB30C0D019DBA1DA202830002251 +:105B3000300708481209880A28824CDC200B8000B4 +:105B40001BDB9C0C4A11ABAA29A28409290B29A6AC +:105B500084D10F006C1004C04118DB9517DB970C43 +:105B60002611A727277030A866256286007104A336 +:105B70005500441A75414822628415DBB802320B85 +:105B8000C922882117DB940884140744017549054C +:105B9000C834C020D10FD10F0809471DDBEBC0B2BC +:105BA0008E201FDB820E0E43AFEC2BC4A00FEE0A3B +:105BB0002DE6242A6284C0200A990B296684D10F1D +:105BC000C020D10F6C1004DB30C0D018DB78DA2095 +:105BD00025300022300708580A28824CDC200B8030 +:105BE000008931709E121BDB720C4A11ABAA29A2EC +:105BF0008409290B29A684D10F09C95268532600AC +:105C0000910418DB6DC0A12F811200AA1A0AFF02AD +:105C10002F85121EDB670C4D11AEDD2CD2840C2CAF +:105C20000B2CD684D10FC0811FDB64B89A0A0A47B7 +:105C30002EF11200A10400881A08EE022EF5121DA2 +:105C4000DB5C0C4C11ADCC2BC2840B2B0B2BC68414 +:105C5000D10F00006C1004DB30C0D019DB54DA2007 +:105C600028300022300709880A28824CDC200B806B +:105C7000001CDB4F0C4B11ACBB2AB2840A2A0B2A46 +:105C8000B684D10F6C1004C04118DB4916DB4B0CF5 +:105C90002711A626266030A872252286006104A35B +:105CA0005500441A75410822228402320BD10F009C +:105CB000C020D10F6C100415DBA502491429561120 +:105CC0002452120208430F8811C073008104003669 +:105CD0001A008104C78F00771A087703074401066A +:105CE0004402245612D10F006C10066E230260008D +:105CF000AC6420A7C0A0851013DB7E16DB94C040E7 +:105D0000A6AA2BA2AE0B194164906668915D6892B9 +:105D10005268933C2AA2AA283C7F288C7F0A0A4D0D +:105D20002980012880002AACF208881109880275B0 +:105D300089462B3D0129B0002BB0010899110B9920 +:105D4000027A9934B8332A2A00B1447249B160000A +:105D50004A7FBF0715DB7F63FFB90000253AE86380 +:105D6000FFB10000253AE863FFA90000250A64633B +:105D7000FFA1C05A63FF9C0000705F082534FF0537 +:105D80008C142C34FE70AF0B0A8D142E3D012AE4C6 +:105D9000012DE400DA405BFD5063FFA7D10FD10F66 +:105DA0006C10041ADB0519DB021CDB6A1BDB6BC001 +:105DB00080C07160000D00000022A430B1AA299CAF +:105DC000107B915F26928679C2156E6262C0206D4B +:105DD000080AB12200210400741A764BDB63FFEE3F +:105DE0002292850D6311032514645FCFD650032DD5 +:105DF000436DD9039820B4220644146D492298209B +:105E000098219822982398249825982698279828AE +:105E10009829982A982B982C982D982E982F222CD8 +:105E20004063FF971EDAE327E68027E681D10F0063 +:105E3000C02063FF830000006C1004C062C04112E8 +:105E4000DADE1ADADA13DB452AA00023322D19DB59 +:105E50003F2BACFE2992AE6EA30260008E090E406D +:105E60002D1AC2C2CD0EDC392C251664B0895BFF19 +:105E70009E15DB3B1ADAE52B3AE80A3A015805761B +:105E80002B21160ABB28D3A02B560058058D8B500A +:105E90000ABB082A0A0058058C15DB322D21022C7A +:105EA0003AE80C3C2804DD022D25029C505805845C +:105EB0008B50AABBC0A15805841CDB2B2D21020CE2 +:105EC0003C2806DD0213DB292D25029C3058057C79 +:105ED0008B30AABBC0A258057C2A2102C0B40BAAF1 +:105EE000020A0A4F2A2502580590D10F242423C301 +:105EF000CC2C251663FF760018DB211CDB1D19DB7B +:105F00001E1BDB1C17DAF085202E0AFD1FDB1D2D62 +:105F1000202E24F47A24F47E24F4820EDD0124F46D +:105F2000862E0AF707552806DD02C0750EDD01052D +:105F30000506AB5BA959C0E8AC5C24C4AB0EDD021E +:105F400027C4AC2E0ADFA85527B4EC0EDD0124B41B +:105F5000EBC2E027942C0EDD0224942B2E0A800D38 +:105F60000D4627546C24546B0EDD022D242E63FE47 +:105F7000FC0000006C10042A0A302B0A035BFF4D62 +:105F800012DAF3C390292616C3A1C0B3C08A28260B +:105F9000175BFF48C03CC3B12B26161ADA872AA02C +:105FA0002023261764A079C3A2C0B15BFF42C3A21D +:105FB000C0B15BFF40C3C22C2616C2AFC0B12326BE +:105FC000175BFF3CC28F282616C0FE2F2617C2E2A1 +:105FD0002E26162A0AA1C0B1C0D82D26175BFF3580 +:105FE0002A0AA12A2616C3A6C0B3C1922926175B86 +:105FF000FF31C3C62C2616C1B32A0AA22B2617C00E +:10600000B35BFF2C290AA2292616C185282617C2B0 +:10601000FB2F2616C0E72E26171DDADA2D2610D103 +:106020000FC3A2C0B35BFF2363FF82006C10041C8C +:10603000DAA41BDA9118DAD417DAD516DAD515DA1C +:10604000D5C0E0C0D414DAA01FDA5CC0288FF06D90 +:106050002A36DAC0D9C07C5B020FC90C1CDA9A0C54 +:106060009C28A8C3A6C22A36802A2584A4C2A7CC0D +:106070002D248C2B248A2B24872E248BB1BB2E36E7 +:106080009F2C369E2C369DB1AC1CDA7B1BDAC3C02C +:10609000286D2A33DAC0D9C07C5B020FC90C1CDA28 +:1060A000890C9C28A8C3A6C22A36802B2584A4C2AA +:1060B000B1BBA7CC2D248C2E248B2A248A2E369F6C +:1060C0002C369E2C369DB1ACC07919DA791BDAB525 +:1060D00013DAB31ADAB318DAB414DA7A16DAB404C3 +:1060E000F42812DAB304660C040506A252A858AAD2 +:1060F0005AA3539B3029A50027848AC091C0A52AA2 +:10610000848C29848B17DAAC18DAABA75726361D96 +:1061100026361E2E361F16DAA913DAA9A655043321 +:106120000C2826C82E75002D54AC2E54AB2E54AA24 +:106130002326E62326E52E26E7D10F006C10061352 +:10614000DA8717DA8224723D2232937F2F0B6D0893 +:10615000052832937F8F0263FFF3C0C4C0B01ADA00 +:1061600016C051D94004593929A4206E44020BB5F8 +:1061700002C3281EDA11DDB025E422052D392DE4F5 +:1061800021C0501EDA9019DA8018DA8016DA821DE2 +:10619000DA8E94102A724517DA4C6DA94BD450B39D +:1061A000557A5B17DF50756B071FDA038FF00F5FAF +:1061B0000C12DA4402F228AE2222D681D54013DA3C +:1061C00041746B0715D9FD855005450C035328B163 +:1061D00045A73FA832A93322369D22369E24368019 +:1061E0002B369F2BF48B2CF48C14DA5C24424DC09C +:1061F00030041414C84C6D0806B133041414C8429A +:1062000063FFF20015D9EAC4400031041AD9EBC08B +:10621000D193A200DD1AC138B0DD9DA318DA502B4E +:10622000824D29824E29A51C2882537A871E2C5420 +:10623000008E106FE45D12D9E02F211D23211C2F49 +:10624000251B04330C23251C23251AD10FC06218EB +:10625000DA3F88807E87D989102654006F94191BF5 +:10626000D9D62AB11C0A1A1404AA0C2AB51C2AB5BC +:106270001D2AB51A2AB51BD10F1BD9CF2AB11C0A6A +:106280001A1403AA0C2AB51C2AB51D2AB51A2AB558 +:106290001BD10F001CD9C92BC11D2DC11C2BC51B27 +:1062A00003DD0C2DC51C2DC51AD10F006C1006196D +:1062B000D9C214DA2612DA2915DA44C73FC0E02E13 +:1062C00056A82E56A92E56AA2E56AB23262918D9E3 +:1062D000EADB101CDA3EC0D42A42452D16019C1080 +:1062E00000B0890A880C2896005BFF942B22E318E3 +:1062F000D9B20B5B149B842A22E48B84B1AA0A5A7C +:10630000140BAA0C9A852922E509591499862F2283 +:10631000CD0F5F149F875BFF455BFF1623463BC194 +:10632000B01DD9A51CDA032AD1022C463A0BAA02C9 +:106330000A0A4F2AD50258047C5BFEBF5BFE98C058 +:1063400050C0B016D99B14D9A317DA12C0C0C73EEB +:1063500093122C262DC0306000430000007F9F0F59 +:10636000B155091914659FF4C0500AA9027FA7EF1F +:1063700018D98FDA5008580A28822C2B0A000B8073 +:1063800000005104D2A0C091C7AF00991A0A990326 +:106390009912CE33642067D3202B200795138C12DB +:1063A0002A62827CA85F18D98108580A28822CDAD0 +:1063B000500B8000D2A0643FDA8A310A8A1404AA02 +:1063C00001C8298B210B8B1404BB017BA945DDA0DF +:1063D0007A7B081DD9792DD2000DAD0CDB3019D98F +:1063E000731AD9B82812030ADA28088C021DD9F5C5 +:1063F00009880A28823C0DAA080B8000652F97D3D4 +:1064000020C0B063FF97CB53B1550050040A09195F +:1064100063FF4900DAB07B7B071AD9678AA00ABA02 +:106420000C1BD9A88C310BAB280C8A141CD9E6ACF8 +:10643000BB1CD9E504AA012BC68163FF907FA7C7C7 +:1064400063FF62006C100427221EC08008E4311B29 +:10645000D9580002002AB28219D958003104C0610B +:1064600000661A2991020A6A022AB68209E43115E5 +:10647000D9B30C3811A8532832822432842A8CFCD8 +:106480007841102921022A368297A009690229251C +:1064900002D10F002B21022C32850B6B022CCCFC7D +:1064A0002C368297C02B2502D10F00006C1004C03F +:1064B000E71DD93B1CD93D0D4911D7208B228A20DD +:1064C0000B4B0BD2A007A80C9B72288CF4C8346F1E +:1064D0008E026000A21FD933A298AF7B78B334C973 +:1064E0003DC081C0F0028F380F0F42C9FA2CD67E12 +:1064F000D5206D4A0500308800508C8870089808B7 +:1065000078B16CD2A09870D10FC0F0038F387FE0C3 +:10651000DE63FFD8027B0CAFBB0B990C643046D80E +:1065200030C0F1C05002F5380505426450792CD6D0 +:106530007E0B36122F6C100F4F366DFA05008088D7 +:1065400000208C06440CC081250A0003B208237C7D +:106550000C0385380505426450592CD67E6D4A05DA +:1065600000208800308CD2A0A798BC889870D10FEA +:10657000D2A0BC799970D10FD2302BAD08C0F1C038 +:10658000500BF538050542CB552CD67E083F14C17B +:10659000600F660C064636D30F6D6A050020880032 +:1065A000B08C827063FF2D00C05003F53875E08019 +:1065B00063FF7A00C06002863876E0A063FF9A002D +:1065C000C05003F53875E0C363FFBD006C1004D6FE +:1065D0002068520F695324DA20DB30DC405800F089 +:1065E000D2A0D10FDA20DB30DC405800ED9A242411 +:1065F000240EC02122640FC020D10F00B83BB04C44 +:106600002A2C7489242D200E2E200FA4DDB1EE2E0D +:10661000240FB0DD2D240E2890072D9003A488B000 +:1066200088B1DD2D94032894075BFFA069511DC03C +:10663000E082242A600F18D9662A240329600E8F6D +:106640002029240708FF029F209E64D10FC020D17B +:106650000F0000006C1004942319D95EC0B3083AEF +:10666000110BAA02992019D8D29A2116D8D0C0505D +:1066700028929D2564A2288C1828969DD10F000091 +:106680006C1004282066C038232406B788282466A6 +:10669000D10F00006C1006035A0C0D36110D5C1161 +:1066A000D8208B2282210CBB0C06550F9B82023214 +:1066B0000B928113D8BCD920A38F6450531CD8B837 +:1066C000C0D71BD8B9A256C0E1290A0004E938098D +:1066D000094276F34A044302C99E2BC67E6DAA0581 +:1066E00000208800308C8981A95909FA0C64A079AE +:1066F00099818A82C8ADD290D10FC06002E6387607 +:10670000D0DA63FFD4C020BC89998199809282D16C +:106710000F7F2304292DF8998165BFD963FFE50018 +:10672000028F0CA3FF0F3312931003AA0CD340CB9C +:106730009E2BC67E86106D6A0500208800308CBCBA +:1067400082290A0004F308240A010349380909428E +:10675000CA982BC67E6DAA0500208800308C0F5980 +:106760000CA989BC99998163FF87BC89998163FFD2 +:1067700080C06002E63876D0BA63FFB4C0700247CA +:106780003877D0D063FFCA006C100414D895C1527A +:10679000A424CA3028221D73811B292102CD952AE9 +:1067A000300075A912DA20033B022C30072D0A02B3 +:1067B0005801C2653FDDD10F2B300703BB0BDAB0A8 +:1067C00074B3022ABDF8D3A063FFC6006C1004297D +:1067D0002006C0706E9741292102C08F2A2014C064 +:1067E000B62B240606AA022A241479800227250241 +:1067F0002A221E2C221D7AC10EC8ABDA20DB302CD7 +:106800000A00033D025BF8146450752D21020D0D42 +:106810004CC9D3C020D10F00002E9CFB64E0822F16 +:1068200021020F0F4C65F0911AD8621CD86029A282 +:106830009EC08A798B5D2BC22668B0048D207BD9DF +:106840005229A29DC0F364904A97901DD8732E21BF +:10685000049D9608EE110FEE029E979E9118D86F38 +:10686000C0E527C4A22E24062BA29D2F21022BBCFB +:106870003008FF022F25022BA69DC020D10F00005B +:10688000002F300068F938DA20DB30DC4058004453 +:1068900063FF7700022A022B0A065800D3220A005F +:1068A000D10F655010283000688924022A02033B6A +:1068B00002DC4058003BC020D10FD270D10F000045 +:1068C0002A2C74033B02044C025BFEF863FF3B007E +:1068D000DB30DC402A2C745BFEF5C020D10F0000B9 +:1068E0006C1004C83F89268829A399992609880C29 +:1068F000080848282525CC52C020D10FDB402A2C7F +:10690000745BF93DD2A0D10F6C1004D820D730822F +:10691000220D451105220C928264207407420B134C +:10692000D821D420A383732302242DF885807451A9 +:106930004CBC82C0906D081600408800708C77397E +:1069400003D720C0918680743901D420746102631A +:10695000FFE2CA98C097C0411BD8A0C0A00B8B0C07 +:106960000B4A380A0A42C9AA1DD80E1CD80F2CD6C9 +:106970007EC140D30F6D4A0500208800308C97807F +:10698000D270D10FBC8FC0E00F4E387E90E263FF13 +:10699000D6BC8292819280C0209282D10F000000EA +:1069A0006C1006C0D71CD7FE1BD8000D4911D7208C +:1069B0002E221F28221D0E4E0BD280078A0C2E7607 +:1069C0001F2AAC80C8346FAE026000CB2F0A801A39 +:1069D000D804A29EAA7A7EA33FC93FC0E1C050025C +:1069E000E538050542CA552BC67EDB20D30F6D4A1C +:1069F0000500308800B08C2E721DAE9E0EA50C6472 +:106A00005086D2802E761DC091298403D10FC050AC +:106A100003E53875D0D363FFCD15D7F1027E0CA501 +:106A2000EE643051C0A1250A0002A538033A0205E0 +:106A300005426450922BC67E0E35129510255C10CF +:106A4000054536D30F6D5A0500A08800208CC0A1E3 +:106A5000A3E2C05023FA8003730C03A538AF73057B +:106A600005426450722BC67E851005450C6D5A0593 +:106A700000208800308CD280C0A10E9B0CAB7BAF75 +:106A8000BB2B761D2A8403D10FD280C0C1AF7D2DD0 +:106A9000761D2C8403D10F00D2302E8D08C0F1C09A +:106AA000500EF538050542CB592BC67E0A3F14C15E +:106AB000600F660C064636D30F6D6A05002088000D +:106AC000E08C22721D63FF03C061C05003653875FE +:106AD000D80263FF6263FF5CC05002A53875D0879F +:106AE00063FF8100C06003F63876D0BF63FFB90052 +:106AF0006C10042A201529201614D7AF0A990CCB44 +:106B00009D2E200B04ED092BD11C8F2809BC36AC1F +:106B1000AA0CBB0C2BD51C0A0A472A2415CAAF8B1A +:106B2000438942B0A800910400881AA8FF0FBB0255 +:106B30009B278F260FB80C783B1AC020D10F00007E +:106B4000292102C0A20A9902292502C021D10F00E1 +:106B50008B2763FFDC2BD11C0CAA0C0A0A472A24C2 +:106B600015ACBB2BD51CC9AE8B438C288F42B0AD66 +:106B700000F10400DD1AADCC0CBB029B27DA20B774 +:106B8000EB580019C021D10F9F2763FFEF000000D1 +:106B90006C100428203C64304705306000073E013B +:106BA000053EB156076539054928C77FA933030655 +:106BB00041076603B166060641A6337E871E222181 +:106BC00025291AFC732B1502380C09816000063E3A +:106BD00001023EB12406423903220AD10FD230D13C +:106BE0000FC05163FFC000006C100427221EC0803C +:106BF00008E4311DD76F0002002CD2821BD76F0032 +:106C00003104C06100661A2BB1020C6C022CD682D2 +:106C10000BE43119D7F20C3A11AA932832829780EB +:106C2000253282243284B45525368275410A2921C1 +:106C300002096902292502D10F2A21022B32830A77 +:106C40006A022B36822A2502D10F00006C1004192B +:106C5000D76327221EC08009770208E4311DD7546C +:106C60000002002CD2821BD754003104C0610066A0 +:106C70001A2BB1020C6C022CD6820BE43119D7D737 +:106C80000C3A11AA932832829780253282243284CA +:106C9000B45525368275410B2A21020A6A022A253B +:106CA00002D10F002B21022C32830B6B022C368277 +:106CB0002B2502D10F0000006C10041BD73D0C2ABD +:106CC00011ABAA29A286B438798B221BD73A19D7DF +:106CD000610B2B0A2BB2A309290868B00274B90D05 +:106CE000299D0129901F6E920822A285D10FC020F4 +:106CF000D10FC892C020D10FDA205BEF35C020D170 +:106D00000F0000006C100414D72A28429E19D727C0 +:106D10006F88026000BA2992266890078A2009AA23 +:106D20000C65A0AC2A429DC0DC64A0A42B200C19E9 +:106D3000D7210CBC11A4CC2EC28609B90A7ED3027D +:106D400060009A2992A36890078D2009DD0C65D018 +:106D50008C25C2856450862D2104C0306ED80D2C40 +:106D60002066B8CC0C0C472C246665C07B1CD79CD5 +:106D700018D7281AD71E19D72F1DD724C0E49E5123 +:106D80009D508F209357935599539A569A5408FFC4 +:106D9000021AD73A9F5288269F5A9E599D58935E51 +:106DA0009C5D935C9A5B080848058811985FC0D881 +:106DB0001FD7080CB911A499289285AFBF23F4CF2F +:106DC000288C402896858E262D24069E29C020D109 +:106DD0000FCA33DA20C0B65BFF84C72FD10FC93A80 +:106DE000DA205BFF81C72FD10FDBD05BFE1A232493 +:106DF000662B200C63FF7500C72FD10FC72FD10F53 +:106E00006C1004C85B29200668941C689607C02093 +:106E1000D10FC020D10FDA20DB30DC40DD502E0A4C +:106E2000005BFE6AD2A0D10F2E200C18D6E10CEF29 +:106E300011A8FF29F286C088798B751AD6DE0AEA76 +:106E40000A2AA2A368A0048B207AB96423F285647D +:106E5000305E1CD6E82A0A802D2068292067282168 +:106E6000040B991104881109880208DD02C09428D6 +:106E70004A1008DD0218D6E0993198308B2B9A37EA +:106E80009D340CBB029B32C0C09C359C362A2C74AE +:106E9000DB40C0D318D6CF29F285A8EE299C202C40 +:106EA000E4CF29F6852D2406DD405BFDFAD2A0D182 +:106EB0000FDA20DBE05BFF4CC020D10F6C100AD64C +:106EC000302A2006941128ACF86583872B2122C034 +:106ED000F22A21246550082AAC010A0A4F2A2524E7 +:106EE0007ABB0260037F2C21020C0C4C65C3192E67 +:106EF00022158D32C0910EDD0C65D39088381ED6D8 +:106F0000AC64836B8C37C0B8C0960CB9399914B493 +:106F10009A9A120D991199138F6718D6A7C9FB2851 +:106F200080217F83168B142C22002A200C5BFF62A9 +:106F3000D4A064A3A88F6760002800002B200C89D0 +:106F4000120CBA11AEAA2CA2861DD69A7C9B3E0DBD +:106F5000BD0A2DD2A368D00488207D893024A28563 +:106F600064436427212E07F73607F90C6F9D01D77C +:106F7000F0DA20DB70C1C42D211F5BFF0589268854 +:106F800027DDA009880C7A8B179A10600006C04094 +:106F900063FFCC0000DA208B105BFED58D1065A25C +:106FA00067C0E09E488C649C498B658A669B4A9AC0 +:106FB0004B97458F677F7302600120CD529D10DA99 +:106FC00020DB302C12015BFE768D10C051D6A08FD5 +:106FD000A7C0C08A68974D9A4C8869896A984E996B +:106FE0004F8E6A8A69AE7E77EB01B1AA9E6A9A6972 +:106FF0008B60C0A00B8E1477B701C0A1C091C08474 +:1070000093159D179516C0D025203CC03008580117 +:10701000089338C082083310085B010535400B9D8A +:107020003807DD100BAB100E19402A211F079910ED +:1070300003DD020DBB020553100933020A55112965 +:1070400021250A2A140929140499110A99020933DD +:10705000028A2B2921040BAA021BD6E208991109E6 +:1070600055020855020BAA029A40892088140899F3 +:107070001109880219D6631DD6DC09880298418B54 +:107080002A9346954783150DBB0285168D179B44A1 +:107090008A658966AACAA97C77CB01B1AA07FB0CCD +:1070A0009C669A6588268E29AD87972607EE0C0E7A +:1070B0000E482E25259B672B200C87131ED63D0CD2 +:1070C000B911AE99289285A78828968517D641C010 +:1070D00090A7BB29B4CF871863FE3C008C60C0E04A +:1070E000C091C0F0C034C0B82A210428203C08AAAE +:1070F000110B8B01038301039F380B9B39C03208AE +:10710000FF10038801089E380C881407EE100FEE5C +:107110000203880108983905BF1029211F0ABB11F5 +:1071200007881008FF020BAA0218D6350929140394 +:10713000AA022B212583200B2B1404BB1108331129 +:107140000FBB020B99028B148F2A0B3302083302F8 +:107150008B2B6470868868974D984C8769886A93F2 +:10716000419946974E984FC07077C701C0719A47B2 +:1071700018D69E0B7C100CEC0208F802984418D626 +:107180009B0CBC0208CC029C402A200C295CFEC04F +:10719000801FD6071CD60F0CAE112B2124ACAAAF32 +:1071A000EEB0BB8F132CE28528A4CFAFCC2CE685A4 +:1071B0002A22152B2524B1AA2A26156490DBC9D2D0 +:1071C0008F262E22090DFF082F26060FEE0C0E0E1D +:1071D000482E25256550E4C020D10F00C070934192 +:1071E0009F4499469A4777C70A1CD5F32CC022C002 +:1071F000810C87381CD67F0B781008E80208B8028B +:107200000C8802984063FF8000CC57DA20DB608C4A +:10721000115BFDE3292102689806689403C020D120 +:107220000F2B221EC0A029221D2A25027B9901C0F6 +:10723000B064BFE813D5DE2CB00728B000DA200315 +:10724000880A28824CC0D10B8000DBA065AFE763C1 +:10725000FFCA000068A779DA20DB30DC40DD505B34 +:10726000FEE8D2A0D10FC16DC19D29252C6000047C +:1072700029252CD6902624672F2468DA20DB308C31 +:1072800011DD502E0A805BFD51D2A0D10FC168C123 +:10729000A82A252C63FFDD000000C8DF8C268B297F +:1072A000ADCC9C260CBB0C0B0B482B25252A2C7433 +:1072B000DB602C12015BFD94D2A0D10F2A2C748BC1 +:1072C000115BF6CDD2A0D10FDA205BFE4763FF3809 +:1072D00000DA20C0B15BFE8B65AF2D63FBEDDA20D9 +:1072E0002B200C5BFE5A63FF1F00000012D6428267 +:1072F00020028257C82163FFFC12D63E03E8300407 +:10730000EE3005B13093209421952263FFFC0000FC +:1073100010D63A910092019302940311D611821073 +:1073200001EA30A21101F031C04004E4160002006D +:1073300011D6338210234A00032202921011D5FD88 +:10734000C021921004E43184038302820181000091 +:10735000D23001230000000010D62A910092019340 +:1073600002940311D600821001EA30A21101F1311A +:10737000C04004E41600020011D621821013D5A7E4 +:10738000032202921004E43184038302820181000B +:1073900000D330013300000010D61B91008101653D +:1073A000104981026510448103CF1F92019302941A +:1073B0000311D5EE821001EA30A21101F231C04072 +:1073C00004E41600020011D60D821013D58E03229C +:1073D00002921004E431840383028201C0109103FD +:1073E00091029101810000D43001430012D5BDC04B +:1073F0003028374028374428374828374C233D0168 +:107400007233ED03020063FFFC00000010D5FF9112 +:107410000092019302940311D5FD8210921011D5B0 +:10742000AF8310032202921011D5FA12D5C1921027 +:10743000C04004E41600020011D5F1821013D5A853 +:10744000032202921004E43184038302820181004A +:1074500000D53001530000006C10026E322FD62090 +:10746000056F04043F04745B2A05440C00410400CA +:10747000331A220A006D490D73630403660CB122AE +:107480000F2211031314736302222C01D10FC83B86 +:10749000D10F000073630CC021D10F000000000069 +:1074A00044495630C020D10F6C10020040046B4C90 +:1074B00007032318020219D10F020319C020D10FAC +:1074C0006C100202EA30D10F6C1002CC2503F031AF +:1074D00060000F006F220503F1316000056F230586 +:1074E00003F231000200D10F6C1002CC2502F03003 +:1074F000D10F00006F220402F130D10F6F2304027C +:10750000F230D10FC020D10F6C1002220A20230AC2 +:10751000006D280E28374028374428374828374C34 +:10752000233D01030200D10F6C100202E431D10FA0 +:107530000A0000004368656C73696F204657204459 +:10754000454255473D3020284275696C7420576587 +:1075500064204F63742020382031353A35303A3575 +:1075600030205044542032303038206F6E20636C0D +:10757000656F70617472613A2F686F6D652F666513 +:107580006C69782F772F66775F372E30292C20563D +:10759000657273696F6E2054337878203030372EDF +:1075A00030312E3030202D203130303730313030F6 +:0875B000100701006F4EF8BB4B +:00000001FF diff --git a/trunk/firmware/cxgb3/t3fw-7.4.0.bin.ihex b/trunk/firmware/cxgb3/t3fw-7.4.0.bin.ihex deleted file mode 100644 index 38dda94bfa6f..000000000000 --- a/trunk/firmware/cxgb3/t3fw-7.4.0.bin.ihex +++ /dev/null @@ -1,1917 +0,0 @@ -:1000000060007400200380002003700000001000D6 -:1000100000002000E100028400070000E1000288E7 -:1000200000010000E0000000E00000A0010000006E -:1000300044444440E3000183200200002001E0002A -:100040002001FF101FFFD0001FFFC000E300043C91 -:100050000200000020006B741FFFC29020006BBCE8 -:100060001FFFC29420006BFC1FFFC29820006C7021 -:100070001FFFC29C200003C0C00000E43100EA3131 -:1000800000A13100A03103020002ED306E2A05000C -:10009000ED3100020002160012FFDBC03014FFDA5F -:1000A000D30FD30FD30F03431F244C107249F0D347 -:1000B0000FD30FD30F12FFD5230A00240A00D30F4A -:1000C000D30FD30F03431F244C107249F0D30FD327 -:1000D0000FD30F14FFCE03421F14FFCB03421F1296 -:1000E000FFCCC0302D37302D37342D37382D373CED -:1000F000233D017233ED00020012FFC4C0302F37E0 -:10010000002F37102F37202F3730233D017233ED6A -:1001100000020012FFBEC0302737002737102737F4 -:1001200020273730233D017233ED03020012FFB95F -:1001300013FFBA0C0200932012FFB913FFB90C028F -:1001400000932012FFB8C0319320822012FFB71312 -:10015000FFB7932012FFB715FFB316FFB6C030D715 -:100160002005660160001B00000000000000000088 -:10017000043605000200D30FD30F05330C6E3B1479 -:100180000747140704437631E604360505330C6F40 -:100190003BED00020012FFA615FFA3230A00D720A3 -:1001A000070443043E0505330C0747146F3BF00377 -:1001B000020012FFA1C03014FFA1D30FD30FD30F41 -:1001C0009340B4447249F2D30FD30FD30F14FF9B63 -:1001D000834014FF9B834012FF9B230A0014FF9A65 -:1001E000D30FD30FD30F9340B4447249F2D30FD33C -:1001F0000FD30F14FF95834012FF95C92F832084DE -:10020000218522BC22743B0F8650B4559630B433FE -:100210007433F463FFE60000653FE1655FDE12FFC3 -:100220007C230A0028374028374428374828374C91 -:10023000233D017233ED03020000020012FF7AC079 -:1002400032032E0503020012FF7813FF819320C0B2 -:1002500011014931004831010200C00014FF7E0441 -:10026000D23115FF7D945014FF7D04D33115FF7CEE -:10027000945014FF7C04D43115FF7C24560014FFE5 -:100280007B04D53115FF7B24560010FF7A03000054 -:10029000000000000000000000000000000000005E -:1002A000000000000000000000000000000000004E -:1002B000000000000000000000000000000000003E -:1002C000000000000000000000000000000000002E -:1002D000000000000000000000000000000000001E -:1002E000000000000000000000000000000000000E -:1002F00000000000000000000000000000000000FE -:1003000000000000000000000000000000000000ED -:1003100000000000000000000000000000000000DD -:1003200000000000000000000000000000000000CD -:1003300000000000000000000000000000000000BD -:1003400000000000000000000000000000000000AD -:10035000000000000000000000000000000000009D -:10036000000000000000000000000000000000008D -:10037000000000000000000000000000000000007D -:10038000000000000000000000000000000000006D -:10039000000000000000000000000000000000005D -:1003A000000000000000000000000000000000004D -:1003B000000000000000000000000000000000003D -:1003C000000000000000000000000000000000002D -:1003D000000000000000000000000000000000001D -:1003E000000000000000000000000000000000000D -:1003F00000000000000000000000000000000000FD -:1004000000000000000000000000000000000000EC -:1004100000000000000000000000000000000000DC -:1004200063FFFC000000000000000000000000006E -:100430000000000000000000000000001FFC0000A1 -:100440001FFC0000E30005C81FFC00001FFC0000AB -:10045000E30005C81FFC00001FFC0000E30005C806 -:100460001FFFC0001FFFC000E30005C81FFFC00042 -:100470001FFFC018E30005C81FFFC0181FFFC018EA -:10048000E30005E01FFFC0181FFFC290E30005E076 -:100490001FFFC2901FFFC290E30008581FFFC290C9 -:1004A0001FFFC58CE3000858200000002000016AEF -:1004B000E3000B542000018020000180E3000CC009 -:1004C0002000020020000203E3000CC02000021CF8 -:1004D00020000220E3000CC420000220200002269D -:1004E000E3000CC82000023C20000240E3000CD0D6 -:1004F0002000024020000249E3000CD42000024CFE -:1005000020000250E3000CE02000025020000259BD -:10051000E3000CE42000025C20000260E3000CF029 -:100520002000026020000269E3000CF42000026C4D -:1005300020000270E3000D0020000270200002790C -:10054000E3000D042000028C2000028CE3000D105B -:100550002000029020000293E3000D10200002AC66 -:10056000200002B0E3000D14200002D0200002F2AF -:10057000E3000D18200003B0200003B0E3000D3CA1 -:10058000200003B0200003B0E3000D3C200003B0C6 -:10059000200003B0E3000D3C200003B0200003B0B6 -:1005A000E3000D3C200003B020006D94E3000D3CFF -:1005B00020006D9420006D94E3007720000000007F -:1005C00000000000000000001FFC00001FFC0000F5 -:1005D0001FFFC5901FFFC67020006D9820006D980A -:1005E000DEFFFE000000080CDEADBEEF1FFFC2A064 -:1005F0001FFCFE001FFFC0941FFFC5C0300000009D -:10060000003FFFFF8040000010000000080FFFFFC8 -:100610001FFFC26D000FFFFF804FFFFF8000000033 -:1006200000000880B000000560500000600000007D -:1006300040000011350000004100000010000001E2 -:100640002000000000001000400000000500000035 -:1006500080000019040000000000080010000005E0 -:10066000806000007000000020000009001FF800FA -:100670008000001EA0000000F800000007FFFFFF40 -:100680000800000018000000010080014200000086 -:100690001FFFC21D1FFFC0DC000100806040000082 -:1006A0001A0000000C0000001000000A00003000DA -:1006B000600008008000001C000100008000001A9B -:1006C00080000018FC0000008000000100004000D5 -:1006D000030000008000040050000003FFFFBFFF84 -:1006E0001FFFC3D400000FFFFFFFF000000016D073 -:1006F0000000FFF7A50000001FFFC4B01FFFC4618A -:100700000001000800000B20202FFF801FFFC455B0 -:1007100000002C00FFFEFFF800FFFFFF1FFFC57861 -:1007200000002000FFFFDFFF0000FFEF01001100CD -:100730001FFFC3D21FFFC590FFFFEFFF0000FFFBAD -:100740001FFFC6301FFFBEA0FFFFF7FF1FFFC064E3 -:100750000000FFFD1FFFC6200001FBD01FFFC5B03A -:100760001FFFC6601FFFC591E0FFFE001FFFC5A071 -:10077000000080001FFFC53C1FFFC5B41FFFC068FD -:100780001FFFC4D01FFCFFD8000100817FFFFFFFC7 -:10079000E1000600000027101FFCFE301FFCFE7069 -:1007A000E10002001FFFC5381FFFC5500003D090B5 -:1007B0001FFFC5642B5063802B5079802B50908095 -:1007C0002B50A6801FFFC4690100110F202FFE00CF -:1007D00020300080202FFF000000FFFF0001FFF805 -:1007E0002B50B2002B50B208000100102B50B180EA -:1007F0002B50B2802B50BA00000100112B50BD28A5 -:100800002B50BC802B50BDA020300000DFFFFE002D -:100810005000000200C0000002000000FFFFF7F4DB -:100820001FFFC06C000FF800044000000010000023 -:100830000C4000001C400000E00000A01FFFC5406D -:100840001FFD00081FFFC5541FFFC5681FFFC57CA3 -:10085000E1000690E10006EC00000000000000004E -:100860000000000000000000010000000000000087 -:100870000000000000000000201000402010004098 -:100880002010004020140080200C0000200C0000EC -:10089000200C000020100040201400802014008054 -:1008A00020140080201800C0201C0100201C010022 -:1008B000201C010020200140201800C0201800C08A -:1008C000201800C0201C0100201800C0201800C003 -:1008D000201800C0201C01002020014020200140E1 -:1008E00020200140202009402020094020200940EC -:1008F0002020094020240980FFFFFFFFFFFFFFFFAA -:10090000FFFFFFFF000000000000000000000000EB -:100910000000000000000000200054902000536000 -:1009200020005490200054902000529C2000529CA3 -:100930002000529C200050DC200050DC200050D4CD -:100940002000504020004EE820004CC820004A9C67 -:100950000000000000000000200054602000532C24 -:10096000200053D0200053D0200051842000518417 -:10097000200051842000518420005184200050CC5C -:100980002000518420004E0820004C7820004A4866 -:10099000000000000000000020000BE820003A30BA -:1009A000200004C02000463C20000BE0200041480D -:1009B000200003F0200045FC20004A2420003E5483 -:1009C00020003D70200039AC2000383C200035ACC0 -:1009D0002000310C20003BCC20002D6C2000280092 -:1009E000200067182000238C2000206C2000201895 -:1009F00020001D04200018182000154820000E2C8F -:100A000020000C2C2000110C200012F82000434084 -:100A100020003E0820000BF0200004C00000000071 -:100A200000000000000000000000000000000000C6 -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000000000000000000000000000000086 -:100A70000000000000000000000000000000000076 -:100A80000000000000000000000000000000000066 -:100A900000000000000000000000000032640000C0 -:100AA0000000000032640000640064006400640020 -:100AB00064006400640064000000000000000000A6 -:100AC0000000000000000000000000000000000026 -:100AD0000000000000000000000000000000000016 -:100AE0000000000000000000000000000000000006 -:100AF00000000000000000000000000000000000F6 -:100B000000001000000000000000000000000000D5 -:100B100000000000000000000000100000000000C5 -:100B200000000000000000000000000000432380DF -:100B300000000000000000000000000000000000B5 -:100B400000000000000000000000000000000000A5 -:100B500000000000005C94015D94025E94035F94C9 -:100B60000043000000000000000000000000000042 -:100B70000000000000000000000000000000000075 -:100B80000000000000000000000000000000000065 -:100B900000000000005C90015D90025E90035F9099 -:100BA00000530000000000000000000000000000F2 -:100BB0000000000000000000000000000000000035 -:100BC0000000000000000000000000000000000025 -:100BD00000000000009C94001D90019D94029E94D2 -:100BE000039F94040894050994060A94070B940043 -:100BF00043000000000000000000000000000000B2 -:100C000000000000000000000000000000000000E4 -:100C100000000000009C90019D90029E90071D9096 -:100C2000039F90047890057990067A90077B900056 -:100C30005300000000000000000000000000000061 -:100C400000000000000000000000000000000000A4 -:100C50000000000000DC94001D9001DD9402DE9491 -:100C600003DF94040494050594060694070794088A -:100C700008940909940A0A940B0B9400430000009D -:100C80000000000000000000000000000000000064 -:100C90000000000000DC9001DD9002DE900B1D9052 -:100CA00003DF9004B49005B59006B69007B790089E -:100CB000B89009B9900ABA900BBB9000530000009D -:100CC00063FFFC0020006B5010FFFF0A00000000D3 -:100CD00020006B7400D23110FFFE0A0000000000FB -:100CE00020006BBC00D33110FFFE0A0000000000A2 -:100CF00020006BFC00D43110FFFE0A000000000051 -:100D000020006C7000D53110FFFE0A0000000000CA -:100D100063FFFC00E00000A012FFF7822002825770 -:100D2000C82163FFFC12FFF303E83004EE3005C076 -:100D30003093209421952263FFFC00001FFFD00018 -:100D4000000400201FFFC5901FFFC670200A00117D -:100D5000FFFB13FFFB03E63101020016FFFA17FF4A -:100D6000FAD30F776B069060B4667763F85415B5C5 -:100D7000541A610F140063FFF90000006C1004C0E6 -:100D800020D10F006C1004C0C71AEF06D830BC2B5E -:100D9000D72085720D4211837105450B9572023380 -:100DA0000C2376017B3B04233D089371A32D12EEA7 -:100DB000FE19EEFEA2767D632C2E0A000882022820 -:100DC0000A01038E380E0E42C8EE29A67E6D4A0532 -:100DD00000208800308C8271D10FC0F0028F387FE4 -:100DE000C0EA63FFE400C0F1C050037E0CA2EE0E27 -:100DF0003D1208820203F538050542CB5729A67E2D -:100E00002FDC100F4F366DFA0500208800308CBCA7 -:100E100075C03008E208280A01058338030342C977 -:100E20003E29A67E0D480CD30F6D8A050020880050 -:100E3000B08C8271D10FC05008F53875C0C163FF06 -:100E4000BBC06002863876C0DA63FFD46C1012161D -:100E5000EED8C1F9C1E8C1C72B221E28221DC0D07F -:100E60007B81312920060BB702299CFA655008289E -:100E70002072288CFF28247264915C2AB0000CA890 -:100E80000C6481670EA90C6492B37FA13769AC2F03 -:100E90006000340000282006D7D0288CFACC572ACE -:100EA00020722AACFF2A24726481352AD0000CA952 -:100EB0000C6491640EAC0C64C31B7FA10768AC0783 -:100EC000C020D10F002D25028A32C0900A6E5065D5 -:100ED000E5B5292467090F4765F5B12C200C1FEEF5 -:100EE000B50CCE11AFEE29E286B4487983026005D5 -:100EF0008219EEB109C90A2992A36890078F2009C7 -:100F0000FF0C65F56E2FE28564F56865559628221D -:100F10001D7B8105D9B060000200C0908B9417EE54 -:100F2000A70B881487740B0B47A87718EEA509BB8D -:100F30001008770297F018EEA317EEA408A8010B8B -:100F400088020747021BEEA097F10B880298F22750 -:100F500090232B902204781006BB1007471208BB81 -:100F6000022890210777100C88100788020B88024E -:100F700017EE988B3307BB0187340B880298F397E1 -:100F80009997F48B9587399BF588968B3898F688D6 -:100F90009797F99BF898F717EE8F28E28507C7080F -:100FA0002D74CF08480B28E68565550F2B221E2887 -:100FB000221D7B89022B0A0064BF042CB00728B0D5 -:100FC00000DA2006880A28824CC0D10B8000DBA002 -:100FD00065AFE763FEE90000292072659E9C60040E -:100FE000E72A207265AEC36004DE00002EB0032C39 -:100FF0002067D4E065C1058A328C330AFF500C4566 -:1010000054BC5564F4EB19EE74882A09A9010988C7 -:101010000C64821FC0926000DD2ED0032A2067D4AA -:10102000E065A0D88A328B330AFC500B4554BC557E -:1010300064C4BE19EE69882A09A9017989D50BEA29 -:101040005064A4E30CEE11C0F02F16132E16168A6E -:10105000E78CE82A16128EE9DFC0AAEA7EAB01B15E -:10106000CF0BA8506583468837DBC0AE89991E78C0 -:101070009B022BCC012B161B29120E2B0A002916C2 -:101080001A7FC3077FC9027EAB01C0B165B49D8BD7 -:10109000352F0A002A0A007AC30564C3CB2F0A0140 -:1010A00065F4892B12162B1619005104C0C100CC0F -:1010B0001A2CCCFF2C16170CFC132C16182B121AFA -:1010C0002A121BDC50581974C0D0C0902E5CF42C2E -:1010D00012172812182F121B2A121A08FF010CAA25 -:1010E000018834074C0AAB8B2812192BC6162F86A1 -:1010F000082A86092E74102924672E70038975B179 -:10110000EA2A7403B09909490C659DB32B20672D19 -:10111000250265B3FA2B221E2C221D7BC901C0B00B -:1011200064BD9C2CB00728B000DA2006880A28820B -:101130004CC0D10B8000DBA065AFE763FD8189BAAD -:10114000B19965909788341CEE2598BA8F331EEEBE -:101150001E0F4F542FB42C8D2A8A320EDD020CAC98 -:10116000017DC9660A49516F92608A3375A65B2C6E -:10117000B0130AED510DCD010D0D410C0C417DC98F -:10118000492EB012B0EE65E3C6C0D08E378CB88A57 -:10119000368FB97CA3077AC9027EFB01C0D1CED9B4 -:1011A00088350AAD020E8E0878EB022DAC0189B7A6 -:1011B000DAC0AF9B79BB01B1CADCB0C0B07DA30778 -:1011C0007AD9027CEB01C0B164B161C09129246776 -:1011D000C020D10F00008ADAB1AA64A0C02C206719 -:1011E0002D250265C3111DEDF88A321EEDFD0DADF2 -:1011F000010EDD0C65D28A0A4E516FE20260028157 -:10120000C090292467090F4765F2F828221D7B89C1 -:10121000022B0A0064BCA82CB00728B000DA200614 -:10122000880A28824CC0D10B8000DBA065AFE76341 -:10123000FC8D00000CE9506492ED0CEF11C0802889 -:101240001611AFBF2F16198EF88BF7DAE08FF92B36 -:101250001610ABFB7FBB01B1EA0CA8506580D688A5 -:1012600037DCE0AF89991C789B022CEC012C161B13 -:1012700029120C2C0A0029161A7AE3077AE9027F50 -:10128000BB01C0C165C2A58B352C0A002A0A007AB1 -:10129000E30564E1CA2C0A0164CE0D60028E883435 -:1012A0001BEDCF98DA8F331EEDC80F4F542FD42C7F -:1012B0008C2A8A320ECC020BAB010CBB0C65BF0A28 -:1012C0000A49516E920263FF018A330AAB5064BE31 -:1012D000F92CD0130AEE510ECE010E0E410C0C412A -:1012E0000ECC0C65CEE42FD012B0FF65F26EC0B00C -:1012F0008E378CD88A362FD2097CA3077AC9027E12 -:10130000FB01C0B165BEC38835DBA0AE8E78EB01B2 -:10131000B1AB89D7DAC0AF9D79DB01B1CAC0C07B60 -:10132000A3077AB9027DEB01C0C165CE9DC09029AB -:101330002467C020D10F88378C3698140CE90C290B -:10134000161408F80C981D78FB07281214B088288A -:101350001614891D9F159B16C0F02B121429161AFE -:101360002B161B8B147AE30B7AE90688158E1678F8 -:10137000EB01C0F165F1BA29121A2F12118A352E2C -:10138000121B9A1AAFEE2F1210C0A0AF9F79FB016B -:10139000B1EE9F11881AC0F098107AE30A7EA90571 -:1013A0002A12017A8B01C0F164F0816001838936D1 -:1013B0008B3799170BE80C981F09C90C291615785B -:1013C000EB07281215B088281615D9C09A199E184F -:1013D0008A1F2E12152A161A2E161BDAC0C0E08C90 -:1013E000177F930B7FA90688188F1978FB01C0E13E -:1013F00065E13E29121A2F12138A352E121B9A1BF1 -:10140000AFEE2F1212C0A0AF9F79FB01B1EE9F1378 -:10141000881BC0F098127AE30A7EA9052A12037A83 -:101420008B01C0F165F10A2E12162E16192A121B15 -:10143000005104C0E100EE1AB0EE2E16170EFF1395 -:101440002F16180FCC01ACAA2F121A0EBC01ACFC3F -:101450007FCB01B1AA2A161B2C161A63FC5E000072 -:101460007FB30263FE3163FE2B7EB30263FC306305 -:10147000FC2A00006450C0DA20DBC0581648C020A7 -:10148000D10FC09163FD7A00C09163FA44DA20DB8A -:1014900070C0D12E0A80C09A2924682C7007581574 -:1014A00038D2A0D10F03470B18ED4FDB70A8287876 -:1014B00073022B7DF8D9B063FA6100002A2C74DB2B -:1014C00040580EB363FAE4000029221D2D25027B4B -:1014D0009901C0B0C9B62CB00728B000DA20068840 -:1014E0000A28824CC0D10B8000DBA065AFE7C0208A -:1014F000D10FC09163FBFF00022A025802440AA2E6 -:1015000002060000022A025802410AA20206000056 -:10151000DB70DA20C0D12E0A80C09E2924682C708E -:1015200007581517C020D10FC09463FBC9C096633C -:10153000FBC4C09663FBBF002A2C74DB30DC405B2D -:10154000FE11DBA0C2A02AB4002C200C63FF2700F0 -:101550008D358CB77DCB0263FDD263FC6D8F358EEC -:10156000D77FEB0263FDC563FC6000006C1004C014 -:1015700020D10F006C1004C020D10F006C10042B80 -:10158000221E28221DC0A0C0942924062A25027BE1 -:101590008901DBA0C9B913ED06DA2028B0002CB010 -:1015A0000703880A28824CC0D10B8000DBA065AFFE -:1015B000E7C020D10F0000006C10042C20062A2167 -:1015C0000268C80528CCF965812E0A094C6591048A -:1015D0008F30C1B80F8F147FB00528212365812774 -:1015E00016ECF529629E6F98026000F819ECF1295B -:1015F00092266890078A2009AA0C65A0E72A629DB6 -:1016000064A0E12B200C0CB911A6992D92866FD9FC -:10161000026000DB1DECE90DBD0A2DD2A368D007E6 -:101620008E200DEE0C65E0C7279285C0E06470BF88 -:101630001DECEE68434E1CECED8A2B0CAA029A704E -:1016400089200899110D99029971882A98748F320E -:101650009F75282104088811987718ECDE0CBF11BB -:10166000A6FF2DF285A8B82E84CF2DDC282DF68577 -:10167000C85A2A2C74DB40580E46D2A0D10FC02085 -:10168000D10F00000029CCF96490B12C206689317B -:10169000B1CC0C0C472C24666EC60260008509F89C -:1016A0005065807F1CECD38A2B0F08400B881008F4 -:1016B000AA020CAA029A7089200899110D99029920 -:1016C00071883398738C329C728A2A9A74893499FF -:1016D0007563FF7D00CC57DA20DB30DC4058151DE8 -:1016E000C020D10F00DA20C0B65815AC63FFE5006A -:1016F000DA205815AA63FFDC00DA20DB30DC40DD9D -:1017000050581638D2A0D10FC858DA20DB30581400 -:101710008A2A210265AFBDC09409A9022925026366 -:10172000FFB200002B21045814351DECAFC0E02E91 -:1017300024668F302B200C0F8F1463FF662921380D -:10174000C08879830263FF5B2C20662B2104B1CC17 -:101750000C0C472C24665814291DECA3C0E02E2441 -:10176000668F302B200C0F8F1463FF376C1004C072 -:10177000B7C0A116ECA015EC92D720D840B822C073 -:10178000400535029671957002A438040442C94B95 -:101790001AEC8519EC8629A67EC140D30F6D4A0547 -:1017A00000808800208C220A88A272D10FC05008C5 -:1017B000A53875B0E363FFD76C1006931394112915 -:1017C0002006655288C0716898052A9CF965A29820 -:1017D00016EC792921028A1309094C6590CD8AA05B -:1017E0000A6A512AACFD65A0C2CC5FDB30DA208CDE -:1017F000115814D8C0519A13C7BF9BA98E132EE25B -:101800000968E0602F629E1DEC6A6FF80260008438 -:101810002DD22668D0052F22007DF9782C629DC735 -:101820009064C0709C108A132B200C2AA0200CBD41 -:1018300011A6DD0A4F14BFA809880129D286AF88F6 -:10184000288C09798B591FEC5C0FBF0A2FF2A36813 -:10185000F0052822007F894729D285D490659075AC -:1018600060004300002B200C1FEC540CBD11A6DDC2 -:1018700029D2860FBF0A6E96102FF2A368F0048853 -:10188000207F890529D285659165DA20581543C9DD -:101890005C6001FF00DA20C0B658154060000C0003 -:1018A000C09063FFB50000DA2058153C6551E48D07 -:1018B000138C11DBD08DD0022A020D6D515813AD5F -:1018C0009A1364A1CEC75F8FA195A9C0510F0F478E -:1018D0009F1163FEFD00C091C0F12820062C2066F8 -:1018E000288CF9A7CC0C0C472C24666FC6098D13E5 -:1018F0008DD170DE02290A00099D02648159C9D385 -:101900008A102B21045813BD8A13C0B02B24662ED5 -:10191000A2092AA0200E28141CEC338D1315EC27E5 -:10192000C1700A773685562DDC28AC2C9C12DED08F -:10193000A8557CD3022EDDF8D3E0DA40055B02DC4B -:10194000305BFF8AD4A028200CB455C0D02B0A8865 -:101950002F0A800C8C11A6CC29C285AF3FAB9929E8 -:10196000C6851CEC1CDEF0AC882D84CF2812022921 -:10197000120378F3022EFDF8289020D3E007880C9C -:10198000C170080847289420087736657FAB891313 -:1019900013EC1A8990C0F47797491BEC18C1CA2838 -:1019A00021048513099E4006EE1187530488118592 -:1019B000520E88020C88029BA09FA18F2B9DA59898 -:1019C000A497A795A603FF029FA22C200C1EEC0152 -:1019D000AECE0CCC1106CC082BC2852DE4CF2BBC8F -:1019E000202BC6852A2C748B11580D69D2A0D10FDB -:1019F00028203DC0E07C877F2E24670E0A4765A023 -:101A00007B1AEBFF88201EEBED8F138EE48FF4081A -:101A100088110A88020F8F14AFEE1FEBFA98910F0E -:101A2000EE029E901EEBF9C0801AEBEA2CD285AA3A -:101A3000BAB8CC28A4CF2CD6852C21022F20720E28 -:101A4000CC02B1FF2F24722C2502C020D10F8713A6 -:101A5000877007074763FD6E282138C099798B028C -:101A600063FE9ADDF063FE9500DA20DB308C11DD39 -:101A70005058155CD2A0D10FC0E163FF7A8B138C54 -:101A800011DD50C0AA2E0A802A2468DA205813BC1F -:101A9000D2A0D10FC020D10F6C1006292102C0D0D6 -:101AA0007597102A32047FA70A8B357FBF052D2535 -:101AB000020DD902090C4C65C18216EBBE1EEBBCAF -:101AC00028629EC0FA78F30260018829E2266890B5 -:101AD000078A2009AA0C65A17A2A629DDFA064A169 -:101AE000772B200C0CBC11A6CC29C286C08C798324 -:101AF0000260015719EBB109B90A2992A36890074E -:101B0000882009880C65814327C2851CEBB364716A -:101B10003A8931098B140CBB016FB11D2C20669FD3 -:101B200010B1CC0C0C472C24666EC6026001400933 -:101B3000FF5065F13A8A102AAC188934C0C47F97E7 -:101B40003C18EBB31BEBB28F359C719B708B209DC7 -:101B50007408BB029B72C08298751BEBAE0F0840E5 -:101B60009B730F881198777FF70B2F2102284A006B -:101B700008FF022F2502C0B4600004000000C0B0BE -:101B80007E97048F362F25227D97048837282521BC -:101B90007C9736C0F1C0900AF9382F3C20090942E1 -:101BA00064908619EB8018EB8128967E00F08800FF -:101BB000A08C00F08800A08C00F08800A08C2A6225 -:101BC0009D2DE4A22AAC182A669D89307797388F1C -:101BD000338A3218EB8A07BE0B2C2104B4BB04CC29 -:101BE0001198E0C08498E1882B9DE59AE69FE71A5A -:101BF000EB82099F4006FF110FCC020A880298E28F -:101C0000C1FC0FCC022CE604C9B82C200C1EEB71D1 -:101C10000CCA11AECC06AA0829A2852DC4CF09B9D9 -:101C20000B29A685CF5CC020D10FC081C0900F8941 -:101C300038C08779880263FF7263FF6600CC57DA89 -:101C400020DB30DC405813C3C020D10FDA205814F9 -:101C50005363FFE8C0A063FE82DA20C0B658144F79 -:101C600063FFD900DB402A2C74580CC9D2A0D10FD5 -:101C70008A102B21045812E11EEB4EC0D02D246691 -:101C800063FEB1006C1006D62019EB491EEB4B2801 -:101C9000610217EB4808084C65805F8A300A6A5178 -:101CA00069A3572B729E6EB83F2A922668A0048CB7 -:101CB000607AC9342A729D2C4CFECAAB2B600CB6DC -:101CC0004F0CBD11A7DD28D2860EBE0A78FB269CDC -:101CD000112EE2A32C160068E0052F62007EF91594 -:101CE00022D285CF2560000D00DA60C0B658142BD3 -:101CF000C85A60010F00DA60581428655106DC40AC -:101D0000DB308D30DA600D6D5158129AD3A064A08B -:101D1000F384A1C05104044763FF6D00C0B02C6080 -:101D2000668931B1CC0C0C472C64666FC602709684 -:101D30000A2B61045812B1C0B02B64666550B42AF6 -:101D40003C10C0E7DC20C0D1C0F002DF380F0F42EA -:101D500064F09019EB1418EB1528967E8D106DDA4F -:101D60000500A08800C08CC0A089301DEB247797A7 -:101D70005388328C108F3302CE0BC02492E1226143 -:101D8000049DE00422118D6B9BE59FE798E61FEB15 -:101D90001A0998400688110822020FDD02C18D9DA4 -:101DA000E208220292E4B4C22E600C1FEB0A0CE897 -:101DB00011A7882C8285AFEE0C220B2BE4CF228654 -:101DC00085D2A0D10F28600CD2A08C1119EB020C87 -:101DD0008D11A988A7DD2ED2852B84CF0ECC0B2C9C -:101DE000D685D10FC0F00ADF387FE80263FF6C634D -:101DF000FF6000002A6C74C0B2DC20DD4058128FF6 -:101E0000C0B063FF63C020D10F0000006C10042C31 -:101E1000221D2A221EC049D320293006243468C03E -:101E2000407AC105DDA060000200C0D06E9738C0C6 -:101E30008F2E0A802B3014C0962934060EBB022E3A -:101E400031022B34147E8004243502DE407AC10E28 -:101E5000C8ABDBD0DA302C0A00580AE52E31020E6E -:101E60000F4CC8FEC020D10F6895F8283102080831 -:101E70004C658FEF1AEAD01CEACE2BA29EC09A7B4B -:101E80009B462BC22668B0048D307BD93B29A29D8E -:101E9000C0E3CB9394901BEAE02D31049B9608DDC0 -:101EA000110EDD029D979D9112EADDC0E524C4A2CA -:101EB0002E34062F310228A29D02FF02288C3028E2 -:101EC000A69D2F3502C020D10FDA30C0B65813B30B -:101ED000C020D10F6C1006292006689805289CF9AF -:101EE00065825D29210209094C659210CD51DB30D4 -:101EF000DA20044C02581317C051D3A0C7AF2A36BA -:101F00000AC0E019EAAD1DEAB31FEAAC8A3A16EA44 -:101F1000A9B1AC64C13528629E6F88026001F129C5 -:101F2000DC332992266890078B2009BB0C65B1E051 -:101F300027629DC08E6471D82B200C0CBC11A6CCDE -:101F400029C2867983026001D219EA9B09B90A295C -:101F500092A3971068900828220009880C6581BB1D -:101F600027C2856471B5292006299CF96491EC2C5F -:101F700020668931B1CC0C0C472C24666EC60260F9 -:101F800001A109F85065819B883689F4088C14AC4E -:101F9000991CEA8B0C99022C2104997019EAA1086A -:101FA00008479971892A09881008990218EA9E0839 -:101FB000990299722830132930120488100699105A -:101FC00008990228302C9A740C881008C8020988D5 -:101FD00002987389379975883898768A39C0819ABA -:101FE000771AEA918935987B99780989140A9902B8 -:101FF000997A8A30893277A73618EA808F33987CAD -:10200000C084987D882B2E76112976122F7613198D -:10201000EA7A0A9F4006FF1104CA110988020FAA32 -:1020200002987EC1F90FAA022A7610C0AA600001A8 -:10203000C0A6ADBF0CBC11A6CC29C2852EF4CF0919 -:10204000A90B29C685655107C020D10F2B200C0C88 -:10205000BC1106CC0828C28609B90A6F8902600142 -:102060002E2992A36890082A220009AA0C65A11FB4 -:102070002AC28564A11928203D08284064808C84E8 -:102080003504841464408485F574537F8436048455 -:1020900014644077745374293013C08C79886CC0F1 -:1020A000902924670908476580ED882089F48435E4 -:1020B0001FEA55048414A4940F440294A014EA5017 -:1020C00008881104880298A1843698A3048414A473 -:1020D000990F990299A219EA4CADB428C2852E44F1 -:1020E000CF288C1028C6852821022F20720988024B -:1020F000B2FF2F2472282502C020D10F00CC57DA5E -:1021000020DB30DC40581293C020D10FC09163FF18 -:102110008FDA20C0B658132163FFE100DA2058138C -:102120001F63FFD88A102B21045811B41DEA2A1FFF -:10213000EA232B200CC0E02E24668A3A63FE480076 -:1021400000DA20DB30DC40DD505813A6D2A0D10FDE -:102150002A2C74DB40580B8ED2A0D10F292138C015 -:102160008879830263FE202A12002C20662B21042A -:102170002CCC010C0C472C24665811A01DEA161F0C -:10218000EA0F2B200CC0E02E24668A3A63FDF8008B -:10219000DA2058130263FF64DA205BFF1CD2A0D15F -:1021A0000F0000006C10089515C061C1B0D9402A1D -:1021B000203DC0400BAA010A64382A2006291606D1 -:1021C00068A8052CACF965C33B1DE9FC6440052FEC -:1021D000120564F29C2621021EE9F806064C65628F -:1021E000E315E9F46440D98A352930039A140A9931 -:1021F0000C6490CC2C200C8B149C110CCC11A5CC15 -:102200009C122CC286B4BB7CB3026002D38F110E29 -:10221000FE0A2EE2A368E0098620D30F0E660C6545 -:1022200062BE88122882856482B6891464905EDA60 -:1022300080D9308C201EE9F21FE9F31DE9E08B14F0 -:102240008DD4D4B07FB718B88A293C10853608C61B -:10225000110E66029681058514A5D50F550295804D -:102260000418146D8927889608CB110888140EBBB2 -:1022700002A8D8299C200F88029BA198A088929B35 -:10228000A3088814A8D80F880298A22AAC1019E9CC -:10229000DEC0C08F141EE9CF86128D11286285AE74 -:1022A000DD08FF0B2CD4CF2821022F66858B352A21 -:1022B0002072098802ABAA2825022A2472C020D1E4 -:1022C0000F29529E18E9BB6F9802600208288226E7 -:1022D00068800829220008990C6591F92A529DC14D -:1022E000CA9A1364A1EF2B200C2620060CB811A566 -:1022F000882D82860EBE0A7DC3026002022EE2A3F2 -:1023000068E0082F22000EFF0C65F1F3288285DEBD -:10231000806481FF9810266CF96461FF2C20668828 -:1023200031B1CC0C0C472C24666EC6026001BC088F -:10233000FD5065D1B617E9BD19E9A21AE9A92C210A -:10234000048B2D2830102F211D0C88100BFB090C3D -:1023500088020A880209BB026441528910C04D9B61 -:1023600090979198928D35D9E064D06CD730DBD0BE -:10237000D8307FD713273C10BCE92632168C39960B -:10238000E69CE78A37B4389AE80B13146430492A7C -:10239000821686799A9696978C778A7D9C982B825E -:1023A000172C7C209A9A2A9C189B99867BB03BB864 -:1023B000896DB9218BC996A52692162AAC18B899B1 -:1023C0009BA196A08BC786CD9BA22B921596A49B12 -:1023D000A386CB2CCC2026A605C0346BD4200D3B85 -:1023E0000C0DD8090E880A7FB705C0909988BC8863 -:1023F000C0900B1A126DAA069988998B288C18C068 -:10240000D01BE98C1CE98B16E981B1FF2A211C2322 -:10241000E6130F0F4F26E6122F251D7FA906C0F0E9 -:10242000C08028251D05F6111AE97A8F202BE615A4 -:102430002CE6162DE61726E6180AFA022AE61429D3 -:102440002006299CF96490FF29200C8D15C0801A64 -:10245000E9610C9C11AA99A5CCDA202BC28528949D -:10246000CF0B4B0B2BC685C0B08C1658118AD2A04F -:10247000D10F8A356FA548D8308BD56DA90C8A86C7 -:102480000A8A14CBA97AB337288C10C08028246715 -:10249000080B4765B112DA20DB302C12065811AD5B -:1024A000D3A0C0C1C0D02DA4039C1563FD268636E1 -:1024B00064610C8910C04D9B909791989263FEA423 -:1024C000C08163FFC78A15CCA7DA20DB308C165891 -:1024D00011A1C020D10FDA20C0B658123063FFE43A -:1024E00000DA208B1158122D63FFD9009E178A1332 -:1024F0002B21045810C28E17C0B02B246663FE3403 -:10250000C08063FE09DA20DB308C16DD505812B52E -:10251000D2A0D10FDA2058122163FFA82D2138C094 -:10252000C87DC30263FE0D8A132B21042C206698FC -:1025300017B1CC0C0C472C24665810B08E17C0D0A5 -:102540002D246663FDEE0000262138B06606064F96 -:10255000262538656EF128206A7F870508294164A1 -:1025600090A5C0D01BE92619E93426200723E61BD5 -:10257000B16609FA022BE61A28200A2DE61D2AE682 -:102580001E09880228E61C882606064728E6202B16 -:10259000220826E53E2BE6212D24072C20062A20A2 -:1025A0006468C347B44463FE9EDB30DA208D15C0F7 -:1025B000CE2E0A802C24688C165810F1D2A0D10F90 -:1025C0008E102A321616E8FD0A2A1486662BE612A9 -:1025D00097E127E61328E614AA6609660296E02E1C -:1025E000EC4869ED50C14663FD7A000064AFB41950 -:1025F000E8F328201689920A880C00910400881AB2 -:10260000A8B8982963FF9C002B21046EB81E2C20CB -:1026100066B8CC0C0C472C2466C9C09E178A135888 -:1026200010778E17C0348F20C0D02D2466C0682646 -:10263000240663FF2C008D35C08064D04AD9E0DCCD -:1026400030DBE0DF301AE8FDB188B4FF17E8FD8623 -:10265000C9249DFF8DC82CCC102D46300767012D55 -:1026600046320A66011DE8F7264631AD6D2D463328 -:1026700026F21597B796B684C3BCBB94B58D3529A1 -:102680009C107D83C22F211DC14663FD4B000000BD -:102690006C1006292006289CF86582BF2921022B90 -:1026A000200C09094C6590E116E8C30CBA11A6AAE2 -:1026B0002DA2862C0A127DC30260028C19E8BF0984 -:1026C000B90A2992A36890078C2009CC0C65C278BE -:1026D00029A2856492722D629E1AE8B56FD80260B5 -:1026E000026E2AA22629160168A0082B22000ABB26 -:1026F0000C65B25C29629DC18C6492542A21200A27 -:10270000806099102C203CC7EF000F3E010B3EB1BA -:10271000BD0FDB390BBB098F260DBD112DDC1C0D48 -:102720000D410EDD038E27B1DD0D0D410FEE0C0DB9 -:10273000BB0B2BBC1C0BB7027EC71C2C21257BCBF3 -:10274000162D1AFC0CBA0C0DA16000093E01073EC3 -:10275000B1780987390B770A77EB0260020A2C21DE -:1027600023282121B1CC0C0C4F2C25237C8B29B0A4 -:10277000CD2D2523C855DA20DB3058106F292102D2 -:10278000CC96C0E80E9E022E2502CC57DA20DB3014 -:10279000DC405810F0C020D10F2C20668931B1CC1C -:1027A0000C0C472C24666EC6026001D309FD5065EF -:1027B000D1CD2F0A012E301129221464E0112822D4 -:1027C0001B090C4400C10400FA1A0A880228261BBF -:1027D0002E3010C0A0C0B0941295131CE878883039 -:1027E0002CC022088D14778704C0F10CFA38C04140 -:1027F000C0F225203CC0840858010F5F010F4B3800 -:1028000005354007BB10C0F0084F3808FF100FBB5C -:102810000228ECFEC0F0084F38842B0BA8100AFFEA -:10282000102A21200F88020B880208440218E8862B -:102830008F110844022821250A2A14082814048824 -:10284000110A88022A210494F08B2004E41008BBAA -:102850001104BB02C04A04BB029BF1842A08AB11DD -:102860000BEB0294F40A54110B44020555100D1B96 -:102870004094F707BB100B5502085502C08195F62E -:102880008433C05094F3B1948B3295F898F99BF24D -:10289000C080C1BC24261499FA9BF598FB85389515 -:1028A000FC843A94FD8B3B9BFE883998FF85352547 -:1028B000F6108436851324F6118B3784122BF6120A -:1028C000C0B064C07E89307797438D3288332E3014 -:1028D000108F111CE84A0999400699112CF614C072 -:1028E000C42CF6158C2B2DF61A28F61B2BF6190482 -:1028F000A81109880208EE0219E840C18008EE021A -:1029000009C90229F6162EF618C09E600001C09A69 -:102910002F200C18E8300CFE11A8FFA6EE2DE28542 -:102920002BF4CF0D9D0B2DE685C87F8A268929A71C -:10293000AA9A260A990C090948292525655050C0EC -:1029400020D10F00C09A63FFC6DA2058111463FE2D -:1029500038DA20C0B658111163FE2E0068973C2B60 -:102960009CFD64BE24C020D10FDA20DB705810CD4E -:10297000C0C0C0D10ADA390ADC3865CDE063FE098F -:102980008A102B2104580F9DC0B02B246663FE21B2 -:10299000DB402A2C7458097ED2A0D10FDA20580FC0 -:1029A000A263FCF76C1004C020D10F006C10042946 -:1029B0000A801EE8261FE8261CE7FF0C2B11ACBB83 -:1029C0002C2CFC2DB2850FCC029ED19CD0C051C0C6 -:1029D0007013E82214E82118E81F2AB285A82804F9 -:1029E000240A234691A986B8AA2AB685A9882784ED -:1029F0009F25649FD10F00006C100AD6302830103C -:102A0000292006288CF964829B68980B2A9CF9651A -:102A1000A1B2022A02580F8489371BE7E8C89164E3 -:102A2000520E2A21020A0C4C65C2588D3019E7E17A -:102A300074D7052E212365E29E2F929E1AE7DD6F43 -:102A4000F8026002532AA22668A0082C22000ACCB1 -:102A50000C65C2442A929D64A23E9A151FE7D78D49 -:102A600067C1E6C8DD2B620618E7D564B00528808B -:102A7000217B8B432B200C18E7CF0CBC11A8CC2951 -:102A8000C28679EB460FBE0A2EE2A368E0052F222C -:102A9000007EF9372CC2859C1864C2332B212F8706 -:102AA000660B7B360B790C6F9D266ED2462C203D33 -:102AB0007BC740CE5560001E2A200CC1B28C205826 -:102AC00010F79A1864A2458D6763FFCFC0C063FFFB -:102AD000C5D7B063FFD300C0E06000022E60030ED4 -:102AE000DB0C6EB20EDC700CEA11AA6A2AAC20581C -:102AF0000199D7A0DA20DB70C1C82D212058109190 -:102B00008C268B279A160CBB0C7AB3348F188963EA -:102B100099F3886298F28E659EF82D60108A189D50 -:102B20001768D729C0D09DA92C22182B22139CAB43 -:102B30009BAA97A58E667E7302600097CF586000AF -:102B40001FDA208B1658105765A13863FFBDC0816E -:102B5000C0908F18C0A29AF999FB98FA97F563FF75 -:102B6000D2DB30DA20DC40580FFBC051D6A0C0C009 -:102B70002BA0102CA4039B172C1208022A02066B10 -:102B800002DF702D60038E179D149E100CDD11C0A6 -:102B9000E0AD6D2DDC205801188C148B16ACAC2CDC -:102BA00064038A268929ABAA0A990C9A26886609A1 -:102BB000094829252507880C98662F2218A7FF2F7A -:102BC000261863FE96DA20DB30DC40DD5058110514 -:102BD000D2A0D10FC0302C20668961B1CC0C0C473B -:102BE0002C24666EC6026000D2C03009FD5065D04C -:102BF000CA8E6764E069647066DB608C18DF70DA27 -:102C0000202D60038E170CDD119E10AD6D2DDC2084 -:102C10001EE78D5800F9232618DA208B16DC402F8A -:102C20002213DD50B1FF2F2613580F9AD2A0D10FD7 -:102C30000028203D084840658DE76F953EDA308DCD -:102C4000B56D990C8CA80C8C14CACF7CD32D2AACF2 -:102C500010C090292467090D4764DDC5600092000B -:102C60002C1208066B022D6C20077F028E17DA20CB -:102C70009E101EE77458007D63FF9A00C09163FFA9 -:102C8000D1000000655081DA20DB60DC40580FB1D4 -:102C9000C020C0F02FA403D10FDA20C0B658103FD7 -:102CA00063FFE000006F950263FD6CDA20DB30DC2F -:102CB00040DD50C4E0580F32D2A0D10F8A152B212D -:102CC00004580ECE232466286010981763FF210055 -:102CD000DA2058103263FFABC858DB30DA20580FC7 -:102CE000162A210265AF9CC09409A9022925026316 -:102CF000FF91DB30DC40DD50C0A32E0A802A24681F -:102D0000DA20580F1FD2A0D10FC020D10FDA202B0C -:102D1000200C58104763FF6B6C1004282006C0621B -:102D2000288CF8658125C050C7DF2B221BC0E12A03 -:102D3000206B29212300A104B099292523B1AA00E1 -:102D4000EC1A0BC4010A0A442A246B04E4390DCCA2 -:102D5000030CBB012B261B64406929200C1BE715C3 -:102D60000C9A110BAA082FA2861BE7136FF90260B9 -:102D700000B60B9B0A2BB2A368B0082C22000BCC28 -:102D80000C65C0A42BA2851DE73664B09B8C2B2458 -:102D900021040DCC029CB08820C0C50888110C8885 -:102DA0000298B1882A08441198B48F3494B79FB51B -:102DB000C0401EE7082DA2850E9E0825E4CF2DDC1D -:102DC000282DA68529210209094C68941A689820A3 -:102DD000C9402A210265A00B2A221E2B221D7AB18E -:102DE0000265A079C020D10F2C212365CFDE6000C1 -:102DF000082E21212D21237EDBD52B221E2F221DE3 -:102E00002525027BF901C0B064BFC413E6E92CB0EC -:102E10000728B000DA2003880A28824CC0D10B8032 -:102E200000DBA065AFE763FFA62A2C74C0B02C0AB4 -:102E300002580E081CE70C9CA08B2008BB1106BB97 -:102E4000029BA1893499A263FF790000262468DAE5 -:102E500020DB30DC40DD50581063D2A0D10FDA20E7 -:102E60002B200C580FCEC020D10F00006C1006078D -:102E70003D14C080DC30DB40DA20C047C02123BCD9 -:102E800030032838080842774001B1DD64815A1EBA -:102E9000E6C519E6C629E67ED30F6DDA050050882F -:102EA00000308CC0E0C02025A03C14E6C4B6D38F0F -:102EB000C0C0D00F87142440220F8940941077F7A8 -:102EC00004C081048238C0F10B2810C044C0220421 -:102ED000540104FD3802520102FE3808DD10821C44 -:102EE00007EE100E6E020EDD02242CFEC0E004FE82 -:102EF000380AEE100E88020D88028DAB1EE6B4086B -:102F0000D8020E880298B0C0E80428100E5E018432 -:102F1000A025A125084411084402052514045511D3 -:102F2000043402C0810E8E3994B18FAA84109FB4EC -:102F300075660C26A11FC0F2062614600009000069 -:102F400026A120C0F20626140565020F7701078727 -:102F50003905E61007781008660206550295B62571 -:102F6000A1040AE61108581108280208660296B75B -:102F7000C060644056649053067E11C0F489C288D4 -:102F8000C30B340B96459847994618E69B9F41041E -:102F900059110E99021FE699020E4708D80298426D -:102FA0000E99029F40C1E00E990299442FA00CB4E3 -:102FB000380CF91114E6881EE67FA4FFAE992E9214 -:102FC0008526F4CF0E880B289685D10F2BA00C1FD9 -:102FD000E6791CE6800CBE11ACBBAFEE2DE2852677 -:102FE000B4CF0D3D0B2DE685D10FC0800528387874 -:102FF000480263FEA263FE966C1006C0C06570F1C5 -:103000008830C030088714778712C0B0C0A619E690 -:103010006B299022C030CC97C031600003C0B0C093 -:10302000A6C0E0C091C0D4C08225203C0B3F1097C1 -:1030300012831CC0700858010D5D01089738C080CC -:103040000B9838077710048810086802087702C0C8 -:10305000800D98382D3CFE0888100D9E388D2B0A67 -:10306000EE1008EE0207EE020CB8100FDD02053B71 -:10307000400EDD029D408920043D100899110D99F4 -:10308000022D210409A90208DD119941872A05B9F9 -:10309000100D3D020ABB110DBB02087702974428B0 -:1030A00021258712082814048811071E4007EE10F6 -:1030B0000E990275660926211F0626146000060077 -:1030C0002621200626140868029B47098802984694 -:1030D00029200CD2C0C0800C9E111BE63E1FE63595 -:1030E000AB99AFEE2DE2852894CF0DAD0B2DE68583 -:1030F000D10FDD40C0A6C0B08E51CAE0B2AAB1BBAC -:103100002DDC108F500E7836981008770C9FD898C9 -:10311000D989538F52991199DB9FDA7E8309B1CCFB -:10312000255C10C97763FFCF88108D1108E70C97D5 -:1031300051AD8DD7F078DB01B1F79D5397528830B0 -:10314000C030088714088840648ED565BEC963FE08 -:10315000BC0000006C1004D720B03A8820C0308238 -:1031600021CAA0742B1E2972046D080FC980C99151 -:103170008575B133A2527A3B0B742B0863FFE900CB -:10318000649FECD10FD240D10F0000006C100AD622 -:10319000302E3027D950DA4015E6092430269A150A -:1031A00029160464E0026493732920062A9CF865BA -:1031B000A3CE2A2102270A040A0B4C65B3978C3050 -:1031C00074C7052D212365D4A0C0A62B0A032C2289 -:1031D00000580F0B64A3B917E5F78E389A1664E30D -:1031E000BA2F6027285021C9F37E8311C2B08C20EA -:1031F0002A200C580F2AD7A0CDA16004A200C2B08B -:103200008C202A200C580EFED7A064A4862F212ED5 -:103210008B680FBF360FB90C6F9D54296027D5B04E -:103220006E920528203D7B8F4CDA20DB50C1C42DE7 -:10323000211F580EC48B269A189A1989272AAC3850 -:103240000B990C7A93538963C08099738F62987835 -:103250009F728E659E798D679D7B8C6695759C7A35 -:103260008E687E53026000B18B1465B050600038E8 -:10327000DBF063FFA5008A14C9A92E60030E9B0C26 -:103280006EB2A5DC500CEA11AA6A2AAC285BFFB129 -:10329000D5A063FF93C0E063FFE2DA208B18580EDD -:1032A0008165A2B163FF9E0000DA20DB308C1558E7 -:1032B0000E29D6A0C0C0C0D12D16042CA403DC70EA -:1032C000DA20DB60DF502D6003C0E09E109D171EEA -:1032D000E5D20CDD110D6D082DDC285BFF478E66F5 -:1032E0008F678817AF5FA8A828640375FB01B1EE4C -:1032F0008A189E669F6789268829AA9909880C9949 -:10330000268E6808084805EE0C28252515E5AC9E94 -:103310006865EECC63FEE6000000C9432F21232B35 -:1033200021212FFC010F0F4F2F25237FBB026003AC -:10333000142C20668961B1CC0C0C472C24666EC617 -:103340000260022809FD5065D22264E1B62E602792 -:1033500064E1B0DC70DF50DA20DB601EE5C32D6075 -:1033600003C08098100CDD11AD6D2DDC285BFF22B1 -:10337000644181C0442B0A008C202A200C580EA0E6 -:103380000AA70265A00FC0B02C22002A200C580EFC -:103390009CD7A064AFEFDA20C1BCC1C82D21208F1B -:1033A000188E268929AFEE9E260E990C0909482908 -:1033B0002525580E64C090C050C0C288609A191E5E -:1033C000E57FC0A12EE022088F14778704C0810E0C -:1033D0008938C0800B93102D203C2921200CDC0162 -:1033E00004DB010929140BA8380CA5380D3D401C3D -:1033F000E5968B2B088810075510085502053302F7 -:103400002821250F154003BB020CBB0207551005F0 -:10341000D3100828140ADD11048811098802053325 -:10342000022921040833029B70C0808A201BE58F8B -:1034300008AA110BAA029A71C0A1852A93769574E5 -:1034400008931103DD020ADD029D778C63C1DC9CC9 -:10345000738B6298789A799B72232214C0C0B1351D -:103460002526149C7B9D75937A2B621A9B7C2A627D -:103470001C9A7D28621D987E25621B957F2362170A -:103480002376102D62182D76112C62192C76126479 -:10349000E0B98E6077E73DC0FE13E5571DE558C1E2 -:1034A000818A628B630495110E9C4006CC110C55E9 -:1034B00002247615085502C0802D76148D2B2B76AC -:1034C0001B2A761A28761925761803DD022D761622 -:1034D0006000030000C0FA2E200C19E53E18E53507 -:1034E000A9E90CEE11A8EEC0802DE2852894CF0D3D -:1034F000FD0B2DE685DA208B198C158D14580D6582 -:10350000D2A0D10FDC70DF50DB602D6C28C0A01E74 -:10351000E5569A10DA205BFE5563FE53002B203DE2 -:103520000B4B4065BC826FE527DA308F556DE90C97 -:103530008EAA0E8E14C9E87EF3162AAC10C090290C -:103540002467090F4764FC6060015F00C0FA63FFF5 -:1035500085C09163FFE88814658168DA20DB608CA0 -:1035600015580D7CC020C09029A403D10F8A162BBA -:103570002104580CA2C0A02A24668E6863FDCA00EC -:10358000002B9CF965B0FDDA20580CA763FC2200E3 -:1035900000DA20C0B6580E0163FFBA002B200C0CD5 -:1035A000BE11A7EE2DE286C1C27DC30260011819CB -:1035B000E50209B90A2992A36890082A220009AAFB -:1035C0000C65A10326E2856460FD2C20668931B17B -:1035D000CC0C0C472C24666FC60270960C8A162BF6 -:1035E0002104580C86C0D02D24668E3077E74D1C00 -:1035F000E5021BE5028F328833C0A42D21040E9909 -:103600004006991104DD1109DD029A61C19009DDBE -:10361000029B60C0908B2B9D649F66986799650C98 -:10362000BB029B6228200C1AE4EBAA8A0C8811A723 -:10363000882F828529A4CF2FFC202F86858A1465A8 -:10364000A0A6C020D10FB0FC8B142C2523C8B70234 -:103650002A02066B02580CB82A210265AEF7C0D8C0 -:103660000DAD022D250263FEEC008E14C8E8DA20B1 -:10367000DB30580CB12A210265AEDA07AF022F25E4 -:103680000263FED100DA20DB308C158D14580E5504 -:10369000D2A0D10FDA202B200C580DC063FEB6004B -:1036A000DA202B200C580DE263FEAADA20DB308CE6 -:1036B000152D12042E0A80280A00282468580CB000 -:1036C00063FAE500C020D10FDA20580DB48914CD7B -:1036D00092DA20DB308C15580D1FDBA0C020C0A073 -:1036E0002AB403D10FC020D10F2A2C748B15580691 -:1036F00028D2A0D10F0000006C100C2821029410D9 -:1037000008084C6583621FE4AB29F29E6F98026043 -:1037100003661DE4A729D2266890082A220009AA78 -:103720000C65A3542CF29D64C34E2B200C0CB611D7 -:10373000AF66286286C1EC78E30260034619E49E16 -:1037400009B90A2992A36890078A2009AA0C65A3DF -:103750003224628564432CC0E12A3109C0702724D9 -:103760006689359A11992A88369912982B89379843 -:1037700013992C883899140858149815982D89395C -:103780002A25042E251D29251C283028C0922824EE -:103790003C2A302908084798160989012A243D2A1D -:1037A000311599170A094109A90C299CEC29251FF3 -:1037B0007E87192D2A000DA06000083E010A3EB147 -:1037C000AD08DA390EAA110A990C29251F2A211FE2 -:1037D00018E4A80A8160C1D0941A951B01083E0024 -:1037E000053EB184054839843C259CFC0D8836296A -:1037F000201408AA1C8D3D2726182E26132E2614C9 -:103800002E261527261B2E246B27246727246808BD -:10381000581C0909432924142932112A252E282548 -:103820002F27252427252527252C27252325252037 -:103830002425212D2522841A2D211C851B6FD202BF -:10384000600209C0A099186D080AB1AA00A104007D -:10385000E91A7D9B0263FFEE8918C080C0E1C07049 -:10386000C0D29B1D951B961C9C1E16E4722C203DFD -:1038700015E4820C0B400DCC010BE7381DE4640A03 -:1038800077100CE8380B8810C0C49C410877029D63 -:1038900040B0A80988118B209C499D48954B9643C0 -:1038A000087702861418E47315E45A08770205BBFA -:1038B000029B4A9B4297468812871108DA149A4E57 -:1038C0000D88100D77110877021AE44E06D8140DF2 -:1038D0006610087702974FC78F984D984C98458788 -:1038E0001598440715140D55110A5502954715E40E -:1038F000638A262D46102D46182D46202C46112C65 -:1039000046192C46212B46122B461A2846142846C7 -:10391000152B462288162546242546268B170A0C89 -:1039200048090D4885130EDD1105CC110839400BEF -:10393000EB390299101EE4520DCC020D5511082DE1 -:10394000400655022E461316E41D0FDD11254616BE -:10395000080840851B0188100DBB0286671DE449DD -:103960000988020CBB0219E4191CE4472B46172DE9 -:10397000461BA7661BE446C0702C461C0988028CB7 -:103980001E28461E2B4623C0908B1D29461D294606 -:103990001F18E43F2946272846252931162E2006E0 -:1039A00029246A243117962D242538861CCCE1273A -:1039B0002407C0D7090E4064E0829A29092841648F -:1039C000809164409B2D2406C098094936280AA09E -:1039D00024628501C404A84428210424668508883B -:1039E000118E3F8A3E2D32100EA41800C4040EAE74 -:1039F0001800EE110ACA530EDD02C0E30E880298C9 -:103A0000C11EE42409084E9EC08E2094C398C59D13 -:103A1000C418E3F01DE42105EE110EAA020DAA025E -:103A2000A8B82784CF9AC21EE3E224F29D27E4A21D -:103A3000244C1824F69D655052C020D10F2D240629 -:103A4000C0A0C09809493604A93863FF7FC0A063AD -:103A5000FE070000654F6DC098C0A82A240663FFCA -:103A60006B2D2406C09063FF63CC57DA20DB308CCB -:103A700010580C38C020D10F00DA20C0B6580CC73F -:103A800063FFE500DA20580CC563FFDC2A2C748B39 -:103A90001058053FD2A0D10F6C10062820068A339B -:103AA0006F8202600161C05013E3C229210216E354 -:103AB000C1699204252502D9502C20159A2814E3B7 -:103AC000BF8F2627200B0AFE0C0477092B711C647C -:103AD000E1398E428D436FBC0260016F00E104B09A -:103AE000C800881A08A80808D80298272B2006685A -:103AF000B32ECE972B221E2C221D0111027BC90151 -:103B0000C0B064B0172CB00728B000DA2003880AD0 -:103B100028824CC0D10B8000DBA065AFE7C020D16C -:103B20000F2D206464DFCA8B29C0F10BAB0C66BF7C -:103B3000C02B200C0CBC11A6CC28C2862E0A0878FB -:103B4000EB611EE39D0EBE0A2EE2A368E00528226B -:103B5000007E894F29C2851EE3A96490461FE3B603 -:103B60009E90C084989128200A95930F880298927D -:103B70008E200FEE029E942F200788262F950A98FC -:103B8000969A972E200625240768E3432921022AC6 -:103B9000C2851DE3902AAC20ADBD25D4CF2AC685B1 -:103BA00063FF4E002E2065CBEDC082282465C9F648 -:103BB00005E4310002002A62821BE3982941020BCE -:103BC000AA022A668209E43129210263FF23000048 -:103BD00064DFB88F422E201600F1040DEE0C00EECB -:103BE0001AAEAE9E2963FFA38A202B3221B1AA9A76 -:103BF000B0293221283223B4992936217989A92B79 -:103C000032222B362163FFA0C020D10F9F2725240D -:103C100015ACB828751C2B2006C0C12EBCFE64E074 -:103C2000AB68B7772DBCFD65DEC72D2064C0F0649E -:103C3000D0868E290EAE0C66E089C0F128205A2865 -:103C40008CFE08CF3865FEE863FF580000E004935F -:103C500010C0810AF30C038339C78F08D80308A862 -:103C60000108F80C080819A83303C80CA8B828756F -:103C70001C030B472B24158310CBB700E104B0BC09 -:103C800000CC1AACAC0CDC029C27659E5EC0B20B6B -:103C9000990209094F29250263FE50002D206A0D63 -:103CA0002D4165DF7EDA20C0B0580C8F64AF18C09C -:103CB000F163FEEF9F2763FFD02E221F65EE326374 -:103CC000FF79000028221F658E2763FF6E252406DA -:103CD00029210263FE1B00006C10066571332B4C1A -:103CE00018C0C7293C18C0A1C08009A838080842DC -:103CF0006481101CE32C1AE32D2AC67E2A5CFDD3B6 -:103D00000F6DAA0500B08800908C8940C0A009887A -:103D1000471FE355080B47094C50090D5304DD10AC -:103D2000B4CC04CC100D5D029D310CBB029B3088DD -:103D3000438E2098350FEE029E328D26D850A6DD98 -:103D40009D268E40C0900E5E5064E0971CE33B1EA3 -:103D5000E32B038B0BC0F49FB19EB02D200A99B3C7 -:103D60000CDD029DB28F200CFF029FB48E262D2009 -:103D7000079EB68C282DB50A9CB72924072F20064C -:103D80002B206469F339CBB61DE30D2320168DD2A9 -:103D90000B330C00D10400331AB48DA3C393292232 -:103DA000200C13E30C1FE3030C2E11AFEEA322290A -:103DB00024CF2FE285D2A00FDD0B2DE685D10F0099 -:103DC0002E200CB48C0CEB111FE3031DE2FAAFEEB6 -:103DD000ADBB22B28529E4CF02C20B22B685D2A0A8 -:103DE000D10F00002E200C1CE2F31FE2FA0CEB11A5 -:103DF000AFEEACBB22B28529E4CF02820B22B6859E -:103E0000D2A0D10FC0D00BAD387DC80263FEEC63E9 -:103E1000FEE08E40272C747BEE12DA70C0B32C3C8F -:103E200018DD50580A868940C08063FEE3066E02A2 -:103E3000022A02DB30DC40DD505800049A10DB50CF -:103E4000DA70580453881063FEF700006C10069275 -:103E5000121EE2E48C40AE2D0C8C472E3C1804CA96 -:103E60000BD9A07DA30229ADF875C302600084C000 -:103E7000B0C023C0A09D106D0844B89F0EB80A8D35 -:103E8000900EB70BB8770D6D36ADAA9D800D660C00 -:103E9000D8F000808800708C879068B124B22277B7 -:103EA000D3278891C0D0CB879890279C100070882A -:103EB00000F08C9D91CB6FC08108BB0375CB36633E -:103EC000FFB4B1222EEC1863FFD485920D770C86D7 -:103ED000939790A6D67D6B01B1559693959260000D -:103EE00016B3CC2D9C188810D9D078D3C729DDF80B -:103EF00063FFC100C0238A421BE2E900CD322D449A -:103F0000029B3092318942854379A1051EE2E50E7C -:103F1000550187121BE2D5897095350B99029932AC -:103F200088420A880C98428676A6A696768F44AF79 -:103F3000AF9F44D10F0000006C10089311D6308859 -:103F400030C0910863510808470598389812282115 -:103F500002293CFD08084C6581656591628A630A07 -:103F60002B5065B18B0A6F142E0AFF7CA60A2C20F9 -:103F70005ACCC42D0A022D245A7FE0026002158912 -:103F80002888261FE2C809880C65820F2E200B0F97 -:103F9000EE0B2DE0FE2EE0FF08DD110EDD021EE22D -:103FA000C2AEDD1EE2C21CE2C20EDD010DCC37C185 -:103FB00080084837B88DB488981089601AE2807BF1 -:103FC00096218B622AA0219C147BA3179D132A2083 -:103FD0000C8B108C20580BB18C148D13DBA0CEAC45 -:103FE0006001C4002E200C1BE2730CEA110BAA081E -:103FF0002BA2861FE2717BDB3B0FEF0A2FF2A36837 -:10400000F0052822007F892C2BA28564B0AA876244 -:104010008826DE700C7936097A0C6FAD1C8F279BD1 -:104020001508FF0C77F3197E7B729D139C149B156A -:10403000CF56600025C0B063FFD0D79063FFDD008E -:10404000009D139C14DA20DB70580B168B158C1412 -:104050008D1365A06A8E6263FFCC00DA208B11DCC1 -:1040600040580ABCD6A08B15C051DE70DA20DC6047 -:10407000DD405BFF768D138C14D9A02E200C1BE243 -:104080004D1FE2540CEA11AFEFC0E0ABAA2BA285A2 -:104090002EF4CF0B990B29A68563FF1D00DA20DCD7 -:1040A00060DD40DE708912282007DF50A9882824AF -:1040B000075BFF09D2A0D10F00DBE0DA20580B37F5 -:1040C0006550EF2A20140A3A4065A0EBDB60DC4023 -:1040D000DD30022A025809A7D6A064A0D584A183A6 -:1040E000A00404470305479512036351C05163FEC2 -:1040F0005C2C2006D30F28CCFD6480A568C704C0C3 -:10410000932924062C2006C0B18D641FE22C9D2724 -:104110009D289D298FF29D2600F10400BB1A00F016 -:1041200004B0BE0EDD01C0F0ADBB8D652F24070DC0 -:104130000E5E01EE11AEBB2E0AFEB0BB0B0B190ECC -:10414000BB36C0E20B0B470EBB372B241618E224FC -:104150000A09450D0B422B240B29240AB4BE2E2438 -:104160000C7D88572920162FCCFDB09D0A5C520D7E -:10417000CC362C246465FDEC0C0C4764CDE618E2CB -:104180000F8E2888820C9F0C00810400FF1AAFEE6E -:104190009E2963FDCF1CE23E63FE13001CE23563E3 -:1041A000FE0C8D6563FFA500DA202B200C580B2038 -:1041B000645F0FC020D10F00C020D10FC09329240D -:1041C00016C09363FFA000006C1004C06017E1F8F4 -:1041D0001DE1FBC3812931012A300829240A78A175 -:1041E00008C3B27BA172D260D10FC0C16550512605 -:1041F00025022AD0202F200B290AFB2B20142E2049 -:104200001526241509BB010DFF0928F11C2B2414C8 -:10421000A8EE2EF51C64A0A92B221E28221D011138 -:10422000027B8901DB6064B0172CB00728B000DA8C -:104230002007880A28824CC0D10B8000DBA065AF24 -:10424000E7DB30DC40DD50DA205800DE29210209AE -:104250000B4CCAB2D2A0D10F00CC5A2C30087BC173 -:10426000372ED02064E02D022A02033B02DC40DD21 -:10427000505800D4D2A0D10F2B2014B0BB2B241443 -:104280000B0F4164F0797CB7CAC0C10C9C022C258D -:1042900002D2A0D10FC020D10F2E200669E2C12684 -:1042A00024062B221E2F221D29200B2820150D99B4 -:1042B000092A911C262415AA8828951C7BF149609F -:1042C0000048B0BB2B24140B0A4164A0627CB702E7 -:1042D0002C25022B221E2C221DD30F7BC901C0B01E -:1042E000C9B62CB00728B000DA2007880A28824C0B -:1042F000C0D10B8000DBA065AFE7C020D10F00006C -:10430000262406D2A0D10F0000DB601DE1AC64BF03 -:104310004F2CB00728B000DA2007880A28824CC04A -:10432000D10B8000DBA065AFE71DE1A463FF310086 -:1043300026240663FF9C00006C1004282006260A31 -:10434000046F856364502A2920147D9724022A0271 -:10435000DB30DC40DD50580019292102090A4CC825 -:10436000A2C020D10FC0B10B9B022B2502C020D1CF -:104370000F00022A02033B022C0A015800D1C9AAED -:10438000DA20DB30DC405809F329A011D3A07E9756 -:10439000082C0AFD0C9C012CA411C0512D201406E0 -:1043A000DD022D241463FFA4DA20DB30DC40DD5075 -:1043B000C0E0580973D2A0D10F0000006C1006169F -:1043C000E17D1CE17D655157C0E117E179282102AB -:1043D0002D220008084C6580932B32000B6951296F -:1043E0009CFD6590872A629E6EA84C2A722668A062 -:1043F000027AD9432A629DCBAD7CBE502B200C0C97 -:10440000BD11A6DD28D2862F4C0478FB160CBF0AFE -:104410002FF2A368F0052822007F89072DD285D3CB -:104420000F65D0742A210419E1A3D30F7A9B2EDAE9 -:104430002058086E600035002D21041BE19E7DBBD5 -:1044400024DA20C0B6580869CA546001030B2B5007 -:104450002B240BB4BB0B0B472B240C63FFA0DA20DF -:10446000580A4E600006DA20C0B6580A4C6550E083 -:10447000DC40DB302D3200022A020D6D515808BDA0 -:104480001CE14ED3A064A0C8C05184A18EA0040436 -:10449000470E0E4763FF3500002B2104C08C893185 -:1044A000C070DF7009F950098F386EB8172C20667C -:1044B000AECC0C0C472C24667CFB099D105808CF11 -:1044C0008D1027246694D11EE151B8DC9ED0655032 -:1044D00056C0D7B83AC0B1C0F00CBF380F0F42CBAE -:1044E000F119E13018E13228967EB04BD30F6DBA46 -:1044F0000500A08800C08C2C200CC0201DE1360CCB -:10450000CF11A6FF2EF285ADCC27C4CF0E4E0B2EB9 -:10451000F685D10FC0800AB83878D0CD63FFC100CE -:104520008E300E0E4763FEA12A2C742B0A01044D17 -:10453000025808C22F200C12E1270CF911A699A2EB -:10454000FF27F4CF289285D2A008480B289685D162 -:104550000FC020D10F0000006C1004C060CB55DBF1 -:1045600030DC40055D02022A025BFF94292102092A -:10457000084CC882D2A0D10F2B2014B0BB2B24141E -:104580000B0C41CBC57DB7EBC0C10C9C022C2502A6 -:10459000D2A0D10F0000022A02033B02066C02C027 -:1045A000D0C7F72E201428310126250228240A0F0F -:1045B000EE012E241458010E63FFA300262406D218 -:1045C000A0D10F006C1006282102D62008084C65E7 -:1045D000809D2B200C12E0F70CB811A2882A82864D -:1045E000B5497A930260009719E0F409B90A299253 -:1045F000A36890082A620009AA0C65A08228828517 -:104600001CE0FF6480799C80B887B14B9B819B1034 -:10461000655074C0A7D970280A01C0D0078D380D25 -:104620000D42CBDE1FE0E01EE0E12EF67ED830D357 -:104630000F6D4A0500808800908C2E3008C0A000C5 -:10464000EE322E740028600C19E0E30C8D11A2DD0F -:10465000A988C0202CD2852284CFD2A00CBC0B2CE0 -:10466000D685D10FC0F0038F387FA0C063FFB400A0 -:10467000CC582A6C74DB30DC405807F6C020D10FD0 -:10468000DA605809C663FFE7DD402A6C74C0B0DC0D -:104690007058086A2E30088B1000EE322E740028F5 -:1046A000600C19E0CC0C8D11A2DDA988C0202CD2A1 -:1046B000852284CFD2A00CBC0B2CD685D10F000054 -:1046C0006C1004292014282006B19929241468812B -:1046D00024C0AF2C0A012B21022C24067BA004C08D -:1046E000D02D2502022A02033B02044C02C0D058FE -:1046F00000C0D2A0D10FC020D10F00006C1004293F -:104700003101C2B429240A2A3011C28378A16C7BFA -:10471000A1696450472C2006C0686FC562CA572D36 -:1047200020147CD722DA20DB30DC40DD505BFFA593 -:10473000292102090E4CC8E2C020D10FC0F10F9F01 -:10474000022F2502C020D10FDA20DB30C0C05BFF72 -:10475000DC28201406880228241463FFC7292015AA -:104760001BE0972A200BC0C09C240BAA092BA11C7C -:104770002C2415AB9929A51C63FF9900C020D10FEB -:10478000DA20DB30DC40DD50C0E058087DD2A0D11B -:104790000F0000006C1004CB5513E09225221F0D72 -:1047A000461106550CA32326221E25261F06440B60 -:1047B00024261E734B1DC852D240D10F280A80C038 -:1047C0004024261FA82828261E28261DD240D10FA7 -:1047D000C020D10F244DF824261E63FFD80000000E -:1047E0006C1004D620282006C0706E85026000D4AC -:1047F0001DE07919E07112E06F2A8CFC64A1302B66 -:104800006102B44C0B0B4C65B0A22B600C8A600C9F -:10481000B8110288082E828609B90A7EC302600098 -:104820009A2992A368900509AA0C65A08E28828512 -:10483000648088B8891BE07594819B80655155C060 -:10484000B7B8382A0A01C0C009AC380C0C4264C0A1 -:10485000421FE0541EE0562EF67EB04AD30F6DAADA -:104860000500808800908CC0A029600C0C9C11A2CF -:10487000CC2BC285AD990B4B0B2BC6852860062728 -:1048800094CF6881222D6015D2A0C9D2C0E22E64D7 -:1048900006D10F00C0F008AF387FB0BD63FFB10094 -:1048A000276406D2A0D10F00D2A0D10F00CC57DAD6 -:1048B00060DB30DC405808A7C020D10FDA6058090F -:1048C0003763FFE80028221E29221DD30F789901A3 -:1048D000C080C1D6C1C11BE043C122AB6B64804222 -:1048E00078913F2A80000CAE0C64E0BB02AF0C64F0 -:1048F000F0B52EACEC64E0AF0DAF0C64F0A92EACBB -:10490000E864E0A32FACE764F09D2EACE664E0978A -:104910002F800708F80BDA807B83022A8DF8D8A055 -:1049200065AFBC28612308D739D97060007B0000CF -:104930002B600C0CB811A2882C82862A0A087CAB4A -:104940007E09BA0A2AA2A368A0052C62007AC96F60 -:104950002A828564A0691FE029276504C0E3C0C4DA -:104960002E64069CA11CE0549FA02E600A97A30C05 -:10497000EE029EA28F600CFF029FA42E60147AEFBD -:104980004627A417ADBC2F828527C4CF2FFC202F2C -:10499000868563FE692A6C74C0B1DC90DD405807DF -:1049A000A71DE00C63FEC100D9A0DA60DB30C2D0E5 -:1049B000C1E0DC4009DE39DD505807F1D2A0D10F4B -:1049C000DA605808F663FEE4290A0129A4170DBF2E -:1049D000082E828527F4CF2EEC202E868564500B7E -:1049E0002A6C74DB4058016AD2A0D10FC020D10FCD -:1049F0006C10062B221E28221D93107B8901C0B04B -:104A0000C0C9C03BC1F20406401DDFF6C0E2C0745D -:104A10000747010E4E01AD2D9E11C0402E0A1464B1 -:104A2000B06E6D084428221D7B81652AB0007EA1EE -:104A30003B7FA1477B51207CA14968A91768AA1434 -:104A400073A111C09F79A10CC18B78A107C1AE29B8 -:104A50000A1E29B4007CA12B2AB0070BAB0BDAB0DD -:104A60007DB3022ABDF8DBA0CAA563FFB428B0104D -:104A700089116987BB649FB863FFDC00647FB463FE -:104A8000FFD50000646FD0C041C1AE2AB40063FFFF -:104A9000C62B2102CEBE2A221D2B221E7AB12A8CC1 -:104AA000107CB1217AB901C0B0C9B913DFC1DA20D5 -:104AB00028B0002CB00703880A28824CC0D10B8094 -:104AC00000DBA065AFE7D240D10F8910659FD463AA -:104AD000FFF300006C1008C0D0C8598C30292102A7 -:104AE0000C0C4760000C8E300E1E5065E19E292193 -:104AF00002C0C116DFB0090B4C65B0908A300A6E57 -:104B00005168E3026000852F629E1BDFA96EF85397 -:104B10002BB22668B0052E22007BE94727629DB79D -:104B200048CB7F97102B200CB04E0CBF11A6FF294D -:104B3000F2869E12798B4117DFA007B70A2772A36E -:104B4000687004882077893029F285DF90D79065D6 -:104B500090652A210419DFD77A9B22DA205806A310 -:104B6000600029002C21041BDFD37CBB18DA20C095 -:104B7000B658069EC95860014CC09063FFCCDA203D -:104B8000580886600006DA20C0B65808846551359A -:104B9000DC40DB308D30DA200D6D515806F6C0D088 -:104BA000D3A064A120292102C05184A18CA00404B7 -:104BB000470C0C4763FF3E00C09C8831DBD008F8EF -:104BC00050089B3828210498116E8823282066AC51 -:104BD0008C0C0C472C24667CBB159F139E148A10EA -:104BE0008B115807068E148F13C0D02D24668A307F -:104BF000C092C1C81BDF867FA6099BF099F12CF4F7 -:104C00000827FC106550A4B83ADF70C051C0800777 -:104C1000583808084264806718DF6319DF64298602 -:104C20007E6A420AD30F6DE90500A08800F08CC0AF -:104C3000A08930B4E37F9628C0F207E90B2C9408D2 -:104C40009B909F912F200C12DF630CF811A68829EE -:104C50008285A2FF2DF4CFD2A009330B238685D104 -:104C60000F22200C891218DF5B0C2B11A6BBA82287 -:104C70002D24CF2CB285D2A00C990B29B685D10F4B -:104C8000C087C0900A593879809663FF8ADB30DA92 -:104C900020C0C1C0D05BFF56292102C0D02A9CFE93 -:104CA00065AE4D2D2502C09063FE45009E142A2C52 -:104CB00074C0B1DC70DD405806E18E14C0D01BDF3B -:104CC00053C1C863FF6AC020D10F00006C100628D2 -:104CD000210216DF3808084C65821929629E6F98F8 -:104CE0000260022019DF332992266890078A200982 -:104CF000AA0C65A20F27629DC0CC6472072B210409 -:104D00008E31C0A0DDA00EFE500ECD386EB8102C36 -:104D10002066B1CC0C0C472C24667CDB026001EFD2 -:104D2000C0C12930081BDF2564909C2F0AFFC0D327 -:104D3000B09E64E1026892136450882A2C74044B7C -:104D4000025800930AA20206000000002B200C2744 -:104D500021040CBC11A6CC29C286280A087983023A -:104D60006001B919DF1509B90A2992A36890082EC4 -:104D7000220009EE0C65E1A42EC28564E19E262086 -:104D80000713DF1E6E7B0260019A17DF151FDF1EFF -:104D900019DF4BC0D228200A93E09DE1A9690F8852 -:104DA0000298E22F90802A9480B1FF07FF029FE3D0 -:104DB0002EC2851FDF080EDE0BAFBF2AF4CF2EC632 -:104DC00085655F76C020D10F2830102930112E3034 -:104DD0001300993200ED326480EE2A30141FDF3860 -:104DE00000AA3278EF050F9E092DE47F1EDF36669C -:104DF000A0050F98092A8480B4A718DF33C76F0075 -:104E00009104AE9EDDE000AF1A00C31A6EE1052DDD -:104E1000B2000DED0C1EDF2D08D81C063303AE8842 -:104E20002A848B2EB02E27848C03EE010FEE022EE7 -:104E3000B42E58018F63FEFF29310829250428303C -:104E4000142E3109B0886480A32E240AC0812E302C -:104E5000162CB4232E240BB4EF2F240C8C378B3656 -:104E6000292504DEB0DFC00C8F390B8E390FEE021E -:104E700064EEC4089F1101C4048D380CB81800C436 -:104E8000040CBE1800EE110EDD02C0E30EFF021E80 -:104E9000DF019F719E701EDF008F2098739D740547 -:104EA000FF110BCD53C18098750FDD020EDD029D01 -:104EB000721EDEBF2A24662F629D2AE4A22FFC18F0 -:104EC0002F669D63FE710000002F30121BDF010072 -:104ED000FA3278FF050B980B2A847F66D0050B9A6F -:104EE0000B2DA4802A301100AA3263FF442F240A1C -:104EF0009E2B63FF56CC57DA20DB30DC4058071579 -:104F0000C020D10F00DA20C0B65807A463FFE50027 -:104F1000DA7058063AC0A02A246663FE02DA2058E6 -:104F2000079F63FFCFB16928200A862009094799A6 -:104F30001129240798107F812693E027E50A9AE338 -:104F400088109DE119DEDD8D11096F029FE42DE4CB -:104F500016098802C0D398E22A240763FE51000094 -:104F60001DDEA60868118F11892B93E008FF02C08F -:104F70008F9FE50D990299E2047F11C0D49DE1084D -:104F8000FF029FE463FFD0006C1004C020D10F002B -:104F90006C100485210D381114DE848622A42408A7 -:104FA000660C962205330B9321743B13C862D230F2 -:104FB000D10FC030BC29992199209322D230D10F32 -:104FC000233DF8932163FFE36C100AD62094181751 -:104FD000DE79D930B83898199914655252C0E1D2A7 -:104FE000E02E61021DDE760E0E4C65E1628F308E82 -:104FF000190F6F512FFCFD65F1558EE129D0230E5D -:105000008F5077E66B8F181EDEB3B0FF0FF4110FD1 -:105010001F146590CE18DEB08C60A8CCC0B119DE2C -:105020006428600B09CC0B0D880929811C28811A82 -:105030002A0A0009880C08BA381BDEA60CA90A291E -:1050400092947B9B0260008C2B600C94160CBD111B -:10505000A7DD29D286B8487983026000D219DE56CE -:1050600009B80A2882A398176880026000A360002C -:10507000A51ADE9A84180AEE01CA981BDE4D8C1917 -:105080002BB0008CC06EB3131DDE4A0C1C520DCC2D -:105090000B2DC295C0A17EDBAE6000380C0C5360B6 -:1050A000000900000018DE8C8C60A8CCC0B119DEAD -:1050B0004028600B09CC0B0D880929811C28811A16 -:1050C0002A0A0009880C08BA380CA90A2992947E89 -:1050D000930263FF72DA60C0BA580730645073609D -:1050E000026600001ADE338C192AA0008CC06EA361 -:1050F0001A18DE2F0C1C5208CC0B18DE762BC2952A -:10510000C0A178B30263FF3F63FFC9000C0C536377 -:10511000FF09896078991829D285C9922B729E1D42 -:10512000DE246EB8232DD226991369D00B60000DB2 -:10513000DA6058071A6000170088607D890A9A1A99 -:1051400029729D9C129915CF95DA60C0B658071345 -:105150006551F58D148C18DBD08DD0066A020D6D6B -:1051600051580584D3A09A1464A1DD82A085A1B80A -:10517000AF9F190505470202479518C05163FE60AD -:105180002B6104C08C8931C0A009F950098A386E9E -:10519000B81F2C6066A2CC0C0C472C64667CAB114B -:1051A0009F119E1B8A155805958E1B8F11C0A02A32 -:1051B00064669F1164F0E12912032812096DF91742 -:1051C0002F810300908DAEFE0080889F9200908C0E -:1051D000008088B89900908C65514E8A10851A8B92 -:1051E000301FDE06881229600708580A2C82942D89 -:1051F00061040ECC0C2C86946FDB3C1CDE30AC9C26 -:1052000029C0800B5D50A29909094729C48065D047 -:10521000DA2E600CC0D01FDDEF0CE811AFEEA788CE -:105220002282852DE4CF02420B228685D2A0D10FA7 -:105230008E300E0E4763FDA6A29C0C0C472C640713 -:105240007AB6CD8B602E600A280AFF08E80C6481CC -:105250000E18DE1983168213B33902330B2C341661 -:105260002D350AC02392319F30C020923308B202FC -:1052700008E80292349832C0802864072B600CD270 -:10528000A01CDDD40CBE11A7EE2DE285ACBB28B46A -:10529000CF0D9D0B2DE685D10F8B1888138D30B85F -:1052A0008C0D8F470D4950B4990499100D0D5F0472 -:1052B000DD1009FF029F800DBB029B8165508D852B -:1052C0001AB83AC0F1C0800CF83808084264806B04 -:1052D0001BDDB519DDB629B67E8D18B0DD6DDA059A -:1052E00000A08800C08CC0A063FEF30082138B1660 -:1052F0001DDDC628600AC0E02EC4800D880202B2FF -:105300000B99239F20C0D298229D2122600CB2BB12 -:105310000C2D11A7DD28D28508BB0B18DDAE2BD6CE -:1053200085A8222E24CFD2A0D10F9E1B851A2A6CCD -:10533000748B185BFF178E1B63FEA300C087C090A1 -:105340000AF93879809263FF86C020D10F9E1B2A0C -:105350006C74C0B18D185805398E1B851A63FE7E9A -:10536000886B8213891608BE110ECE0202920B9E24 -:1053700025B4991EDDA19F200E88029822C0EF045B -:10538000D8110E88029824C0E49E21C080D2A02BA0 -:10539000600C2864071CDD8F0CBE11A7EE2DE28582 -:1053A000ACBB28B4CF0D9D0B2DE685D10F000000BE -:1053B0006C1004C020D10F006C10048633C071C083 -:1053C00030600001B13300310400741A04620174CA -:1053D00060F1D10F6C1004022A02033B025BFFF65E -:1053E0001CDD771BDDBFC79F88B009A903098A01AF -:1053F0009AB079801EC0F00FE4311DDD6E0002000E -:105400002BD2821EDDB82AC1020EBB022BD6820A25 -:10541000E431D10F28C102C19009880208084F2841 -:10542000C50208E431D10F006C1004C0C00CE43197 -:1054300012DD631ADD6000020029A28218DDAC1BB8 -:10544000DDAA2621020B990108660129A6822625DC -:105450000206E43114DDA715DDA2236A902326128B -:105460008550242611252613222C40D10F00000040 -:105470006C1008D6102B0A64291AB41ADD4D0D23BE -:10548000111CDD4E0F2511B81898130E551118DD9B -:1054900099AC55A838AA332C80FF2A80FEA933285E -:1054A0008D0129800108AA112880000CAA02088811 -:1054B0001109880208AA1C288C08281604580862BA -:1054C00014DD3F0AA7022441162A30802B1204075C -:1054D000AA2858085DB1338B13B4559A6004AC28E0 -:1054E000B4662C56277B69E016DD769412C050C056 -:1054F000D017DD329D15D370D4102F60802E6082BE -:105500009F169E17881672891A8D128C402A607F0A -:105510000DCC282B3A200CAA2858084BC0B10ABE43 -:10552000372E35408F1772F91A8D128C402A608100 -:105530000DCC282B3A200CAA28580843C0B10ABE2B -:10554000372E3542B233B444B1556952B6B466C051 -:10555000508F15B877D370B2FF9F156EF899D10FA1 -:105560006C1004C021D10F006C1004270A001CDD50 -:10557000111FDD221EDD251DDD0E1ADD501BDD5E37 -:10558000C02824B0006D2A75AA48288080C0916484 -:10559000806100410415DD09C03125502E00361A06 -:1055A0000655010595390C56110C66082962966E50 -:1055B000974D0D590A29922468900812DD42024243 -:1055C0000872993B23629512DD06CB349F3002822C -:1055D000020E4402C092993194329233AD52246249 -:1055E00095C090244C1024669524B0002924A0AACC -:1055F00042292480B177B14404044224B400D10F7D -:10560000D10FD10F6C10041ADCEA2AA00058021C3A -:105610005BFFD5022A02033B025BFFD11BDCE8C91A -:10562000A12CB102C0D40DCC020C0C4F2CB5020C35 -:10563000E431D10FC0A00AE43118DCDE0002002FF3 -:10564000828219DCF12EB10209FF022F86820EE45C -:1056500031D10F006C1004C02002E43114DCD816E4 -:10566000DCD5000200226282234102732F0603E48C -:1056700031C020D10F19DD221ADD212841020A2A6A -:10568000010988012A668228450208E43115DD18DF -:1056900012DD1D25461DD10F6C1004292006289C03 -:1056A000F96480A02A9CFD65A0968A288D262F0A81 -:1056B000087AD9042B221FC8BD2C206464C0812E17 -:1056C00022090EAE0C66E0782B200C1EDCBA0CBC56 -:1056D00011AECC28C28619DCB878F3026000AD099F -:1056E000B90A2992A36890082E220009EE0C65E001 -:1056F0009B29C2851FDCC26490929F90C0E41FDC8E -:10570000CE9E9128200AC0E09E930F88029892882E -:10571000200F880298942F20079A979D962F950A1C -:105720002E240728200629206468833328C2851286 -:10573000DCA9288C20A2B22E24CF28C685C020D177 -:105740000FC020D10F2A206A0111020A2A4165AF39 -:1057500052DA20C0B05805E464AFE5C021D10F0093 -:10576000649FC81FDC962D20168FF209DD0C00F116 -:105770000400DD1AADAD9D2912DC9728C285A2B2C6 -:105780002E24CF288C2028C685C020D10FC021D13F -:105790000F0000006C1004260A001BDCDB15DC8700 -:1057A00028206517DC84288CFE6480940C4D110D34 -:1057B000BD082CD2F52BD2F42ED2F77CB13DB4BB70 -:1057C0002BD6F47BE9052BD2F62BD6F47CB92C2A08 -:1057D000D2F62AD6F52AD6F406E431000200287261 -:1057E000822AFAFF004104290A012F510200991A66 -:1057F0000A99030988012876820FE4312624652B53 -:10580000D2F48E5A2CD2F5B0EE9E5A7BCB1629D20A -:10581000F62FD2F70CB80C09FF0C08FF0C0F2F1451 -:10582000C8F96000320BCA0C0A2A14CEA92B510207 -:10583000C0C20CBB020B0B4F2B55020BE431D10F36 -:1058400000DB30DA205BFF941BDCB064AF5D0C4DF5 -:1058500011ADBD63FFA8000006E4310002002F7205 -:105860008218DC6E2E510208FF022F76820EE43180 -:10587000D10F00006C1004C03003E43116DC4E156B -:10588000DC4F00020024628274472118DCA0875A92 -:10589000084801286682CD7319DC9E0C2A11AA994A -:1058A0002292832992847291038220CC292B510267 -:1058B0000BE431C020D10F001FDC972E51020FEEF8 -:1058C000012E55020EE431B02DB17C9C5A12DC92AF -:1058D00008DD112D5619D10F6C10061BDC351EDCAE -:1058E0003722B0001ADC8E6F23721DDC75C0481899 -:1058F000DC8D1FDC8BDC10D5C083F000808600506F -:105900008A6D4A4F0F35110D34092440800B560A19 -:10591000296294B1330E55092251400F44110C44B1 -:105920000A874009A80C02883622514107883608A8 -:10593000770CA8992966949740296295874109A810 -:105940000C02883607883608770CA899296695973F -:1059500041030342B13808084298F0D10F1CDC72B1 -:1059600013DC7327B0002332B5647057C091C0D0E8 -:1059700016DC7115DC6FC0402AC00003884328C4C0 -:10598000006D793C004104B14400971A7780148E71 -:10599000502FB2952DB695AFEE2EED2006EE369E29 -:1059A0005060001877A00983509D5023B695600081 -:1059B0000223B295223D2006223622B695B455B870 -:1059C000BBD10F0003884328C400D10F6C1004C062 -:1059D0004004E43115DC59000200885013DC58CB38 -:1059E000815BFFBD1CDC570C2D11ADCC2BC2822A74 -:1059F000C28394507BAB142EC28429C2850ABD0C8D -:105A00000E990C0D990C0929146000050BA90C09BD -:105A10002914993015DBEA2A51020AE4312A2CFCB8 -:105A200058004B2B32000AA2022BBCFF9B30CCB695 -:105A3000C8A4D2A0D10F000004E4311EDBDE0002B6 -:105A4000002DE2822FBAFF2C51020FDD012DE682DC -:105A50000CE431D10F0000006C1004D10F000000E5 -:105A60006C1004C020D10F006C100413DC36C0D1C0 -:105A700003230923318DC0A06F340260008D19DB30 -:105A8000CD1BDBCE17DC2F0C2811A87726728325BF -:105A900072822CFAFF76514788502E7285255C045D -:105AA00025768275E9052572842576827659292E18 -:105AB00072842E76822E76830AE4310002002392CD -:105AC000820021042FB10200D61A0C6603063301AE -:105AD0002396820FE43126728325728260000200D1 -:105AE000D8A07659220AE4310002002392820021D4 -:105AF0000400D21A2FB1020C220302320122968234 -:105B00000FE431D280D10F00D280D10FC020D10F4D -:105B10006C1004DB30862015DBA6280A002825023D -:105B2000DA2028B0002CB00705880A28824C2D0AFC -:105B3000010B8000DBA065AFE61ADB9F0A4A0A2949 -:105B4000A2A3C7BF769101D10F2BA6A3D10F00004E -:105B50006C1004C0D1C7CF1BDB9919DB9617DB94FF -:105B60000C2811A87786758574C0A076516288507C -:105B70008E77B455957475E90385769574765927B3 -:105B80008F769F759F740AE431000200239282B4DD -:105B90002E2FB10200E10400D61A0C660306330171 -:105BA0002396820FE431867583747639280AE431AE -:105BB0000002002E9282B42200210424B10200DFF0 -:105BC0001A0CFF030FEE012E968204E431D280D12D -:105BD0000FD8A07651D6D280D10F00006C100429C6 -:105BE0000A801EDB9A1FDB9A1CDB730C2B11ACBBEB -:105BF0002C2CFC2DB2850FCC029ED19CD0C051C064 -:105C00007013DB9614DB9518DB932AB285A8280461 -:105C1000240A234691A986B8AA2AB685A98827848A -:105C20009F25649FD10F00006C100419DBC70C2A5C -:105C300011A9A98990C484798B761BDBB5ABAC2AFA -:105C4000C2832CC2847AC1688AA02BBC30D3A064E2 -:105C5000A05E0B2B0A2CB2A319DB7F68C0071DDBEB -:105C6000BBD30F7DC94AA929299D0129901F68919D -:105C70003270A603D3A0CA9E689210C7AF2AB6A3FB -:105C80002A2CFC5BFFB3D230D10F000013DBB10331 -:105C9000A3018C311DDB510C8C140DCC012CB6A34F -:105CA00063FFDC00C020D10FDA205BFFCCC020D125 -:105CB0000FC020D10F0000006C1004DB30C0D019E1 -:105CC000DB3CDA2028300022300708481209880A15 -:105CD00028824CDC200B80001BDB370C4A11ABAA5E -:105CE00029A28409290B29A684D10F006C1004C0B5 -:105CF0004118DB3017DB320C2611A727277030A89C -:105D000066256286007104A35500441A7541482235 -:105D1000628415DB5202320BC922882117DB2F085F -:105D20008414074401754905C834C020D10FD10F30 -:105D30000809471DDB86C0B28E201FDB1D0E0E43F7 -:105D4000AFEC2BC4A00FEE0A2DE6242A6284C020FB -:105D50000A990B296684D10FC020D10F6C1004DB87 -:105D600030C0D018DB13DA20253000223007085865 -:105D70000A28824CDC200B80008931709E121BDBCC -:105D80000D0C4A11ABAA29A28409290B29A684D19A -:105D90000F09C95268532600910418DB08C0A12FCF -:105DA000811200AA1A0AFF022F85121EDB020C4D77 -:105DB00011AEDD2CD2840C2C0B2CD684D10FC081DB -:105DC0001FDAFFB89A0A0A472EF11200A1040088D0 -:105DD0001A08EE022EF5121DDAF70C4C11ADCC2B81 -:105DE000C2840B2B0B2BC684D10F00006C1004DB7C -:105DF00030C0D019DAEFDA202830002230070988C5 -:105E00000A28824CDC200B80001CDAEA0C4B11AC17 -:105E1000BB2AB2840A2A0B2AB684D10F6C1004C0A4 -:105E20004118DAE416DAE60C2711A626266030A817 -:105E300072252286006104A35500441A7541082288 -:105E4000228402320BD10F00C020D10F6C10041538 -:105E5000DB410249142956112452120208430F88CB -:105E600011C07300810400361A008104C78F0077C7 -:105E70001A087703074401064402245612D10F0082 -:105E80006C10066E23026000AC6420A7C0A08510D1 -:105E900013DB1916DB30C040A6AA2BA2AE0B1941AA -:105EA00064906668915D68925268933C2AA2AA2821 -:105EB0003C7F288C7F0A0A4D2980012880002AAC6B -:105EC000F20888110988027589462B3D0129B00026 -:105ED0002BB0010899110B99027A9934B8332A2A08 -:105EE00000B1447249B160004A7FBF0715DB1B63F4 -:105EF000FFB90000253AE863FFB10000253AE863E6 -:105F0000FFA90000250A6463FFA1C05A63FF9C003B -:105F100000705F082534FF058C142C34FE70AF0B25 -:105F20000A8D142E3D012AE4012DE400DA405BFDC8 -:105F30005063FFA7D10FD10F6C10041ADAA019DA41 -:105F40009D1CDB061BDB07C080C07160000D0000DC -:105F50000022A430B1AA299C107B915F26928679F9 -:105F6000C2156E6262C0206D080AB12200210400D1 -:105F7000741A764BDB63FFEE2292850D63110325C5 -:105F800014645FCFD650032D436DD9039820B422FB -:105F90000644146D49229820982198229823982429 -:105FA00098259826982798289829982A982B982CED -:105FB000982D982E982F222C4063FF971EDA7E276B -:105FC000E68027E681D10F00C02063FF8300000038 -:105FD0006C1004C062C04112DA791ADA7513DAE182 -:105FE0002AA00023322D19DADB2BACFE2992AE6EEB -:105FF000A30260008E090E402D1AC2C2CD0EDC39FC -:106000002C251664B0895BFF9E15DAD71ADAD12BDE -:106010003AE80A3A0158058C2B21160ABB28D3A06E -:106020009B505805A32B52000ABB082A0A005805AA -:10603000A215DACE2D21022C3AE80C3C2804DD0210 -:106040002D25029C5058059A8B50AABBC0A158051B -:106050009A1CDAC72D21020C3C2806DD0213DAC592 -:106060002D25029C305805928B30AABBC0A2580542 -:10607000922A2102C0B40BAA020A0A4F2A2502580A -:1060800005A6D10F242423C3CC2C251663FF76004C -:1060900018DABD1CDAB919DABA1BDAB817DA8B8547 -:1060A000202E0AFD1FDAB92D202E24F47A24F47E46 -:1060B00024F4820EDD0124F4862E0AF70755280603 -:1060C000DD02C0750EDD01050506AB5BA959C0E810 -:1060D000AC5C24C4AB0EDD0227C4AC2E0ADFA8558D -:1060E00027B4EC0EDD0124B4EBC2E027942C0EDDC6 -:1060F0000224942B2E0A800D0D4627546C24546BD9 -:106100000EDD022D242E63FEFC0000006C10042A1C -:106110000A302B0A035BFF4D12DA8FC39029261633 -:10612000C3A1C0B3C08A2826175BFF48C03CC3B1D7 -:106130002B26161ADA222AA02023261764A079C358 -:10614000A2C0B15BFF42C3A2C0B15BFF40C3C22C7F -:106150002616C2AFC0B12326175BFF3CC28F28268C -:1061600016C0FE2F2617C2E22E26162A0AA1C0B19B -:10617000C0D82D26175BFF352A0AA12A2616C3A6EA -:10618000C0B3C1922926175BFF31C3C62C2616C1A6 -:10619000B32A0AA22B2617C0B35BFF2C290AA22917 -:1061A0002616C185282617C2FB2F2616C0E72E26E5 -:1061B000171DDA762D2610D10FC3A2C0B35BFF23C3 -:1061C00063FF82006C10041CDA3F1BDA2C18DA70B3 -:1061D00017DA7116DA7115DA71C0E0C0D414DA3B3F -:1061E0001FD9F7C0288FF06D2A36DAC0D9C07C5B82 -:1061F000020FC90C1CDA350C9C28A8C3A6C22A368B -:10620000802A2584A4C2A7CC2D248C2B248A2B245D -:10621000872E248BB1BB2E369F2C369E2C369DB1FB -:10622000AC1CDA161BDA5FC0286D2A33DAC0D9C07D -:106230007C5B020FC90C1CDA240C9C28A8C3A6C2E4 -:106240002A36802B2584A4C2B1BBA7CC2D248C2E4A -:10625000248B2A248A2E369F2C369E2C369DB1AC58 -:10626000C07919DA141BDA5113DA4F1ADA4F18DA37 -:106270005014DA1516DA5004F42812DA4F04660CBA -:10628000040506A252A858AA5AA3539B3029A50078 -:1062900027848AC091C0A52A848C29848B17DA4868 -:1062A00018DA47A75726361D26361E2E361F16DA51 -:1062B0004513DA45A65504330C2826C82E75002D43 -:1062C00054AC2E54AB2E54AA2326E62326E52E26C4 -:1062D000E7D10F006C100613DA2317DA1E24723D83 -:1062E0002232937F2F0B6D08052832937F8F026334 -:1062F000FFF3C0C4C0B01AD9B1C051D94004593954 -:1063000029A4206E44020BB502C3281ED9ACDDB00F -:1063100025E422052D392DE421C0501EDA2C19DA8E -:106320001C18DA1C16DA1E1DDA2A94102A72451778 -:10633000D9E76DA94BD450B3557A5B17DF50756B15 -:10634000071FD99E8FF00F5F0C12D9DF02F228AE23 -:106350002222D681D54013D9DC746B0715D99885D4 -:106360005005450C035328B145A73FA832A9332255 -:10637000369D22369E2436802B369F2BF48B2CF4B0 -:106380008C14D9F824424DC030041414C84C6D0844 -:1063900006B133041414C84263FFF20015D985C452 -:1063A000400031041AD986C0D193A200DD1AC13849 -:1063B000B0DD9DA318D9EC2B824D29824E29A51C56 -:1063C0002882537A871E2C54008E106FE45D12D9F8 -:1063D0007B2F211D23211C2F251B04330C23251C5F -:1063E00023251AD10FC06218D9DB88807E87D9890E -:1063F000102654006F94191BD9712AB11C0A1A1463 -:1064000004AA0C2AB51C2AB51D2AB51A2AB51BD117 -:106410000F1BD96A2AB11C0A1A1403AA0C2AB51C2C -:106420002AB51D2AB51A2AB51BD10F001CD9642B19 -:10643000C11D2DC11C2BC51B03DD0C2DC51C2DC57D -:106440001AD10F006C100619D95D14D9C212D9C522 -:1064500015D9E0C73FC0E02E56A82E56A92E56AA41 -:106460002E56AB23262918D985DB101CD9DAC0D4C7 -:106470002A42452D16019C1000B0890A880C2896E6 -:10648000005BFF942B22E318D94D0B5B149B842AED -:1064900022E48B84B1AA0A5A140BAA0C9A852922E9 -:1064A000E509591499862F22CD0F5F149F875BFF52 -:1064B000455BFF1623463BC1B01DD9401CD99E2A1F -:1064C000D1022C463A0BAA020A0A4F2AD5025804D6 -:1064D000925BFEBF5BFE98C050C0B016D93614D98F -:1064E0003E17D9AEC0C0C73E93122C262DC03060D7 -:1064F00000440000007F9F0FB155091914659FF4F7 -:10650000C0500AA9027FA7EF18D92ADA5008580A02 -:1065100028822C2B0A000B8000005104D2A0C091CD -:10652000C7AF00991A0A99039912CE3864206BD329 -:10653000202B20072516032C12022A62827CA863D6 -:1065400018D91C01110208580A28822CDA500B8035 -:1065500000D2A0643FD58A310A8A1404AA01C82A4D -:106560002B22010B8B1404BB017BA945DDA07A7B98 -:10657000081DD9122DD2000DAD0CDB3019D90D1A22 -:10658000D95288130ADA28DC801DD99009880A2894 -:10659000823C0DAA080B8000652F93D320C0B06306 -:1065A000FF9400007FAF34B1550050040A0919630D -:1065B000FF42DAB07B7B081AD9012AA2000ABA0C82 -:1065C0001BD9428C310BAB280C8A141CD980ACBB74 -:1065D0001CD98004AA012BC68163FF8F645F60C051 -:1065E00050C0B0C7CE9C1263FF5500006C1004274A -:1065F000221EC08008E4311BD8EF0002002AB282BC -:1066000019D8EF003104C06100661A2991020A6AA4 -:10661000022AB68209E43115D94A0C3811A8532848 -:1066200032822432842A8CFC7841102921022A36B5 -:106630008297A0096902292502D10F002B21022C83 -:1066400032850B6B022CCCFC2C368297C02B25029A -:10665000D10F00006C1004C0E71DD8D21CD8D40D97 -:106660004911D7208B228A200B4B0BD2A007A80CF4 -:106670009B72288CF4C8346F8E026000A31FD8CAA6 -:10668000A298AF7B78B334C93DC081C0F0028F3887 -:106690000F0F42C9FA2CD67ED5206D4A05003088EE -:1066A00000508C887008980878B16DD2A09870D18D -:1066B0000FC0F0038F387FE0DE63FFD8027B0CAFA2 -:1066C000BB0B990C643047D830C0F1C05002F5388C -:1066D0000505426450792CD67E0B36122F6C100FB4 -:1066E0004F366DFA0500808800208C06440CC0816E -:1066F000C05003B208237C0C038538050542645062 -:106700005A2CD67ED30F6D4A0500208800308CD2DB -:10671000A0A798BC889870D10FD2A0BC799970D1ED -:106720000FD2302BAD08C0F1C0500BF53805054233 -:10673000CB542CD67E083F14260A100F660C064652 -:10674000366D6A0500208800B08C827063FF2D00D2 -:10675000C05003F53875E08063FF7A00C0600286A0 -:106760003876E09F63FF9900C05003F53875E0C4A8 -:1067700063FFBE006C1004D62068520F695324DA00 -:1067800020DB30DC405800F3D2A0D10FDA20DB3020 -:10679000DC405800F09A2424240EC02122640FC04B -:1067A00020D10F00B83BB04C2A2C7489242D200E28 -:1067B0002E200FA4DDB1EE2E240FB0DD2D240E28E7 -:1067C00090072D9003A488B088B1DD2D9403289400 -:1067D000075BFFA069511DC0E082242A600F18D812 -:1067E000FE2A240329600E8F2029240708FF029F18 -:1067F000209E64D10FC020D10F0000006C100494C3 -:106800002319D8F6C0B3083A110BAA02992019D857 -:10681000699A2116D867C05028929D2564A2288CB9 -:106820001828969DD10F00006C1004282066C038EF -:10683000232406B788282466D10F00006C100603B5 -:106840005A0C0D36110D5C11D8208B2282210CBB05 -:106850000C06550F9B8202320B928113D853D9201C -:10686000A38F6450561CD84FC0D71BD850A256C017 -:10687000E1C09004E93809094276F34F044302CAA3 -:10688000912BC67ED30F6DAA0500208800308C891D -:1068900081A95909FA0C64A07D99818A8264A00FAC -:1068A000D290D10FC06002E63876D0D763FFD10016 -:1068B000C020BC89998199809282D10F7F230429BD -:1068C0002DF8998165BFD863FFE50000028F0CA306 -:1068D000FF0F3312931003AA0CD3406490402BC6D1 -:1068E0007E8610D30F6D6A0500208800308CBC8234 -:1068F000C090A4F3C041034938090942CA9B2BC682 -:106900007E6DAA0500208800308C0F590CA989BC27 -:1069100099998163FF8400BC89998163FF7C00C0E1 -:106920006002E63876D0B963FFB300C07002473822 -:1069300077D0CD63FFC700006C100414D82AC15271 -:10694000A424CA3128221D73811C292102659016B6 -:106950002A300075A912022A02033B022C3007C01C -:10696000D25801D0653FDCD10F2B300703BB0B0B96 -:10697000BA0274B3022ABDF8D3A063FFC4000000BA -:106980006C1004292006C0706E9741292102C08F27 -:106990002A2014C0B62B240606AA022A24147980C1 -:1069A000022725022A221E2C221D7AC10EC8ABDA2C -:1069B00020DB302C0A00033D025BF80D6450742D7F -:1069C00021020D0D4CC9D3C020D10F00002E9CFB1D -:1069D00064E0822F21020F0F4C65F0911AD7F61C4C -:1069E000D7F429A29EC08A798B5D2BC22668B00499 -:1069F0008D207BD95229A29DC0F364904A97901DA7 -:106A0000D8062E21049D9608EE110FEE029E979E49 -:106A10009118D802C0E527C4A22E24062BA29D2FD0 -:106A200021022BBC3008FF022F25022BA69DC0207F -:106A3000D10F00002F300068F939DA20DB30044C28 -:106A40000258004463FF7700022A022B0A0658000E -:106A5000D3220A00D10F6550102830006889240223 -:106A60002A02033B02DC4058003BC020D10FD27009 -:106A7000D10F00002A2C74033B02044C025BFEF58C -:106A800063FF3B00DB30DC402A2C745BFEF2C0204D -:106A9000D10F00006C1004C83F89268829A399995A -:106AA0002609880C080848282525CC52C020D10F7B -:106AB000DB402A2C745BF936D2A0D10F6C1004D8BD -:106AC00020D73082220D451105220C928264207459 -:106AD00007420B13D7B5D420A383732302242DF8C8 -:106AE000858074514CBC82C0906D081600408800AF -:106AF000708C773903D720C0918680743901D420F7 -:106B000074610263FFE2CA98C097C0411BD835C0C8 -:106B1000A00B8B0C0B4A380A0A42C9AA1DD7A21C2B -:106B2000D7A32CD67EC140D30F6D4A050020880024 -:106B3000308C9780D270D10FBC8FC0E00F4E387E62 -:106B400090E263FFD6BC8292819280C0209282D173 -:106B50000F0000006C1006C0D71CD7921BD7940DF5 -:106B60004911D7202E221F28221D0E4E0BD280073E -:106B70008A0C2E761F2AAC80C8346FAE026000CB20 -:106B80002F0A801AD798A29EAA7A7EA33FC93FC037 -:106B9000E1C05002E538050542CA552BC67EDB2010 -:106BA000D30F6D4A0500308800B08C2E721DAE9E4A -:106BB0000EA50C645086D2802E761DC091298403C8 -:106BC000D10FC05003E53875D0D363FFCD15D785FD -:106BD000027E0CA5EE643051C0A1250A0002A53842 -:106BE000033A020505426450922BC67E0E3512957B -:106BF00010255C10054536D30F6D5A0500A088009E -:106C0000208CC0A1A3E2C05023FA8003730C03A51B -:106C100038AF730505426450722BC67E851005455A -:106C20000C6D5A0500208800308CD280C0A10E9BCC -:106C30000CAB7BAFBB2B761D2A8403D10FD280C057 -:106C4000C1AF7D2D761D2C8403D10F00D2302E8D47 -:106C500008C0F1C0500EF538050542CB592BC67E51 -:106C60000A3F14C1600F660C064636D30F6D6A05E5 -:106C700000208800E08C22721D63FF03C061C050B9 -:106C800003653875D80263FF6263FF5CC05002A5DC -:106C90003875D08763FF8100C06003F63876D0BFB7 -:106CA00063FFB9006C10042A201529201614D7435D -:106CB0000A990CCB9D2E200B04ED092BD11C8F289B -:106CC00009BC36ACAA0CBB0C2BD51C0A0A472A24DB -:106CD00015CAAF8B438942B0A800910400881AA856 -:106CE000FF0FBB029B278F260FB80C783B1AC020E2 -:106CF000D10F0000292102C0A20A9902292502C051 -:106D000021D10F008B2763FFDC2BD11C0CAA0C0AAE -:106D10000A472A2415ACBB2BD51CC9AE8B438C2843 -:106D20008F42B0AD00F10400DD1AADCC0CBB029B6C -:106D300027DA20B7EB580019C021D10F9F2763FF36 -:106D4000EF0000006C100428203C643047053060E0 -:106D500000073E01053EB156076539054928C77F42 -:106D6000A933030641076603B166060641A6337ED2 -:106D7000871E222125291AFC732B1502380C098144 -:106D80006000063E01023EB12406423903220AD1C8 -:106D90000FD230D10FC05163FFC000006C10042728 -:106DA000221EC08008E4311DD7030002002CD282CD -:106DB0001BD703003104C06100661A2BB1020C6CB2 -:106DC000022CD6820BE43119D7870C3A11AA9328EA -:106DD00032829780253282243284B45525368275DA -:106DE000410A292102096902292502D10F2A21021B -:106DF0002B32830A6A022B36822A2502D10F000029 -:106E00006C100418D6EC0C2711087708267286251A -:106E10003C04765B1315D6E805220A2222A36820DB -:106E200002742904227285D10FC020D10F00000006 -:106E30006C100419D6EB27221EC08009770208E4E3 -:106E4000311DD6DC0002002CD2821BD6DC003104BE -:106E5000C06100661A2BB1020C6C022CD6820BE4C6 -:106E60003119D7600C3A11AA9328328297802532C3 -:106E700082243284B45525368275410B2A21020AB8 -:106E80006A022A2502D10F002B21022C32830B6BC0 -:106E9000022C36822B2502D10F0000006C10041B3F -:106EA000D6C50C2A11ABAA29A286B438798B221B2D -:106EB000D6C219D6E80B2B0A2BB2A309290868B051 -:106EC0000274B90D299D0129901F6E920822A28596 -:106ED000D10FC020D10FC892C020D10FDA205BEEB5 -:106EE000B3C020D10F0000006C100414D6B22842A9 -:106EF0009E19D6AF6F88026000BA29922668900763 -:106F00008A2009AA0C65A0AC2A429DC0DC64A0A41A -:106F10002B200C19D6A90CBC11A4CC2EC28609B901 -:106F20000A7ED30260009A2992A36890078D2009F7 -:106F3000DD0C65D08C25C2856450862D2104C030BF -:106F40006ED80D2C2066B8CC0C0C472C246665C07E -:106F50007B1CD72518D6AF1AD6A619D6B61DD6AB28 -:106F6000C0E49E519D508F209357935599539A5644 -:106F70009A5408FF021AD6C29F5288269F5A9E59D9 -:106F80009D58935E9C5D935C9A5B08084805881148 -:106F9000985FC0D81FD6900CB911A499289285AFDC -:106FA000BF23F4CF288C402896858E262D24069E5C -:106FB00029C020D10FCA33DA20C0B65BFF78C72FB3 -:106FC000D10FC93ADA205BFF75C72FD10FDBD05B39 -:106FD000FE0B2324662B200C63FF7500C72FD10FF7 -:106FE000C72FD10F6C1004C85B29200668941C6859 -:106FF0009607C020D10FC020D10FDA20DB30DC4053 -:10700000DD502E0A005BFE5ED2A0D10F2E200C18A0 -:10701000D6690CEF11A8FF29F286C088798B791AFE -:10702000D6660AEA0A2AA2A368A0048B207AB96865 -:1070300023F2856430621BD670290A802C206828D0 -:1070400020672D21040B881104DD1108DD020DCC11 -:1070500002C0842D4A100DCC021DD66898319D3097 -:107060008A2B99379C340BAA02C0C09C359C369A57 -:10707000322A2C74DB4028F285C0D3288C2028F6D5 -:10708000852C25042D24061FD653DD40AFEE2CE4BD -:10709000CF5BFDEAD2A0D10F00DA20DBE05BFF3F3F -:1070A000C020D10F6C100AD6302A200624160128E1 -:1070B000ACF86583862B2122C0F22A2124CC572AE2 -:1070C000AC010A0A4F2A25247ABB0260037F2C21D7 -:1070D000020C0C4C65C3192E22158D32C0910EDDA9 -:1070E0000C65D39088381ED63364836B8C37C0B858 -:1070F000C0960CB9399914B49A9A120D9911991332 -:107100008F6718D62EC9FB2880217F83168B142CFD -:1071100022002A200C5BFF61D4A064A3B38F6760B8 -:10712000002800002B200C89120CBA11AEAA2CA248 -:10713000861DD6217C9B3E0DBD0A2DD2A368D004AE -:1071400088207D893024A28564436427212E07F797 -:107150003607F90C6F9D01D7F0DA20DB70C1C42D22 -:10716000211F5BFEF889268827DDA009880C7A8B11 -:10717000179A10600006C04063FFCC0000DA208B35 -:10718000105BFEC88D1065A267C0E09E488C649CB1 -:10719000498B658A669B4A9A4B97458F677F730236 -:1071A000600120CD529D10DA20DB302C12015BFEF5 -:1071B000698D10C051D6A08FA7C0C08A68974D9A1C -:1071C0004C8869896A984E994F8E6A8A69AE7E7733 -:1071D000EB01B1AA9E6A9A698B60C0A00B8E1477EE -:1071E000B701C0A1C091C08493159D179516C0D05A -:1071F00025203CC030085801089338C0820833105D -:10720000085B010535400B9D3807DD100BAB100EF8 -:1072100019402A211F07991003DD020DBB020553F7 -:10722000100933020A55112921250A2A14092914A3 -:107230000499110A99020933028A2B2921040BAA05 -:10724000021BD66A0899110955020855020BAA02B9 -:107250009A408920881408991109880219D5EA1DD5 -:10726000D66409880298418B2A9346954783150D69 -:10727000BB0285168D179B448A658966AACAA97CBC -:1072800077CB01B1AA07FB0C9C669A6588268E29EC -:10729000AD87972607EE0C0E0E482E25259B672BF3 -:1072A000200C87131ED5C40CB911AE99289285A75E -:1072B0008828968517D5C8C090A7BB29B4CF871852 -:1072C00063FE3C008C60C0E0C091C0F0C034C0B828 -:1072D0002A210428203C08AA110B8B0103830103F7 -:1072E0009F380B9B39C03208FF10038801089E3875 -:1072F0000C881407EE100FEE020388010898390578 -:10730000BF1029211F0ABB1107881008FF020BAA12 -:107310000218D5BC09291403AA022B212583200BAE -:107320002B1404BB110833110FBB020B99028B14F1 -:107330008F2A0B33020833028B2B64708688689780 -:107340004D984C8769886A93419946974E984FC0EB -:107350007077C701C0719A4718D6260B7C100CECC9 -:107360000208F802984418D6230CBC0208CC029CF0 -:10737000402A200C295CFEC0801FD58E1CD5960C9F -:10738000AE112B2124ACAAAFEEB0BB8F132CE2853B -:1073900028A4CFAFCC2CE6852A22152B2524B1AA10 -:1073A0002A26156490DBC9D28F262E22090DFF08EC -:1073B0002F26060FEE0C0E0E482E25256550E4C034 -:1073C00020D10F00C07093419F4499469A4777C7D8 -:1073D0000A1CD57A2CC022C0810C87381CD6070B1A -:1073E000781008E80208B8020C8802984063FF8011 -:1073F00000CC57DA20DB608C115BFDD629210268B6 -:107400009806689403C020D10F2B221EC0A0292209 -:107410001D2A25027B9901C0B064BFE813D5652CF5 -:10742000B00728B000DA2003880A28824CC0D10BAC -:107430008000DBA065AFE763FFCA000068A779DAC8 -:1074400020DB30DC40DD505BFEE7D2A0D10FC16D08 -:10745000C19D29252C60000429252CD6902624675F -:107460002F2468DA20DB308C11DD502E0A805BFD82 -:1074700044D2A0D10FC168C1A82A252C63FFDD002A -:107480000000C8DF8C268B29ADCC9C260CBB0C0BD6 -:107490000B482B25252A2C74DB602C12015BFD8701 -:1074A000D2A0D10F2A2C748B115BF6B9D2A0D10FC8 -:1074B000DA205BFE3A63FF3800DA20C0B15BFE8A57 -:1074C00064ABF1655F352D2124B1DD2D252463FFEB -:1074D0001FDA202B200C5BFE5663FF1412D5C882E6 -:1074E00020028257C82163FFFC12D5C403E8300490 -:1074F000EE3005B13093209421952263FFFC00000B -:1075000010D5C0910092019302940311D597821077 -:1075100001EA30A21101F031C04004E4160002007B -:1075200011D5B98210234A00032202921011D5828C -:10753000C021921004E4318403830282018100009F -:10754000D23001230000000010D5B09100920193C9 -:1075500002940311D586821001EA30A21101F131A3 -:10756000C04004E41600020011D5A7821013D52BE9 -:10757000032202921004E431840383028201810019 -:1075800000D330013300000010D5A19100810165C6 -:10759000104981026510448103CF1F920193029428 -:1075A0000311D574821001EA30A21101F231C040FA -:1075B00004E41600020011D593821013D5130322A0 -:1075C00002921004E431840383028201C01091030B -:1075D00091029101810000D43001430012D542C0D4 -:1075E0003028374028374428374828374C233D0176 -:1075F0007233ED03020063FFFC00000010D585919B -:107600000092019302940311D5838210921011D538 -:10761000348310032202921011D58012D5469210A5 -:10762000C04004E41600020011D577821013D52D56 -:10763000032202921004E431840383028201810058 -:1076400000D53001530000006C10026E322FD6209E -:10765000056F04043F04745B2A05440C00410400D8 -:10766000331A220A006D490D73630403660CB122BC -:107670000F2211031314736302222C01D10FC83B94 -:10768000D10F000073630CC021D10F000000000077 -:1076900044495630C020D10F6C10020040046B4C9E -:1076A00007032318020219D10F020319C020D10FBA -:1076B0006C100202EA30D10F6C1002CC2503F031BD -:1076C00060000F006F220503F1316000056F230594 -:1076D00003F231000200D10F6C1002CC2502F03011 -:1076E000D10F00006F220402F130D10F6F2304028A -:1076F000F230D10FC020D10F6C1002220A20230AD1 -:10770000006D280E28374028374428374828374C42 -:10771000233D01030200D10F6C100202E431D10FAE -:107720000A004368656C73696F20465720444542E0 -:1077300055473D3020284275696C74204672692097 -:107740004D61792020382031363A30373A333620AF -:107750005044542032303039206F6E20636C656F96 -:1077600070617472612E6173696364657369676EB9 -:107770006572732E636F6D3A2F686F6D652F666546 -:107780006C69782F772F66775F372E31292C20563A -:10779000657273696F6E2054337878203030372EDD -:1077A00030342E3030202D203130303730343030EE -:0877B000100704000071489469 -:00000001FF diff --git a/trunk/include/asm-generic/errno.h b/trunk/include/asm-generic/errno.h index 28cc03bf19e6..e8852c092fea 100644 --- a/trunk/include/asm-generic/errno.h +++ b/trunk/include/asm-generic/errno.h @@ -106,6 +106,4 @@ #define EOWNERDEAD 130 /* Owner died */ #define ENOTRECOVERABLE 131 /* State not recoverable */ -#define ERFKILL 132 /* Operation not possible due to RF-kill */ - #endif diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index 7e09c5c1ed02..3f0eaa397ef5 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -311,7 +311,6 @@ unifdef-y += ptrace.h unifdef-y += qnx4_fs.h unifdef-y += quota.h unifdef-y += random.h -unifdef-y += rfkill.h unifdef-y += irqnr.h unifdef-y += reboot.h unifdef-y += reiserfs_fs.h diff --git a/trunk/include/linux/can/platform/sja1000.h b/trunk/include/linux/can/platform/sja1000.h index 01ee2aeb048d..37966e630ff5 100644 --- a/trunk/include/linux/can/platform/sja1000.h +++ b/trunk/include/linux/can/platform/sja1000.h @@ -13,7 +13,6 @@ #define OCR_MODE_TEST 0x01 #define OCR_MODE_NORMAL 0x02 #define OCR_MODE_CLOCK 0x03 -#define OCR_MODE_MASK 0x07 #define OCR_TX0_INVERT 0x04 #define OCR_TX0_PULLDOWN 0x08 #define OCR_TX0_PULLUP 0x10 @@ -22,8 +21,6 @@ #define OCR_TX1_PULLDOWN 0x40 #define OCR_TX1_PULLUP 0x80 #define OCR_TX1_PUSHPULL 0xc0 -#define OCR_TX_MASK 0xfc -#define OCR_TX_SHIFT 2 struct sja1000_platform_data { u32 clock; /* CAN bus oscillator frequency in Hz */ diff --git a/trunk/include/linux/ethtool.h b/trunk/include/linux/ethtool.h index 9b660bd2e2b3..380b04272bf1 100644 --- a/trunk/include/linux/ethtool.h +++ b/trunk/include/linux/ethtool.h @@ -30,8 +30,7 @@ struct ethtool_cmd { __u32 maxtxpkt; /* Tx pkts before generating tx int */ __u32 maxrxpkt; /* Rx pkts before generating rx int */ __u16 speed_hi; - __u8 eth_tp_mdix; - __u8 reserved2; + __u16 reserved2; __u32 lp_advertising; /* Features the link partner advertises */ __u32 reserved[2]; }; @@ -633,11 +632,6 @@ struct ethtool_ops { #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 -/* Mode MDI or MDI-X */ -#define ETH_TP_MDI_INVALID 0x00 -#define ETH_TP_MDI 0x01 -#define ETH_TP_MDI_X 0x02 - /* Wake-On-Lan options. */ #define WAKE_PHY (1 << 0) #define WAKE_UCAST (1 << 1) diff --git a/trunk/include/linux/ieee80211.h b/trunk/include/linux/ieee80211.h index a9173d5434d1..34de8b21f6d4 100644 --- a/trunk/include/linux/ieee80211.h +++ b/trunk/include/linux/ieee80211.h @@ -1092,7 +1092,6 @@ enum ieee80211_key_len { WLAN_KEY_LEN_WEP104 = 13, WLAN_KEY_LEN_CCMP = 16, WLAN_KEY_LEN_TKIP = 32, - WLAN_KEY_LEN_AES_CMAC = 16, }; /* diff --git a/trunk/include/linux/if_arp.h b/trunk/include/linux/if_arp.h index b554300ef8bf..5ff89809a581 100644 --- a/trunk/include/linux/if_arp.h +++ b/trunk/include/linux/if_arp.h @@ -86,8 +86,6 @@ #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ -#define ARPHRD_IEEE802154 804 -#define ARPHRD_IEEE802154_PHY 805 #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ diff --git a/trunk/include/linux/if_ether.h b/trunk/include/linux/if_ether.h index 11a60e4f0a66..cfe4fe1b7132 100644 --- a/trunk/include/linux/if_ether.h +++ b/trunk/include/linux/if_ether.h @@ -106,7 +106,6 @@ #define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ #define ETH_P_TRAILER 0x001C /* Trailer switch tagging */ #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ -#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ /* * This is an Ethernet frame header. diff --git a/trunk/include/linux/in.h b/trunk/include/linux/in.h index cf196da04ec9..d60122a3a088 100644 --- a/trunk/include/linux/in.h +++ b/trunk/include/linux/in.h @@ -107,7 +107,6 @@ struct in_addr { #define MCAST_JOIN_SOURCE_GROUP 46 #define MCAST_LEAVE_SOURCE_GROUP 47 #define MCAST_MSFILTER 48 -#define IP_MULTICAST_ALL 49 #define MCAST_EXCLUDE 0 #define MCAST_INCLUDE 1 diff --git a/trunk/include/linux/ipv6.h b/trunk/include/linux/ipv6.h index c662efa68289..476d9464ac82 100644 --- a/trunk/include/linux/ipv6.h +++ b/trunk/include/linux/ipv6.h @@ -169,12 +169,6 @@ struct ipv6_devconf { __s32 accept_dad; void *sysctl; }; - -struct ipv6_params { - __s32 disable_ipv6; - __s32 autoconf; -}; -extern struct ipv6_params ipv6_defaults; #endif /* index values for the variables in ipv6_devconf */ diff --git a/trunk/include/linux/isdn/capilli.h b/trunk/include/linux/isdn/capilli.h index 7acb87a44872..35e9b0fd014b 100644 --- a/trunk/include/linux/isdn/capilli.h +++ b/trunk/include/linux/isdn/capilli.h @@ -79,7 +79,7 @@ int attach_capi_ctr(struct capi_ctr *); int detach_capi_ctr(struct capi_ctr *); void capi_ctr_ready(struct capi_ctr * card); -void capi_ctr_down(struct capi_ctr * card); +void capi_ctr_reseted(struct capi_ctr * card); void capi_ctr_suspend_output(struct capi_ctr * card); void capi_ctr_resume_output(struct capi_ctr * card); void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb); diff --git a/trunk/include/linux/mISDNhw.h b/trunk/include/linux/mISDNhw.h index 7f9831da847f..ce900f4c2458 100644 --- a/trunk/include/linux/mISDNhw.h +++ b/trunk/include/linux/mISDNhw.h @@ -89,6 +89,11 @@ struct dchannel { void (*phfunc) (struct dchannel *); u_int state; void *l1; + /* HW access */ + u_char (*read_reg) (void *, u_char); + void (*write_reg) (void *, u_char, u_char); + void (*read_fifo) (void *, u_char *, int); + void (*write_fifo) (void *, u_char *, int); void *hw; int slot; /* multiport card channel slot */ struct timer_list timer; @@ -146,6 +151,11 @@ struct bchannel { u_long Flags; struct work_struct workq; u_int state; + /* HW access */ + u_char (*read_reg) (void *, u_char); + void (*write_reg) (void *, u_char, u_char); + void (*read_fifo) (void *, u_char *, int); + void (*write_fifo) (void *, u_char *, int); void *hw; int slot; /* multiport card channel slot */ struct timer_list timer; diff --git a/trunk/include/linux/mdio.h b/trunk/include/linux/mdio.h index cfdf1df2875e..56851646529a 100644 --- a/trunk/include/linux/mdio.h +++ b/trunk/include/linux/mdio.h @@ -45,7 +45,6 @@ #define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */ /* Media-dependent registers. */ -#define MDIO_PMA_10GBT_SWAPPOL 130 /* 10GBASE-T pair swap & polarity */ #define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */ #define MDIO_PMA_10GBT_SNR 133 /* 10GBASE-T SNR margin, lane A. * Lanes B-D are numbered 134-136. */ @@ -196,14 +195,6 @@ #define MDIO_PHYXS_LNSTAT_SYNC3 0x0008 #define MDIO_PHYXS_LNSTAT_ALIGN 0x1000 -/* PMA 10GBASE-T pair swap & polarity */ -#define MDIO_PMA_10GBT_SWAPPOL_ABNX 0x0001 /* Pair A/B uncrossed */ -#define MDIO_PMA_10GBT_SWAPPOL_CDNX 0x0002 /* Pair C/D uncrossed */ -#define MDIO_PMA_10GBT_SWAPPOL_AREV 0x0100 /* Pair A polarity reversed */ -#define MDIO_PMA_10GBT_SWAPPOL_BREV 0x0200 /* Pair B polarity reversed */ -#define MDIO_PMA_10GBT_SWAPPOL_CREV 0x0400 /* Pair C polarity reversed */ -#define MDIO_PMA_10GBT_SWAPPOL_DREV 0x0800 /* Pair D polarity reversed */ - /* PMA 10GBASE-T TX power register. */ #define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 9ea8d6dfe540..371ece521e58 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -215,12 +215,9 @@ struct netdev_hw_addr { struct list_head list; unsigned char addr[MAX_ADDR_LEN]; unsigned char type; -#define NETDEV_HW_ADDR_T_LAN 1 -#define NETDEV_HW_ADDR_T_SAN 2 -#define NETDEV_HW_ADDR_T_SLAVE 3 -#define NETDEV_HW_ADDR_T_UNICAST 4 - int refcount; - bool synced; +#define NETDEV_HW_ADDR_T_LAN 1 +#define NETDEV_HW_ADDR_T_SAN 2 +#define NETDEV_HW_ADDR_T_SLAVE 3 struct rcu_head rcu_head; }; @@ -776,11 +773,10 @@ struct net_device unsigned char addr_len; /* hardware address length */ unsigned short dev_id; /* for shared network cards */ - struct list_head uc_list; /* Secondary unicast mac - addresses */ + spinlock_t addr_list_lock; + struct dev_addr_list *uc_list; /* Secondary unicast mac addresses */ int uc_count; /* Number of installed ucasts */ int uc_promisc; - spinlock_t addr_list_lock; struct dev_addr_list *mc_list; /* Multicast mac addresses */ int mc_count; /* Number of installed mcasts */ unsigned int promiscuity; @@ -909,6 +905,7 @@ struct net_device #define to_net_dev(d) container_of(d, struct net_device, dev) #define NETDEV_ALIGN 32 +#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) static inline struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev, @@ -979,7 +976,9 @@ static inline bool netdev_uses_trailer_tags(struct net_device *dev) */ static inline void *netdev_priv(const struct net_device *dev) { - return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN); + return (char *)dev + ((sizeof(struct net_device) + + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST); } /* Set the sysfs physical device reference for the network logical device @@ -1840,8 +1839,8 @@ extern int dev_addr_del_multiple(struct net_device *to_dev, /* Functions used for secondary unicast and multicast support */ extern void dev_set_rx_mode(struct net_device *dev); extern void __dev_set_rx_mode(struct net_device *dev); -extern int dev_unicast_delete(struct net_device *dev, void *addr); -extern int dev_unicast_add(struct net_device *dev, void *addr); +extern int dev_unicast_delete(struct net_device *dev, void *addr, int alen); +extern int dev_unicast_add(struct net_device *dev, void *addr, int alen); extern int dev_unicast_sync(struct net_device *to, struct net_device *from); extern void dev_unicast_unsync(struct net_device *to, struct net_device *from); extern int dev_mc_delete(struct net_device *dev, void *addr, int alen, int all); @@ -1903,14 +1902,15 @@ static inline int net_gso_ok(int features, int gso_type) static inline int skb_gso_ok(struct sk_buff *skb, int features) { - return net_gso_ok(features, skb_shinfo(skb)->gso_type) && - (!skb_has_frags(skb) || (features & NETIF_F_FRAGLIST)); + return net_gso_ok(features, skb_shinfo(skb)->gso_type); } static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) { return skb_is_gso(skb) && (!skb_gso_ok(skb, dev->features) || + (skb_shinfo(skb)->frag_list && + !(dev->features & NETIF_F_FRAGLIST)) || unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); } @@ -1920,16 +1920,6 @@ static inline void netif_set_gso_max_size(struct net_device *dev, dev->gso_max_size = size; } -static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, - struct net_device *master) -{ - if (skb->pkt_type == PACKET_HOST) { - u16 *dest = (u16 *) eth_hdr(skb)->h_dest; - - memcpy(dest, master->dev_addr, ETH_ALEN); - } -} - /* On bonding slaves other than the currently active slave, suppress * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and * ARP on active-backup slaves with arp_validate enabled. @@ -1943,14 +1933,6 @@ static inline int skb_bond_should_drop(struct sk_buff *skb) if (master->priv_flags & IFF_MASTER_ARPMON) dev->last_rx = jiffies; - if ((master->priv_flags & IFF_MASTER_ALB) && master->br_port) { - /* Do address unmangle. The local destination address - * will be always the one master has. Provides the right - * functionality in a bridge. - */ - skb_bond_set_mac_by_master(skb, master); - } - if (dev->priv_flags & IFF_SLAVE_INACTIVE) { if ((dev->priv_flags & IFF_SLAVE_NEEDARP) && skb->protocol == __cpu_to_be16(ETH_P_ARP)) @@ -1996,4 +1978,4 @@ static inline u32 dev_ethtool_get_flags(struct net_device *dev) } #endif /* __KERNEL__ */ -#endif /* _LINUX_NETDEVICE_H */ +#endif /* _LINUX_DEV_H */ diff --git a/trunk/include/linux/netfilter/nf_conntrack_tcp.h b/trunk/include/linux/netfilter/nf_conntrack_tcp.h index b2f384d42611..3066789b972a 100644 --- a/trunk/include/linux/netfilter/nf_conntrack_tcp.h +++ b/trunk/include/linux/netfilter/nf_conntrack_tcp.h @@ -35,9 +35,6 @@ enum tcp_conntrack { /* Has unacknowledged data */ #define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10 -/* The field td_maxack has been set */ -#define IP_CT_TCP_FLAG_MAXACK_SET 0x20 - struct nf_ct_tcp_flags { __u8 flags; __u8 mask; @@ -49,7 +46,6 @@ struct ip_ct_tcp_state { u_int32_t td_end; /* max of seq + len */ u_int32_t td_maxend; /* max of ack + max(win, 1) */ u_int32_t td_maxwin; /* max(win) */ - u_int32_t td_maxack; /* max of ack */ u_int8_t td_scale; /* window scale factor */ u_int8_t flags; /* per direction options */ }; diff --git a/trunk/include/linux/netfilter/nfnetlink_conntrack.h b/trunk/include/linux/netfilter/nfnetlink_conntrack.h index 1a865e48b8eb..ed4ef8d0b11b 100644 --- a/trunk/include/linux/netfilter/nfnetlink_conntrack.h +++ b/trunk/include/linux/netfilter/nfnetlink_conntrack.h @@ -101,6 +101,7 @@ enum ctattr_protoinfo_dccp { CTA_PROTOINFO_DCCP_UNSPEC, CTA_PROTOINFO_DCCP_STATE, CTA_PROTOINFO_DCCP_ROLE, + CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ, __CTA_PROTOINFO_DCCP_MAX, }; #define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1) diff --git a/trunk/include/linux/nl802154.h b/trunk/include/linux/nl802154.h deleted file mode 100644 index 2cda00ccfcca..000000000000 --- a/trunk/include/linux/nl802154.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * nl802154.h - * - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef NL802154_H -#define NL802154_H - -#define IEEE802154_NL_NAME "802.15.4 MAC" -#define IEEE802154_MCAST_COORD_NAME "coordinator" -#define IEEE802154_MCAST_BEACON_NAME "beacon" - -enum { - __IEEE802154_ATTR_INVALID, - - IEEE802154_ATTR_DEV_NAME, - IEEE802154_ATTR_DEV_INDEX, - - IEEE802154_ATTR_STATUS, - - IEEE802154_ATTR_SHORT_ADDR, - IEEE802154_ATTR_HW_ADDR, - IEEE802154_ATTR_PAN_ID, - - IEEE802154_ATTR_CHANNEL, - - IEEE802154_ATTR_COORD_SHORT_ADDR, - IEEE802154_ATTR_COORD_HW_ADDR, - IEEE802154_ATTR_COORD_PAN_ID, - - IEEE802154_ATTR_SRC_SHORT_ADDR, - IEEE802154_ATTR_SRC_HW_ADDR, - IEEE802154_ATTR_SRC_PAN_ID, - - IEEE802154_ATTR_DEST_SHORT_ADDR, - IEEE802154_ATTR_DEST_HW_ADDR, - IEEE802154_ATTR_DEST_PAN_ID, - - IEEE802154_ATTR_CAPABILITY, - IEEE802154_ATTR_REASON, - IEEE802154_ATTR_SCAN_TYPE, - IEEE802154_ATTR_CHANNELS, - IEEE802154_ATTR_DURATION, - IEEE802154_ATTR_ED_LIST, - IEEE802154_ATTR_BCN_ORD, - IEEE802154_ATTR_SF_ORD, - IEEE802154_ATTR_PAN_COORD, - IEEE802154_ATTR_BAT_EXT, - IEEE802154_ATTR_COORD_REALIGN, - IEEE802154_ATTR_SEC, - - __IEEE802154_ATTR_MAX, -}; - -#define IEEE802154_ATTR_MAX (__IEEE802154_ATTR_MAX - 1) - -extern struct nla_policy ieee802154_policy[]; - -/* commands */ -/* REQ should be responded with CONF - * and INDIC with RESP - */ -enum { - __IEEE802154_COMMAND_INVALID, - - IEEE802154_ASSOCIATE_REQ, - IEEE802154_ASSOCIATE_CONF, - IEEE802154_DISASSOCIATE_REQ, - IEEE802154_DISASSOCIATE_CONF, - IEEE802154_GET_REQ, - IEEE802154_GET_CONF, - IEEE802154_RESET_REQ, - IEEE802154_RESET_CONF, - IEEE802154_SCAN_REQ, - IEEE802154_SCAN_CONF, - IEEE802154_SET_REQ, - IEEE802154_SET_CONF, - IEEE802154_START_REQ, - IEEE802154_START_CONF, - IEEE802154_SYNC_REQ, - IEEE802154_POLL_REQ, - IEEE802154_POLL_CONF, - - IEEE802154_ASSOCIATE_INDIC, - IEEE802154_ASSOCIATE_RESP, - IEEE802154_DISASSOCIATE_INDIC, - IEEE802154_BEACON_NOTIFY_INDIC, - IEEE802154_ORPHAN_INDIC, - IEEE802154_ORPHAN_RESP, - IEEE802154_COMM_STATUS_INDIC, - IEEE802154_SYNC_LOSS_INDIC, - - IEEE802154_GTS_REQ, /* Not supported yet */ - IEEE802154_GTS_INDIC, /* Not supported yet */ - IEEE802154_GTS_CONF, /* Not supported yet */ - IEEE802154_RX_ENABLE_REQ, /* Not supported yet */ - IEEE802154_RX_ENABLE_CONF, /* Not supported yet */ - - __IEEE802154_CMD_MAX, -}; - -#define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1) - -#endif diff --git a/trunk/include/linux/notifier.h b/trunk/include/linux/notifier.h index 81bc252dc8ac..b86fa2ffca0c 100644 --- a/trunk/include/linux/notifier.h +++ b/trunk/include/linux/notifier.h @@ -198,7 +198,6 @@ static inline int notifier_to_errno(int ret) #define NETDEV_CHANGENAME 0x000A #define NETDEV_FEAT_CHANGE 0x000B #define NETDEV_BONDING_FAILOVER 0x000C -#define NETDEV_PRE_UP 0x000D #define SYS_DOWN 0x0001 /* Notify of system down */ #define SYS_RESTART SYS_DOWN diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index b87c51aea14c..12db06cf0e23 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1066,6 +1066,8 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS 0x0034 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 +#define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 +#define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA 0x0040 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800 0x0041 @@ -1076,16 +1078,21 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 +#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 +#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 #define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 #define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005d #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 +#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 #define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS 0x0084 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 +#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086 #define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089 #define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a +#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT 0x0090 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX 0x0091 @@ -1101,12 +1108,15 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 #define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da +#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df #define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS 0x00e4 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6 #define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee #define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0 @@ -1166,6 +1176,7 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01b4 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc #define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM 0x01c1 +#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3 #define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201 @@ -1188,6 +1199,8 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F +#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 +#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 @@ -1234,21 +1247,46 @@ #define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2 0x0348 #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000 0x034C #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E +#define PCI_DEVICE_ID_NVIDIA_NVENET_14 0x0372 #define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 +#define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS 0x03EB #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC +#define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE +#define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS 0x0446 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448 +#define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450 +#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451 +#define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452 +#define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS 0x0542 +#define PCI_DEVICE_ID_NVIDIA_NVENET_24 0x054C +#define PCI_DEVICE_ID_NVIDIA_NVENET_25 0x054D +#define PCI_DEVICE_ID_NVIDIA_NVENET_26 0x054E +#define PCI_DEVICE_ID_NVIDIA_NVENET_27 0x054F +#define PCI_DEVICE_ID_NVIDIA_NVENET_28 0x07DC +#define PCI_DEVICE_ID_NVIDIA_NVENET_29 0x07DD +#define PCI_DEVICE_ID_NVIDIA_NVENET_30 0x07DE +#define PCI_DEVICE_ID_NVIDIA_NVENET_31 0x07DF #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE 0x056C #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS 0x0752 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE 0x0759 +#define PCI_DEVICE_ID_NVIDIA_NVENET_32 0x0760 +#define PCI_DEVICE_ID_NVIDIA_NVENET_33 0x0761 +#define PCI_DEVICE_ID_NVIDIA_NVENET_34 0x0762 +#define PCI_DEVICE_ID_NVIDIA_NVENET_35 0x0763 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS 0x07D8 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS 0x0AA2 +#define PCI_DEVICE_ID_NVIDIA_NVENET_36 0x0AB0 +#define PCI_DEVICE_ID_NVIDIA_NVENET_37 0x0AB1 +#define PCI_DEVICE_ID_NVIDIA_NVENET_38 0x0AB2 +#define PCI_DEVICE_ID_NVIDIA_NVENET_39 0x0AB3 #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_TT128 0x9128 diff --git a/trunk/include/linux/rfkill.h b/trunk/include/linux/rfkill.h index 16e39c7a67fc..de18ef227e00 100644 --- a/trunk/include/linux/rfkill.h +++ b/trunk/include/linux/rfkill.h @@ -4,7 +4,6 @@ /* * Copyright (C) 2006 - 2007 Ivo van Doorn * Copyright (C) 2007 Dmitry Torokhov - * Copyright 2009 Johannes Berg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,331 +22,117 @@ */ #include - -/* define userspace visible states */ -#define RFKILL_STATE_SOFT_BLOCKED 0 -#define RFKILL_STATE_UNBLOCKED 1 -#define RFKILL_STATE_HARD_BLOCKED 2 +#include +#include +#include +#include +#include /** * enum rfkill_type - type of rfkill switch. - * - * @RFKILL_TYPE_ALL: toggles all switches (userspace only) - * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. - * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. - * @RFKILL_TYPE_UWB: switch is on a ultra wideband device. - * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device. - * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device. - * @NUM_RFKILL_TYPES: number of defined rfkill types + * RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. + * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. + * RFKILL_TYPE_UWB: switch is on a ultra wideband device. + * RFKILL_TYPE_WIMAX: switch is on a WiMAX device. + * RFKILL_TYPE_WWAN: switch is on a wireless WAN device. */ enum rfkill_type { - RFKILL_TYPE_ALL = 0, - RFKILL_TYPE_WLAN, + RFKILL_TYPE_WLAN , RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_UWB, RFKILL_TYPE_WIMAX, RFKILL_TYPE_WWAN, - NUM_RFKILL_TYPES, + RFKILL_TYPE_MAX, }; -/** - * enum rfkill_operation - operation types - * @RFKILL_OP_ADD: a device was added - * @RFKILL_OP_DEL: a device was removed - * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device - * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all) - */ -enum rfkill_operation { - RFKILL_OP_ADD = 0, - RFKILL_OP_DEL, - RFKILL_OP_CHANGE, - RFKILL_OP_CHANGE_ALL, +enum rfkill_state { + RFKILL_STATE_SOFT_BLOCKED = 0, /* Radio output blocked */ + RFKILL_STATE_UNBLOCKED = 1, /* Radio output allowed */ + RFKILL_STATE_HARD_BLOCKED = 2, /* Output blocked, non-overrideable */ + RFKILL_STATE_MAX, /* marker for last valid state */ }; /** - * struct rfkill_event - events for userspace on /dev/rfkill - * @idx: index of dev rfkill - * @type: type of the rfkill struct - * @op: operation code - * @hard: hard state (0/1) - * @soft: soft state (0/1) - * - * Structure used for userspace communication on /dev/rfkill, - * used for events from the kernel and control to the kernel. - */ -struct rfkill_event { - __u32 idx; - __u8 type; - __u8 op; - __u8 soft, hard; -} __packed; - -/* ioctl for turning off rfkill-input (if present) */ -#define RFKILL_IOC_MAGIC 'R' -#define RFKILL_IOC_NOINPUT 1 -#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT) - -/* and that's all userspace gets */ -#ifdef __KERNEL__ -/* don't allow anyone to use these in the kernel */ -enum rfkill_user_states { - RFKILL_USER_STATE_SOFT_BLOCKED = RFKILL_STATE_SOFT_BLOCKED, - RFKILL_USER_STATE_UNBLOCKED = RFKILL_STATE_UNBLOCKED, - RFKILL_USER_STATE_HARD_BLOCKED = RFKILL_STATE_HARD_BLOCKED, -}; -#undef RFKILL_STATE_SOFT_BLOCKED -#undef RFKILL_STATE_UNBLOCKED -#undef RFKILL_STATE_HARD_BLOCKED + * struct rfkill - rfkill control structure. + * @name: Name of the switch. + * @type: Radio type which the button controls, the value stored + * here should be a value from enum rfkill_type. + * @state: State of the switch, "UNBLOCKED" means radio can operate. + * @mutex: Guards switch state transitions. It serializes callbacks + * and also protects the state. + * @data: Pointer to the RF button drivers private data which will be + * passed along when toggling radio state. + * @toggle_radio(): Mandatory handler to control state of the radio. + * only RFKILL_STATE_SOFT_BLOCKED and RFKILL_STATE_UNBLOCKED are + * valid parameters. + * @get_state(): handler to read current radio state from hardware, + * may be called from atomic context, should return 0 on success. + * Either this handler OR judicious use of rfkill_force_state() is + * MANDATORY for any driver capable of RFKILL_STATE_HARD_BLOCKED. + * @led_trigger: A LED trigger for this button's LED. + * @dev: Device structure integrating the switch into device tree. + * @node: Used to place switch into list of all switches known to the + * the system. + * + * This structure represents a RF switch located on a network device. + */ +struct rfkill { + const char *name; + enum rfkill_type type; + + /* the mutex serializes callbacks and also protects + * the state */ + struct mutex mutex; + enum rfkill_state state; + void *data; + int (*toggle_radio)(void *data, enum rfkill_state state); + int (*get_state)(void *data, enum rfkill_state *state); -#include -#include -#include -#include -#include -#include -#include - -/* this is opaque */ -struct rfkill; +#ifdef CONFIG_RFKILL_LEDS + struct led_trigger led_trigger; +#endif -/** - * struct rfkill_ops - rfkill driver methods - * - * @poll: poll the rfkill block state(s) -- only assign this method - * when you need polling. When called, simply call one of the - * rfkill_set{,_hw,_sw}_state family of functions. If the hw - * is getting unblocked you need to take into account the return - * value of those functions to make sure the software block is - * properly used. - * @query: query the rfkill block state(s) and call exactly one of the - * rfkill_set{,_hw,_sw}_state family of functions. Assign this - * method if input events can cause hardware state changes to make - * the rfkill core query your driver before setting a requested - * block. - * @set_block: turn the transmitter on (blocked == false) or off - * (blocked == true) -- ignore and return 0 when hard blocked. - * This callback must be assigned. - */ -struct rfkill_ops { - void (*poll)(struct rfkill *rfkill, void *data); - void (*query)(struct rfkill *rfkill, void *data); - int (*set_block)(void *data, bool blocked); + struct device dev; + struct list_head node; + enum rfkill_state state_for_resume; }; +#define to_rfkill(d) container_of(d, struct rfkill, dev) -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -/** - * rfkill_alloc - allocate rfkill structure - * @name: name of the struct -- the string is not copied internally - * @parent: device that has rf switch on it - * @type: type of the switch (RFKILL_TYPE_*) - * @ops: rfkill methods - * @ops_data: data passed to each method - * - * This function should be called by the transmitter driver to allocate an - * rfkill structure. Returns %NULL on failure. - */ -struct rfkill * __must_check rfkill_alloc(const char *name, - struct device *parent, - const enum rfkill_type type, - const struct rfkill_ops *ops, - void *ops_data); - -/** - * rfkill_register - Register a rfkill structure. - * @rfkill: rfkill structure to be registered - * - * This function should be called by the transmitter driver to register - * the rfkill structure. Before calling this function the driver needs - * to be ready to service method calls from rfkill. - * - * If the software blocked state is not set before registration, - * set_block will be called to initialize it to a default value. - * - * If the hardware blocked state is not set before registration, - * it is assumed to be unblocked. - */ +struct rfkill * __must_check rfkill_allocate(struct device *parent, + enum rfkill_type type); +void rfkill_free(struct rfkill *rfkill); int __must_check rfkill_register(struct rfkill *rfkill); - -/** - * rfkill_pause_polling(struct rfkill *rfkill) - * - * Pause polling -- say transmitter is off for other reasons. - * NOTE: not necessary for suspend/resume -- in that case the - * core stops polling anyway - */ -void rfkill_pause_polling(struct rfkill *rfkill); - -/** - * rfkill_resume_polling(struct rfkill *rfkill) - * - * Pause polling -- say transmitter is off for other reasons. - * NOTE: not necessary for suspend/resume -- in that case the - * core stops polling anyway - */ -void rfkill_resume_polling(struct rfkill *rfkill); - - -/** - * rfkill_unregister - Unregister a rfkill structure. - * @rfkill: rfkill structure to be unregistered - * - * This function should be called by the network driver during device - * teardown to destroy rfkill structure. Until it returns, the driver - * needs to be able to service method calls. - */ void rfkill_unregister(struct rfkill *rfkill); -/** - * rfkill_destroy - free rfkill structure - * @rfkill: rfkill structure to be destroyed - * - * Destroys the rfkill structure. - */ -void rfkill_destroy(struct rfkill *rfkill); - -/** - * rfkill_set_hw_state - Set the internal rfkill hardware block state - * @rfkill: pointer to the rfkill class to modify. - * @state: the current hardware block state to set - * - * rfkill drivers that get events when the hard-blocked state changes - * use this function to notify the rfkill core (and through that also - * userspace) of the current state. They should also use this after - * resume if the state could have changed. - * - * You need not (but may) call this function if poll_state is assigned. - * - * This function can be called in any context, even from within rfkill - * callbacks. - * - * The function returns the combined block state (true if transmitter - * should be blocked) so that drivers need not keep track of the soft - * block state -- which they might not be able to. - */ -bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); - -/** - * rfkill_set_sw_state - Set the internal rfkill software block state - * @rfkill: pointer to the rfkill class to modify. - * @state: the current software block state to set - * - * rfkill drivers that get events when the soft-blocked state changes - * (yes, some platforms directly act on input but allow changing again) - * use this function to notify the rfkill core (and through that also - * userspace) of the current state. It is not necessary to notify on - * resume; since hibernation can always change the soft-blocked state, - * the rfkill core will unconditionally restore the previous state. - * - * This function can be called in any context, even from within rfkill - * callbacks. - * - * The function returns the combined block state (true if transmitter - * should be blocked). - */ -bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked); - -/** - * rfkill_set_states - Set the internal rfkill block states - * @rfkill: pointer to the rfkill class to modify. - * @sw: the current software block state to set - * @hw: the current hardware block state to set - * - * This function can be called in any context, even from within rfkill - * callbacks. - */ -void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); +int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state); +int rfkill_set_default(enum rfkill_type type, enum rfkill_state state); /** - * rfkill_blocked - query rfkill block + * rfkill_state_complement - return complementar state + * @state: state to return the complement of * - * @rfkill: rfkill struct to query + * Returns RFKILL_STATE_SOFT_BLOCKED if @state is RFKILL_STATE_UNBLOCKED, + * returns RFKILL_STATE_UNBLOCKED otherwise. */ -bool rfkill_blocked(struct rfkill *rfkill); -#else /* !RFKILL */ -static inline struct rfkill * __must_check -rfkill_alloc(const char *name, - struct device *parent, - const enum rfkill_type type, - const struct rfkill_ops *ops, - void *ops_data) -{ - return ERR_PTR(-ENODEV); -} - -static inline int __must_check rfkill_register(struct rfkill *rfkill) -{ - if (rfkill == ERR_PTR(-ENODEV)) - return 0; - return -EINVAL; -} - -static inline void rfkill_pause_polling(struct rfkill *rfkill) -{ -} - -static inline void rfkill_resume_polling(struct rfkill *rfkill) -{ -} - -static inline void rfkill_unregister(struct rfkill *rfkill) -{ -} - -static inline void rfkill_destroy(struct rfkill *rfkill) +static inline enum rfkill_state rfkill_state_complement(enum rfkill_state state) { + return (state == RFKILL_STATE_UNBLOCKED) ? + RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED; } -static inline bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) -{ - return blocked; -} - -static inline bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) -{ - return blocked; -} - -static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) -{ -} - -static inline bool rfkill_blocked(struct rfkill *rfkill) -{ - return false; -} -#endif /* RFKILL || RFKILL_MODULE */ - - -#ifdef CONFIG_RFKILL_LEDS /** - * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED. + * rfkill_get_led_name - Get the LED trigger name for the button's LED. * This function might return a NULL pointer if registering of the - * LED trigger failed. Use this as "default_trigger" for the LED. + * LED trigger failed. + * Use this as "default_trigger" for the LED. */ -const char *rfkill_get_led_trigger_name(struct rfkill *rfkill); - -/** - * rfkill_set_led_trigger_name -- set the LED trigger name - * @rfkill: rfkill struct - * @name: LED trigger name - * - * This function sets the LED trigger name of the radio LED - * trigger that rfkill creates. It is optional, but if called - * must be called before rfkill_register() to be effective. - */ -void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name); -#else -static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) +static inline char *rfkill_get_led_name(struct rfkill *rfkill) { +#ifdef CONFIG_RFKILL_LEDS + return (char *)(rfkill->led_trigger.name); +#else return NULL; -} - -static inline void -rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name) -{ -} #endif - -#endif /* __KERNEL__ */ +} #endif /* RFKILL_H */ diff --git a/trunk/include/linux/sctp.h b/trunk/include/linux/sctp.h index b464b9d3d242..c2731bfe04d8 100644 --- a/trunk/include/linux/sctp.h +++ b/trunk/include/linux/sctp.h @@ -487,17 +487,17 @@ typedef enum { * * Value Cause Code * --------- ---------------- - * 0x00A0 Request to Delete Last Remaining IP Address. - * 0x00A1 Operation Refused Due to Resource Shortage. - * 0x00A2 Request to Delete Source IP Address. - * 0x00A3 Association Aborted due to illegal ASCONF-ACK - * 0x00A4 Request refused - no authorization. + * 0x0100 Request to Delete Last Remaining IP Address. + * 0x0101 Operation Refused Due to Resource Shortage. + * 0x0102 Request to Delete Source IP Address. + * 0x0103 Association Aborted due to illegal ASCONF-ACK + * 0x0104 Request refused - no authorization. */ - SCTP_ERROR_DEL_LAST_IP = cpu_to_be16(0x00A0), - SCTP_ERROR_RSRC_LOW = cpu_to_be16(0x00A1), - SCTP_ERROR_DEL_SRC_IP = cpu_to_be16(0x00A2), - SCTP_ERROR_ASCONF_ACK = cpu_to_be16(0x00A3), - SCTP_ERROR_REQ_REFUSED = cpu_to_be16(0x00A4), + SCTP_ERROR_DEL_LAST_IP = cpu_to_be16(0x0100), + SCTP_ERROR_RSRC_LOW = cpu_to_be16(0x0101), + SCTP_ERROR_DEL_SRC_IP = cpu_to_be16(0x0102), + SCTP_ERROR_ASCONF_ACK = cpu_to_be16(0x0103), + SCTP_ERROR_REQ_REFUSED = cpu_to_be16(0x0104), /* AUTH Section 4. New Error Cause * diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index fa51293f2708..aff494ba6a31 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -189,19 +189,19 @@ struct skb_shared_info { atomic_t dataref; unsigned short nr_frags; unsigned short gso_size; -#ifdef CONFIG_HAS_DMA - dma_addr_t dma_head; -#endif /* Warning: this field is not always filled in (UFO)! */ unsigned short gso_segs; unsigned short gso_type; __be32 ip6_frag_id; union skb_shared_tx tx_flags; +#ifdef CONFIG_HAS_DMA + unsigned int num_dma_maps; +#endif struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; skb_frag_t frags[MAX_SKB_FRAGS]; #ifdef CONFIG_HAS_DMA - dma_addr_t dma_maps[MAX_SKB_FRAGS]; + dma_addr_t dma_maps[MAX_SKB_FRAGS + 1]; #endif /* Intermediate layers must ensure that destructor_arg * remains valid until skb destructor */ @@ -304,6 +304,9 @@ typedef unsigned char *sk_buff_data_t; * @tc_verd: traffic control verdict * @ndisc_nodetype: router type (from link layer) * @do_not_encrypt: set to prevent encryption of this frame + * @requeue: set to indicate that the wireless core should attempt + * a software retry on this frame if we failed to + * receive an ACK for it * @dma_cookie: a cookie to one of several possible DMA operations * done by skb DMA functions * @secmark: security marking @@ -319,7 +322,10 @@ struct sk_buff { ktime_t tstamp; struct net_device *dev; - unsigned long _skb_dst; + union { + struct dst_entry *dst; + struct rtable *rtable; + }; #ifdef CONFIG_XFRM struct sec_path *sp; #endif @@ -377,6 +383,7 @@ struct sk_buff { #endif #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) __u8 do_not_encrypt:1; + __u8 requeue:1; #endif /* 0/13/14 bit hole */ @@ -419,21 +426,6 @@ extern void skb_dma_unmap(struct device *dev, struct sk_buff *skb, enum dma_data_direction dir); #endif -static inline struct dst_entry *skb_dst(const struct sk_buff *skb) -{ - return (struct dst_entry *)skb->_skb_dst; -} - -static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) -{ - skb->_skb_dst = (unsigned long)dst; -} - -static inline struct rtable *skb_rtable(const struct sk_buff *skb) -{ - return (struct rtable *)skb_dst(skb); -} - extern void kfree_skb(struct sk_buff *skb); extern void consume_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); @@ -1073,7 +1065,7 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, int size); #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) -#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frags(skb)) +#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_shinfo(skb)->frag_list) #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) #ifdef NET_SKBUFF_DATA_USES_OFFSET @@ -1712,25 +1704,6 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb = skb->prev) -static inline bool skb_has_frags(const struct sk_buff *skb) -{ - return skb_shinfo(skb)->frag_list != NULL; -} - -static inline void skb_frag_list_init(struct sk_buff *skb) -{ - skb_shinfo(skb)->frag_list = NULL; -} - -static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag) -{ - frag->next = skb_shinfo(skb)->frag_list; - skb_shinfo(skb)->frag_list = frag; -} - -#define skb_walk_frags(skb, iter) \ - for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next) - extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, int *peeked, int *err); extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index 3b461dffe244..d2310cb45d2f 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -194,8 +194,7 @@ struct ucred { #define AF_RXRPC 33 /* RxRPC sockets */ #define AF_ISDN 34 /* mISDN sockets */ #define AF_PHONET 35 /* Phonet sockets */ -#define AF_IEEE802154 36 /* IEEE802154 sockets */ -#define AF_MAX 37 /* For now.. */ +#define AF_MAX 36 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -234,7 +233,6 @@ struct ucred { #define PF_RXRPC AF_RXRPC #define PF_ISDN AF_ISDN #define PF_PHONET AF_PHONET -#define PF_IEEE802154 AF_IEEE802154 #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ diff --git a/trunk/include/linux/spi/libertas_spi.h b/trunk/include/linux/spi/libertas_spi.h index 1b5d5384fcd3..79506f5f9e67 100644 --- a/trunk/include/linux/spi/libertas_spi.h +++ b/trunk/include/linux/spi/libertas_spi.h @@ -22,6 +22,9 @@ struct libertas_spi_platform_data { * speed, you may want to use 0 here. */ u16 use_dummy_writes; + /* GPIO number to use as chip select */ + u16 gpio_cs; + /* Board specific setup/teardown */ int (*setup)(struct spi_device *spi); int (*teardown)(struct spi_device *spi); diff --git a/trunk/include/linux/wimax.h b/trunk/include/linux/wimax.h index 4fdcc5635518..c89de7f4e5b9 100644 --- a/trunk/include/linux/wimax.h +++ b/trunk/include/linux/wimax.h @@ -59,7 +59,7 @@ enum { * M - Major: change if removing or modifying an existing call. * m - minor: change when adding a new call */ - WIMAX_GNL_VERSION = 01, + WIMAX_GNL_VERSION = 00, /* Generic NetLink attributes */ WIMAX_GNL_ATTR_INVALID = 0x00, WIMAX_GNL_ATTR_MAX = 10, @@ -78,7 +78,6 @@ enum { WIMAX_GNL_OP_RFKILL, /* Run wimax_rfkill() */ WIMAX_GNL_OP_RESET, /* Run wimax_rfkill() */ WIMAX_GNL_RE_STATE_CHANGE, /* Report: status change */ - WIMAX_GNL_OP_STATE_GET, /* Request for current state */ }; @@ -114,10 +113,6 @@ enum { WIMAX_GNL_RESET_IFIDX = 1, }; -/* Atributes for wimax_state_get() */ -enum { - WIMAX_GNL_STGET_IFIDX = 1, -}; /* * Attributes for the Report State Change diff --git a/trunk/include/linux/wimax/i2400m.h b/trunk/include/linux/wimax/i2400m.h index 433693ef2bb0..d5148a7889a6 100644 --- a/trunk/include/linux/wimax/i2400m.h +++ b/trunk/include/linux/wimax/i2400m.h @@ -266,7 +266,7 @@ enum i2400m_ro_type { /* Misc constants */ enum { - I2400M_PL_ALIGN = 16, /* Payload data size alignment */ + I2400M_PL_PAD = 16, /* Payload data size alignment */ I2400M_PL_SIZE_MAX = 0x3EFF, I2400M_MAX_PLS_IN_MSG = 60, /* protocol barkers: sync sequences; for notifications they diff --git a/trunk/include/net/bluetooth/bluetooth.h b/trunk/include/net/bluetooth/bluetooth.h index 968166a45f86..3ad5390a4dd5 100644 --- a/trunk/include/net/bluetooth/bluetooth.h +++ b/trunk/include/net/bluetooth/bluetooth.h @@ -81,6 +81,12 @@ enum { BT_CLOSED }; +/* Endianness conversions */ +#define htobs(a) __cpu_to_le16(a) +#define htobl(a) __cpu_to_le32(a) +#define btohs(a) __le16_to_cpu(a) +#define btohl(a) __le32_to_cpu(a) + /* BD Address */ typedef struct { __u8 b[6]; @@ -165,6 +171,15 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l return skb; } +static inline int skb_frags_no(struct sk_buff *skb) +{ + register struct sk_buff *frag = skb_shinfo(skb)->frag_list; + register int n = 1; + + for (; frag; frag=frag->next, n++); + return n; +} + int bt_err(__u16 code); extern int hci_sock_init(void); diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index c4ca4228b083..73aead222b32 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -137,8 +137,6 @@ struct hci_dev { struct device *parent; struct device dev; - struct rfkill *rfkill; - struct module *owner; int (*open)(struct hci_dev *hdev); diff --git a/trunk/include/net/bluetooth/l2cap.h b/trunk/include/net/bluetooth/l2cap.h index e919fca1072a..f566aa1f0a4c 100644 --- a/trunk/include/net/bluetooth/l2cap.h +++ b/trunk/include/net/bluetooth/l2cap.h @@ -26,13 +26,8 @@ #define __L2CAP_H /* L2CAP defaults */ -#define L2CAP_DEFAULT_MTU 672 -#define L2CAP_DEFAULT_FLUSH_TO 0xffff -#define L2CAP_DEFAULT_RX_WINDOW 1 -#define L2CAP_DEFAULT_MAX_RECEIVE 1 -#define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */ -#define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */ -#define L2CAP_DEFAULT_MAX_RX_APDU 0xfff7 +#define L2CAP_DEFAULT_MTU 672 +#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ @@ -69,29 +64,17 @@ struct l2cap_conninfo { #define L2CAP_LM_SECURE 0x0020 /* L2CAP command codes */ -#define L2CAP_COMMAND_REJ 0x01 -#define L2CAP_CONN_REQ 0x02 -#define L2CAP_CONN_RSP 0x03 -#define L2CAP_CONF_REQ 0x04 -#define L2CAP_CONF_RSP 0x05 -#define L2CAP_DISCONN_REQ 0x06 -#define L2CAP_DISCONN_RSP 0x07 -#define L2CAP_ECHO_REQ 0x08 -#define L2CAP_ECHO_RSP 0x09 -#define L2CAP_INFO_REQ 0x0a -#define L2CAP_INFO_RSP 0x0b - -/* L2CAP feature mask */ -#define L2CAP_FEAT_FLOWCTL 0x00000001 -#define L2CAP_FEAT_RETRANS 0x00000002 -#define L2CAP_FEAT_ERTM 0x00000008 -#define L2CAP_FEAT_STREAMING 0x00000010 -#define L2CAP_FEAT_FCS 0x00000020 -#define L2CAP_FEAT_FIXED_CHAN 0x00000080 - -/* L2CAP checksum option */ -#define L2CAP_FCS_NONE 0x00 -#define L2CAP_FCS_CRC16 0x01 +#define L2CAP_COMMAND_REJ 0x01 +#define L2CAP_CONN_REQ 0x02 +#define L2CAP_CONN_RSP 0x03 +#define L2CAP_CONF_REQ 0x04 +#define L2CAP_CONF_RSP 0x05 +#define L2CAP_DISCONN_REQ 0x06 +#define L2CAP_DISCONN_RSP 0x07 +#define L2CAP_ECHO_REQ 0x08 +#define L2CAP_ECHO_RSP 0x09 +#define L2CAP_INFO_REQ 0x0a +#define L2CAP_INFO_RSP 0x0b /* L2CAP structures */ struct l2cap_hdr { @@ -123,23 +106,17 @@ struct l2cap_conn_rsp { __le16 status; } __attribute__ ((packed)); -/* channel indentifier */ -#define L2CAP_CID_SIGNALING 0x0001 -#define L2CAP_CID_CONN_LESS 0x0002 -#define L2CAP_CID_DYN_START 0x0040 -#define L2CAP_CID_DYN_END 0xffff - /* connect result */ -#define L2CAP_CR_SUCCESS 0x0000 -#define L2CAP_CR_PEND 0x0001 -#define L2CAP_CR_BAD_PSM 0x0002 -#define L2CAP_CR_SEC_BLOCK 0x0003 -#define L2CAP_CR_NO_MEM 0x0004 +#define L2CAP_CR_SUCCESS 0x0000 +#define L2CAP_CR_PEND 0x0001 +#define L2CAP_CR_BAD_PSM 0x0002 +#define L2CAP_CR_SEC_BLOCK 0x0003 +#define L2CAP_CR_NO_MEM 0x0004 /* connect status */ -#define L2CAP_CS_NO_INFO 0x0000 -#define L2CAP_CS_AUTHEN_PEND 0x0001 -#define L2CAP_CS_AUTHOR_PEND 0x0002 +#define L2CAP_CS_NO_INFO 0x0000 +#define L2CAP_CS_AUTHEN_PEND 0x0001 +#define L2CAP_CS_AUTHOR_PEND 0x0002 struct l2cap_conf_req { __le16 dcid; @@ -166,14 +143,10 @@ struct l2cap_conf_opt { } __attribute__ ((packed)); #define L2CAP_CONF_OPT_SIZE 2 -#define L2CAP_CONF_HINT 0x80 -#define L2CAP_CONF_MASK 0x7f - #define L2CAP_CONF_MTU 0x01 #define L2CAP_CONF_FLUSH_TO 0x02 #define L2CAP_CONF_QOS 0x03 #define L2CAP_CONF_RFC 0x04 -#define L2CAP_CONF_FCS 0x05 #define L2CAP_CONF_MAX_SIZE 22 @@ -189,8 +162,6 @@ struct l2cap_conf_rfc { #define L2CAP_MODE_BASIC 0x00 #define L2CAP_MODE_RETRANS 0x01 #define L2CAP_MODE_FLOWCTL 0x02 -#define L2CAP_MODE_ERTM 0x03 -#define L2CAP_MODE_STREAM 0x04 struct l2cap_disconn_req { __le16 dcid; diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 1a21895b732b..f20da7d63b1e 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -751,19 +751,6 @@ enum wiphy_params_flags { WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, }; -/** - * enum tx_power_setting - TX power adjustment - * - * @TX_POWER_AUTOMATIC: the dbm parameter is ignored - * @TX_POWER_LIMITED: limit TX power by the dbm parameter - * @TX_POWER_FIXED: fix TX power to the dbm parameter - */ -enum tx_power_setting { - TX_POWER_AUTOMATIC, - TX_POWER_LIMITED, - TX_POWER_FIXED, -}; - /** * struct cfg80211_ops - backend description for wireless configuration * @@ -850,13 +837,6 @@ enum tx_power_setting { * @changed bitfield (see &enum wiphy_params_flags) describes which values * have changed. The actual parameter values are available in * struct wiphy. If returning an error, no value should be changed. - * - * @set_tx_power: set the transmit power according to the parameters - * @get_tx_power: store the current TX power into the dbm variable; - * return 0 if successful - * - * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting - * functions to adjust rfkill hw state */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); @@ -948,12 +928,6 @@ struct cfg80211_ops { int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); - - int (*set_tx_power)(struct wiphy *wiphy, - enum tx_power_setting type, int dbm); - int (*get_tx_power)(struct wiphy *wiphy, int *dbm); - - void (*rfkill_poll)(struct wiphy *wiphy); }; /* @@ -1477,12 +1451,6 @@ int cfg80211_wext_siwencode(struct net_device *dev, int cfg80211_wext_giwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *keybuf); -int cfg80211_wext_siwtxpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *keybuf); -int cfg80211_wext_giwtxpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *keybuf); /* * callbacks for asynchronous cfg80211 methods, notification @@ -1668,23 +1636,4 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, */ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); -/** - * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state - * @wiphy: the wiphy - * @blocked: block status - */ -void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked); - -/** - * wiphy_rfkill_start_polling - start polling rfkill - * @wiphy: the wiphy - */ -void wiphy_rfkill_start_polling(struct wiphy *wiphy); - -/** - * wiphy_rfkill_stop_polling - stop polling rfkill - * @wiphy: the wiphy - */ -void wiphy_rfkill_stop_polling(struct wiphy *wiphy); - #endif /* __NET_CFG80211_H */ diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 7fc409c19b37..6be3b082a070 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -195,12 +195,6 @@ struct dst_entry * dst_clone(struct dst_entry * dst) } extern void dst_release(struct dst_entry *dst); -static inline void skb_dst_drop(struct sk_buff *skb) -{ - if (skb->_skb_dst) - dst_release(skb_dst(skb)); - skb->_skb_dst = 0UL; -} /* Children define the path of the packet through the * Linux networking. Thus, destinations are stackable. @@ -252,7 +246,7 @@ static inline void dst_negative_advice(struct dst_entry **dst_p) static inline void dst_link_failure(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry * dst = skb->dst; if (dst && dst->ops && dst->ops->link_failure) dst->ops->link_failure(skb); } @@ -271,13 +265,13 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout) /* Output packet to network from transport. */ static inline int dst_output(struct sk_buff *skb) { - return skb_dst(skb)->output(skb); + return skb->dst->output(skb); } /* Input packet from network to transport. */ static inline int dst_input(struct sk_buff *skb) { - return skb_dst(skb)->input(skb); + return skb->dst->input(skb); } static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie) diff --git a/trunk/include/net/ieee802154/af_ieee802154.h b/trunk/include/net/ieee802154/af_ieee802154.h deleted file mode 100644 index 0d78605fb1a6..000000000000 --- a/trunk/include/net/ieee802154/af_ieee802154.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * IEEE 802.15.4 inteface for userspace - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#ifndef _AF_IEEE802154_H -#define _AF_IEEE802154_H - -#include /* for sa_family_t */ - -enum { - IEEE802154_ADDR_NONE = 0x0, - /* RESERVED = 0x01, */ - IEEE802154_ADDR_SHORT = 0x2, /* 16-bit address + PANid */ - IEEE802154_ADDR_LONG = 0x3, /* 64-bit address + PANid */ -}; - -/* address length, octets */ -#define IEEE802154_ADDR_LEN 8 - -struct ieee802154_addr { - int addr_type; - u16 pan_id; - union { - u8 hwaddr[IEEE802154_ADDR_LEN]; - u16 short_addr; - }; -}; - -#define IEEE802154_PANID_BROADCAST 0xffff -#define IEEE802154_ADDR_BROADCAST 0xffff -#define IEEE802154_ADDR_UNDEF 0xfffe - -struct sockaddr_ieee802154 { - sa_family_t family; /* AF_IEEE802154 */ - struct ieee802154_addr addr; -}; - -/* master device */ -#define IEEE802154_SIOC_ADD_SLAVE (SIOCDEVPRIVATE + 0) - -#endif diff --git a/trunk/include/net/ieee802154/mac_def.h b/trunk/include/net/ieee802154/mac_def.h deleted file mode 100644 index 8cb684635650..000000000000 --- a/trunk/include/net/ieee802154/mac_def.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * IEEE802.15.4-2003 specification - * - * Copyright (C) 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Maxim Osipov - * Dmitry Eremin-Solenikov - */ - -#ifndef IEEE802154_MAC_DEF_H -#define IEEE802154_MAC_DEF_H - -#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ -#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ -#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ -#define IEEE802154_FC_TYPE_MAC_CMD 0x3 /* Frame is MAC command */ - -#define IEEE802154_FC_TYPE_SHIFT 0 -#define IEEE802154_FC_TYPE_MASK ((1 << 3) - 1) -#define IEEE802154_FC_TYPE(x) ((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT) -#define IEEE802154_FC_SET_TYPE(v, x) do { \ - v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \ - (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \ - } while (0) - -#define IEEE802154_FC_SECEN (1 << 3) -#define IEEE802154_FC_FRPEND (1 << 4) -#define IEEE802154_FC_ACK_REQ (1 << 5) -#define IEEE802154_FC_INTRA_PAN (1 << 6) - -#define IEEE802154_FC_SAMODE_SHIFT 14 -#define IEEE802154_FC_SAMODE_MASK (3 << IEEE802154_FC_SAMODE_SHIFT) -#define IEEE802154_FC_DAMODE_SHIFT 10 -#define IEEE802154_FC_DAMODE_MASK (3 << IEEE802154_FC_DAMODE_SHIFT) - -#define IEEE802154_FC_SAMODE(x) \ - (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT) - -#define IEEE802154_FC_DAMODE(x) \ - (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) - - -/* MAC's Command Frames Identifiers */ -#define IEEE802154_CMD_ASSOCIATION_REQ 0x01 -#define IEEE802154_CMD_ASSOCIATION_RESP 0x02 -#define IEEE802154_CMD_DISASSOCIATION_NOTIFY 0x03 -#define IEEE802154_CMD_DATA_REQ 0x04 -#define IEEE802154_CMD_PANID_CONFLICT_NOTIFY 0x05 -#define IEEE802154_CMD_ORPHAN_NOTIFY 0x06 -#define IEEE802154_CMD_BEACON_REQ 0x07 -#define IEEE802154_CMD_COORD_REALIGN_NOTIFY 0x08 -#define IEEE802154_CMD_GTS_REQ 0x09 - -/* - * The return values of MAC operations - */ -enum { - /* - * The requested operation was completed successfully. - * For a transmission request, this value indicates - * a successful transmission. - */ - IEEE802154_SUCCESS = 0x0, - - /* The beacon was lost following a synchronization request. */ - IEEE802154_BEACON_LOSS = 0xe0, - /* - * A transmission could not take place due to activity on the - * channel, i.e., the CSMA-CA mechanism has failed. - */ - IEEE802154_CHNL_ACCESS_FAIL = 0xe1, - /* The GTS request has been denied by the PAN coordinator. */ - IEEE802154_DENINED = 0xe2, - /* The attempt to disable the transceiver has failed. */ - IEEE802154_DISABLE_TRX_FAIL = 0xe3, - /* - * The received frame induces a failed security check according to - * the security suite. - */ - IEEE802154_FAILED_SECURITY_CHECK = 0xe4, - /* - * The frame resulting from secure processing has a length that is - * greater than aMACMaxFrameSize. - */ - IEEE802154_FRAME_TOO_LONG = 0xe5, - /* - * The requested GTS transmission failed because the specified GTS - * either did not have a transmit GTS direction or was not defined. - */ - IEEE802154_INVALID_GTS = 0xe6, - /* - * A request to purge an MSDU from the transaction queue was made using - * an MSDU handle that was not found in the transaction table. - */ - IEEE802154_INVALID_HANDLE = 0xe7, - /* A parameter in the primitive is out of the valid range.*/ - IEEE802154_INVALID_PARAMETER = 0xe8, - /* No acknowledgment was received after aMaxFrameRetries. */ - IEEE802154_NO_ACK = 0xe9, - /* A scan operation failed to find any network beacons.*/ - IEEE802154_NO_BEACON = 0xea, - /* No response data were available following a request. */ - IEEE802154_NO_DATA = 0xeb, - /* The operation failed because a short address was not allocated. */ - IEEE802154_NO_SHORT_ADDRESS = 0xec, - /* - * A receiver enable request was unsuccessful because it could not be - * completed within the CAP. - */ - IEEE802154_OUT_OF_CAP = 0xed, - /* - * A PAN identifier conflict has been detected and communicated to the - * PAN coordinator. - */ - IEEE802154_PANID_CONFLICT = 0xee, - /* A coordinator realignment command has been received. */ - IEEE802154_REALIGMENT = 0xef, - /* The transaction has expired and its information discarded. */ - IEEE802154_TRANSACTION_EXPIRED = 0xf0, - /* There is no capacity to store the transaction. */ - IEEE802154_TRANSACTION_OVERFLOW = 0xf1, - /* - * The transceiver was in the transmitter enabled state when the - * receiver was requested to be enabled. - */ - IEEE802154_TX_ACTIVE = 0xf2, - /* The appropriate key is not available in the ACL. */ - IEEE802154_UNAVAILABLE_KEY = 0xf3, - /* - * A SET/GET request was issued with the identifier of a PIB attribute - * that is not supported. - */ - IEEE802154_UNSUPPORTED_ATTR = 0xf4, - /* - * A request to perform a scan operation failed because the MLME was - * in the process of performing a previously initiated scan operation. - */ - IEEE802154_SCAN_IN_PROGRESS = 0xfc, -}; - - -#endif - - diff --git a/trunk/include/net/ieee802154/netdevice.h b/trunk/include/net/ieee802154/netdevice.h deleted file mode 100644 index e2506af3e7c8..000000000000 --- a/trunk/include/net/ieee802154/netdevice.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * An interface between IEEE802.15.4 device and rest of the kernel. - * - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Maxim Osipov - * Dmitry Eremin-Solenikov - */ - -#ifndef IEEE802154_NETDEVICE_H -#define IEEE802154_NETDEVICE_H - -/* - * A control block of skb passed between the ARPHRD_IEEE802154 device - * and other stack parts. - */ -struct ieee802154_mac_cb { - u8 lqi; - struct ieee802154_addr sa; - struct ieee802154_addr da; - u8 flags; - u8 seq; -}; - -static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb) -{ - return (struct ieee802154_mac_cb *)skb->cb; -} - -#define MAC_CB_FLAG_TYPEMASK ((1 << 3) - 1) - -#define MAC_CB_FLAG_ACKREQ (1 << 3) -#define MAC_CB_FLAG_SECEN (1 << 4) -#define MAC_CB_FLAG_INTRAPAN (1 << 5) - -static inline int mac_cb_is_ackreq(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ; -} - -static inline int mac_cb_is_secen(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN; -} - -static inline int mac_cb_is_intrapan(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN; -} - -static inline int mac_cb_type(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK; -} - -#define IEEE802154_MAC_SCAN_ED 0 -#define IEEE802154_MAC_SCAN_ACTIVE 1 -#define IEEE802154_MAC_SCAN_PASSIVE 2 -#define IEEE802154_MAC_SCAN_ORPHAN 3 - -/* - * This should be located at net_device->ml_priv - */ -struct ieee802154_mlme_ops { - int (*assoc_req)(struct net_device *dev, - struct ieee802154_addr *addr, - u8 channel, u8 cap); - int (*assoc_resp)(struct net_device *dev, - struct ieee802154_addr *addr, - u16 short_addr, u8 status); - int (*disassoc_req)(struct net_device *dev, - struct ieee802154_addr *addr, - u8 reason); - int (*start_req)(struct net_device *dev, - struct ieee802154_addr *addr, - u8 channel, u8 bcn_ord, u8 sf_ord, - u8 pan_coord, u8 blx, u8 coord_realign); - int (*scan_req)(struct net_device *dev, - u8 type, u32 channels, u8 duration); - - /* - * FIXME: these should become the part of PIB/MIB interface. - * However we still don't have IB interface of any kind - */ - u16 (*get_pan_id)(struct net_device *dev); - u16 (*get_short_addr)(struct net_device *dev); - u8 (*get_dsn)(struct net_device *dev); - u8 (*get_bsn)(struct net_device *dev); -}; - -static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops( - struct net_device *dev) -{ - return dev->ml_priv; -} - -#endif - - diff --git a/trunk/include/net/ieee802154/nl802154.h b/trunk/include/net/ieee802154/nl802154.h deleted file mode 100644 index 78efcdf52b59..000000000000 --- a/trunk/include/net/ieee802154/nl802154.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * nl802154.h - * - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef IEEE802154_NL_H -#define IEEE802154_NL_H - -struct net_device; -struct ieee802154_addr; - -int ieee802154_nl_assoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 cap); -int ieee802154_nl_assoc_confirm(struct net_device *dev, - u16 short_addr, u8 status); -int ieee802154_nl_disassoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 reason); -int ieee802154_nl_disassoc_confirm(struct net_device *dev, - u8 status); -int ieee802154_nl_scan_confirm(struct net_device *dev, - u8 status, u8 scan_type, u32 unscanned, - u8 *edl/*, struct list_head *pan_desc_list */); -int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid, - u16 coord_addr); - -#endif diff --git a/trunk/include/net/inet6_hashtables.h b/trunk/include/net/inet6_hashtables.h index 22c73a77cd99..f74665d7bea8 100644 --- a/trunk/include/net/inet6_hashtables.h +++ b/trunk/include/net/inet6_hashtables.h @@ -100,7 +100,7 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, if (unlikely(sk = skb_steal_sock(skb))) return sk; - else return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, + else return __inet6_lookup(dev_net(skb->dst->dev), hashinfo, &ipv6_hdr(skb)->saddr, sport, &ipv6_hdr(skb)->daddr, ntohs(dport), inet6_iif(skb)); diff --git a/trunk/include/net/inet_hashtables.h b/trunk/include/net/inet_hashtables.h index d522dcf3031a..a44e2248b2ef 100644 --- a/trunk/include/net/inet_hashtables.h +++ b/trunk/include/net/inet_hashtables.h @@ -385,7 +385,7 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, if (unlikely(sk = skb_steal_sock(skb))) return sk; else - return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo, + return __inet_lookup(dev_net(skb->dst->dev), hashinfo, iph->saddr, sport, iph->daddr, dport, inet_iif(skb)); } diff --git a/trunk/include/net/inet_sock.h b/trunk/include/net/inet_sock.h index 20a6957af870..de0ecc71cf03 100644 --- a/trunk/include/net/inet_sock.h +++ b/trunk/include/net/inet_sock.h @@ -130,8 +130,7 @@ struct inet_sock { freebind:1, hdrincl:1, mc_loop:1, - transparent:1, - mc_all:1; + transparent:1; int mc_index; __be32 mc_addr; struct ip_mc_socklist *mc_list; diff --git a/trunk/include/net/ip6_route.h b/trunk/include/net/ip6_route.h index 0e1b8aebaff8..5f53db7e4e57 100644 --- a/trunk/include/net/ip6_route.h +++ b/trunk/include/net/ip6_route.h @@ -142,7 +142,7 @@ static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, static inline int ipv6_unicast_destination(struct sk_buff *skb) { - struct rt6_info *rt = (struct rt6_info *) skb_dst(skb); + struct rt6_info *rt = (struct rt6_info *) skb->dst; return rt->rt6i_flags & RTF_LOCAL; } diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index c06104476973..d72346ff3247 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -239,8 +239,6 @@ struct ieee80211_bss_conf { * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, * used to indicate that a pending frame requires TX processing before * it can be sent out. - * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, - * used to indicate that a frame was already retried due to PS */ enum mac80211_tx_control_flags { IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), @@ -258,7 +256,6 @@ enum mac80211_tx_control_flags { IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), IEEE80211_TX_INTFL_RCALGO = BIT(13), IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), - IEEE80211_TX_INTFL_RETRIED = BIT(15), }; /** @@ -529,7 +526,8 @@ enum ieee80211_conf_flags { /** * enum ieee80211_conf_changed - denotes which configuration changed * - * @_IEEE80211_CONF_CHANGE_RADIO_ENABLED: DEPRECATED + * @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed + * @_IEEE80211_CONF_CHANGE_BEACON_INTERVAL: DEPRECATED * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed @@ -539,7 +537,8 @@ enum ieee80211_conf_flags { * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed */ enum ieee80211_conf_changed { - _IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0), + IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0), + _IEEE80211_CONF_CHANGE_BEACON_INTERVAL = BIT(1), IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2), IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3), IEEE80211_CONF_CHANGE_PS = BIT(4), @@ -550,12 +549,12 @@ enum ieee80211_conf_changed { }; static inline __deprecated enum ieee80211_conf_changed -__IEEE80211_CONF_CHANGE_RADIO_ENABLED(void) +__IEEE80211_CONF_CHANGE_BEACON_INTERVAL(void) { - return _IEEE80211_CONF_CHANGE_RADIO_ENABLED; + return _IEEE80211_CONF_CHANGE_BEACON_INTERVAL; } -#define IEEE80211_CONF_CHANGE_RADIO_ENABLED \ - __IEEE80211_CONF_CHANGE_RADIO_ENABLED() +#define IEEE80211_CONF_CHANGE_BEACON_INTERVAL \ + __IEEE80211_CONF_CHANGE_BEACON_INTERVAL() /** * struct ieee80211_conf - configuration of the device @@ -565,7 +564,7 @@ __IEEE80211_CONF_CHANGE_RADIO_ENABLED(void) * @flags: configuration flags defined above * * @radio_enabled: when zero, driver is required to switch off the radio. - * @beacon_int: DEPRECATED, DO NOT USE + * @beacon_int: beacon interval (TODO make interface config) * * @listen_interval: listen interval in units of beacon interval * @max_sleep_period: the maximum number of beacon intervals to sleep for @@ -590,13 +589,13 @@ __IEEE80211_CONF_CHANGE_RADIO_ENABLED(void) * number of transmissions not the number of retries */ struct ieee80211_conf { - int __deprecated beacon_int; + int beacon_int; u32 flags; int power_level, dynamic_ps_timeout; int max_sleep_period; u16 listen_interval; - bool __deprecated radio_enabled; + bool radio_enabled; u8 long_frame_max_tx_count, short_frame_max_tx_count; @@ -1407,10 +1406,6 @@ enum ieee80211_ampdu_mlme_action { * is the first frame we expect to perform the action on. Notice * that TX/RX_STOP can pass NULL for this parameter. * Returns a negative error code on failure. - * - * @rfkill_poll: Poll rfkill hardware state. If you need this, you also - * need to set wiphy->rfkill_poll to %true before registration, - * and need to call wiphy_rfkill_set_hw_state() in the callback. */ struct ieee80211_ops { int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -1459,8 +1454,6 @@ struct ieee80211_ops { int (*ampdu_action)(struct ieee80211_hw *hw, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn); - - void (*rfkill_poll)(struct ieee80211_hw *hw); }; /** diff --git a/trunk/include/net/netlink.h b/trunk/include/net/netlink.h index eddb50289d6d..007bdb07dabb 100644 --- a/trunk/include/net/netlink.h +++ b/trunk/include/net/netlink.h @@ -939,6 +939,15 @@ static inline u64 nla_get_u64(const struct nlattr *nla) return tmp; } +/** + * nla_get_be64 - return payload of __be64 attribute + * @nla: __be64 netlink attribute + */ +static inline __be64 nla_get_be64(const struct nlattr *nla) +{ + return *(__be64 *) nla_data(nla); +} + /** * nla_get_flag - return payload of flag attribute * @nla: flag netlink attribute diff --git a/trunk/include/net/pkt_sched.h b/trunk/include/net/pkt_sched.h index 120935b2abd8..e37fe3129c17 100644 --- a/trunk/include/net/pkt_sched.h +++ b/trunk/include/net/pkt_sched.h @@ -41,10 +41,9 @@ static inline void *qdisc_priv(struct Qdisc *q) typedef u64 psched_time_t; typedef long psched_tdiff_t; -/* Avoid doing 64 bit divide */ -#define PSCHED_SHIFT 6 -#define PSCHED_US2NS(x) ((s64)(x) << PSCHED_SHIFT) -#define PSCHED_NS2US(x) ((x) >> PSCHED_SHIFT) +/* Avoid doing 64 bit divide by 1000 */ +#define PSCHED_US2NS(x) ((s64)(x) << 10) +#define PSCHED_NS2US(x) ((x) >> 10) #define PSCHED_TICKS_PER_SEC PSCHED_NS2US(NSEC_PER_SEC) #define PSCHED_PASTPERFECT 0 diff --git a/trunk/include/net/route.h b/trunk/include/net/route.h index 40f6346ef496..4e8cae0e5841 100644 --- a/trunk/include/net/route.h +++ b/trunk/include/net/route.h @@ -210,7 +210,7 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt) static inline int inet_iif(const struct sk_buff *skb) { - return skb_rtable(skb)->rt_iif; + return skb->rtable->rt_iif; } #endif /* _ROUTE_H */ diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index edfcacf3250e..23f08fe1d50a 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -1939,8 +1939,10 @@ void sctp_association_free(struct sctp_association *); void sctp_association_put(struct sctp_association *); void sctp_association_hold(struct sctp_association *); -struct sctp_transport *sctp_assoc_choose_alter_transport( - struct sctp_association *, struct sctp_transport *); +struct sctp_transport *sctp_assoc_choose_init_transport( + struct sctp_association *); +struct sctp_transport *sctp_assoc_choose_shutdown_transport( + struct sctp_association *); void sctp_assoc_update_retran_path(struct sctp_association *); struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *, const union sctp_addr *); diff --git a/trunk/include/net/sctp/user.h b/trunk/include/net/sctp/user.h index 1580c04f68bc..b259fc5798fb 100644 --- a/trunk/include/net/sctp/user.h +++ b/trunk/include/net/sctp/user.h @@ -147,8 +147,6 @@ enum sctp_optname { #define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */ #define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX - SCTP_SOCKOPT_CONNECTX3, /* CONNECTX requests. (new implementation) */ -#define SCTP_SOCKOPT_CONNECTX3 SCTP_SOCKOPT_CONNECTX3 }; /* diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 010e14a93c92..4bb1ff9fd15b 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -1217,13 +1217,9 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from, static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) { + sock_hold(sk); skb->sk = sk; skb->destructor = sock_wfree; - /* - * We used to take a refcount on sk, but following operation - * is enough to guarantee sk_free() wont free this sock until - * all in-flight packets are completed - */ atomic_add(skb->truesize, &sk->sk_wmem_alloc); } diff --git a/trunk/include/net/wimax.h b/trunk/include/net/wimax.h index 2af7bf839f23..6b3824edb39e 100644 --- a/trunk/include/net/wimax.h +++ b/trunk/include/net/wimax.h @@ -253,6 +253,7 @@ struct net_device; struct genl_info; struct wimax_dev; +struct input_dev; /** * struct wimax_dev - Generic WiMAX device @@ -292,8 +293,8 @@ struct wimax_dev; * See wimax_reset()'s documentation. * * @name: [fill] A way to identify this device. We need to register a - * name with many subsystems (rfkill, workqueue creation, etc). - * We can't use the network device name as that + * name with many subsystems (input for RFKILL, workqueue + * creation, etc). We can't use the network device name as that * might change and in some instances we don't know it yet (until * we don't call register_netdev()). So we generate an unique one * using the driver name and device bus id, place it here and use @@ -315,6 +316,9 @@ struct wimax_dev; * * @rfkill: [private] integration into the RF-Kill infrastructure. * + * @rfkill_input: [private] virtual input device to process the + * hardware RF Kill switches. + * * @rf_sw: [private] State of the software radio switch (OFF/ON) * * @rf_hw: [private] State of the hardware radio switch (OFF/ON) diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 736bca450886..2e9f5c0018ae 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -994,7 +994,7 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir, return __xfrm_policy_check(sk, ndir, skb, family); return (!net->xfrm.policy_count[dir] && !skb->sp) || - (skb_dst(skb)->flags & DST_NOPOLICY) || + (skb->dst->flags & DST_NOPOLICY) || __xfrm_policy_check(sk, ndir, skb, family); } @@ -1048,7 +1048,7 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) struct net *net = dev_net(skb->dev); return !net->xfrm.policy_count[XFRM_POLICY_OUT] || - (skb_dst(skb)->flags & DST_NOXFRM) || + (skb->dst->flags & DST_NOXFRM) || __xfrm_route_forward(skb, family); } diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index fe649081fbdc..d1e10546eb85 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -378,13 +378,13 @@ static void vlan_sync_address(struct net_device *dev, * the new address */ if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) - dev_unicast_delete(dev, vlandev->dev_addr); + dev_unicast_delete(dev, vlandev->dev_addr, ETH_ALEN); /* vlan address was equal to the old address and is different from * the new address */ if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) - dev_unicast_add(dev, vlandev->dev_addr); + dev_unicast_add(dev, vlandev->dev_addr, ETH_ALEN); memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); } @@ -758,7 +758,7 @@ static void __exit vlan_cleanup_module(void) BUG_ON(!hlist_empty(&vlan_group_hash[i])); unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ + synchronize_net(); vlan_gvrp_uninit(); } diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index 96bad8f233e2..1e2ad4c7c59b 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -441,7 +441,7 @@ static int vlan_dev_open(struct net_device *dev) return -ENETDOWN; if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { - err = dev_unicast_add(real_dev, dev->dev_addr); + err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN); if (err < 0) goto out; } @@ -470,7 +470,7 @@ static int vlan_dev_open(struct net_device *dev) dev_set_allmulti(real_dev, -1); del_unicast: if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) - dev_unicast_delete(real_dev, dev->dev_addr); + dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); out: netif_carrier_off(dev); return err; @@ -492,7 +492,7 @@ static int vlan_dev_stop(struct net_device *dev) dev_set_promiscuity(real_dev, -1); if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) - dev_unicast_delete(real_dev, dev->dev_addr); + dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len); netif_carrier_off(dev); return 0; @@ -511,13 +511,13 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) goto out; if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { - err = dev_unicast_add(real_dev, addr->sa_data); + err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN); if (err < 0) return err; } if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) - dev_unicast_delete(real_dev, dev->dev_addr); + dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); out: memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index 7051b9710675..c19f549c8e74 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -179,7 +179,6 @@ source "net/lapb/Kconfig" source "net/econet/Kconfig" source "net/wanrouter/Kconfig" source "net/phonet/Kconfig" -source "net/ieee802154/Kconfig" source "net/sched/Kconfig" source "net/dcb/Kconfig" diff --git a/trunk/net/Makefile b/trunk/net/Makefile index ba324aefda73..9e00a55a901b 100644 --- a/trunk/net/Makefile +++ b/trunk/net/Makefile @@ -60,7 +60,6 @@ obj-$(CONFIG_NET_9P) += 9p/ ifneq ($(CONFIG_DCB),) obj-y += dcb/ endif -obj-y += ieee802154/ ifeq ($(CONFIG_NET),y) obj-$(CONFIG_SYSCTL) += sysctl_net.o diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index b603cbacdc58..d6a9243641af 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -939,7 +939,6 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, int len, unsigned long sum) { int start = skb_headlen(skb); - struct sk_buff *frag_iter; int i, copy; /* checksum stuff in header space */ @@ -978,22 +977,26 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - WARN_ON(start > offset + len); + for (; list; list = list->next) { + int end; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - sum = atalk_sum_skb(frag_iter, offset - start, - copy, sum); - if ((len -= copy) == 0) - return sum; - offset += copy; + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_skb(list, offset - start, + copy, sum); + if ((len -= copy) == 0) + return sum; + offset += copy; + } + start = end; } - start = end; } BUG_ON(len > 0); diff --git a/trunk/net/atm/br2684.c b/trunk/net/atm/br2684.c index 2912665fc58c..3100a8940afc 100644 --- a/trunk/net/atm/br2684.c +++ b/trunk/net/atm/br2684.c @@ -228,7 +228,7 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev) struct br2684_dev *brdev = BRPRIV(dev); struct br2684_vcc *brvcc; - pr_debug("br2684_start_xmit, skb_dst(skb)=%p\n", skb_dst(skb)); + pr_debug("br2684_start_xmit, skb->dst=%p\n", skb->dst); read_lock(&devs_lock); brvcc = pick_outgoing_vcc(skb, brdev); if (brvcc == NULL) { @@ -445,10 +445,9 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) */ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) { - struct sk_buff_head queue; int err; struct br2684_vcc *brvcc; - struct sk_buff *skb, *tmp; + struct sk_buff *skb; struct sk_buff_head *rq; struct br2684_dev *brdev; struct net_device *net_dev; @@ -506,20 +505,29 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) barrier(); atmvcc->push = br2684_push; - __skb_queue_head_init(&queue); rq = &sk_atm(atmvcc)->sk_receive_queue; spin_lock_irqsave(&rq->lock, flags); - skb_queue_splice_init(rq, &queue); + if (skb_queue_empty(rq)) { + skb = NULL; + } else { + /* NULL terminate the list. */ + rq->prev->next = NULL; + skb = rq->next; + } + rq->prev = rq->next = (struct sk_buff *)rq; + rq->qlen = 0; spin_unlock_irqrestore(&rq->lock, flags); - skb_queue_walk_safe(&queue, skb, tmp) { - struct net_device *dev = skb->dev; - - dev->stats.rx_bytes -= skb->len; - dev->stats.rx_packets--; + while (skb) { + struct sk_buff *next = skb->next; + skb->next = skb->prev = NULL; br2684_push(atmvcc, skb); + skb->dev->stats.rx_bytes -= skb->len; + skb->dev->stats.rx_packets--; + + skb = next; } __module_get(THIS_MODULE); return 0; diff --git a/trunk/net/atm/clip.c b/trunk/net/atm/clip.c index e65a3b1477f8..3dc0a3a42a57 100644 --- a/trunk/net/atm/clip.c +++ b/trunk/net/atm/clip.c @@ -369,16 +369,16 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; pr_debug("clip_start_xmit (skb %p)\n", skb); - if (!skb_dst(skb)) { - printk(KERN_ERR "clip_start_xmit: skb_dst(skb) == NULL\n"); + if (!skb->dst) { + printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n"); dev_kfree_skb(skb); dev->stats.tx_dropped++; return 0; } - if (!skb_dst(skb)->neighbour) { + if (!skb->dst->neighbour) { #if 0 - skb_dst(skb)->neighbour = clip_find_neighbour(skb_dst(skb), 1); - if (!skb_dst(skb)->neighbour) { + skb->dst->neighbour = clip_find_neighbour(skb->dst, 1); + if (!skb->dst->neighbour) { dev_kfree_skb(skb); /* lost that one */ dev->stats.tx_dropped++; return 0; @@ -389,7 +389,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_dropped++; return 0; } - entry = NEIGH2ENTRY(skb_dst(skb)->neighbour); + entry = NEIGH2ENTRY(skb->dst->neighbour); if (!entry->vccs) { if (time_after(jiffies, entry->expires)) { /* should be resolved */ @@ -406,7 +406,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev) } pr_debug("neigh %p, vccs %p\n", entry, entry->vccs); ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc; - pr_debug("using neighbour %p, vcc %p\n", skb_dst(skb)->neighbour, vcc); + pr_debug("using neighbour %p, vcc %p\n", skb->dst->neighbour, vcc); if (entry->vccs->encap) { void *here; @@ -445,9 +445,9 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev) static int clip_mkip(struct atm_vcc *vcc, int timeout) { - struct sk_buff_head *rq, queue; struct clip_vcc *clip_vcc; - struct sk_buff *skb, *tmp; + struct sk_buff *skb; + struct sk_buff_head *rq; unsigned long flags; if (!vcc->push) @@ -469,28 +469,39 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout) vcc->push = clip_push; vcc->pop = clip_pop; - __skb_queue_head_init(&queue); rq = &sk_atm(vcc)->sk_receive_queue; spin_lock_irqsave(&rq->lock, flags); - skb_queue_splice_init(rq, &queue); + if (skb_queue_empty(rq)) { + skb = NULL; + } else { + /* NULL terminate the list. */ + rq->prev->next = NULL; + skb = rq->next; + } + rq->prev = rq->next = (struct sk_buff *)rq; + rq->qlen = 0; spin_unlock_irqrestore(&rq->lock, flags); /* re-process everything received between connection setup and MKIP */ - skb_queue_walk_safe(&queue, skb, tmp) { + while (skb) { + struct sk_buff *next = skb->next; + + skb->next = skb->prev = NULL; if (!clip_devs) { atm_return(vcc, skb->truesize); kfree_skb(skb); } else { - struct net_device *dev = skb->dev; unsigned int len = skb->len; skb_get(skb); clip_push(vcc, skb); - dev->stats.rx_packets--; - dev->stats.rx_bytes -= len; + skb->dev->stats.rx_packets--; + skb->dev->stats.rx_bytes -= len; kfree_skb(skb); } + + skb = next; } return 0; } @@ -557,7 +568,6 @@ static void clip_setup(struct net_device *dev) /* without any more elaborate queuing. 100 is a reasonable */ /* compromise between decent burst-tolerance and protection */ /* against memory hogs. */ - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; } static int clip_create(int number) diff --git a/trunk/net/bluetooth/cmtp/capi.c b/trunk/net/bluetooth/cmtp/capi.c index 97f8d68d574d..78958c0f9a40 100644 --- a/trunk/net/bluetooth/cmtp/capi.c +++ b/trunk/net/bluetooth/cmtp/capi.c @@ -382,7 +382,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) BT_DBG("ctrl %p", ctrl); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); atomic_inc(&session->terminate); cmtp_schedule(session); diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 406ad07cdea1..cd061510b6bd 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -477,11 +476,6 @@ int hci_dev_open(__u16 dev) hci_req_lock(hdev); - if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { - ret = -ERFKILL; - goto done; - } - if (test_bit(HCI_UP, &hdev->flags)) { ret = -EALREADY; goto done; @@ -819,24 +813,6 @@ int hci_get_dev_info(void __user *arg) /* ---- Interface to HCI drivers ---- */ -static int hci_rfkill_set_block(void *data, bool blocked) -{ - struct hci_dev *hdev = data; - - BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); - - if (!blocked) - return 0; - - hci_dev_do_close(hdev); - - return 0; -} - -static const struct rfkill_ops hci_rfkill_ops = { - .set_block = hci_rfkill_set_block, -}; - /* Alloc HCI device */ struct hci_dev *hci_alloc_dev(void) { @@ -868,8 +844,7 @@ int hci_register_dev(struct hci_dev *hdev) struct list_head *head = &hci_dev_list, *p; int i, id = 0; - BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, - hdev->type, hdev->owner); + BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); if (!hdev->open || !hdev->close || !hdev->destruct) return -EINVAL; @@ -925,15 +900,6 @@ int hci_register_dev(struct hci_dev *hdev) hci_register_sysfs(hdev); - hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, - RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); - if (hdev->rfkill) { - if (rfkill_register(hdev->rfkill) < 0) { - rfkill_destroy(hdev->rfkill); - hdev->rfkill = NULL; - } - } - hci_notify(hdev, HCI_DEV_REG); return id; @@ -958,11 +924,6 @@ int hci_unregister_dev(struct hci_dev *hdev) hci_notify(hdev, HCI_DEV_UNREG); - if (hdev->rfkill) { - rfkill_unregister(hdev->rfkill); - rfkill_destroy(hdev->rfkill); - } - hci_unregister_sysfs(hdev); __hci_dev_put(hdev); diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index 95f7a7a544b4..4cc3624bd22d 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -90,6 +90,9 @@ static void add_conn(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, work_add); struct hci_dev *hdev = conn->hdev; + /* ensure previous del is complete */ + flush_work(&conn->work_del); + dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); if (device_add(&conn->dev) < 0) { @@ -115,6 +118,9 @@ static void del_conn(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, work_del); struct hci_dev *hdev = conn->hdev; + /* ensure previous add is complete */ + flush_work(&conn->work_add); + if (!device_is_registered(&conn->dev)) return; diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index bd0a4c1bced0..ca4d3b40d5ce 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -40,10 +40,10 @@ #include #include #include -#include #include #include +#include #include #include @@ -52,7 +52,7 @@ #define VERSION "2.13" -static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; +static u32 l2cap_feat_mask = 0x0080; static u8 l2cap_fixed_chan[8] = { 0x02, }; static const struct proto_ops l2cap_sock_ops; @@ -134,8 +134,7 @@ static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 struct sock *s; read_lock(&l->lock); s = __l2cap_get_chan_by_scid(l, cid); - if (s) - bh_lock_sock(s); + if (s) bh_lock_sock(s); read_unlock(&l->lock); return s; } @@ -155,18 +154,17 @@ static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 struct sock *s; read_lock(&l->lock); s = __l2cap_get_chan_by_ident(l, ident); - if (s) - bh_lock_sock(s); + if (s) bh_lock_sock(s); read_unlock(&l->lock); return s; } static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) { - u16 cid = L2CAP_CID_DYN_START; + u16 cid = 0x0040; - for (; cid < L2CAP_CID_DYN_END; cid++) { - if (!__l2cap_get_chan_by_scid(l, cid)) + for (; cid < 0xffff; cid++) { + if(!__l2cap_get_chan_by_scid(l, cid)) return cid; } @@ -206,8 +204,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so { struct l2cap_chan_list *l = &conn->chan_list; - BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, - l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); + BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); conn->disc_reason = 0x13; @@ -218,13 +215,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so l2cap_pi(sk)->scid = l2cap_alloc_cid(l); } else if (sk->sk_type == SOCK_DGRAM) { /* Connectionless socket */ - l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS; - l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS; + l2cap_pi(sk)->scid = 0x0002; + l2cap_pi(sk)->dcid = 0x0002; l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; } else { /* Raw socket can send/recv signalling messages only */ - l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING; - l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING; + l2cap_pi(sk)->scid = 0x0001; + l2cap_pi(sk)->dcid = 0x0001; l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; } @@ -275,7 +272,7 @@ static inline int l2cap_check_security(struct sock *sk) if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) auth_type = HCI_AT_NO_BONDING_MITM; else - auth_type = HCI_AT_NO_BONDING; + auth_type = HCI_AT_NO_BONDING; if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; @@ -591,8 +588,7 @@ static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t struct sock *s; read_lock(&l2cap_sk_list.lock); s = __l2cap_get_sock_by_psm(state, psm, src); - if (s) - bh_lock_sock(s); + if (s) bh_lock_sock(s); read_unlock(&l2cap_sk_list.lock); return s; } @@ -812,7 +808,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) goto done; } - if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 && + if (la.l2_psm && btohs(la.l2_psm) < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { err = -EACCES; goto done; @@ -829,8 +825,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) l2cap_pi(sk)->sport = la.l2_psm; sk->sk_state = BT_BOUND; - if (__le16_to_cpu(la.l2_psm) == 0x0001 || - __le16_to_cpu(la.l2_psm) == 0x0003) + if (btohs(la.l2_psm) == 0x0001 || btohs(la.l2_psm) == 0x0003) l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; } @@ -849,13 +844,12 @@ static int l2cap_do_connect(struct sock *sk) struct hci_conn *hcon; struct hci_dev *hdev; __u8 auth_type; - int err; + int err = 0; BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); - hdev = hci_get_route(dst, src); - if (!hdev) + if (!(hdev = hci_get_route(dst, src))) return -EHOSTUNREACH; hci_dev_lock_bh(hdev); @@ -956,7 +950,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al goto done; } - switch (sk->sk_state) { + switch(sk->sk_state) { case BT_CONNECT: case BT_CONNECT2: case BT_CONFIG: @@ -981,8 +975,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); l2cap_pi(sk)->psm = la.l2_psm; - err = l2cap_do_connect(sk); - if (err) + if ((err = l2cap_do_connect(sk))) goto done; wait: @@ -1016,9 +1009,9 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) write_lock_bh(&l2cap_sk_list.lock); for (psm = 0x1001; psm < 0x1100; psm += 2) - if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) { - l2cap_pi(sk)->psm = cpu_to_le16(psm); - l2cap_pi(sk)->sport = cpu_to_le16(psm); + if (!__l2cap_get_sock_by_addr(htobs(psm), src)) { + l2cap_pi(sk)->psm = htobs(psm); + l2cap_pi(sk)->sport = htobs(psm); err = 0; break; } @@ -1107,11 +1100,11 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l if (peer) { la->l2_psm = l2cap_pi(sk)->psm; bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); - la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid); + la->l2_cid = htobs(l2cap_pi(sk)->dcid); } else { la->l2_psm = l2cap_pi(sk)->sport; bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); - la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid); + la->l2_cid = htobs(l2cap_pi(sk)->scid); } return 0; @@ -1121,7 +1114,7 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len) { struct l2cap_conn *conn = l2cap_pi(sk)->conn; struct sk_buff *skb, **frag; - int err, hlen, count, sent = 0; + int err, hlen, count, sent=0; struct l2cap_hdr *lh; BT_DBG("sk %p len %d", sk, len); @@ -1174,8 +1167,8 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len) frag = &(*frag)->next; } - err = hci_send_acl(conn->hcon, skb, 0); - if (err < 0) + + if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0) goto fail; return sent; @@ -1563,7 +1556,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) { struct l2cap_chan_list *l = &conn->chan_list; struct sk_buff *nskb; - struct sock *sk; + struct sock * sk; BT_DBG("conn %p", conn); @@ -1575,8 +1568,8 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) /* Don't send frame to the socket it came from */ if (skb->sk == sk) continue; - nskb = skb_clone(skb, GFP_ATOMIC); - if (!nskb) + + if (!(nskb = skb_clone(skb, GFP_ATOMIC))) continue; if (sock_queue_rcv_skb(sk, nskb)) @@ -1594,8 +1587,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, struct l2cap_hdr *lh; int len, count; - BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", - conn, code, ident, dlen); + BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen); len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; count = min_t(unsigned int, conn->mtu, len); @@ -1606,7 +1598,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); - lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); + lh->cid = cpu_to_le16(0x0001); cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); cmd->code = code; @@ -1747,8 +1739,8 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data) while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&req, &type, &olen, &val); - hint = type & L2CAP_CONF_HINT; - type &= L2CAP_CONF_MASK; + hint = type & 0x80; + type &= 0x7f; switch (type) { case L2CAP_CONF_MTU: @@ -1974,12 +1966,10 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); if (scid) { - sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); - if (!sk) + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid))) return 0; } else { - sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); - if (!sk) + if (!(sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident))) return 0; } @@ -2022,8 +2012,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); - sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); - if (!sk) + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) return -ENOENT; if (sk->sk_state == BT_DISCONN) @@ -2090,11 +2079,9 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr flags = __le16_to_cpu(rsp->flags); result = __le16_to_cpu(rsp->result); - BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", - scid, flags, result); + BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result); - sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); - if (!sk) + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid))) return 0; switch (result) { @@ -2155,8 +2142,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); - sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); - if (!sk) + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) return 0; rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); @@ -2183,8 +2169,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); - sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); - if (!sk) + if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid))) return 0; l2cap_chan_del(sk, 0); @@ -2245,7 +2230,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm if (type == L2CAP_IT_FEAT_MASK) { conn->feat_mask = get_unaligned_le32(rsp->data); - if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) { + if (conn->feat_mask & 0x0080) { struct l2cap_info_req req; req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); @@ -2418,8 +2403,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str kfree_skb(skb); done: - if (sk) - bh_unlock_sock(sk); + if (sk) bh_unlock_sock(sk); return 0; } @@ -2436,11 +2420,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) BT_DBG("len %d, cid 0x%4.4x", len, cid); switch (cid) { - case L2CAP_CID_SIGNALING: + case 0x0001: l2cap_sig_channel(conn, skb); break; - case L2CAP_CID_CONN_LESS: + case 0x0002: psm = get_unaligned((__le16 *) skb->data); skb_pull(skb, 2); l2cap_conless_channel(conn, psm, skb); @@ -2666,8 +2650,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl } /* Allocate skb for the complete frame (with header) */ - conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); - if (!conn->rx_skb) + if (!(conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC))) goto drop; skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), @@ -2721,13 +2704,13 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state, __le16_to_cpu(pi->psm), pi->scid, - pi->dcid, pi->imtu, pi->omtu, pi->sec_level); + sk->sk_state, btohs(pi->psm), pi->scid, pi->dcid, + pi->imtu, pi->omtu, pi->sec_level); } read_unlock_bh(&l2cap_sk_list.lock); - return str - buf; + return (str - buf); } static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index e50566ebf9f9..374536e050aa 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -679,7 +679,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst bacpy(&addr.l2_bdaddr, dst); addr.l2_family = AF_BLUETOOTH; - addr.l2_psm = cpu_to_le16(RFCOMM_PSM); + addr.l2_psm = htobs(RFCOMM_PSM); addr.l2_cid = 0; *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK); if (*err == 0 || *err == -EINPROGRESS) @@ -852,9 +852,9 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d } if (cr && channel_mtu >= 0) - pn->mtu = cpu_to_le16(channel_mtu); + pn->mtu = htobs(channel_mtu); else - pn->mtu = cpu_to_le16(d->mtu); + pn->mtu = htobs(d->mtu); *ptr = __fcs(buf); ptr++; @@ -1056,7 +1056,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr) if (len > 127) { hdr = (void *) skb_push(skb, 4); - put_unaligned(cpu_to_le16(__len16(len)), (__le16 *) &hdr->len); + put_unaligned(htobs(__len16(len)), (__le16 *) &hdr->len); } else { hdr = (void *) skb_push(skb, 3); hdr->len = __len8(len); @@ -1289,7 +1289,7 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn) d->priority = pn->priority; - d->mtu = __le16_to_cpu(pn->mtu); + d->mtu = btohs(pn->mtu); if (cr && d->mtu > s->mtu) d->mtu = s->mtu; @@ -1922,7 +1922,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) /* Bind socket */ bacpy(&addr.l2_bdaddr, ba); addr.l2_family = AF_BLUETOOTH; - addr.l2_psm = cpu_to_le16(RFCOMM_PSM); + addr.l2_psm = htobs(RFCOMM_PSM); addr.l2_cid = 0; err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0) { diff --git a/trunk/net/bridge/br_fdb.c b/trunk/net/bridge/br_fdb.c index cb3e97b93aeb..a48f5efdb6bf 100644 --- a/trunk/net/bridge/br_fdb.c +++ b/trunk/net/bridge/br_fdb.c @@ -398,7 +398,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, if (unlikely(fdb->is_local)) { if (net_ratelimit()) printk(KERN_WARNING "%s: received packet with " - "own address as source address\n", + " own address as source address\n", source->dev->name); } else { /* fastpath: update of existing entry */ diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index d22f611e4004..e4a418fcb35b 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -228,7 +228,6 @@ int nf_bridge_copy_header(struct sk_buff *skb) static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) { struct nf_bridge_info *nf_bridge = skb->nf_bridge; - struct rtable *rt; if (nf_bridge->mask & BRNF_PKT_TYPE) { skb->pkt_type = PACKET_OTHERHOST; @@ -236,13 +235,12 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb) } nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; - rt = bridge_parent_rtable(nf_bridge->physindev); - if (!rt) { + skb->rtable = bridge_parent_rtable(nf_bridge->physindev); + if (!skb->rtable) { kfree_skb(skb); return 0; } - dst_hold(&rt->u.dst); - skb_dst_set(skb, &rt->u.dst); + dst_hold(&skb->rtable->u.dst); skb->dev = nf_bridge->physindev; nf_bridge_push_encap_header(skb); @@ -322,7 +320,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) skb->dev = bridge_parent(skb->dev); if (skb->dev) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; nf_bridge_pull_encap_header(skb); @@ -340,7 +338,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) struct net_device *dev = skb->dev; struct iphdr *iph = ip_hdr(skb); struct nf_bridge_info *nf_bridge = skb->nf_bridge; - struct rtable *rt; int err; if (nf_bridge->mask & BRNF_PKT_TYPE) { @@ -350,6 +347,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; if (dnat_took_place(skb)) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { + struct rtable *rt; struct flowi fl = { .nl_u = { .ip4_u = { @@ -375,7 +373,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) /* - Bridged-and-DNAT'ed traffic doesn't * require ip_forwarding. */ if (((struct dst_entry *)rt)->dev == dev) { - skb_dst_set(skb, (struct dst_entry *)rt); + skb->dst = (struct dst_entry *)rt; goto bridged_dnat; } /* we are sure that forwarding is disabled, so printing @@ -389,7 +387,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) kfree_skb(skb); return 0; } else { - if (skb_dst(skb)->dev == dev) { + if (skb->dst->dev == dev) { bridged_dnat: /* Tell br_nf_local_out this is a * bridged frame */ @@ -406,13 +404,12 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) skb->pkt_type = PACKET_HOST; } } else { - rt = bridge_parent_rtable(nf_bridge->physindev); - if (!rt) { + skb->rtable = bridge_parent_rtable(nf_bridge->physindev); + if (!skb->rtable) { kfree_skb(skb); return 0; } - dst_hold(&rt->u.dst); - skb_dst_set(skb, &rt->u.dst); + dst_hold(&skb->rtable->u.dst); } skb->dev = nf_bridge->physindev; @@ -631,10 +628,10 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb, const struct net_device *out, int (*okfn)(struct sk_buff *)) { - struct rtable *rt = skb_rtable(skb); - - if (rt && rt == bridge_parent_rtable(in)) - skb_dst_drop(skb); + if (skb->rtable && skb->rtable == bridge_parent_rtable(in)) { + dst_release(&skb->rtable->u.dst); + skb->rtable = NULL; + } return NF_ACCEPT; } @@ -849,7 +846,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb, return NF_ACCEPT; #ifdef CONFIG_NETFILTER_DEBUG - if (skb_dst(skb) == NULL) { + if (skb->dst == NULL) { printk(KERN_INFO "br_netfilter post_routing: skb->dst == NULL\n"); goto print_error; } diff --git a/trunk/net/can/af_can.c b/trunk/net/can/af_can.c index e733725b11d4..10f0528c3bf5 100644 --- a/trunk/net/can/af_can.c +++ b/trunk/net/can/af_can.c @@ -903,8 +903,6 @@ static __exit void can_exit(void) } spin_unlock(&can_rcvlists_lock); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ - kmem_cache_destroy(rcv_cache); } diff --git a/trunk/net/core/datagram.c b/trunk/net/core/datagram.c index 58abee1f1df1..e2a36f05cdf7 100644 --- a/trunk/net/core/datagram.c +++ b/trunk/net/core/datagram.c @@ -282,7 +282,6 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; /* Copy header. */ if (copy > 0) { @@ -323,24 +322,28 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_iovec(frag_iter, - offset - start, - to, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_iovec(list, + offset - start, + to, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -366,7 +369,6 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; /* Copy header. */ if (copy > 0) { @@ -409,26 +411,30 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_const_iovec(frag_iter, - offset - start, - to, to_offset, - copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - to_offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_const_iovec(list, + offset - start, + to, to_offset, + copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + to_offset += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -455,14 +461,12 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; /* Copy header. */ if (copy > 0) { if (copy > len) copy = len; - if (memcpy_fromiovecend(skb->data + offset, from, from_offset, - copy)) + if (memcpy_fromiovecend(skb->data + offset, from, 0, copy)) goto fault; if ((len -= copy) == 0) return 0; @@ -501,27 +505,31 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_from_iovec(frag_iter, - offset - start, - from, - from_offset, - copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - from_offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_from_iovec(list, + offset - start, + from, + from_offset, + copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + from_offset += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -536,9 +544,8 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, __wsum *csump) { int start = skb_headlen(skb); - int i, copy = start - offset; - struct sk_buff *frag_iter; int pos = 0; + int i, copy = start - offset; /* Copy header. */ if (copy > 0) { @@ -589,29 +596,33 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - __wsum csum2 = 0; - if (copy > len) - copy = len; - if (skb_copy_and_csum_datagram(frag_iter, - offset - start, - to, copy, - &csum2)) - goto fault; - *csump = csum_block_add(*csump, csum2, pos); - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; - pos += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list=list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + __wsum csum2 = 0; + if (copy > len) + copy = len; + if (skb_copy_and_csum_datagram(list, + offset - start, + to, copy, + &csum2)) + goto fault; + *csump = csum_block_add(*csump, csum2, pos); + if ((len -= copy) == 0) + return 0; + offset += copy; + to += copy; + pos += copy; + } + start = end; } - start = end; } if (!len) return 0; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 11560e3258b5..ed4550fd9ece 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -269,8 +269,7 @@ static const unsigned short netdev_lock_type[] = ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, - ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY, - ARPHRD_VOID, ARPHRD_NONE}; + ARPHRD_PHONET_PIPE, ARPHRD_VOID, ARPHRD_NONE}; static const char *netdev_lock_name[] = {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", @@ -287,8 +286,7 @@ static const char *netdev_lock_name[] = "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", - "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY", - "_xmit_VOID", "_xmit_NONE"}; + "_xmit_PHONET_PIPE", "_xmit_VOID", "_xmit_NONE"}; static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; @@ -1050,7 +1048,7 @@ void dev_load(struct net *net, const char *name) int dev_open(struct net_device *dev) { const struct net_device_ops *ops = dev->netdev_ops; - int ret; + int ret = 0; ASSERT_RTNL(); @@ -1067,11 +1065,6 @@ int dev_open(struct net_device *dev) if (!netif_device_present(dev)) return -ENODEV; - ret = call_netdevice_notifiers(NETDEV_PRE_UP, dev); - ret = notifier_to_errno(ret); - if (ret) - return ret; - /* * Call device private open method */ @@ -1700,9 +1693,10 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, * If device doesnt need skb->dst, release it right now while * its hot in this cpu cache */ - if (dev->priv_flags & IFF_XMIT_DST_RELEASE) - skb_dst_drop(skb); - + if ((dev->priv_flags & IFF_XMIT_DST_RELEASE) && skb->dst) { + dst_release(skb->dst); + skb->dst = NULL; + } rc = ops->ndo_start_xmit(skb, dev); if (rc == 0) txq_trans_update(txq); @@ -1822,7 +1816,7 @@ int dev_queue_xmit(struct sk_buff *skb) if (netif_needs_gso(dev, skb)) goto gso; - if (skb_has_frags(skb) && + if (skb_shinfo(skb)->frag_list && !(dev->features & NETIF_F_FRAGLIST) && __skb_linearize(skb)) goto out_kfree_skb; @@ -2409,7 +2403,7 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) if (!(skb->dev->features & NETIF_F_GRO)) goto normal; - if (skb_is_gso(skb) || skb_has_frags(skb)) + if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list) goto normal; rcu_read_lock(); @@ -3479,9 +3473,8 @@ void dev_set_rx_mode(struct net_device *dev) /* hw addresses list handling functions */ -static int __hw_addr_add(struct list_head *list, int *delta, - unsigned char *addr, int addr_len, - unsigned char addr_type) +static int __hw_addr_add(struct list_head *list, unsigned char *addr, + int addr_len, unsigned char addr_type) { struct netdev_hw_addr *ha; int alloc_size; @@ -3489,15 +3482,6 @@ static int __hw_addr_add(struct list_head *list, int *delta, if (addr_len > MAX_ADDR_LEN) return -EINVAL; - list_for_each_entry(ha, list, list) { - if (!memcmp(ha->addr, addr, addr_len) && - ha->type == addr_type) { - ha->refcount++; - return 0; - } - } - - alloc_size = sizeof(*ha); if (alloc_size < L1_CACHE_BYTES) alloc_size = L1_CACHE_BYTES; @@ -3506,11 +3490,7 @@ static int __hw_addr_add(struct list_head *list, int *delta, return -ENOMEM; memcpy(ha->addr, addr, addr_len); ha->type = addr_type; - ha->refcount = 1; - ha->synced = false; list_add_tail_rcu(&ha->list, list); - if (delta) - (*delta)++; return 0; } @@ -3522,30 +3502,29 @@ static void ha_rcu_free(struct rcu_head *head) kfree(ha); } -static int __hw_addr_del(struct list_head *list, int *delta, - unsigned char *addr, int addr_len, - unsigned char addr_type) +static int __hw_addr_del_ii(struct list_head *list, unsigned char *addr, + int addr_len, unsigned char addr_type, + int ignore_index) { struct netdev_hw_addr *ha; + int i = 0; list_for_each_entry(ha, list, list) { - if (!memcmp(ha->addr, addr, addr_len) && + if (i++ != ignore_index && + !memcmp(ha->addr, addr, addr_len) && (ha->type == addr_type || !addr_type)) { - if (--ha->refcount) - return 0; list_del_rcu(&ha->list); call_rcu(&ha->rcu_head, ha_rcu_free); - if (delta) - (*delta)--; return 0; } } return -ENOENT; } -static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, - struct list_head *from_list, int addr_len, - unsigned char addr_type) +static int __hw_addr_add_multiple_ii(struct list_head *to_list, + struct list_head *from_list, + int addr_len, unsigned char addr_type, + int ignore_index) { int err; struct netdev_hw_addr *ha, *ha2; @@ -3553,8 +3532,7 @@ static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, list_for_each_entry(ha, from_list, list) { type = addr_type ? addr_type : ha->type; - err = __hw_addr_add(to_list, to_delta, ha->addr, - addr_len, type); + err = __hw_addr_add(to_list, ha->addr, addr_len, type); if (err) goto unroll; } @@ -3565,69 +3543,27 @@ static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, if (ha2 == ha) break; type = addr_type ? addr_type : ha2->type; - __hw_addr_del(to_list, to_delta, ha2->addr, - addr_len, type); + __hw_addr_del_ii(to_list, ha2->addr, addr_len, type, + ignore_index); } return err; } -static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta, - struct list_head *from_list, int addr_len, - unsigned char addr_type) +static void __hw_addr_del_multiple_ii(struct list_head *to_list, + struct list_head *from_list, + int addr_len, unsigned char addr_type, + int ignore_index) { struct netdev_hw_addr *ha; unsigned char type; list_for_each_entry(ha, from_list, list) { type = addr_type ? addr_type : ha->type; - __hw_addr_del(to_list, to_delta, ha->addr, - addr_len, addr_type); - } -} - -static int __hw_addr_sync(struct list_head *to_list, int *to_delta, - struct list_head *from_list, int *from_delta, - int addr_len) -{ - int err = 0; - struct netdev_hw_addr *ha, *tmp; - - list_for_each_entry_safe(ha, tmp, from_list, list) { - if (!ha->synced) { - err = __hw_addr_add(to_list, to_delta, ha->addr, - addr_len, ha->type); - if (err) - break; - ha->synced = true; - ha->refcount++; - } else if (ha->refcount == 1) { - __hw_addr_del(to_list, to_delta, ha->addr, - addr_len, ha->type); - __hw_addr_del(from_list, from_delta, ha->addr, - addr_len, ha->type); - } - } - return err; -} - -static void __hw_addr_unsync(struct list_head *to_list, int *to_delta, - struct list_head *from_list, int *from_delta, - int addr_len) -{ - struct netdev_hw_addr *ha, *tmp; - - list_for_each_entry_safe(ha, tmp, from_list, list) { - if (ha->synced) { - __hw_addr_del(to_list, to_delta, ha->addr, - addr_len, ha->type); - ha->synced = false; - __hw_addr_del(from_list, from_delta, ha->addr, - addr_len, ha->type); - } + __hw_addr_del_ii(to_list, ha->addr, addr_len, addr_type, + ignore_index); } } - static void __hw_addr_flush(struct list_head *list) { struct netdev_hw_addr *ha, *tmp; @@ -3657,8 +3593,8 @@ static int dev_addr_init(struct net_device *dev) /* rtnl_mutex must be held here */ INIT_LIST_HEAD(&dev->dev_addr_list); - memset(addr, 0, sizeof(addr)); - err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr), + memset(addr, 0, sizeof(*addr)); + err = __hw_addr_add(&dev->dev_addr_list, addr, sizeof(*addr), NETDEV_HW_ADDR_T_LAN); if (!err) { /* @@ -3690,7 +3626,7 @@ int dev_addr_add(struct net_device *dev, unsigned char *addr, ASSERT_RTNL(); - err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len, + err = __hw_addr_add(&dev->dev_addr_list, addr, dev->addr_len, addr_type); if (!err) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); @@ -3713,20 +3649,11 @@ int dev_addr_del(struct net_device *dev, unsigned char *addr, unsigned char addr_type) { int err; - struct netdev_hw_addr *ha; ASSERT_RTNL(); - /* - * We can not remove the first address from the list because - * dev->dev_addr points to that. - */ - ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list); - if (ha->addr == dev->dev_addr && ha->refcount == 1) - return -ENOENT; - - err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len, - addr_type); + err = __hw_addr_del_ii(&dev->dev_addr_list, addr, dev->addr_len, + addr_type, 0); if (!err) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); return err; @@ -3753,9 +3680,9 @@ int dev_addr_add_multiple(struct net_device *to_dev, if (from_dev->addr_len != to_dev->addr_len) return -EINVAL; - err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL, - &from_dev->dev_addr_list, - to_dev->addr_len, addr_type); + err = __hw_addr_add_multiple_ii(&to_dev->dev_addr_list, + &from_dev->dev_addr_list, + to_dev->addr_len, addr_type, 0); if (!err) call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); return err; @@ -3780,9 +3707,9 @@ int dev_addr_del_multiple(struct net_device *to_dev, if (from_dev->addr_len != to_dev->addr_len) return -EINVAL; - __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL, - &from_dev->dev_addr_list, - to_dev->addr_len, addr_type); + __hw_addr_del_multiple_ii(&to_dev->dev_addr_list, + &from_dev->dev_addr_list, + to_dev->addr_len, addr_type, 0); call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); return 0; } @@ -3852,22 +3779,24 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, * dev_unicast_delete - Release secondary unicast address. * @dev: device * @addr: address to delete + * @alen: length of @addr * * Release reference to a secondary unicast address and remove it * from the device if the reference count drops to zero. * * The caller must hold the rtnl_mutex. */ -int dev_unicast_delete(struct net_device *dev, void *addr) +int dev_unicast_delete(struct net_device *dev, void *addr, int alen) { int err; ASSERT_RTNL(); - err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr, - dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); + netif_addr_lock_bh(dev); + err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); if (!err) __dev_set_rx_mode(dev); + netif_addr_unlock_bh(dev); return err; } EXPORT_SYMBOL(dev_unicast_delete); @@ -3876,22 +3805,24 @@ EXPORT_SYMBOL(dev_unicast_delete); * dev_unicast_add - add a secondary unicast address * @dev: device * @addr: address to add + * @alen: length of @addr * * Add a secondary unicast address to the device or increase * the reference count if it already exists. * * The caller must hold the rtnl_mutex. */ -int dev_unicast_add(struct net_device *dev, void *addr) +int dev_unicast_add(struct net_device *dev, void *addr, int alen) { int err; ASSERT_RTNL(); - err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr, - dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); + netif_addr_lock_bh(dev); + err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); if (!err) __dev_set_rx_mode(dev); + netif_addr_unlock_bh(dev); return err; } EXPORT_SYMBOL(dev_unicast_add); @@ -3948,7 +3879,8 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, * @from: source device * * Add newly added addresses to the destination device and release - * addresses that have no users left. + * addresses that have no users left. The source device must be + * locked by netif_tx_lock_bh. * * This function is intended to be called from the dev->set_rx_mode * function of layered software devices. @@ -3957,15 +3889,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) { int err = 0; - ASSERT_RTNL(); - - if (to->addr_len != from->addr_len) - return -EINVAL; - - err = __hw_addr_sync(&to->uc_list, &to->uc_count, - &from->uc_list, &from->uc_count, to->addr_len); + netif_addr_lock_bh(to); + err = __dev_addr_sync(&to->uc_list, &to->uc_count, + &from->uc_list, &from->uc_count); if (!err) __dev_set_rx_mode(to); + netif_addr_unlock_bh(to); return err; } EXPORT_SYMBOL(dev_unicast_sync); @@ -3981,32 +3910,17 @@ EXPORT_SYMBOL(dev_unicast_sync); */ void dev_unicast_unsync(struct net_device *to, struct net_device *from) { - ASSERT_RTNL(); - - if (to->addr_len != from->addr_len) - return; + netif_addr_lock_bh(from); + netif_addr_lock(to); - __hw_addr_unsync(&to->uc_list, &to->uc_count, - &from->uc_list, &from->uc_count, to->addr_len); + __dev_addr_unsync(&to->uc_list, &to->uc_count, + &from->uc_list, &from->uc_count); __dev_set_rx_mode(to); -} -EXPORT_SYMBOL(dev_unicast_unsync); - -static void dev_unicast_flush(struct net_device *dev) -{ - /* rtnl_mutex must be held here */ - - __hw_addr_flush(&dev->uc_list); - dev->uc_count = 0; -} -static void dev_unicast_init(struct net_device *dev) -{ - /* rtnl_mutex must be held here */ - - INIT_LIST_HEAD(&dev->uc_list); + netif_addr_unlock(to); + netif_addr_unlock_bh(from); } - +EXPORT_SYMBOL(dev_unicast_unsync); static void __dev_addr_discard(struct dev_addr_list **list) { @@ -4026,6 +3940,9 @@ static void dev_addr_discard(struct net_device *dev) { netif_addr_lock_bh(dev); + __dev_addr_discard(&dev->uc_list); + dev->uc_count = 0; + __dev_addr_discard(&dev->mc_list); dev->mc_count = 0; @@ -4618,7 +4535,6 @@ static void rollback_registered(struct net_device *dev) /* * Flush the unicast and multicast chains */ - dev_unicast_flush(dev); dev_addr_discard(dev); if (dev->netdev_ops->ndo_uninit) @@ -5072,18 +4988,18 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, struct netdev_queue *tx; struct net_device *dev; size_t alloc_size; - struct net_device *p; + void *p; BUG_ON(strlen(name) >= sizeof(dev->name)); alloc_size = sizeof(struct net_device); if (sizeof_priv) { /* ensure 32-byte alignment of private area */ - alloc_size = ALIGN(alloc_size, NETDEV_ALIGN); + alloc_size = (alloc_size + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; alloc_size += sizeof_priv; } /* ensure 32-byte alignment of whole construct */ - alloc_size += NETDEV_ALIGN - 1; + alloc_size += NETDEV_ALIGN_CONST; p = kzalloc(alloc_size, GFP_KERNEL); if (!p) { @@ -5098,14 +5014,13 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, goto free_p; } - dev = PTR_ALIGN(p, NETDEV_ALIGN); + dev = (struct net_device *) + (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); dev->padded = (char *)dev - (char *)p; if (dev_addr_init(dev)) goto free_tx; - dev_unicast_init(dev); - dev_net_set(dev, &init_net); dev->_tx = tx; @@ -5309,7 +5224,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* * Flush the unicast and multicast chains */ - dev_unicast_flush(dev); dev_addr_discard(dev); netdev_unregister_kobject(dev); diff --git a/trunk/net/core/iovec.c b/trunk/net/core/iovec.c index 16ad45d4882b..40a76ce19d9f 100644 --- a/trunk/net/core/iovec.c +++ b/trunk/net/core/iovec.c @@ -112,9 +112,9 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, continue; } copy = min_t(unsigned int, iov->iov_len - offset, len); - if (copy_to_user(iov->iov_base + offset, kdata, copy)) - return -EFAULT; offset = 0; + if (copy_to_user(iov->iov_base, kdata, copy)) + return -EFAULT; kdata += copy; len -= copy; } diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 163b4f5b0365..a1cbce7fdae5 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -771,28 +771,6 @@ static __inline__ int neigh_max_probes(struct neighbour *n) p->ucast_probes + p->app_probes + p->mcast_probes); } -static void neigh_invalidate(struct neighbour *neigh) -{ - struct sk_buff *skb; - - NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); - NEIGH_PRINTK2("neigh %p is failed.\n", neigh); - neigh->updated = jiffies; - - /* It is very thin place. report_unreachable is very complicated - routine. Particularly, it can hit the same neighbour entry! - - So that, we try to be accurate and avoid dead loop. --ANK - */ - while (neigh->nud_state == NUD_FAILED && - (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { - write_unlock(&neigh->lock); - neigh->ops->error_report(neigh, skb); - write_lock(&neigh->lock); - } - skb_queue_purge(&neigh->arp_queue); -} - /* Called when a timer expires for a neighbour entry. */ static void neigh_timer_handler(unsigned long arg) @@ -857,9 +835,26 @@ static void neigh_timer_handler(unsigned long arg) if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { + struct sk_buff *skb; + neigh->nud_state = NUD_FAILED; + neigh->updated = jiffies; notify = 1; - neigh_invalidate(neigh); + NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); + NEIGH_PRINTK2("neigh %p is failed.\n", neigh); + + /* It is very thin place. report_unreachable is very complicated + routine. Particularly, it can hit the same neighbour entry! + + So that, we try to be accurate and avoid dead loop. --ANK + */ + while (neigh->nud_state == NUD_FAILED && + (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { + write_unlock(&neigh->lock); + neigh->ops->error_report(neigh, skb); + write_lock(&neigh->lock); + } + skb_queue_purge(&neigh->arp_queue); } if (neigh->nud_state & NUD_IN_TIMER) { @@ -1006,11 +1001,6 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, neigh->nud_state = new; err = 0; notify = old & NUD_VALID; - if ((old & (NUD_INCOMPLETE | NUD_PROBE)) && - (new & NUD_FAILED)) { - neigh_invalidate(neigh); - notify = 1; - } goto out; } @@ -1098,8 +1088,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, struct neighbour *n1 = neigh; write_unlock_bh(&neigh->lock); /* On shaper/eql skb->dst->neighbour != neigh :( */ - if (skb_dst(skb) && skb_dst(skb)->neighbour) - n1 = skb_dst(skb)->neighbour; + if (skb->dst && skb->dst->neighbour) + n1 = skb->dst->neighbour; n1->output(skb); write_lock_bh(&neigh->lock); } @@ -1192,7 +1182,7 @@ EXPORT_SYMBOL(neigh_compat_output); int neigh_resolve_output(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct neighbour *neigh; int rc = 0; @@ -1239,7 +1229,7 @@ EXPORT_SYMBOL(neigh_resolve_output); int neigh_connected_output(struct sk_buff *skb) { int err; - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct neighbour *neigh = dst->neighbour; struct net_device *dev = neigh->dev; @@ -1308,7 +1298,8 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, if (time_before(tbl->proxy_timer.expires, sched_next)) sched_next = tbl->proxy_timer.expires; } - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; dev_hold(skb->dev); __skb_queue_tail(&tbl->proxy_queue, skb); mod_timer(&tbl->proxy_timer, sched_next); diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 19b8c20e98a4..b8ccd3c88d63 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -3691,7 +3691,8 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) #ifdef CONFIG_XFRM free_SAs(pkt_dev); #endif - vfree(pkt_dev->flows); + if (pkt_dev->flows) + vfree(pkt_dev->flows); kfree(pkt_dev); return err; } @@ -3790,7 +3791,8 @@ static int pktgen_remove_device(struct pktgen_thread *t, #ifdef CONFIG_XFRM free_SAs(pkt_dev); #endif - vfree(pkt_dev->flows); + if (pkt_dev->flows) + vfree(pkt_dev->flows); kfree(pkt_dev); return 0; } diff --git a/trunk/net/core/skb_dma_map.c b/trunk/net/core/skb_dma_map.c index 79687dfd6957..86234923a3b7 100644 --- a/trunk/net/core/skb_dma_map.c +++ b/trunk/net/core/skb_dma_map.c @@ -20,7 +20,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, if (dma_mapping_error(dev, map)) goto out_err; - sp->dma_head = map; + sp->dma_maps[0] = map; for (i = 0; i < sp->nr_frags; i++) { skb_frag_t *fp = &sp->frags[i]; @@ -28,8 +28,9 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, fp->size, dir); if (dma_mapping_error(dev, map)) goto unwind; - sp->dma_maps[i] = map; + sp->dma_maps[i + 1] = map; } + sp->num_dma_maps = i + 1; return 0; @@ -37,10 +38,10 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, while (--i >= 0) { skb_frag_t *fp = &sp->frags[i]; - dma_unmap_page(dev, sp->dma_maps[i], + dma_unmap_page(dev, sp->dma_maps[i + 1], fp->size, dir); } - dma_unmap_single(dev, sp->dma_head, + dma_unmap_single(dev, sp->dma_maps[0], skb_headlen(skb), dir); out_err: return -ENOMEM; @@ -53,12 +54,12 @@ void skb_dma_unmap(struct device *dev, struct sk_buff *skb, struct skb_shared_info *sp = skb_shinfo(skb); int i; - dma_unmap_single(dev, sp->dma_head, + dma_unmap_single(dev, sp->dma_maps[0], skb_headlen(skb), dir); for (i = 0; i < sp->nr_frags; i++) { skb_frag_t *fp = &sp->frags[i]; - dma_unmap_page(dev, sp->dma_maps[i], + dma_unmap_page(dev, sp->dma_maps[i + 1], fp->size, dir); } } diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index b94d777e3eb4..8e815e685f28 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -210,7 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, shinfo->gso_type = 0; shinfo->ip6_frag_id = 0; shinfo->tx_flags.flags = 0; - skb_frag_list_init(skb); + shinfo->frag_list = NULL; memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); if (fclone) { @@ -323,7 +323,7 @@ static void skb_clone_fraglist(struct sk_buff *skb) { struct sk_buff *list; - skb_walk_frags(skb, list) + for (list = skb_shinfo(skb)->frag_list; list; list = list->next) skb_get(list); } @@ -338,7 +338,7 @@ static void skb_release_data(struct sk_buff *skb) put_page(skb_shinfo(skb)->frags[i].page); } - if (skb_has_frags(skb)) + if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); kfree(skb->head); @@ -381,7 +381,7 @@ static void kfree_skbmem(struct sk_buff *skb) static void skb_release_head_state(struct sk_buff *skb) { - skb_dst_drop(skb); + dst_release(skb->dst); #ifdef CONFIG_XFRM secpath_put(skb->sp); #endif @@ -503,7 +503,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) shinfo->gso_type = 0; shinfo->ip6_frag_id = 0; shinfo->tx_flags.flags = 0; - skb_frag_list_init(skb); + shinfo->frag_list = NULL; memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); memset(skb, 0, offsetof(struct sk_buff, tail)); @@ -521,7 +521,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->transport_header = old->transport_header; new->network_header = old->network_header; new->mac_header = old->mac_header; - skb_dst_set(new, dst_clone(skb_dst(old))); + new->dst = dst_clone(old->dst); #ifdef CONFIG_XFRM new->sp = secpath_get(old->sp); #endif @@ -552,6 +552,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->vlan_tci = old->vlan_tci; #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) new->do_not_encrypt = old->do_not_encrypt; + new->requeue = old->requeue; #endif skb_copy_secmark(new, old); @@ -757,7 +758,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) skb_shinfo(n)->nr_frags = i; } - if (skb_has_frags(skb)) { + if (skb_shinfo(skb)->frag_list) { skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; skb_clone_fraglist(n); } @@ -820,7 +821,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) get_page(skb_shinfo(skb)->frags[i].page); - if (skb_has_frags(skb)) + if (skb_shinfo(skb)->frag_list) skb_clone_fraglist(skb); skb_release_data(skb); @@ -1092,7 +1093,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) for (; i < nfrags; i++) put_page(skb_shinfo(skb)->frags[i].page); - if (skb_has_frags(skb)) + if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); goto done; } @@ -1187,7 +1188,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) /* Optimization: no fragments, no reasons to preestimate * size of pulled pages. Superb. */ - if (!skb_has_frags(skb)) + if (!skb_shinfo(skb)->frag_list) goto pull_pages; /* Estimate size of pulled pages. */ @@ -1284,9 +1285,8 @@ EXPORT_SYMBOL(__pskb_pull_tail); int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) { - int start = skb_headlen(skb); - struct sk_buff *frag_iter; int i, copy; + int start = skb_headlen(skb); if (offset > (int)skb->len - len) goto fault; @@ -1328,23 +1328,28 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_bits(frag_iter, offset - start, to, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_bits(list, offset - start, + to, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + to += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -1529,7 +1534,6 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, .ops = &sock_pipe_buf_ops, .spd_release = sock_spd_release, }; - struct sk_buff *frag_iter; struct sock *sk = skb->sk; /* @@ -1544,11 +1548,13 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, /* * now see if we have a frag_list to map */ - skb_walk_frags(skb, frag_iter) { - if (!tlen) - break; - if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk)) - break; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list && tlen; list = list->next) { + if (__skb_splice_bits(list, &offset, &tlen, &spd, sk)) + break; + } } done: @@ -1587,9 +1593,8 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) { - int start = skb_headlen(skb); - struct sk_buff *frag_iter; int i, copy; + int start = skb_headlen(skb); if (offset > (int)skb->len - len) goto fault; @@ -1630,24 +1635,28 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_store_bits(frag_iter, offset - start, - from, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - from += copy; + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_store_bits(list, offset - start, + from, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + from += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -1664,7 +1673,6 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; int pos = 0; /* Checksum header. */ @@ -1704,25 +1712,29 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - __wsum csum2; - if (copy > len) - copy = len; - csum2 = skb_checksum(frag_iter, offset - start, - copy, 0); - csum = csum_block_add(csum, csum2, pos); - if ((len -= copy) == 0) - return csum; - offset += copy; - pos += copy; + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + __wsum csum2; + if (copy > len) + copy = len; + csum2 = skb_checksum(list, offset - start, + copy, 0); + csum = csum_block_add(csum, csum2, pos); + if ((len -= copy) == 0) + return csum; + offset += copy; + pos += copy; + } + start = end; } - start = end; } BUG_ON(len); @@ -1737,7 +1749,6 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; int pos = 0; /* Copy header. */ @@ -1782,27 +1793,31 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - __wsum csum2; - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - csum2 = skb_copy_and_csum_bits(frag_iter, - offset - start, - to, copy, 0); - csum = csum_block_add(csum, csum2, pos); - if ((len -= copy) == 0) - return csum; - offset += copy; - to += copy; - pos += copy; + for (; list; list = list->next) { + __wsum csum2; + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + csum2 = skb_copy_and_csum_bits(list, + offset - start, + to, copy, 0); + csum = csum_block_add(csum, csum2, pos); + if ((len -= copy) == 0) + return csum; + offset += copy; + to += copy; + pos += copy; + } + start = end; } - start = end; } BUG_ON(len); return csum; @@ -2312,7 +2327,8 @@ unsigned int skb_seq_read(unsigned int consumed, const u8 **data, st->frag_data = NULL; } - if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) { + if (st->root_skb == st->cur_skb && + skb_shinfo(st->root_skb)->frag_list) { st->cur_skb = skb_shinfo(st->root_skb)->frag_list; st->frag_idx = 0; goto next_skb; @@ -2623,7 +2639,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) } else skb_get(fskb2); - SKB_FRAG_ASSERT(nskb); + BUG_ON(skb_shinfo(nskb)->frag_list); skb_shinfo(nskb)->frag_list = fskb2; } @@ -2780,7 +2796,6 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; int elt = 0; if (copy > 0) { @@ -2814,22 +2829,26 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) start = end; } - skb_walk_frags(skb, frag_iter) { - int end; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - WARN_ON(start > offset + len); + for (; list; list = list->next) { + int end; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start, - copy); - if ((len -= copy) == 0) - return elt; - offset += copy; + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + elt += __skb_to_sgvec(list, sg+elt, offset - start, + copy); + if ((len -= copy) == 0) + return elt; + offset += copy; + } + start = end; } - start = end; } BUG_ON(len); return elt; @@ -2877,7 +2896,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) return -ENOMEM; /* Easy case. Most of packets will go this way. */ - if (!skb_has_frags(skb)) { + if (!skb_shinfo(skb)->frag_list) { /* A little of trouble, not enough of space for trailer. * This should not happen, when stack is tuned to generate * good frames. OK, on miss we reallocate and reserve even more @@ -2912,7 +2931,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) if (skb1->next == NULL && tailbits) { if (skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1) || + skb_shinfo(skb1)->frag_list || skb_tailroom(skb1) < tailbits) ntail = tailbits + 128; } @@ -2921,7 +2940,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) skb_cloned(skb1) || ntail || skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1)) { + skb_shinfo(skb1)->frag_list) { struct sk_buff *skb2; /* Fuck, we are miserable poor guys... */ @@ -3007,12 +3026,12 @@ EXPORT_SYMBOL_GPL(skb_tstamp_tx); */ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) { - if (unlikely(start > skb_headlen(skb)) || - unlikely((int)start + off > skb_headlen(skb) - 2)) { + if (unlikely(start > skb->len - 2) || + unlikely((int)start + off > skb->len - 2)) { if (net_ratelimit()) printk(KERN_WARNING "bad partial csum: csum=%u/%u len=%u\n", - start, off, skb_headlen(skb)); + start, off, skb->len); return false; } skb->ip_summed = CHECKSUM_PARTIAL; diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 06e26b77ad9e..7dbf3ffb35cc 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -155,7 +155,6 @@ static const char *af_family_key_strings[AF_MAX+1] = { "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , - "sk_lock-AF_IEEE802154", "sk_lock-AF_MAX" }; static const char *af_family_slock_key_strings[AF_MAX+1] = { @@ -171,7 +170,6 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = { "slock-27" , "slock-28" , "slock-AF_CAN" , "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , - "slock-AF_IEEE802154", "slock-AF_MAX" }; static const char *af_family_clock_key_strings[AF_MAX+1] = { @@ -187,7 +185,6 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = { "clock-27" , "clock-28" , "clock-AF_CAN" , "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , - "clock-AF_IEEE802154", "clock-AF_MAX" }; @@ -215,7 +212,6 @@ __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX; /* Maximal space eaten by iovec or ancilliary data plus some space */ int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512); -EXPORT_SYMBOL(sysctl_optmem_max); static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) { @@ -448,7 +444,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) int sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { - struct sock *sk = sock->sk; + struct sock *sk=sock->sk; int val; int valbool; struct linger ling; @@ -467,15 +463,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname, if (get_user(val, (int __user *)optval)) return -EFAULT; - valbool = val ? 1 : 0; + valbool = val?1:0; lock_sock(sk); - switch (optname) { + switch(optname) { case SO_DEBUG: - if (val && !capable(CAP_NET_ADMIN)) + if (val && !capable(CAP_NET_ADMIN)) { ret = -EACCES; - else + } else sock_valbool_flag(sk, SOCK_DBG, valbool); break; case SO_REUSEADDR: @@ -586,7 +582,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, ret = -EINVAL; /* 1003.1g */ break; } - if (copy_from_user(&ling, optval, sizeof(ling))) { + if (copy_from_user(&ling,optval,sizeof(ling))) { ret = -EFAULT; break; } @@ -694,8 +690,9 @@ int sock_setsockopt(struct socket *sock, int level, int optname, case SO_MARK: if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else + else { sk->sk_mark = val; + } break; /* We implement the SO_SNDLOWAT etc to @@ -707,7 +704,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname, release_sock(sk); return ret; } -EXPORT_SYMBOL(sock_setsockopt); int sock_getsockopt(struct socket *sock, int level, int optname, @@ -731,7 +727,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, memset(&v, 0, sizeof(v)); - switch (optname) { + switch(optname) { case SO_DEBUG: v.val = sock_flag(sk, SOCK_DBG); break; @@ -766,7 +762,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, case SO_ERROR: v.val = -sock_error(sk); - if (v.val == 0) + if (v.val==0) v.val = xchg(&sk->sk_err_soft, 0); break; @@ -820,7 +816,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_RCVTIMEO: - lv = sizeof(struct timeval); + lv=sizeof(struct timeval); if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) { v.tm.tv_sec = 0; v.tm.tv_usec = 0; @@ -831,7 +827,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_SNDTIMEO: - lv = sizeof(struct timeval); + lv=sizeof(struct timeval); if (sk->sk_sndtimeo == MAX_SCHEDULE_TIMEOUT) { v.tm.tv_sec = 0; v.tm.tv_usec = 0; @@ -846,7 +842,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_SNDLOWAT: - v.val = 1; + v.val=1; break; case SO_PASSCRED: @@ -1006,9 +1002,8 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, return sk; } -EXPORT_SYMBOL(sk_alloc); -static void __sk_free(struct sock *sk) +void sk_free(struct sock *sk) { struct sk_filter *filter; @@ -1032,18 +1027,6 @@ static void __sk_free(struct sock *sk) sk_prot_free(sk->sk_prot_creator, sk); } -void sk_free(struct sock *sk) -{ - /* - * We substract one from sk_wmem_alloc and can know if - * some packets are still in some tx queue. - * If not null, sock_wfree() will call __sk_free(sk) later - */ - if (atomic_dec_and_test(&sk->sk_wmem_alloc)) - __sk_free(sk); -} -EXPORT_SYMBOL(sk_free); - /* * Last sock_put should drop referrence to sk->sk_net. It has already * been dropped in sk_change_net. Taking referrence to stopping namespace @@ -1082,10 +1065,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; atomic_set(&newsk->sk_rmem_alloc, 0); - /* - * sk_wmem_alloc set to one (see sk_free() and sock_wfree()) - */ - atomic_set(&newsk->sk_wmem_alloc, 1); + atomic_set(&newsk->sk_wmem_alloc, 0); atomic_set(&newsk->sk_omem_alloc, 0); skb_queue_head_init(&newsk->sk_receive_queue); skb_queue_head_init(&newsk->sk_write_queue); @@ -1146,6 +1126,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) out: return newsk; } + EXPORT_SYMBOL_GPL(sk_clone); void sk_setup_caps(struct sock *sk, struct dst_entry *dst) @@ -1189,20 +1170,13 @@ void __init sk_init(void) void sock_wfree(struct sk_buff *skb) { struct sock *sk = skb->sk; - int res; /* In case it might be waiting for more memory. */ - res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); + atomic_sub(skb->truesize, &sk->sk_wmem_alloc); if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) sk->sk_write_space(sk); - /* - * if sk_wmem_alloc reached 0, we are last user and should - * free this sock, as sk_free() call could not do it. - */ - if (res == 0) - __sk_free(sk); + sock_put(sk); } -EXPORT_SYMBOL(sock_wfree); /* * Read buffer destructor automatically called from kfree_skb. @@ -1214,7 +1188,6 @@ void sock_rfree(struct sk_buff *skb) atomic_sub(skb->truesize, &sk->sk_rmem_alloc); sk_mem_uncharge(skb->sk, skb->truesize); } -EXPORT_SYMBOL(sock_rfree); int sock_i_uid(struct sock *sk) @@ -1226,7 +1199,6 @@ int sock_i_uid(struct sock *sk) read_unlock(&sk->sk_callback_lock); return uid; } -EXPORT_SYMBOL(sock_i_uid); unsigned long sock_i_ino(struct sock *sk) { @@ -1237,7 +1209,6 @@ unsigned long sock_i_ino(struct sock *sk) read_unlock(&sk->sk_callback_lock); return ino; } -EXPORT_SYMBOL(sock_i_ino); /* * Allocate a skb from the socket's send buffer. @@ -1246,7 +1217,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, gfp_t priority) { if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { - struct sk_buff *skb = alloc_skb(size, priority); + struct sk_buff * skb = alloc_skb(size, priority); if (skb) { skb_set_owner_w(skb, sk); return skb; @@ -1254,7 +1225,6 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, } return NULL; } -EXPORT_SYMBOL(sock_wmalloc); /* * Allocate a skb from the socket's receive buffer. @@ -1291,7 +1261,6 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority) } return NULL; } -EXPORT_SYMBOL(sock_kmalloc); /* * Free an option memory block. @@ -1301,12 +1270,11 @@ void sock_kfree_s(struct sock *sk, void *mem, int size) kfree(mem); atomic_sub(size, &sk->sk_omem_alloc); } -EXPORT_SYMBOL(sock_kfree_s); /* It is almost wait_for_tcp_memory minus release_sock/lock_sock. I think, these locks should be removed for datagram sockets. */ -static long sock_wait_for_wmem(struct sock *sk, long timeo) +static long sock_wait_for_wmem(struct sock * sk, long timeo) { DEFINE_WAIT(wait); @@ -1424,7 +1392,6 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, { return sock_alloc_send_pskb(sk, size, 0, noblock, errcode); } -EXPORT_SYMBOL(sock_alloc_send_skb); static void __lock_sock(struct sock *sk) { @@ -1493,6 +1460,7 @@ int sk_wait_data(struct sock *sk, long *timeo) finish_wait(sk->sk_sleep, &wait); return rc; } + EXPORT_SYMBOL(sk_wait_data); /** @@ -1573,6 +1541,7 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) atomic_sub(amt, prot->memory_allocated); return 0; } + EXPORT_SYMBOL(__sk_mem_schedule); /** @@ -1591,6 +1560,7 @@ void __sk_mem_reclaim(struct sock *sk) (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) *prot->memory_pressure = 0; } + EXPORT_SYMBOL(__sk_mem_reclaim); @@ -1605,92 +1575,78 @@ int sock_no_bind(struct socket *sock, struct sockaddr *saddr, int len) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_bind); int sock_no_connect(struct socket *sock, struct sockaddr *saddr, int len, int flags) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_connect); int sock_no_socketpair(struct socket *sock1, struct socket *sock2) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_socketpair); int sock_no_accept(struct socket *sock, struct socket *newsock, int flags) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_accept); int sock_no_getname(struct socket *sock, struct sockaddr *saddr, int *len, int peer) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_getname); -unsigned int sock_no_poll(struct file *file, struct socket *sock, poll_table *pt) +unsigned int sock_no_poll(struct file * file, struct socket *sock, poll_table *pt) { return 0; } -EXPORT_SYMBOL(sock_no_poll); int sock_no_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_ioctl); int sock_no_listen(struct socket *sock, int backlog) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_listen); int sock_no_shutdown(struct socket *sock, int how) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_shutdown); int sock_no_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_setsockopt); int sock_no_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_getsockopt); int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t len) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_sendmsg); int sock_no_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t len, int flags) { return -EOPNOTSUPP; } -EXPORT_SYMBOL(sock_no_recvmsg); int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma) { /* Mirror missing mmap method error code */ return -ENODEV; } -EXPORT_SYMBOL(sock_no_mmap); ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) { @@ -1704,7 +1660,6 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, siz kunmap(page); return res; } -EXPORT_SYMBOL(sock_no_sendpage); /* * Default Socket Callbacks @@ -1768,7 +1723,6 @@ void sk_send_sigurg(struct sock *sk) if (send_sigurg(&sk->sk_socket->file->f_owner)) sk_wake_async(sk, SOCK_WAKE_URG, POLL_PRI); } -EXPORT_SYMBOL(sk_send_sigurg); void sk_reset_timer(struct sock *sk, struct timer_list* timer, unsigned long expires) @@ -1776,6 +1730,7 @@ void sk_reset_timer(struct sock *sk, struct timer_list* timer, if (!mod_timer(timer, expires)) sock_hold(sk); } + EXPORT_SYMBOL(sk_reset_timer); void sk_stop_timer(struct sock *sk, struct timer_list* timer) @@ -1783,6 +1738,7 @@ void sk_stop_timer(struct sock *sk, struct timer_list* timer) if (timer_pending(timer) && del_timer(timer)) __sock_put(sk); } + EXPORT_SYMBOL(sk_stop_timer); void sock_init_data(struct socket *sock, struct sock *sk) @@ -1839,10 +1795,8 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_stamp = ktime_set(-1L, 0); atomic_set(&sk->sk_refcnt, 1); - atomic_set(&sk->sk_wmem_alloc, 1); atomic_set(&sk->sk_drops, 0); } -EXPORT_SYMBOL(sock_init_data); void lock_sock_nested(struct sock *sk, int subclass) { @@ -1858,6 +1812,7 @@ void lock_sock_nested(struct sock *sk, int subclass) mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); local_bh_enable(); } + EXPORT_SYMBOL(lock_sock_nested); void release_sock(struct sock *sk) @@ -1940,6 +1895,7 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname, return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen); } + EXPORT_SYMBOL(sock_common_getsockopt); #ifdef CONFIG_COMPAT @@ -1969,6 +1925,7 @@ int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, msg->msg_namelen = addr_len; return err; } + EXPORT_SYMBOL(sock_common_recvmsg); /* @@ -1981,6 +1938,7 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname, return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen); } + EXPORT_SYMBOL(sock_common_setsockopt); #ifdef CONFIG_COMPAT @@ -2031,6 +1989,7 @@ void sk_common_release(struct sock *sk) sk_refcnt_debug_release(sk); sock_put(sk); } + EXPORT_SYMBOL(sk_common_release); static DEFINE_RWLOCK(proto_list_lock); @@ -2212,6 +2171,7 @@ int proto_register(struct proto *prot, int alloc_slab) out: return -ENOBUFS; } + EXPORT_SYMBOL(proto_register); void proto_unregister(struct proto *prot) @@ -2238,6 +2198,7 @@ void proto_unregister(struct proto *prot) prot->twsk_prot->twsk_slab = NULL; } } + EXPORT_SYMBOL(proto_unregister); #ifdef CONFIG_PROC_FS @@ -2363,3 +2324,33 @@ static int __init proto_init(void) subsys_initcall(proto_init); #endif /* PROC_FS */ + +EXPORT_SYMBOL(sk_alloc); +EXPORT_SYMBOL(sk_free); +EXPORT_SYMBOL(sk_send_sigurg); +EXPORT_SYMBOL(sock_alloc_send_skb); +EXPORT_SYMBOL(sock_init_data); +EXPORT_SYMBOL(sock_kfree_s); +EXPORT_SYMBOL(sock_kmalloc); +EXPORT_SYMBOL(sock_no_accept); +EXPORT_SYMBOL(sock_no_bind); +EXPORT_SYMBOL(sock_no_connect); +EXPORT_SYMBOL(sock_no_getname); +EXPORT_SYMBOL(sock_no_getsockopt); +EXPORT_SYMBOL(sock_no_ioctl); +EXPORT_SYMBOL(sock_no_listen); +EXPORT_SYMBOL(sock_no_mmap); +EXPORT_SYMBOL(sock_no_poll); +EXPORT_SYMBOL(sock_no_recvmsg); +EXPORT_SYMBOL(sock_no_sendmsg); +EXPORT_SYMBOL(sock_no_sendpage); +EXPORT_SYMBOL(sock_no_setsockopt); +EXPORT_SYMBOL(sock_no_shutdown); +EXPORT_SYMBOL(sock_no_socketpair); +EXPORT_SYMBOL(sock_rfree); +EXPORT_SYMBOL(sock_setsockopt); +EXPORT_SYMBOL(sock_wfree); +EXPORT_SYMBOL(sock_wmalloc); +EXPORT_SYMBOL(sock_i_uid); +EXPORT_SYMBOL(sock_i_ino); +EXPORT_SYMBOL(sysctl_optmem_max); diff --git a/trunk/net/core/user_dma.c b/trunk/net/core/user_dma.c index 25d717ebc92e..164b090d5ac3 100644 --- a/trunk/net/core/user_dma.c +++ b/trunk/net/core/user_dma.c @@ -51,7 +51,6 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; dma_cookie_t cookie = 0; /* Copy header. */ @@ -95,28 +94,31 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - copy = end - offset; - if (copy > 0) { - if (copy > len) - copy = len; - cookie = dma_skb_copy_datagram_iovec(chan, frag_iter, - offset - start, - to, copy, - pinned_list); - if (cookie < 0) - goto fault; - len -= copy; - if (len == 0) - goto end; - offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + copy = end - offset; + if (copy > 0) { + if (copy > len) + copy = len; + cookie = dma_skb_copy_datagram_iovec(chan, list, + offset - start, to, copy, + pinned_list); + if (cookie < 0) + goto fault; + len -= copy; + if (len == 0) + goto end; + offset += copy; + } + start = end; } - start = end; } end: diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index a0a36c9e6cce..d1dd95289b89 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -452,7 +452,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, struct sk_buff *skb) { struct rtable *rt; - struct flowi fl = { .oif = skb_rtable(skb)->rt_iif, + struct flowi fl = { .oif = skb->rtable->rt_iif, .nl_u = { .ip4_u = { .daddr = ip_hdr(skb)->saddr, .saddr = ip_hdr(skb)->daddr, @@ -507,14 +507,14 @@ static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) const struct iphdr *rxiph; struct sk_buff *skb; struct dst_entry *dst; - struct net *net = dev_net(skb_dst(rxskb)->dev); + struct net *net = dev_net(rxskb->dst->dev); struct sock *ctl_sk = net->dccp.v4_ctl_sk; /* Never send a reset in response to a reset. */ if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET) return; - if (skb_rtable(rxskb)->rt_type != RTN_LOCAL) + if (rxskb->rtable->rt_type != RTN_LOCAL) return; dst = dccp_v4_route_skb(net, ctl_sk, rxskb); @@ -528,7 +528,7 @@ static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) rxiph = ip_hdr(rxskb); dccp_hdr(skb)->dccph_checksum = dccp_v4_csum_finish(skb, rxiph->saddr, rxiph->daddr); - skb_dst_set(skb, dst_clone(dst)); + skb->dst = dst_clone(dst); bh_lock_sock(ctl_sk); err = ip_build_and_send_pkt(skb, ctl_sk, @@ -567,7 +567,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */ - if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) + if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) return 0; /* discard, don't send a reset here */ if (dccp_bad_service_code(sk, service)) { diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index 05ea7440d9e5..b963f35c65f6 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -314,9 +314,8 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) struct ipv6hdr *rxip6h; struct sk_buff *skb; struct flowi fl; - struct net *net = dev_net(skb_dst(rxskb)->dev); + struct net *net = dev_net(rxskb->dst->dev); struct sock *ctl_sk = net->dccp.v6_ctl_sk; - struct dst_entry *dst; if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET) return; @@ -343,9 +342,8 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) security_skb_classify_flow(rxskb, &fl); /* sk = NULL, but it is safe for now. RST socket required. */ - if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { - if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { - skb_dst_set(skb, dst); + if (!ip6_dst_lookup(ctl_sk, &skb->dst, &fl)) { + if (xfrm_lookup(net, &skb->dst, &fl, NULL, 0) >= 0) { ip6_xmit(ctl_sk, skb, &fl, NULL, 0); DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); diff --git a/trunk/net/dccp/output.c b/trunk/net/dccp/output.c index c0e88c16d088..36bcc00654d3 100644 --- a/trunk/net/dccp/output.c +++ b/trunk/net/dccp/output.c @@ -350,7 +350,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, /* Reserve space for headers. */ skb_reserve(skb, sk->sk_prot->max_header); - skb_dst_set(skb, dst_clone(dst)); + skb->dst = dst_clone(dst); dreq = dccp_rsk(req); if (inet_rsk(req)->acked) /* increase ISS upon retransmission */ diff --git a/trunk/net/decnet/af_decnet.c b/trunk/net/decnet/af_decnet.c index a5e3a593e472..9647d911f916 100644 --- a/trunk/net/decnet/af_decnet.c +++ b/trunk/net/decnet/af_decnet.c @@ -1075,7 +1075,6 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) int err = 0; unsigned char type; long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); - struct dst_entry *dst; lock_sock(sk); @@ -1103,9 +1102,8 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) } release_sock(sk); - dst = skb_dst(skb); - dst_release(xchg(&newsk->sk_dst_cache, dst)); - skb_dst_set(skb, NULL); + dst_release(xchg(&newsk->sk_dst_cache, skb->dst)); + skb->dst = NULL; DN_SK(newsk)->state = DN_CR; DN_SK(newsk)->addrrem = cb->src_port; @@ -1252,8 +1250,14 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if (skb) { amount = skb->len; } else { - skb_queue_walk(&sk->sk_receive_queue, skb) + skb = sk->sk_receive_queue.next; + for (;;) { + if (skb == + (struct sk_buff *)&sk->sk_receive_queue) + break; amount += skb->len; + skb = skb->next; + } } release_sock(sk); err = put_user(amount, (int __user *)arg); @@ -1640,13 +1644,13 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int target) { - struct sk_buff *skb; + struct sk_buff *skb = q->next; int len = 0; if (flags & MSG_OOB) return !skb_queue_empty(q) ? 1 : 0; - skb_queue_walk(q, skb) { + while(skb != (struct sk_buff *)q) { struct dn_skb_cb *cb = DN_SKB_CB(skb); len += skb->len; @@ -1662,6 +1666,8 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int /* minimum data length for read exceeded */ if (len >= target) return 1; + + skb = skb->next; } return 0; @@ -1677,7 +1683,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, size_t target = size > 1 ? 1 : 0; size_t copied = 0; int rv = 0; - struct sk_buff *skb, *n; + struct sk_buff *skb, *nskb; struct dn_skb_cb *cb = NULL; unsigned char eor = 0; long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); @@ -1752,7 +1758,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, finish_wait(sk->sk_sleep, &wait); } - skb_queue_walk_safe(queue, skb, n) { + for(skb = queue->next; skb != (struct sk_buff *)queue; skb = nskb) { unsigned int chunk = skb->len; cb = DN_SKB_CB(skb); @@ -1769,6 +1775,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, skb_pull(skb, chunk); eor = cb->nsp_flags & 0x40; + nskb = skb->next; if (skb->len == 0) { skb_unlink(skb, queue); diff --git a/trunk/net/decnet/dn_neigh.c b/trunk/net/decnet/dn_neigh.c index 923786bd6d01..05b5aa05e50e 100644 --- a/trunk/net/decnet/dn_neigh.c +++ b/trunk/net/decnet/dn_neigh.c @@ -204,7 +204,7 @@ static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb) static int dn_neigh_output_packet(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct dn_route *rt = (struct dn_route *)dst; struct neighbour *neigh = dst->neighbour; struct net_device *dev = neigh->dev; @@ -224,7 +224,7 @@ static int dn_neigh_output_packet(struct sk_buff *skb) static int dn_long_output(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct neighbour *neigh = dst->neighbour; struct net_device *dev = neigh->dev; int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3; @@ -270,7 +270,7 @@ static int dn_long_output(struct sk_buff *skb) static int dn_short_output(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct neighbour *neigh = dst->neighbour; struct net_device *dev = neigh->dev; int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2; @@ -313,7 +313,7 @@ static int dn_short_output(struct sk_buff *skb) */ static int dn_phase3_output(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct neighbour *neigh = dst->neighbour; struct net_device *dev = neigh->dev; int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2; diff --git a/trunk/net/decnet/dn_nsp_out.c b/trunk/net/decnet/dn_nsp_out.c index a65e929ce76c..2013c25b7f5a 100644 --- a/trunk/net/decnet/dn_nsp_out.c +++ b/trunk/net/decnet/dn_nsp_out.c @@ -85,7 +85,7 @@ static void dn_nsp_send(struct sk_buff *skb) dst = sk_dst_check(sk, 0); if (dst) { try_again: - skb_dst_set(skb, dst); + skb->dst = dst; dst_output(skb); return; } @@ -382,7 +382,7 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff { struct dn_skb_cb *cb = DN_SKB_CB(skb); struct dn_scp *scp = DN_SK(sk); - struct sk_buff *skb2, *n, *ack = NULL; + struct sk_buff *skb2, *list, *ack = NULL; int wakeup = 0; int try_retrans = 0; unsigned long reftime = cb->stamp; @@ -390,7 +390,9 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff unsigned short xmit_count; unsigned short segnum; - skb_queue_walk_safe(q, skb2, n) { + skb2 = q->next; + list = (struct sk_buff *)q; + while(list != skb2) { struct dn_skb_cb *cb2 = DN_SKB_CB(skb2); if (dn_before_or_equal(cb2->segnum, acknum)) @@ -398,6 +400,8 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff /* printk(KERN_DEBUG "ack: %s %04x %04x\n", ack ? "ACK" : "SKIP", (int)cb2->segnum, (int)acknum); */ + skb2 = skb2->next; + if (ack == NULL) continue; @@ -582,7 +586,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, * to be able to send disc packets out which have no socket * associations. */ - skb_dst_set(skb, dst_clone(dst)); + skb->dst = dst_clone(dst); dst_output(skb); } @@ -611,7 +615,7 @@ void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg, int ddl = 0; gfp_t gfp = GFP_ATOMIC; - dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb_dst(skb), ddl, + dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb->dst, ddl, NULL, cb->src_port, cb->dst_port); } diff --git a/trunk/net/decnet/dn_route.c b/trunk/net/decnet/dn_route.c index 1d6ca8a98dc6..0cc4394117df 100644 --- a/trunk/net/decnet/dn_route.c +++ b/trunk/net/decnet/dn_route.c @@ -678,7 +678,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type static int dn_output(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct dn_route *rt = (struct dn_route *)dst; struct net_device *dev = dst->dev; struct dn_skb_cb *cb = DN_SKB_CB(skb); @@ -717,7 +717,7 @@ static int dn_output(struct sk_buff *skb) static int dn_forward(struct sk_buff *skb) { struct dn_skb_cb *cb = DN_SKB_CB(skb); - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct dn_dev *dn_db = dst->dev->dn_ptr; struct dn_route *rt; struct neighbour *neigh = dst->neighbour; @@ -730,7 +730,7 @@ static int dn_forward(struct sk_buff *skb) goto drop; /* Ensure that we have enough space for headers */ - rt = (struct dn_route *)skb_dst(skb); + rt = (struct dn_route *)skb->dst; header_len = dn_db->use_long ? 21 : 6; if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+header_len)) goto drop; @@ -1392,8 +1392,7 @@ static int dn_route_input_slow(struct sk_buff *skb) goto e_neighbour; hash = dn_hash(rt->fl.fld_src, rt->fl.fld_dst); - dn_insert_route(rt, hash, &rt); - skb_dst_set(skb, &rt->u.dst); + dn_insert_route(rt, hash, (struct dn_route **)&skb->dst); done: if (neigh) @@ -1425,7 +1424,7 @@ static int dn_route_input(struct sk_buff *skb) struct dn_skb_cb *cb = DN_SKB_CB(skb); unsigned hash = dn_hash(cb->src, cb->dst); - if (skb_dst(skb)) + if (skb->dst) return 0; rcu_read_lock(); @@ -1438,7 +1437,7 @@ static int dn_route_input(struct sk_buff *skb) (rt->fl.iif == cb->iif)) { dst_use(&rt->u.dst, jiffies); rcu_read_unlock(); - skb_dst_set(skb, (struct dst_entry *)rt); + skb->dst = (struct dst_entry *)rt; return 0; } } @@ -1450,7 +1449,7 @@ static int dn_route_input(struct sk_buff *skb) static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int nowait, unsigned int flags) { - struct dn_route *rt = (struct dn_route *)skb_dst(skb); + struct dn_route *rt = (struct dn_route *)skb->dst; struct rtmsg *r; struct nlmsghdr *nlh; unsigned char *b = skb_tail_pointer(skb); @@ -1555,7 +1554,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void err = dn_route_input(skb); local_bh_enable(); memset(cb, 0, sizeof(struct dn_skb_cb)); - rt = (struct dn_route *)skb_dst(skb); + rt = (struct dn_route *)skb->dst; if (!err && -rt->u.dst.error) err = rt->u.dst.error; } else { @@ -1571,7 +1570,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void skb->dev = NULL; if (err) goto out_free; - skb_dst_set(skb, &rt->u.dst); + skb->dst = &rt->u.dst; if (rtm->rtm_flags & RTM_F_NOTIFY) rt->rt_flags |= RTCF_NOTIFY; @@ -1623,15 +1622,15 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb) rt = rcu_dereference(rt->u.dst.dn_next), idx++) { if (idx < s_idx) continue; - skb_dst_set(skb, dst_clone(&rt->u.dst)); + skb->dst = dst_clone(&rt->u.dst); if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1, NLM_F_MULTI) <= 0) { - skb_dst_drop(skb); + dst_release(xchg(&skb->dst, NULL)); rcu_read_unlock_bh(); goto done; } - skb_dst_drop(skb); + dst_release(xchg(&skb->dst, NULL)); } rcu_read_unlock_bh(); } diff --git a/trunk/net/dsa/slave.c b/trunk/net/dsa/slave.c index 2175e6d5cc8d..ed131181215d 100644 --- a/trunk/net/dsa/slave.c +++ b/trunk/net/dsa/slave.c @@ -67,7 +67,7 @@ static int dsa_slave_open(struct net_device *dev) return -ENETDOWN; if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { - err = dev_unicast_add(master, dev->dev_addr); + err = dev_unicast_add(master, dev->dev_addr, ETH_ALEN); if (err < 0) goto out; } @@ -90,7 +90,7 @@ static int dsa_slave_open(struct net_device *dev) dev_set_allmulti(master, -1); del_unicast: if (compare_ether_addr(dev->dev_addr, master->dev_addr)) - dev_unicast_delete(master, dev->dev_addr); + dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); out: return err; } @@ -108,7 +108,7 @@ static int dsa_slave_close(struct net_device *dev) dev_set_promiscuity(master, -1); if (compare_ether_addr(dev->dev_addr, master->dev_addr)) - dev_unicast_delete(master, dev->dev_addr); + dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); return 0; } @@ -147,13 +147,13 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a) goto out; if (compare_ether_addr(addr->sa_data, master->dev_addr)) { - err = dev_unicast_add(master, addr->sa_data); + err = dev_unicast_add(master, addr->sa_data, ETH_ALEN); if (err < 0) return err; } if (compare_ether_addr(dev->dev_addr, master->dev_addr)) - dev_unicast_delete(master, dev->dev_addr); + dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); out: memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); diff --git a/trunk/net/econet/af_econet.c b/trunk/net/econet/af_econet.c index 8121bf0029e3..6f479fa522c3 100644 --- a/trunk/net/econet/af_econet.c +++ b/trunk/net/econet/af_econet.c @@ -901,10 +901,15 @@ static void aun_tx_ack(unsigned long seq, int result) struct ec_cb *eb; spin_lock_irqsave(&aun_queue_lock, flags); - skb_queue_walk(&aun_queue, skb) { + skb = skb_peek(&aun_queue); + while (skb && skb != (struct sk_buff *)&aun_queue) + { + struct sk_buff *newskb = skb->next; eb = (struct ec_cb *)&skb->cb; if (eb->seq == seq) goto foundit; + + skb = newskb; } spin_unlock_irqrestore(&aun_queue_lock, flags); printk(KERN_DEBUG "AUN: unknown sequence %ld\n", seq); @@ -977,18 +982,23 @@ static void aun_data_available(struct sock *sk, int slen) static void ab_cleanup(unsigned long h) { - struct sk_buff *skb, *n; + struct sk_buff *skb; unsigned long flags; spin_lock_irqsave(&aun_queue_lock, flags); - skb_queue_walk_safe(&aun_queue, skb, n) { + skb = skb_peek(&aun_queue); + while (skb && skb != (struct sk_buff *)&aun_queue) + { + struct sk_buff *newskb = skb->next; struct ec_cb *eb = (struct ec_cb *)&skb->cb; - if ((jiffies - eb->start) > eb->timeout) { + if ((jiffies - eb->start) > eb->timeout) + { tx_result(skb->sk, eb->cookie, ECTYPE_TRANSMIT_NOT_PRESENT); skb_unlink(skb, &aun_queue); kfree_skb(skb); } + skb = newskb; } spin_unlock_irqrestore(&aun_queue_lock, flags); diff --git a/trunk/net/ieee802154/Kconfig b/trunk/net/ieee802154/Kconfig deleted file mode 100644 index 1c1de97d264a..000000000000 --- a/trunk/net/ieee802154/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config IEEE802154 - tristate "IEEE Std 802.15.4 Low-Rate Wireless Personal Area Networks support (EXPERIMENTAL)" - depends on EXPERIMENTAL - ---help--- - IEEE Std 802.15.4 defines a low data rate, low power and low - complexity short range wireless personal area networks. It was - designed to organise networks of sensors, switches, etc automation - devices. Maximum allowed data rate is 250 kb/s and typical personal - operating space around 10m. - - Say Y here to compile LR-WPAN support into the kernel or say M to - compile it as modules. diff --git a/trunk/net/ieee802154/Makefile b/trunk/net/ieee802154/Makefile deleted file mode 100644 index f99338a26100..000000000000 --- a/trunk/net/ieee802154/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_IEEE802154) += nl802154.o af_802154.o -nl802154-y := netlink.o nl_policy.o -af_802154-y := af_ieee802154.o raw.o dgram.o - -ccflags-y += -Wall -DDEBUG diff --git a/trunk/net/ieee802154/af802154.h b/trunk/net/ieee802154/af802154.h deleted file mode 100644 index b1ec52537522..000000000000 --- a/trunk/net/ieee802154/af802154.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Internal interfaces for ieee 802.15.4 address family. - * - * Copyright 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#ifndef AF802154_H -#define AF802154_H - -struct sk_buff; -struct net_devce; -extern struct proto ieee802154_raw_prot; -extern struct proto ieee802154_dgram_prot; -void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb); -int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb); -struct net_device *ieee802154_get_dev(struct net *net, - struct ieee802154_addr *addr); - -#endif diff --git a/trunk/net/ieee802154/af_ieee802154.c b/trunk/net/ieee802154/af_ieee802154.c deleted file mode 100644 index 882a927cefae..000000000000 --- a/trunk/net/ieee802154/af_ieee802154.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * IEEE802154.4 socket interface - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Maxim Gorbachyov - */ - -#include -#include -#include -#include -#include -#include /* For TIOCOUTQ/INQ */ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "af802154.h" - -#define DBG_DUMP(data, len) { \ - int i; \ - pr_debug("function: %s: data: len %d:\n", __func__, len); \ - for (i = 0; i < len; i++) {\ - pr_debug("%02x: %02x\n", i, (data)[i]); \ - } \ -} - -/* - * Utility function for families - */ -struct net_device *ieee802154_get_dev(struct net *net, - struct ieee802154_addr *addr) -{ - struct net_device *dev = NULL; - struct net_device *tmp; - u16 pan_id, short_addr; - - switch (addr->addr_type) { - case IEEE802154_ADDR_LONG: - rtnl_lock(); - dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr); - if (dev) - dev_hold(dev); - rtnl_unlock(); - break; - case IEEE802154_ADDR_SHORT: - if (addr->pan_id == 0xffff || - addr->short_addr == IEEE802154_ADDR_UNDEF || - addr->short_addr == 0xffff) - break; - - rtnl_lock(); - - for_each_netdev(net, tmp) { - if (tmp->type != ARPHRD_IEEE802154) - continue; - - pan_id = ieee802154_mlme_ops(tmp)->get_pan_id(tmp); - short_addr = - ieee802154_mlme_ops(tmp)->get_short_addr(tmp); - - if (pan_id == addr->pan_id && - short_addr == addr->short_addr) { - dev = tmp; - dev_hold(dev); - break; - } - } - - rtnl_unlock(); - break; - default: - pr_warning("Unsupported ieee802154 address type: %d\n", - addr->addr_type); - break; - } - - return dev; -} - -static int ieee802154_sock_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - if (sk) { - sock->sk = NULL; - sk->sk_prot->close(sk, 0); - } - return 0; -} -static int ieee802154_sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) -{ - struct sock *sk = sock->sk; - - return sk->sk_prot->sendmsg(iocb, sk, msg, len); -} - -static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr, - int addr_len) -{ - struct sock *sk = sock->sk; - - if (sk->sk_prot->bind) - return sk->sk_prot->bind(sk, uaddr, addr_len); - - return sock_no_bind(sock, uaddr, addr_len); -} - -static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags) -{ - struct sock *sk = sock->sk; - - if (uaddr->sa_family == AF_UNSPEC) - return sk->sk_prot->disconnect(sk, flags); - - return sk->sk_prot->connect(sk, uaddr, addr_len); -} - -static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, - unsigned int cmd) -{ - struct ifreq ifr; - int ret = -EINVAL; - struct net_device *dev; - - if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) - return -EFAULT; - - ifr.ifr_name[IFNAMSIZ-1] = 0; - - dev_load(sock_net(sk), ifr.ifr_name); - dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); - if (dev->type == ARPHRD_IEEE802154 || - dev->type == ARPHRD_IEEE802154_PHY) - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); - - if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) - ret = -EFAULT; - dev_put(dev); - - return ret; -} - -static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd, - unsigned long arg) -{ - struct sock *sk = sock->sk; - - switch (cmd) { - case SIOCGSTAMP: - return sock_get_timestamp(sk, (struct timeval __user *)arg); - case SIOCGSTAMPNS: - return sock_get_timestampns(sk, (struct timespec __user *)arg); - case SIOCGIFADDR: - case SIOCSIFADDR: - return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg, - cmd); - default: - if (!sk->sk_prot->ioctl) - return -ENOIOCTLCMD; - return sk->sk_prot->ioctl(sk, cmd, arg); - } -} - -static const struct proto_ops ieee802154_raw_ops = { - .family = PF_IEEE802154, - .owner = THIS_MODULE, - .release = ieee802154_sock_release, - .bind = ieee802154_sock_bind, - .connect = ieee802154_sock_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = datagram_poll, - .ioctl = ieee802154_sock_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_common_setsockopt, - .getsockopt = sock_common_getsockopt, - .sendmsg = ieee802154_sock_sendmsg, - .recvmsg = sock_common_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -#ifdef CONFIG_COMPAT - .compat_setsockopt = compat_sock_common_setsockopt, - .compat_getsockopt = compat_sock_common_getsockopt, -#endif -}; - -static const struct proto_ops ieee802154_dgram_ops = { - .family = PF_IEEE802154, - .owner = THIS_MODULE, - .release = ieee802154_sock_release, - .bind = ieee802154_sock_bind, - .connect = ieee802154_sock_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = datagram_poll, - .ioctl = ieee802154_sock_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_common_setsockopt, - .getsockopt = sock_common_getsockopt, - .sendmsg = ieee802154_sock_sendmsg, - .recvmsg = sock_common_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -#ifdef CONFIG_COMPAT - .compat_setsockopt = compat_sock_common_setsockopt, - .compat_getsockopt = compat_sock_common_getsockopt, -#endif -}; - - -/* - * Create a socket. Initialise the socket, blank the addresses - * set the state. - */ -static int ieee802154_create(struct net *net, struct socket *sock, - int protocol) -{ - struct sock *sk; - int rc; - struct proto *proto; - const struct proto_ops *ops; - - if (net != &init_net) - return -EAFNOSUPPORT; - - switch (sock->type) { - case SOCK_RAW: - proto = &ieee802154_raw_prot; - ops = &ieee802154_raw_ops; - break; - case SOCK_DGRAM: - proto = &ieee802154_dgram_prot; - ops = &ieee802154_dgram_ops; - break; - default: - rc = -ESOCKTNOSUPPORT; - goto out; - } - - rc = -ENOMEM; - sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto); - if (!sk) - goto out; - rc = 0; - - sock->ops = ops; - - sock_init_data(sock, sk); - /* FIXME: sk->sk_destruct */ - sk->sk_family = PF_IEEE802154; - - /* Checksums on by default */ - sock_set_flag(sk, SOCK_ZAPPED); - - if (sk->sk_prot->hash) - sk->sk_prot->hash(sk); - - if (sk->sk_prot->init) { - rc = sk->sk_prot->init(sk); - if (rc) - sk_common_release(sk); - } -out: - return rc; -} - -static struct net_proto_family ieee802154_family_ops = { - .family = PF_IEEE802154, - .create = ieee802154_create, - .owner = THIS_MODULE, -}; - -static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - DBG_DUMP(skb->data, skb->len); - if (!netif_running(dev)) - return -ENODEV; - pr_debug("got frame, type %d, dev %p\n", dev->type, dev); - - if (!net_eq(dev_net(dev), &init_net)) - goto drop; - - ieee802154_raw_deliver(dev, skb); - - if (dev->type != ARPHRD_IEEE802154) - goto drop; - - if (skb->pkt_type != PACKET_OTHERHOST) - return ieee802154_dgram_deliver(dev, skb); - -drop: - kfree_skb(skb); - return NET_RX_DROP; -} - - -static struct packet_type ieee802154_packet_type = { - .type = __constant_htons(ETH_P_IEEE802154), - .func = ieee802154_rcv, -}; - -static int __init af_ieee802154_init(void) -{ - int rc = -EINVAL; - - rc = proto_register(&ieee802154_raw_prot, 1); - if (rc) - goto out; - - rc = proto_register(&ieee802154_dgram_prot, 1); - if (rc) - goto err_dgram; - - /* Tell SOCKET that we are alive */ - rc = sock_register(&ieee802154_family_ops); - if (rc) - goto err_sock; - dev_add_pack(&ieee802154_packet_type); - - rc = 0; - goto out; - -err_sock: - proto_unregister(&ieee802154_dgram_prot); -err_dgram: - proto_unregister(&ieee802154_raw_prot); -out: - return rc; -} -static void __exit af_ieee802154_remove(void) -{ - dev_remove_pack(&ieee802154_packet_type); - sock_unregister(PF_IEEE802154); - proto_unregister(&ieee802154_dgram_prot); - proto_unregister(&ieee802154_raw_prot); -} - -module_init(af_ieee802154_init); -module_exit(af_ieee802154_remove); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_NETPROTO(PF_IEEE802154); diff --git a/trunk/net/ieee802154/dgram.c b/trunk/net/ieee802154/dgram.c deleted file mode 100644 index 1779677aed46..000000000000 --- a/trunk/net/ieee802154/dgram.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * ZigBee socket interface - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "af802154.h" - -static HLIST_HEAD(dgram_head); -static DEFINE_RWLOCK(dgram_lock); - -struct dgram_sock { - struct sock sk; - - int bound; - struct ieee802154_addr src_addr; - struct ieee802154_addr dst_addr; -}; - -static inline struct dgram_sock *dgram_sk(const struct sock *sk) -{ - return container_of(sk, struct dgram_sock, sk); -} - - -static void dgram_hash(struct sock *sk) -{ - write_lock_bh(&dgram_lock); - sk_add_node(sk, &dgram_head); - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); - write_unlock_bh(&dgram_lock); -} - -static void dgram_unhash(struct sock *sk) -{ - write_lock_bh(&dgram_lock); - if (sk_del_node_init(sk)) - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); - write_unlock_bh(&dgram_lock); -} - -static int dgram_init(struct sock *sk) -{ - struct dgram_sock *ro = dgram_sk(sk); - - ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; - ro->dst_addr.pan_id = 0xffff; - memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); - return 0; -} - -static void dgram_close(struct sock *sk, long timeout) -{ - sk_common_release(sk); -} - -static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len) -{ - struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; - struct dgram_sock *ro = dgram_sk(sk); - int err = 0; - struct net_device *dev; - - ro->bound = 0; - - if (len < sizeof(*addr)) - return -EINVAL; - - if (addr->family != AF_IEEE802154) - return -EINVAL; - - lock_sock(sk); - - dev = ieee802154_get_dev(sock_net(sk), &addr->addr); - if (!dev) { - err = -ENODEV; - goto out; - } - - if (dev->type != ARPHRD_IEEE802154) { - err = -ENODEV; - goto out_put; - } - - memcpy(&ro->src_addr, &addr->addr, sizeof(struct ieee802154_addr)); - - ro->bound = 1; -out_put: - dev_put(dev); -out: - release_sock(sk); - - return err; -} - -static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCOUTQ: - { - int amount = atomic_read(&sk->sk_wmem_alloc); - return put_user(amount, (int __user *)arg); - } - - case SIOCINQ: - { - struct sk_buff *skb; - unsigned long amount; - - amount = 0; - spin_lock_bh(&sk->sk_receive_queue.lock); - skb = skb_peek(&sk->sk_receive_queue); - if (skb != NULL) { - /* - * We will only return the amount - * of this packet since that is all - * that will be read. - */ - /* FIXME: parse the header for more correct value */ - amount = skb->len - (3+8+8); - } - spin_unlock_bh(&sk->sk_receive_queue.lock); - return put_user(amount, (int __user *)arg); - } - - } - return -ENOIOCTLCMD; -} - -/* FIXME: autobind */ -static int dgram_connect(struct sock *sk, struct sockaddr *uaddr, - int len) -{ - struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; - struct dgram_sock *ro = dgram_sk(sk); - int err = 0; - - if (len < sizeof(*addr)) - return -EINVAL; - - if (addr->family != AF_IEEE802154) - return -EINVAL; - - lock_sock(sk); - - if (!ro->bound) { - err = -ENETUNREACH; - goto out; - } - - memcpy(&ro->dst_addr, &addr->addr, sizeof(struct ieee802154_addr)); - -out: - release_sock(sk); - return err; -} - -static int dgram_disconnect(struct sock *sk, int flags) -{ - struct dgram_sock *ro = dgram_sk(sk); - - lock_sock(sk); - - ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; - memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); - - release_sock(sk); - - return 0; -} - -static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, - struct msghdr *msg, size_t size) -{ - struct net_device *dev; - unsigned mtu; - struct sk_buff *skb; - struct dgram_sock *ro = dgram_sk(sk); - int err; - - if (msg->msg_flags & MSG_OOB) { - pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); - return -EOPNOTSUPP; - } - - if (!ro->bound) - dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); - else - dev = ieee802154_get_dev(sock_net(sk), &ro->src_addr); - - if (!dev) { - pr_debug("no dev\n"); - err = -ENXIO; - goto out; - } - mtu = dev->mtu; - pr_debug("name = %s, mtu = %u\n", dev->name, mtu); - - skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, - msg->msg_flags & MSG_DONTWAIT, - &err); - if (!skb) - goto out_dev; - - skb_reserve(skb, LL_RESERVED_SPACE(dev)); - - skb_reset_network_header(skb); - - mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA | MAC_CB_FLAG_ACKREQ; - mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev); - err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr, - ro->bound ? &ro->src_addr : NULL, size); - if (err < 0) - goto out_skb; - - skb_reset_mac_header(skb); - - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); - if (err < 0) - goto out_skb; - - if (size > mtu) { - pr_debug("size = %Zu, mtu = %u\n", size, mtu); - err = -EINVAL; - goto out_skb; - } - - skb->dev = dev; - skb->sk = sk; - skb->protocol = htons(ETH_P_IEEE802154); - - dev_put(dev); - - err = dev_queue_xmit(skb); - if (err > 0) - err = net_xmit_errno(err); - - return err ?: size; - -out_skb: - kfree_skb(skb); -out_dev: - dev_put(dev); -out: - return err; -} - -static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk, - struct msghdr *msg, size_t len, int noblock, int flags, - int *addr_len) -{ - size_t copied = 0; - int err = -EOPNOTSUPP; - struct sk_buff *skb; - - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) - goto out; - - copied = skb->len; - if (len < copied) { - msg->msg_flags |= MSG_TRUNC; - copied = len; - } - - /* FIXME: skip headers if necessary ?! */ - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - if (err) - goto done; - - sock_recv_timestamp(msg, sk, skb); - - if (flags & MSG_TRUNC) - copied = skb->len; -done: - skb_free_datagram(sk, skb); -out: - if (err) - return err; - return copied; -} - -static int dgram_rcv_skb(struct sock *sk, struct sk_buff *skb) -{ - if (sock_queue_rcv_skb(sk, skb) < 0) { - atomic_inc(&sk->sk_drops); - kfree_skb(skb); - return NET_RX_DROP; - } - - return NET_RX_SUCCESS; -} - -static inline int ieee802154_match_sock(u8 *hw_addr, u16 pan_id, - u16 short_addr, struct dgram_sock *ro) -{ - if (!ro->bound) - return 1; - - if (ro->src_addr.addr_type == IEEE802154_ADDR_LONG && - !memcmp(ro->src_addr.hwaddr, hw_addr, IEEE802154_ADDR_LEN)) - return 1; - - if (ro->src_addr.addr_type == IEEE802154_ADDR_SHORT && - pan_id == ro->src_addr.pan_id && - short_addr == ro->src_addr.short_addr) - return 1; - - return 0; -} - -int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb) -{ - struct sock *sk, *prev = NULL; - struct hlist_node *node; - int ret = NET_RX_SUCCESS; - u16 pan_id, short_addr; - - /* Data frame processing */ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); - short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev); - - read_lock(&dgram_lock); - sk_for_each(sk, node, &dgram_head) { - if (ieee802154_match_sock(dev->dev_addr, pan_id, short_addr, - dgram_sk(sk))) { - if (prev) { - struct sk_buff *clone; - clone = skb_clone(skb, GFP_ATOMIC); - if (clone) - dgram_rcv_skb(prev, clone); - } - - prev = sk; - } - } - - if (prev) - dgram_rcv_skb(prev, skb); - else { - kfree_skb(skb); - ret = NET_RX_DROP; - } - read_unlock(&dgram_lock); - - return ret; -} - -struct proto ieee802154_dgram_prot = { - .name = "IEEE-802.15.4-MAC", - .owner = THIS_MODULE, - .obj_size = sizeof(struct dgram_sock), - .init = dgram_init, - .close = dgram_close, - .bind = dgram_bind, - .sendmsg = dgram_sendmsg, - .recvmsg = dgram_recvmsg, - .hash = dgram_hash, - .unhash = dgram_unhash, - .connect = dgram_connect, - .disconnect = dgram_disconnect, - .ioctl = dgram_ioctl, -}; - diff --git a/trunk/net/ieee802154/netlink.c b/trunk/net/ieee802154/netlink.c deleted file mode 100644 index 105ad10876af..000000000000 --- a/trunk/net/ieee802154/netlink.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Netlink inteface for IEEE 802.15.4 stack - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int ieee802154_seq_num; - -static struct genl_family ieee802154_coordinator_family = { - .id = GENL_ID_GENERATE, - .hdrsize = 0, - .name = IEEE802154_NL_NAME, - .version = 1, - .maxattr = IEEE802154_ATTR_MAX, -}; - -static struct genl_multicast_group ieee802154_coord_mcgrp = { - .name = IEEE802154_MCAST_COORD_NAME, -}; - -static struct genl_multicast_group ieee802154_beacon_mcgrp = { - .name = IEEE802154_MCAST_BEACON_NAME, -}; - -/* Requests to userspace */ -static struct sk_buff *ieee802154_nl_create(int flags, u8 req) -{ - void *hdr; - struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); - - if (!msg) - return NULL; - - hdr = genlmsg_put(msg, 0, ieee802154_seq_num++, - &ieee802154_coordinator_family, flags, req); - if (!hdr) { - nlmsg_free(msg); - return NULL; - } - - return msg; -} - -static int ieee802154_nl_finish(struct sk_buff *msg) -{ - /* XXX: nlh is right at the start of msg */ - void *hdr = genlmsg_data(NLMSG_DATA(msg->data)); - - if (!genlmsg_end(msg, hdr)) - goto out; - - return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id, - GFP_ATOMIC); -out: - nlmsg_free(msg); - return -ENOBUFS; -} - -int ieee802154_nl_assoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 cap) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - if (addr->addr_type != IEEE802154_ADDR_LONG) { - pr_err("%s: received non-long source address!\n", __func__); - return -EINVAL; - } - - msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_INDIC); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, - addr->hwaddr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_assoc_indic); - -int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr, - u8 status) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr); - NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_assoc_confirm); - -int ieee802154_nl_disassoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 reason) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - if (addr->addr_type == IEEE802154_ADDR_LONG) - NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, - addr->hwaddr); - else - NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR, - addr->short_addr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_disassoc_indic); - -int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_CONF); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm); - -int ieee802154_nl_beacon_indic(struct net_device *dev, - u16 panid, u16 coord_addr) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr); - NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_beacon_indic); - -int ieee802154_nl_scan_confirm(struct net_device *dev, - u8 status, u8 scan_type, u32 unscanned, - u8 *edl/* , struct list_head *pan_desc_list */) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); - NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type); - NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned); - - if (edl) - NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_scan_confirm); - -/* Requests from userspace */ -static struct net_device *ieee802154_nl_get_dev(struct genl_info *info) -{ - struct net_device *dev; - - if (info->attrs[IEEE802154_ATTR_DEV_NAME]) { - char name[IFNAMSIZ + 1]; - nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME], - sizeof(name)); - dev = dev_get_by_name(&init_net, name); - } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) - dev = dev_get_by_index(&init_net, - nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX])); - else - return NULL; - - if (dev->type != ARPHRD_IEEE802154) { - dev_put(dev); - return NULL; - } - - return dev; -} - -static int ieee802154_associate_req(struct sk_buff *skb, - struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - int ret = -EINVAL; - - if (!info->attrs[IEEE802154_ATTR_CHANNEL] || - !info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || - (!info->attrs[IEEE802154_ATTR_COORD_HW_ADDR] && - !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]) || - !info->attrs[IEEE802154_ATTR_CAPABILITY]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) { - addr.addr_type = IEEE802154_ADDR_LONG; - nla_memcpy(addr.hwaddr, - info->attrs[IEEE802154_ATTR_COORD_HW_ADDR], - IEEE802154_ADDR_LEN); - } else { - addr.addr_type = IEEE802154_ADDR_SHORT; - addr.short_addr = nla_get_u16( - info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); - } - addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); - - ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr, - nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]), - nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY])); - - dev_put(dev); - return ret; -} - -static int ieee802154_associate_resp(struct sk_buff *skb, - struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - int ret = -EINVAL; - - if (!info->attrs[IEEE802154_ATTR_STATUS] || - !info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] || - !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - addr.addr_type = IEEE802154_ADDR_LONG; - nla_memcpy(addr.hwaddr, info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], - IEEE802154_ADDR_LEN); - addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); - - - ret = ieee802154_mlme_ops(dev)->assoc_resp(dev, &addr, - nla_get_u16(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]), - nla_get_u8(info->attrs[IEEE802154_ATTR_STATUS])); - - dev_put(dev); - return ret; -} - -static int ieee802154_disassociate_req(struct sk_buff *skb, - struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - int ret = -EINVAL; - - if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] && - !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) || - !info->attrs[IEEE802154_ATTR_REASON]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) { - addr.addr_type = IEEE802154_ADDR_LONG; - nla_memcpy(addr.hwaddr, - info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], - IEEE802154_ADDR_LEN); - } else { - addr.addr_type = IEEE802154_ADDR_SHORT; - addr.short_addr = nla_get_u16( - info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]); - } - addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); - - ret = ieee802154_mlme_ops(dev)->disassoc_req(dev, &addr, - nla_get_u8(info->attrs[IEEE802154_ATTR_REASON])); - - dev_put(dev); - return ret; -} - -/* - * PANid, channel, beacon_order = 15, superframe_order = 15, - * PAN_coordinator, battery_life_extension = 0, - * coord_realignment = 0, security_enable = 0 -*/ -static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - - u8 channel, bcn_ord, sf_ord; - int pan_coord, blx, coord_realign; - int ret; - - if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || - !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] || - !info->attrs[IEEE802154_ATTR_CHANNEL] || - !info->attrs[IEEE802154_ATTR_BCN_ORD] || - !info->attrs[IEEE802154_ATTR_SF_ORD] || - !info->attrs[IEEE802154_ATTR_PAN_COORD] || - !info->attrs[IEEE802154_ATTR_BAT_EXT] || - !info->attrs[IEEE802154_ATTR_COORD_REALIGN] - ) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - addr.addr_type = IEEE802154_ADDR_SHORT; - addr.short_addr = nla_get_u16( - info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); - addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); - - channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]); - bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]); - sf_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_SF_ORD]); - pan_coord = nla_get_u8(info->attrs[IEEE802154_ATTR_PAN_COORD]); - blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]); - coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]); - - ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, - bcn_ord, sf_ord, pan_coord, blx, coord_realign); - - dev_put(dev); - return ret; -} - -static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) -{ - struct net_device *dev; - int ret; - u8 type; - u32 channels; - u8 duration; - - if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] || - !info->attrs[IEEE802154_ATTR_CHANNELS] || - !info->attrs[IEEE802154_ATTR_DURATION]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - type = nla_get_u8(info->attrs[IEEE802154_ATTR_SCAN_TYPE]); - channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]); - duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]); - - ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, - duration); - - dev_put(dev); - return ret; -} - -#define IEEE802154_OP(_cmd, _func) \ - { \ - .cmd = _cmd, \ - .policy = ieee802154_policy, \ - .doit = _func, \ - .dumpit = NULL, \ - .flags = GENL_ADMIN_PERM, \ - } - -static struct genl_ops ieee802154_coordinator_ops[] = { - IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req), - IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp), - IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req), - IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req), - IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req), -}; - -static int __init ieee802154_nl_init(void) -{ - int rc; - int i; - - rc = genl_register_family(&ieee802154_coordinator_family); - if (rc) - goto fail; - - rc = genl_register_mc_group(&ieee802154_coordinator_family, - &ieee802154_coord_mcgrp); - if (rc) - goto fail; - - rc = genl_register_mc_group(&ieee802154_coordinator_family, - &ieee802154_beacon_mcgrp); - if (rc) - goto fail; - - - for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) { - rc = genl_register_ops(&ieee802154_coordinator_family, - &ieee802154_coordinator_ops[i]); - if (rc) - goto fail; - } - - return 0; - -fail: - genl_unregister_family(&ieee802154_coordinator_family); - return rc; -} -module_init(ieee802154_nl_init); - -static void __exit ieee802154_nl_exit(void) -{ - genl_unregister_family(&ieee802154_coordinator_family); -} -module_exit(ieee802154_nl_exit); - diff --git a/trunk/net/ieee802154/nl_policy.c b/trunk/net/ieee802154/nl_policy.c deleted file mode 100644 index c7d71d1adcac..000000000000 --- a/trunk/net/ieee802154/nl_policy.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * nl802154.h - * - * Copyright (C) 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -#include - -#define NLA_HW_ADDR NLA_U64 - -struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { - [IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, }, - [IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, }, - - [IEEE802154_ATTR_STATUS] = { .type = NLA_U8, }, - [IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, - [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, - [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, - [IEEE802154_ATTR_SRC_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_SRC_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_SRC_PAN_ID] = { .type = NLA_U16, }, - [IEEE802154_ATTR_DEST_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_DEST_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_DEST_PAN_ID] = { .type = NLA_U16, }, - - [IEEE802154_ATTR_CAPABILITY] = { .type = NLA_U8, }, - [IEEE802154_ATTR_REASON] = { .type = NLA_U8, }, - [IEEE802154_ATTR_SCAN_TYPE] = { .type = NLA_U8, }, - [IEEE802154_ATTR_CHANNELS] = { .type = NLA_U32, }, - [IEEE802154_ATTR_DURATION] = { .type = NLA_U8, }, - [IEEE802154_ATTR_ED_LIST] = { .len = 27 }, -}; diff --git a/trunk/net/ieee802154/raw.c b/trunk/net/ieee802154/raw.c deleted file mode 100644 index fca44d59f97e..000000000000 --- a/trunk/net/ieee802154/raw.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Raw IEEE 802.15.4 sockets - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#include -#include -#include -#include -#include -#include - -#include "af802154.h" - -static HLIST_HEAD(raw_head); -static DEFINE_RWLOCK(raw_lock); - -static void raw_hash(struct sock *sk) -{ - write_lock_bh(&raw_lock); - sk_add_node(sk, &raw_head); - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); - write_unlock_bh(&raw_lock); -} - -static void raw_unhash(struct sock *sk) -{ - write_lock_bh(&raw_lock); - if (sk_del_node_init(sk)) - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); - write_unlock_bh(&raw_lock); -} - -static void raw_close(struct sock *sk, long timeout) -{ - sk_common_release(sk); -} - -static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len) -{ - struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; - int err = 0; - struct net_device *dev = NULL; - - if (len < sizeof(*addr)) - return -EINVAL; - - if (addr->family != AF_IEEE802154) - return -EINVAL; - - lock_sock(sk); - - dev = ieee802154_get_dev(sock_net(sk), &addr->addr); - if (!dev) { - err = -ENODEV; - goto out; - } - - if (dev->type != ARPHRD_IEEE802154_PHY && - dev->type != ARPHRD_IEEE802154) { - err = -ENODEV; - goto out_put; - } - - sk->sk_bound_dev_if = dev->ifindex; - sk_dst_reset(sk); - -out_put: - dev_put(dev); -out: - release_sock(sk); - - return err; -} - -static int raw_connect(struct sock *sk, struct sockaddr *uaddr, - int addr_len) -{ - return -ENOTSUPP; -} - -static int raw_disconnect(struct sock *sk, int flags) -{ - return 0; -} - -static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, - size_t size) -{ - struct net_device *dev; - unsigned mtu; - struct sk_buff *skb; - int err; - - if (msg->msg_flags & MSG_OOB) { - pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); - return -EOPNOTSUPP; - } - - lock_sock(sk); - if (!sk->sk_bound_dev_if) - dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); - else - dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); - release_sock(sk); - - if (!dev) { - pr_debug("no dev\n"); - err = -ENXIO; - goto out; - } - - mtu = dev->mtu; - pr_debug("name = %s, mtu = %u\n", dev->name, mtu); - - if (size > mtu) { - pr_debug("size = %Zu, mtu = %u\n", size, mtu); - err = -EINVAL; - goto out_dev; - } - - skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, - msg->msg_flags & MSG_DONTWAIT, &err); - if (!skb) - goto out_dev; - - skb_reserve(skb, LL_RESERVED_SPACE(dev)); - - skb_reset_mac_header(skb); - skb_reset_network_header(skb); - - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); - if (err < 0) - goto out_skb; - - skb->dev = dev; - skb->sk = sk; - skb->protocol = htons(ETH_P_IEEE802154); - - dev_put(dev); - - err = dev_queue_xmit(skb); - if (err > 0) - err = net_xmit_errno(err); - - return err ?: size; - -out_skb: - kfree_skb(skb); -out_dev: - dev_put(dev); -out: - return err; -} - -static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, - size_t len, int noblock, int flags, int *addr_len) -{ - size_t copied = 0; - int err = -EOPNOTSUPP; - struct sk_buff *skb; - - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) - goto out; - - copied = skb->len; - if (len < copied) { - msg->msg_flags |= MSG_TRUNC; - copied = len; - } - - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - if (err) - goto done; - - sock_recv_timestamp(msg, sk, skb); - - if (flags & MSG_TRUNC) - copied = skb->len; -done: - skb_free_datagram(sk, skb); -out: - if (err) - return err; - return copied; -} - -static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) -{ - if (sock_queue_rcv_skb(sk, skb) < 0) { - atomic_inc(&sk->sk_drops); - kfree_skb(skb); - return NET_RX_DROP; - } - - return NET_RX_SUCCESS; -} - - -void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb) -{ - struct sock *sk; - struct hlist_node *node; - - read_lock(&raw_lock); - sk_for_each(sk, node, &raw_head) { - bh_lock_sock(sk); - if (!sk->sk_bound_dev_if || - sk->sk_bound_dev_if == dev->ifindex) { - - struct sk_buff *clone; - - clone = skb_clone(skb, GFP_ATOMIC); - if (clone) - raw_rcv_skb(sk, clone); - } - bh_unlock_sock(sk); - } - read_unlock(&raw_lock); -} - -struct proto ieee802154_raw_prot = { - .name = "IEEE-802.15.4-RAW", - .owner = THIS_MODULE, - .obj_size = sizeof(struct sock), - .close = raw_close, - .bind = raw_bind, - .sendmsg = raw_sendmsg, - .recvmsg = raw_recvmsg, - .hash = raw_hash, - .unhash = raw_unhash, - .connect = raw_connect, - .disconnect = raw_disconnect, -}; - diff --git a/trunk/net/ipv4/af_inet.c b/trunk/net/ipv4/af_inet.c index 566ea6c4321d..5abee4c97449 100644 --- a/trunk/net/ipv4/af_inet.c +++ b/trunk/net/ipv4/af_inet.c @@ -116,6 +116,7 @@ #include #endif +extern void ip_mc_drop_socket(struct sock *sk); /* The inetsw table contains everything that inet_create needs to * build a new socket. @@ -374,7 +375,6 @@ static int inet_create(struct net *net, struct socket *sock, int protocol) inet->uc_ttl = -1; inet->mc_loop = 1; inet->mc_ttl = 1; - inet->mc_all = 1; inet->mc_index = 0; inet->mc_list = NULL; diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index 8a3881e28aca..f11931c18381 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -468,13 +468,13 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb) __be32 paddr; struct neighbour *n; - if (!skb_dst(skb)) { + if (!skb->dst) { printk(KERN_DEBUG "arp_find is called with dst==NULL\n"); kfree_skb(skb); return 1; } - paddr = skb_rtable(skb)->rt_gateway; + paddr = skb->rtable->rt_gateway; if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev)) return 0; @@ -817,7 +817,7 @@ static int arp_process(struct sk_buff *skb) if (arp->ar_op == htons(ARPOP_REQUEST) && ip_route_input(skb, tip, sip, 0, dev) == 0) { - rt = skb_rtable(skb); + rt = skb->rtable; addr_type = rt->rt_type; if (addr_type == RTN_LOCAL) { diff --git a/trunk/net/ipv4/icmp.c b/trunk/net/ipv4/icmp.c index 97c410e84388..3f50807237e0 100644 --- a/trunk/net/ipv4/icmp.c +++ b/trunk/net/ipv4/icmp.c @@ -356,7 +356,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) { struct ipcm_cookie ipc; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct net *net = dev_net(rt->u.dst.dev); struct sock *sk; struct inet_sock *inet; @@ -416,7 +416,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) struct iphdr *iph; int room; struct icmp_bxm icmp_param; - struct rtable *rt = skb_rtable(skb_in); + struct rtable *rt = skb_in->rtable; struct ipcm_cookie ipc; __be32 saddr; u8 tos; @@ -591,13 +591,13 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) goto relookup_failed; /* Ugh! */ - odst = skb_dst(skb_in); + odst = skb_in->dst; err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, RT_TOS(tos), rt2->u.dst.dev); dst_release(&rt2->u.dst); - rt2 = skb_rtable(skb_in); - skb_dst_set(skb_in, odst); + rt2 = skb_in->rtable; + skb_in->dst = odst; } if (err) @@ -659,7 +659,7 @@ static void icmp_unreach(struct sk_buff *skb) u32 info = 0; struct net *net; - net = dev_net(skb_dst(skb)->dev); + net = dev_net(skb->dst->dev); /* * Incomplete header ? @@ -822,7 +822,7 @@ static void icmp_echo(struct sk_buff *skb) { struct net *net; - net = dev_net(skb_dst(skb)->dev); + net = dev_net(skb->dst->dev); if (!net->ipv4.sysctl_icmp_echo_ignore_all) { struct icmp_bxm icmp_param; @@ -873,7 +873,7 @@ static void icmp_timestamp(struct sk_buff *skb) out: return; out_err: - ICMP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS); + ICMP_INC_STATS_BH(dev_net(skb->dst->dev), ICMP_MIB_INERRORS); goto out; } @@ -926,7 +926,7 @@ static void icmp_address(struct sk_buff *skb) static void icmp_address_reply(struct sk_buff *skb) { - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct net_device *dev = skb->dev; struct in_device *in_dev; struct in_ifaddr *ifa; @@ -970,7 +970,7 @@ static void icmp_discard(struct sk_buff *skb) int icmp_rcv(struct sk_buff *skb) { struct icmphdr *icmph; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct net *net = dev_net(rt->u.dst.dev); if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index 01b4284ed694..9eb6219af615 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -311,7 +311,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) return NULL; } - skb_dst_set(skb, &rt->u.dst); + skb->dst = &rt->u.dst; skb->dev = dev; skb_reserve(skb, LL_RESERVED_SPACE(dev)); @@ -659,7 +659,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, return -1; } - skb_dst_set(skb, &rt->u.dst); + skb->dst = &rt->u.dst; skb_reserve(skb, LL_RESERVED_SPACE(dev)); @@ -948,7 +948,7 @@ int igmp_rcv(struct sk_buff *skb) case IGMPV2_HOST_MEMBERSHIP_REPORT: case IGMPV3_HOST_MEMBERSHIP_REPORT: /* Is it our report looped back? */ - if (skb_rtable(skb)->fl.iif == 0) + if (skb->rtable->fl.iif == 0) break; /* don't rely on MC router hearing unicast reports */ if (skb->pkt_type == PACKET_MULTICAST || @@ -2196,7 +2196,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) break; } if (!pmc) - return inet->mc_all; + return 1; psl = pmc->sflist; if (!psl) return pmc->sfmode == MCAST_EXCLUDE; diff --git a/trunk/net/ipv4/ip_forward.c b/trunk/net/ipv4/ip_forward.c index a2991bc8e32e..df3fe50bbf0d 100644 --- a/trunk/net/ipv4/ip_forward.c +++ b/trunk/net/ipv4/ip_forward.c @@ -42,7 +42,7 @@ static int ip_forward_finish(struct sk_buff *skb) { struct ip_options * opt = &(IPCB(skb)->opt); - IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); + IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); if (unlikely(opt->optlen)) ip_forward_options(skb); @@ -81,7 +81,7 @@ int ip_forward(struct sk_buff *skb) if (!xfrm4_route_forward(skb)) goto drop; - rt = skb_rtable(skb); + rt = skb->rtable; if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) goto sr_failed; @@ -123,7 +123,7 @@ int ip_forward(struct sk_buff *skb) too_many_hops: /* Tell the sender its packet died... */ - IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_INHDRERRORS); + IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_INHDRERRORS); icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); drop: kfree_skb(skb); diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 575f9bd51ccd..7985346653bd 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -507,7 +507,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_shinfo(head)->frag_list) { struct sk_buff *clone; int i, plen = 0; @@ -516,7 +516,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, clone->next = head->next; head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); + skb_shinfo(head)->frag_list = NULL; for (i=0; inr_frags; i++) plen += skb_shinfo(head)->frags[i].size; clone->len = clone->data_len = head->data_len - plen; @@ -573,7 +573,7 @@ int ip_defrag(struct sk_buff *skb, u32 user) struct ipq *qp; struct net *net; - net = skb->dev ? dev_net(skb->dev) : dev_net(skb_dst(skb)->dev); + net = skb->dev ? dev_net(skb->dev) : dev_net(skb->dst->dev); IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); /* Start by cleaning up the memory. */ diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 44e2a3d2359a..e62510d5ea5a 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -602,7 +602,7 @@ static int ipgre_rcv(struct sk_buff *skb) #ifdef CONFIG_NET_IPGRE_BROADCAST if (ipv4_is_multicast(iph->daddr)) { /* Looped back packet, drop it! */ - if (skb_rtable(skb)->fl.iif == 0) + if (skb->rtable->fl.iif == 0) goto drop; stats->multicast++; skb->pkt_type = PACKET_BROADCAST; @@ -643,7 +643,8 @@ static int ipgre_rcv(struct sk_buff *skb) stats->rx_packets++; stats->rx_bytes += len; skb->dev = tunnel->dev; - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; nf_reset(skb); skb_reset_network_header(skb); @@ -697,13 +698,13 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if ((dst = tiph->daddr) == 0) { /* NBMA tunnel */ - if (skb_dst(skb) == NULL) { + if (skb->dst == NULL) { stats->tx_fifo_errors++; goto tx_error; } if (skb->protocol == htons(ETH_P_IP)) { - rt = skb_rtable(skb); + rt = skb->rtable; if ((dst = rt->rt_gateway) == 0) goto tx_error_icmp; } @@ -711,7 +712,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) else if (skb->protocol == htons(ETH_P_IPV6)) { struct in6_addr *addr6; int addr_type; - struct neighbour *neigh = skb_dst(skb)->neighbour; + struct neighbour *neigh = skb->dst->neighbour; if (neigh == NULL) goto tx_error; @@ -765,10 +766,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (df) mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen; else - mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; + mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; - if (skb_dst(skb)) - skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + if (skb->dst) + skb->dst->ops->update_pmtu(skb->dst, mtu); if (skb->protocol == htons(ETH_P_IP)) { df |= (old_iph->frag_off&htons(IP_DF)); @@ -782,14 +783,14 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) } #ifdef CONFIG_IPV6 else if (skb->protocol == htons(ETH_P_IPV6)) { - struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb); + struct rt6_info *rt6 = (struct rt6_info *)skb->dst; - if (rt6 && mtu < dst_mtu(skb_dst(skb)) && mtu >= IPV6_MIN_MTU) { + if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) { if ((tunnel->parms.iph.daddr && !ipv4_is_multicast(tunnel->parms.iph.daddr)) || rt6->rt6i_dst.plen == 128) { rt6->rt6i_flags |= RTF_MODIFIED; - skb_dst(skb)->metrics[RTAX_MTU-1] = mtu; + skb->dst->metrics[RTAX_MTU-1] = mtu; } } @@ -836,8 +837,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* * Push down and install the IPIP header. @@ -1237,7 +1238,6 @@ static void ipgre_tunnel_setup(struct net_device *dev) dev->iflink = 0; dev->addr_len = 4; dev->features |= NETIF_F_NETNS_LOCAL; - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; } static int ipgre_tunnel_init(struct net_device *dev) diff --git a/trunk/net/ipv4/ip_input.c b/trunk/net/ipv4/ip_input.c index 490ce20faf38..40f6206b2aa9 100644 --- a/trunk/net/ipv4/ip_input.c +++ b/trunk/net/ipv4/ip_input.c @@ -329,7 +329,7 @@ static int ip_rcv_finish(struct sk_buff *skb) * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ - if (skb_dst(skb) == NULL) { + if (skb->dst == NULL) { int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, skb->dev); if (unlikely(err)) { @@ -344,9 +344,9 @@ static int ip_rcv_finish(struct sk_buff *skb) } #ifdef CONFIG_NET_CLS_ROUTE - if (unlikely(skb_dst(skb)->tclassid)) { + if (unlikely(skb->dst->tclassid)) { struct ip_rt_acct *st = per_cpu_ptr(ip_rt_acct, smp_processor_id()); - u32 idx = skb_dst(skb)->tclassid; + u32 idx = skb->dst->tclassid; st[idx&0xFF].o_packets++; st[idx&0xFF].o_bytes += skb->len; st[(idx>>16)&0xFF].i_packets++; @@ -357,7 +357,7 @@ static int ip_rcv_finish(struct sk_buff *skb) if (iph->ihl > 5 && ip_rcv_options(skb)) goto drop; - rt = skb_rtable(skb); + rt = skb->rtable; if (rt->rt_type == RTN_MULTICAST) { IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST, skb->len); diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index 94bf105ef3c9..2c88da6e7862 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -102,7 +102,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) sptr = skb_network_header(skb); dptr = dopt->__data; - daddr = skb_rtable(skb)->rt_spec_dst; + daddr = skb->rtable->rt_spec_dst; if (sopt->rr) { optlen = sptr[sopt->rr+1]; @@ -143,7 +143,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) __be32 addr; memcpy(&addr, sptr+soffset-1, 4); - if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) { + if (inet_addr_type(dev_net(skb->dst->dev), addr) != RTN_LOCAL) { dopt->ts_needtime = 1; soffset += 8; } @@ -257,7 +257,7 @@ int ip_options_compile(struct net *net, struct rtable *rt = NULL; if (skb != NULL) { - rt = skb_rtable(skb); + rt = skb->rtable; optptr = (unsigned char *)&(ip_hdr(skb)[1]); } else optptr = opt->__data; @@ -550,7 +550,7 @@ void ip_forward_options(struct sk_buff *skb) { struct ip_options * opt = &(IPCB(skb)->opt); unsigned char * optptr; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; unsigned char *raw = skb_network_header(skb); if (opt->rr_needaddr) { @@ -598,7 +598,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) __be32 nexthop; struct iphdr *iph = ip_hdr(skb); unsigned char *optptr = skb_network_header(skb) + opt->srr; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct rtable *rt2; int err; @@ -623,13 +623,13 @@ int ip_options_rcv_srr(struct sk_buff *skb) } memcpy(&nexthop, &optptr[srrptr-1], 4); - rt = skb_rtable(skb); - skb_dst_set(skb, NULL); + rt = skb->rtable; + skb->rtable = NULL; err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); - rt2 = skb_rtable(skb); + rt2 = skb->rtable; if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { ip_rt_put(rt2); - skb_dst_set(skb, &rt->u.dst); + skb->rtable = rt; return -EINVAL; } ip_rt_put(rt); diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 247026282669..ea19c37ccc0c 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -95,7 +95,7 @@ int __ip_local_out(struct sk_buff *skb) iph->tot_len = htons(skb->len); ip_send_check(iph); - return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, + return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); } @@ -118,7 +118,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) __skb_pull(newskb, skb_network_offset(newskb)); newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; - WARN_ON(!skb_dst(newskb)); + WARN_ON(!newskb->dst); netif_rx(newskb); return 0; } @@ -140,7 +140,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, __be32 saddr, __be32 daddr, struct ip_options *opt) { struct inet_sock *inet = inet_sk(sk); - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct iphdr *iph; /* Build the IP header. */ @@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(ip_build_and_send_pkt); static inline int ip_finish_output2(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct rtable *rt = (struct rtable *)dst; struct net_device *dev = dst->dev; unsigned int hh_len = LL_RESERVED_SPACE(dev); @@ -217,14 +217,14 @@ static inline int ip_skb_dst_mtu(struct sk_buff *skb) struct inet_sock *inet = skb->sk ? inet_sk(skb->sk) : NULL; return (inet && inet->pmtudisc == IP_PMTUDISC_PROBE) ? - skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); + skb->dst->dev->mtu : dst_mtu(skb->dst); } static int ip_finish_output(struct sk_buff *skb) { #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) /* Policy lookup after SNAT yielded a new policy */ - if (skb_dst(skb)->xfrm != NULL) { + if (skb->dst->xfrm != NULL) { IPCB(skb)->flags |= IPSKB_REROUTED; return dst_output(skb); } @@ -238,7 +238,7 @@ static int ip_finish_output(struct sk_buff *skb) int ip_mc_output(struct sk_buff *skb) { struct sock *sk = skb->sk; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct net_device *dev = rt->u.dst.dev; /* @@ -296,7 +296,7 @@ int ip_mc_output(struct sk_buff *skb) int ip_output(struct sk_buff *skb) { - struct net_device *dev = skb_dst(skb)->dev; + struct net_device *dev = skb->dst->dev; IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len); @@ -319,7 +319,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) /* Skip all of this if the packet is already routed, * f.e. by something like SCTP. */ - rt = skb_rtable(skb); + rt = skb->rtable; if (rt != NULL) goto packet_routed; @@ -355,7 +355,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok) } sk_setup_caps(sk, &rt->u.dst); } - skb_dst_set(skb, dst_clone(&rt->u.dst)); + skb->dst = dst_clone(&rt->u.dst); packet_routed: if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) @@ -401,8 +401,8 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->pkt_type = from->pkt_type; to->priority = from->priority; to->protocol = from->protocol; - skb_dst_drop(to); - skb_dst_set(to, dst_clone(skb_dst(from))); + dst_release(to->dst); + to->dst = dst_clone(from->dst); to->dev = from->dev; to->mark = from->mark; @@ -440,7 +440,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) unsigned int mtu, hlen, left, len, ll_rs, pad; int offset; __be16 not_last_frag; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; int err = 0; dev = rt->u.dst.dev; @@ -474,7 +474,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) * LATER: this step can be merged to real generation of fragments, * we can switch to copy when see the first bad fragment. */ - if (skb_has_frags(skb)) { + if (skb_shinfo(skb)->frag_list) { struct sk_buff *frag; int first_len = skb_pagelen(skb); int truesizes = 0; @@ -485,7 +485,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb_cloned(skb)) goto slow_path; - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* Correct geometry. */ if (frag->len > mtu || ((frag->len & 7) && frag->next) || @@ -498,6 +498,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) BUG_ON(frag->sk); if (skb->sk) { + sock_hold(skb->sk); frag->sk = skb->sk; frag->destructor = sock_wfree; truesizes += frag->truesize; @@ -509,7 +510,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) err = 0; offset = 0; frag = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; skb->data_len = first_len - skb_headlen(skb); skb->truesize -= truesizes; skb->len = first_len; @@ -1293,7 +1294,7 @@ int ip_push_pending_frames(struct sock *sk) * on dst refcount */ inet->cork.dst = NULL; - skb_dst_set(skb, &rt->u.dst); + skb->dst = &rt->u.dst; if (iph->protocol == IPPROTO_ICMP) icmp_out_count(net, ((struct icmphdr *) @@ -1361,7 +1362,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar } replyopts; struct ipcm_cookie ipc; __be32 daddr; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; if (ip_options_echo(&replyopts.opt, skb)) return; diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index fc7993e9061f..43c05854d752 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -57,7 +57,7 @@ static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) { struct in_pktinfo info; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; info.ipi_addr.s_addr = ip_hdr(skb)->daddr; if (rt) { @@ -157,39 +157,38 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) /* Ordered by supposed usage frequency */ if (flags & 1) ip_cmsg_recv_pktinfo(msg, skb); - if ((flags >>= 1) == 0) + if ((flags>>=1) == 0) return; if (flags & 1) ip_cmsg_recv_ttl(msg, skb); - if ((flags >>= 1) == 0) + if ((flags>>=1) == 0) return; if (flags & 1) ip_cmsg_recv_tos(msg, skb); - if ((flags >>= 1) == 0) + if ((flags>>=1) == 0) return; if (flags & 1) ip_cmsg_recv_opts(msg, skb); - if ((flags >>= 1) == 0) + if ((flags>>=1) == 0) return; if (flags & 1) ip_cmsg_recv_retopts(msg, skb); - if ((flags >>= 1) == 0) + if ((flags>>=1) == 0) return; if (flags & 1) ip_cmsg_recv_security(msg, skb); - if ((flags >>= 1) == 0) + if ((flags>>=1) == 0) return; if (flags & 1) ip_cmsg_recv_dstaddr(msg, skb); } -EXPORT_SYMBOL(ip_cmsg_recv); int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) { @@ -204,8 +203,7 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) switch (cmsg->cmsg_type) { case IP_RETOPTS: err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); - err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), - err < 40 ? err : 40); + err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40); if (err) return err; break; @@ -240,8 +238,7 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) struct ip_ra_chain *ip_ra_chain; DEFINE_RWLOCK(ip_ra_lock); -int ip_ra_control(struct sock *sk, unsigned char on, - void (*destructor)(struct sock *)) +int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)) { struct ip_ra_chain *ra, *new_ra, **rap; @@ -251,7 +248,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; write_lock_bh(&ip_ra_lock); - for (rap = &ip_ra_chain; (ra = *rap) != NULL; rap = &ra->next) { + for (rap = &ip_ra_chain; (ra=*rap) != NULL; rap = &ra->next) { if (ra->sk == sk) { if (on) { write_unlock_bh(&ip_ra_lock); @@ -419,8 +416,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) /* Reset and regenerate socket error */ spin_lock_bh(&sk->sk_error_queue.lock); sk->sk_err = 0; - skb2 = skb_peek(&sk->sk_error_queue); - if (skb2 != NULL) { + if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) { sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno; spin_unlock_bh(&sk->sk_error_queue.lock); sk->sk_error_report(sk); @@ -435,8 +431,8 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) /* - * Socket option code for IP. This is the end of the line after any - * TCP,UDP etc options on an IP socket. + * Socket option code for IP. This is the end of the line after any TCP,UDP etc options on + * an IP socket. */ static int do_ip_setsockopt(struct sock *sk, int level, @@ -453,7 +449,6 @@ static int do_ip_setsockopt(struct sock *sk, int level, (1<= sizeof(int)) { @@ -479,7 +474,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, switch (optname) { case IP_OPTIONS: { - struct ip_options *opt = NULL; + struct ip_options * opt = NULL; if (optlen > 40 || optlen < 0) goto e_inval; err = ip_options_get_from_user(sock_net(sk), &opt, @@ -561,9 +556,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, } break; case IP_TTL: - if (optlen < 1) + if (optlen<1) goto e_inval; - if (val != -1 && (val < 0 || val > 255)) + if (val != -1 && (val < 1 || val>255)) goto e_inval; inet->uc_ttl = val; break; @@ -575,7 +570,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, inet->hdrincl = val ? 1 : 0; break; case IP_MTU_DISCOVER: - if (val < 0 || val > 3) + if (val<0 || val>3) goto e_inval; inet->pmtudisc = val; break; @@ -587,7 +582,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, case IP_MULTICAST_TTL: if (sk->sk_type == SOCK_STREAM) goto e_inval; - if (optlen < 1) + if (optlen<1) goto e_inval; if (val == -1) val = 1; @@ -596,7 +591,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, inet->mc_ttl = val; break; case IP_MULTICAST_LOOP: - if (optlen < 1) + if (optlen<1) goto e_inval; inet->mc_loop = !!val; break; @@ -618,8 +613,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, } else { memset(&mreq, 0, sizeof(mreq)); if (optlen >= sizeof(struct in_addr) && - copy_from_user(&mreq.imr_address, optval, - sizeof(struct in_addr))) + copy_from_user(&mreq.imr_address, optval, sizeof(struct in_addr))) break; } @@ -683,6 +677,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, } case IP_MSFILTER: { + extern int sysctl_igmp_max_msf; struct ip_msfilter *msf; if (optlen < IP_MSFILTER_SIZE(0)) @@ -836,6 +831,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, } case MCAST_MSFILTER: { + extern int sysctl_igmp_max_msf; struct sockaddr_in *psin; struct ip_msfilter *msf = NULL; struct group_filter *gsf = NULL; @@ -853,9 +849,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, break; } err = -EFAULT; - if (copy_from_user(gsf, optval, optlen)) + if (copy_from_user(gsf, optval, optlen)) { goto mc_msf_out; - + } /* numsrc >= (4G-140)/128 overflow in 32 bits */ if (gsf->gf_numsrc >= 0x1ffffff || gsf->gf_numsrc > sysctl_igmp_max_msf) { @@ -883,7 +879,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, msf->imsf_fmode = gsf->gf_fmode; msf->imsf_numsrc = gsf->gf_numsrc; err = -EADDRNOTAVAIL; - for (i = 0; i < gsf->gf_numsrc; ++i) { + for (i=0; igf_numsrc; ++i) { psin = (struct sockaddr_in *)&gsf->gf_slist[i]; if (psin->sin_family != AF_INET) @@ -894,24 +890,17 @@ static int do_ip_setsockopt(struct sock *sk, int level, gsf = NULL; err = ip_mc_msfilter(sk, msf, ifindex); -mc_msf_out: + mc_msf_out: kfree(msf); kfree(gsf); break; } - case IP_MULTICAST_ALL: - if (optlen < 1) - goto e_inval; - if (val != 0 && val != 1) - goto e_inval; - inet->mc_all = val; - break; case IP_ROUTER_ALERT: err = ip_ra_control(sk, val ? 1 : 0, NULL); break; case IP_FREEBIND: - if (optlen < 1) + if (optlen<1) goto e_inval; inet->freebind = !!val; break; @@ -968,7 +957,6 @@ int ip_setsockopt(struct sock *sk, int level, #endif return err; } -EXPORT_SYMBOL(ip_setsockopt); #ifdef CONFIG_COMPAT int compat_ip_setsockopt(struct sock *sk, int level, int optname, @@ -998,12 +986,13 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname, #endif return err; } + EXPORT_SYMBOL(compat_ip_setsockopt); #endif /* - * Get the options. Note for future reference. The GET of IP options gets - * the _received_ ones. The set sets the _sent_ ones. + * Get the options. Note for future reference. The GET of IP options gets the + * _received_ ones. The set sets the _sent_ ones. */ static int do_ip_getsockopt(struct sock *sk, int level, int optname, @@ -1154,14 +1143,10 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, return -EFAULT; } err = ip_mc_gsfget(sk, &gsf, - (struct group_filter __user *)optval, - optlen); + (struct group_filter __user *)optval, optlen); release_sock(sk); return err; } - case IP_MULTICAST_ALL: - val = inet->mc_all; - break; case IP_PKTOPTIONS: { struct msghdr msg; @@ -1202,7 +1187,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, } release_sock(sk); - if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) { + if (len < sizeof(int) && len > 0 && val>=0 && val<=255) { unsigned char ucval = (unsigned char)val; len = 1; if (put_user(len, optlen)) @@ -1245,7 +1230,6 @@ int ip_getsockopt(struct sock *sk, int level, #endif return err; } -EXPORT_SYMBOL(ip_getsockopt); #ifdef CONFIG_COMPAT int compat_ip_getsockopt(struct sock *sk, int level, int optname, @@ -1278,5 +1262,11 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, #endif return err; } + EXPORT_SYMBOL(compat_ip_getsockopt); #endif + +EXPORT_SYMBOL(ip_cmsg_recv); + +EXPORT_SYMBOL(ip_getsockopt); +EXPORT_SYMBOL(ip_setsockopt); diff --git a/trunk/net/ipv4/ipip.c b/trunk/net/ipv4/ipip.c index 93e2b787da20..9054139795af 100644 --- a/trunk/net/ipv4/ipip.c +++ b/trunk/net/ipv4/ipip.c @@ -370,7 +370,8 @@ static int ipip_rcv(struct sk_buff *skb) tunnel->dev->stats.rx_packets++; tunnel->dev->stats.rx_bytes += skb->len; skb->dev = tunnel->dev; - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; nf_reset(skb); ipip_ecn_decapsulate(iph, skb); netif_rx(skb); @@ -415,7 +416,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (!dst) { /* NBMA tunnel */ - if ((rt = skb_rtable(skb)) == NULL) { + if ((rt = skb->rtable) == NULL) { stats->tx_fifo_errors++; goto tx_error; } @@ -446,15 +447,15 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (tiph->frag_off) mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); else - mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; + mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; if (mtu < 68) { stats->collisions++; ip_rt_put(rt); goto tx_error; } - if (skb_dst(skb)) - skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + if (skb->dst) + skb->dst->ops->update_pmtu(skb->dst, mtu); df |= (old_iph->frag_off&htons(IP_DF)); @@ -501,8 +502,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* * Push down and install the IPIP header. @@ -712,7 +713,6 @@ static void ipip_tunnel_setup(struct net_device *dev) dev->iflink = 0; dev->addr_len = 4; dev->features |= NETIF_F_NETNS_LOCAL; - dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; } static void ipip_tunnel_init(struct net_device *dev) diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index ffd986104468..13e9dd3012b3 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -651,7 +651,7 @@ static int ipmr_cache_report(struct net *net, ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ msg = (struct igmpmsg *)skb_network_header(skb); msg->im_vif = vifi; - skb_dst_set(skb, dst_clone(skb_dst(pkt))); + skb->dst = dst_clone(pkt->dst); /* * Add our header @@ -1201,7 +1201,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) iph->protocol = IPPROTO_IPIP; iph->ihl = 5; iph->tot_len = htons(skb->len); - ip_select_ident(iph, skb_dst(skb), NULL); + ip_select_ident(iph, skb->dst, NULL); ip_send_check(iph); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); @@ -1212,7 +1212,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) { struct ip_options * opt = &(IPCB(skb)->opt); - IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); + IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); if (unlikely(opt->optlen)) ip_forward_options(skb); @@ -1290,8 +1290,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) vif->pkt_out++; vif->bytes_out += skb->len; - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; ip_decrease_ttl(ip_hdr(skb)); /* FIXME: forward and output firewalls used to be called here. @@ -1354,7 +1354,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local if (net->ipv4.vif_table[vif].dev != skb->dev) { int true_vifi; - if (skb_rtable(skb)->fl.iif == 0) { + if (skb->rtable->fl.iif == 0) { /* It is our own packet, looped back. Very complicated situation... @@ -1430,7 +1430,7 @@ int ip_mr_input(struct sk_buff *skb) { struct mfc_cache *cache; struct net *net = dev_net(skb->dev); - int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; + int local = skb->rtable->rt_flags&RTCF_LOCAL; /* Packet is looped back after forward, it should not be forwarded second time, but still can be delivered locally. @@ -1543,7 +1543,8 @@ static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen) skb->protocol = htons(ETH_P_IP); skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; reg_dev->stats.rx_bytes += skb->len; reg_dev->stats.rx_packets++; nf_reset(skb); @@ -1645,7 +1646,7 @@ int ipmr_get_route(struct net *net, { int err; struct mfc_cache *cache; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; read_lock(&mrt_lock); cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst); diff --git a/trunk/net/ipv4/netfilter.c b/trunk/net/ipv4/netfilter.c index 1725dc0ef688..fdf6811c31a2 100644 --- a/trunk/net/ipv4/netfilter.c +++ b/trunk/net/ipv4/netfilter.c @@ -12,7 +12,7 @@ /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) { - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); const struct iphdr *iph = ip_hdr(skb); struct rtable *rt; struct flowi fl = {}; @@ -41,8 +41,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) return -1; /* Drop old route. */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; } else { /* non-local src, find valid iif to satisfy * rp-filter when calling ip_route_input. */ @@ -50,7 +50,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) if (ip_route_output_key(net, &rt, &fl) != 0) return -1; - odst = skb_dst(skb); + odst = skb->dst; if (ip_route_input(skb, iph->daddr, iph->saddr, RT_TOS(iph->tos), rt->u.dst.dev) != 0) { dst_release(&rt->u.dst); @@ -60,22 +60,18 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) dst_release(odst); } - if (skb_dst(skb)->error) + if (skb->dst->error) return -1; #ifdef CONFIG_XFRM if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && - xfrm_decode_session(skb, &fl, AF_INET) == 0) { - struct dst_entry *dst = skb_dst(skb); - skb_dst_set(skb, NULL); - if (xfrm_lookup(net, &dst, &fl, skb->sk, 0)) + xfrm_decode_session(skb, &fl, AF_INET) == 0) + if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0)) return -1; - skb_dst_set(skb, dst); - } #endif /* Change in oif may mean change in hh_len. */ - hh_len = skb_dst(skb)->dev->hard_header_len; + hh_len = skb->dst->dev->hard_header_len; if (skb_headroom(skb) < hh_len && pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) return -1; @@ -96,7 +92,7 @@ int ip_xfrm_me_harder(struct sk_buff *skb) if (xfrm_decode_session(skb, &fl, AF_INET) < 0) return -1; - dst = skb_dst(skb); + dst = skb->dst; if (dst->xfrm) dst = ((struct xfrm_dst *)dst)->route; dst_hold(dst); @@ -104,11 +100,11 @@ int ip_xfrm_me_harder(struct sk_buff *skb) if (xfrm_lookup(dev_net(dst->dev), &dst, &fl, skb->sk, 0) < 0) return -1; - skb_dst_drop(skb); - skb_dst_set(skb, dst); + dst_release(skb->dst); + skb->dst = dst; /* Change in oif may mean change in hh_len. */ - hh_len = skb_dst(skb)->dev->hard_header_len; + hh_len = skb->dst->dev->hard_header_len; if (skb_headroom(skb) < hh_len && pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC)) return -1; diff --git a/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c b/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c index c0992c75bdac..f389f60cb105 100644 --- a/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -72,7 +72,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par) return NF_ACCEPT; mr = par->targinfo; - rt = skb_rtable(skb); + rt = skb->rtable; newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE); if (!newsrc) { printk("MASQUERADE: %s ate my IP address\n", par->out->name); diff --git a/trunk/net/ipv4/netfilter/ipt_REJECT.c b/trunk/net/ipv4/netfilter/ipt_REJECT.c index c93ae44bff2a..0b4b6e0ff2b9 100644 --- a/trunk/net/ipv4/netfilter/ipt_REJECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REJECT.c @@ -108,16 +108,17 @@ static void send_reset(struct sk_buff *oldskb, int hook) addr_type = RTN_LOCAL; /* ip_route_me_harder expects skb->dst to be set */ - skb_dst_set(nskb, dst_clone(skb_dst(oldskb))); + dst_hold(oldskb->dst); + nskb->dst = oldskb->dst; if (ip_route_me_harder(nskb, addr_type)) goto free_nskb; - niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT); + niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); nskb->ip_summed = CHECKSUM_NONE; /* "Never happens" */ - if (nskb->len > dst_mtu(skb_dst(nskb))) + if (nskb->len > dst_mtu(nskb->dst)) goto free_nskb; nf_ct_attach(nskb, oldskb); diff --git a/trunk/net/ipv4/netfilter/nf_nat_helper.c b/trunk/net/ipv4/netfilter/nf_nat_helper.c index 155c008626c8..cf7a42bf9820 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_helper.c +++ b/trunk/net/ipv4/netfilter/nf_nat_helper.c @@ -140,7 +140,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, const char *rep_buffer, unsigned int rep_len) { - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct iphdr *iph; struct tcphdr *tcph; int oldlen, datalen; @@ -218,7 +218,7 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb, const char *rep_buffer, unsigned int rep_len) { - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct iphdr *iph; struct udphdr *udph; int datalen, oldlen; diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c index 3fc598eeeb1a..65e470bc6123 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c @@ -33,7 +33,6 @@ sctp_manip_pkt(struct sk_buff *skb, enum nf_nat_manip_type maniptype) { const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); - struct sk_buff *frag; sctp_sctphdr_t *hdr; unsigned int hdroff = iphdroff + iph->ihl*4; __be32 oldip, newip; @@ -58,8 +57,8 @@ sctp_manip_pkt(struct sk_buff *skb, } crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff); - skb_walk_frags(skb, frag) - crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag), + for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) + crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb), crc32); crc32 = sctp_end_cksum(crc32); hdr->checksum = crc32; diff --git a/trunk/net/ipv4/netfilter/nf_nat_standalone.c b/trunk/net/ipv4/netfilter/nf_nat_standalone.c index 5567bd0d0750..b7dd695691a0 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_standalone.c +++ b/trunk/net/ipv4/netfilter/nf_nat_standalone.c @@ -167,9 +167,10 @@ nf_nat_in(unsigned int hooknum, ret = nf_nat_fn(hooknum, skb, in, out, okfn); if (ret != NF_DROP && ret != NF_STOLEN && - daddr != ip_hdr(skb)->daddr) - skb_dst_drop(skb); - + daddr != ip_hdr(skb)->daddr) { + dst_release(skb->dst); + skb->dst = NULL; + } return ret; } diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index 3dc9171a272f..f774651f0a47 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -343,7 +343,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; - skb_dst_set(skb, dst_clone(&rt->u.dst)); + skb->dst = dst_clone(&rt->u.dst); skb_reset_network_header(skb); iph = ip_hdr(skb); diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index a849bb15d864..28205e5bfa9b 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -1064,8 +1064,7 @@ static int rt_garbage_collect(struct dst_ops *ops) out: return 0; } -static int rt_intern_hash(unsigned hash, struct rtable *rt, - struct rtable **rp, struct sk_buff *skb) +static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp) { struct rtable *rth, **rthp; unsigned long now; @@ -1115,10 +1114,7 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, spin_unlock_bh(rt_hash_lock_addr(hash)); rt_drop(rt); - if (rp) - *rp = rth; - else - skb_dst_set(skb, &rth->u.dst); + *rp = rth; return 0; } @@ -1214,10 +1210,7 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, rcu_assign_pointer(rt_hash_table[hash].chain, rt); spin_unlock_bh(rt_hash_lock_addr(hash)); - if (rp) - *rp = rt; - else - skb_dst_set(skb, &rt->u.dst); + *rp = rt; return 0; } @@ -1414,7 +1407,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, &netevent); rt_del(hash, rth); - if (!rt_intern_hash(hash, rt, &rt, NULL)) + if (!rt_intern_hash(hash, rt, &rt)) ip_rt_put(rt); goto do_next; } @@ -1480,7 +1473,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) void ip_rt_send_redirect(struct sk_buff *skb) { - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct in_device *in_dev = in_dev_get(rt->u.dst.dev); if (!in_dev) @@ -1528,7 +1521,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) static int ip_error(struct sk_buff *skb) { - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; unsigned long now; int code; @@ -1705,7 +1698,7 @@ static void ipv4_link_failure(struct sk_buff *skb) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); - rt = skb_rtable(skb); + rt = skb->rtable; if (rt) dst_set_expires(&rt->u.dst, 0); } @@ -1865,7 +1858,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, in_dev_put(in_dev); hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); - return rt_intern_hash(hash, rth, NULL, skb); + return rt_intern_hash(hash, rth, &skb->rtable); e_nobufs: in_dev_put(in_dev); @@ -2026,7 +2019,7 @@ static int ip_mkroute_input(struct sk_buff *skb, /* put it into the cache */ hash = rt_hash(daddr, saddr, fl->iif, rt_genid(dev_net(rth->u.dst.dev))); - return rt_intern_hash(hash, rth, NULL, skb); + return rt_intern_hash(hash, rth, &skb->rtable); } /* @@ -2182,7 +2175,7 @@ out: return err; } rth->rt_type = res.type; hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); - err = rt_intern_hash(hash, rth, NULL, skb); + err = rt_intern_hash(hash, rth, &skb->rtable); goto done; no_route: @@ -2251,7 +2244,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, dst_use(&rth->u.dst, jiffies); RT_CACHE_STAT_INC(in_hit); rcu_read_unlock(); - skb_dst_set(skb, &rth->u.dst); + skb->rtable = rth; return 0; } RT_CACHE_STAT_INC(in_hlist_search); @@ -2427,7 +2420,7 @@ static int ip_mkroute_output(struct rtable **rp, if (err == 0) { hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, rt_genid(dev_net(dev_out))); - err = rt_intern_hash(hash, rth, rp, NULL); + err = rt_intern_hash(hash, rth, rp); } return err; @@ -2770,7 +2763,7 @@ static int rt_fill_info(struct net *net, struct sk_buff *skb, u32 pid, u32 seq, int event, int nowait, unsigned int flags) { - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct rtmsg *r; struct nlmsghdr *nlh; long expires; @@ -2914,7 +2907,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); local_bh_enable(); - rt = skb_rtable(skb); + rt = skb->rtable; if (err == 0 && rt->u.dst.error) err = -rt->u.dst.error; } else { @@ -2934,7 +2927,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void if (err) goto errout_free; - skb_dst_set(skb, &rt->u.dst); + skb->rtable = rt; if (rtm->rtm_flags & RTM_F_NOTIFY) rt->rt_flags |= RTCF_NOTIFY; @@ -2975,15 +2968,15 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) continue; if (rt_is_expired(rt)) continue; - skb_dst_set(skb, dst_clone(&rt->u.dst)); + skb->dst = dst_clone(&rt->u.dst); if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1, NLM_F_MULTI) <= 0) { - skb_dst_drop(skb); + dst_release(xchg(&skb->dst, NULL)); rcu_read_unlock_bh(); goto done; } - skb_dst_drop(skb); + dst_release(xchg(&skb->dst, NULL)); } rcu_read_unlock_bh(); } diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 17b89c523f9d..0fb8b441f1f9 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -439,14 +439,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) !tp->urg_data || before(tp->urg_seq, tp->copied_seq) || !before(tp->urg_seq, tp->rcv_nxt)) { - struct sk_buff *skb; - answ = tp->rcv_nxt - tp->copied_seq; /* Subtract 1, if FIN is in queue. */ - skb = skb_peek_tail(&sk->sk_receive_queue); - if (answ && skb) - answ -= tcp_hdr(skb)->fin; + if (answ && !skb_queue_empty(&sk->sk_receive_queue)) + answ -= + tcp_hdr((struct sk_buff *)sk->sk_receive_queue.prev)->fin; } else answ = tp->urg_seq - tp->copied_seq; release_sock(sk); @@ -1384,7 +1382,11 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* Next get a buffer. */ - skb_queue_walk(&sk->sk_receive_queue, skb) { + skb = skb_peek(&sk->sk_receive_queue); + do { + if (!skb) + break; + /* Now that we have two receive queues this * shouldn't happen. */ @@ -1401,7 +1403,8 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (tcp_hdr(skb)->fin) goto found_fin_ok; WARN_ON(!(flags & MSG_PEEK)); - } + skb = skb->next; + } while (skb != (struct sk_buff *)&sk->sk_receive_queue); /* Well, if we have backlog, try to process it now yet. */ diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 2bdb0da237e6..eeb8a92aa416 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -4426,7 +4426,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) } __skb_queue_head(&tp->out_of_order_queue, skb); } else { - struct sk_buff *skb1 = skb_peek_tail(&tp->out_of_order_queue); + struct sk_buff *skb1 = tp->out_of_order_queue.prev; u32 seq = TCP_SKB_CB(skb)->seq; u32 end_seq = TCP_SKB_CB(skb)->end_seq; @@ -4443,18 +4443,15 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) } /* Find place to insert this segment. */ - while (1) { + do { if (!after(TCP_SKB_CB(skb1)->seq, seq)) break; - if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) { - skb1 = NULL; - break; - } - skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1); - } + } while ((skb1 = skb1->prev) != + (struct sk_buff *)&tp->out_of_order_queue); /* Do skb overlap to previous one? */ - if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { + if (skb1 != (struct sk_buff *)&tp->out_of_order_queue && + before(seq, TCP_SKB_CB(skb1)->end_seq)) { if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { /* All the bits are present. Drop. */ __kfree_skb(skb); @@ -4466,26 +4463,15 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) tcp_dsack_set(sk, seq, TCP_SKB_CB(skb1)->end_seq); } else { - if (skb_queue_is_first(&tp->out_of_order_queue, - skb1)) - skb1 = NULL; - else - skb1 = skb_queue_prev( - &tp->out_of_order_queue, - skb1); + skb1 = skb1->prev; } } - if (!skb1) - __skb_queue_head(&tp->out_of_order_queue, skb); - else - __skb_queue_after(&tp->out_of_order_queue, skb1, skb); + __skb_queue_after(&tp->out_of_order_queue, skb1, skb); /* And clean segments covered by new one as whole. */ - while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) { - skb1 = skb_queue_next(&tp->out_of_order_queue, skb); - - if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) - break; + while ((skb1 = skb->next) != + (struct sk_buff *)&tp->out_of_order_queue && + after(end_seq, TCP_SKB_CB(skb1)->seq)) { if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) { tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, end_seq); @@ -4506,10 +4492,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *list) { - struct sk_buff *next = NULL; - - if (!skb_queue_is_last(list, skb)) - next = skb_queue_next(list, skb); + struct sk_buff *next = skb->next; __skb_unlink(skb, list); __kfree_skb(skb); @@ -4520,9 +4503,6 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb, /* Collapse contiguous sequence of skbs head..tail with * sequence numbers start..end. - * - * If tail is NULL, this means until the end of the list. - * * Segments with FIN/SYN are not collapsed (only because this * simplifies code) */ @@ -4531,23 +4511,15 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, struct sk_buff *head, struct sk_buff *tail, u32 start, u32 end) { - struct sk_buff *skb, *n; - bool end_of_skbs; + struct sk_buff *skb; /* First, check that queue is collapsible and find * the point where collapsing can be useful. */ - skb = head; -restart: - end_of_skbs = true; - skb_queue_walk_from_safe(list, skb, n) { - if (skb == tail) - break; + for (skb = head; skb != tail;) { /* No new bits? It is possible on ofo queue. */ if (!before(start, TCP_SKB_CB(skb)->end_seq)) { skb = tcp_collapse_one(sk, skb, list); - if (!skb) - break; - goto restart; + continue; } /* The first skb to collapse is: @@ -4557,24 +4529,16 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, */ if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin && (tcp_win_from_space(skb->truesize) > skb->len || - before(TCP_SKB_CB(skb)->seq, start))) { - end_of_skbs = false; + before(TCP_SKB_CB(skb)->seq, start) || + (skb->next != tail && + TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb->next)->seq))) break; - } - - if (!skb_queue_is_last(list, skb)) { - struct sk_buff *next = skb_queue_next(list, skb); - if (next != tail && - TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(next)->seq) { - end_of_skbs = false; - break; - } - } /* Decided to skip this, advance start seq. */ start = TCP_SKB_CB(skb)->end_seq; + skb = skb->next; } - if (end_of_skbs || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) + if (skb == tail || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) return; while (before(start, end)) { @@ -4619,8 +4583,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, } if (!before(start, TCP_SKB_CB(skb)->end_seq)) { skb = tcp_collapse_one(sk, skb, list); - if (!skb || - skb == tail || + if (skb == tail || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin) return; @@ -4647,21 +4610,17 @@ static void tcp_collapse_ofo_queue(struct sock *sk) head = skb; for (;;) { - struct sk_buff *next = NULL; - - if (!skb_queue_is_last(&tp->out_of_order_queue, skb)) - next = skb_queue_next(&tp->out_of_order_queue, skb); - skb = next; + skb = skb->next; /* Segment is terminated when we see gap or when * we are at the end of all the queue. */ - if (!skb || + if (skb == (struct sk_buff *)&tp->out_of_order_queue || after(TCP_SKB_CB(skb)->seq, end) || before(TCP_SKB_CB(skb)->end_seq, start)) { tcp_collapse(sk, &tp->out_of_order_queue, head, skb, start, end); head = skb; - if (!skb) + if (skb == (struct sk_buff *)&tp->out_of_order_queue) break; /* Start new segment */ start = TCP_SKB_CB(skb)->seq; @@ -4722,11 +4681,10 @@ static int tcp_prune_queue(struct sock *sk) tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); tcp_collapse_ofo_queue(sk); - if (!skb_queue_empty(&sk->sk_receive_queue)) - tcp_collapse(sk, &sk->sk_receive_queue, - skb_peek(&sk->sk_receive_queue), - NULL, - tp->copied_seq, tp->rcv_nxt); + tcp_collapse(sk, &sk->sk_receive_queue, + sk->sk_receive_queue.next, + (struct sk_buff *)&sk->sk_receive_queue, + tp->copied_seq, tp->rcv_nxt); sk_mem_reclaim(sk); if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 5a1ca2698c88..fc79e3416288 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -546,7 +546,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) if (th->rst) return; - if (skb_rtable(skb)->rt_type != RTN_LOCAL) + if (skb->rtable->rt_type != RTN_LOCAL) return; /* Swap the send and the receive. */ @@ -590,7 +590,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) arg.csumoffset = offsetof(struct tcphdr, check) / 2; arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0; - net = dev_net(skb_dst(skb)->dev); + net = dev_net(skb->dst->dev); ip_send_reply(net->ipv4.tcp_sock, skb, &arg, arg.iov[0].iov_len); @@ -617,7 +617,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, ]; } rep; struct ip_reply_arg arg; - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); memset(&rep.th, 0, sizeof(struct tcphdr)); memset(&arg, 0, sizeof(arg)); @@ -1185,7 +1185,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) #endif /* Never answer to SYNs send to broadcast or multicast */ - if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) + if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) goto drop; /* TW buckets are converted to open requests without diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 416fc4c2e7eb..79c39dc9b01c 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -2202,7 +2202,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, /* Reserve space for headers. */ skb_reserve(skb, MAX_TCP_HEADER); - skb_dst_set(skb, dst_clone(dst)); + skb->dst = dst_clone(dst); mss = dst_metric(dst, RTAX_ADVMSS); if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) diff --git a/trunk/net/ipv4/tcp_vegas.c b/trunk/net/ipv4/tcp_vegas.c index c6743eec9b7d..a453aac91bd3 100644 --- a/trunk/net/ipv4/tcp_vegas.c +++ b/trunk/net/ipv4/tcp_vegas.c @@ -158,11 +158,6 @@ void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event) } EXPORT_SYMBOL_GPL(tcp_vegas_cwnd_event); -static inline u32 tcp_vegas_ssthresh(struct tcp_sock *tp) -{ - return min(tp->snd_ssthresh, tp->snd_cwnd-1); -} - static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) { struct tcp_sock *tp = tcp_sk(sk); @@ -226,10 +221,11 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) */ diff = tp->snd_cwnd * (rtt-vegas->baseRTT) / vegas->baseRTT; - if (diff > gamma && tp->snd_cwnd <= tp->snd_ssthresh) { + if (diff > gamma && tp->snd_ssthresh > 2 ) { /* Going too fast. Time to slow down * and switch to congestion avoidance. */ + tp->snd_ssthresh = 2; /* Set cwnd to match the actual rate * exactly: @@ -239,7 +235,6 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) * utilization. */ tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1); - tp->snd_ssthresh = tcp_vegas_ssthresh(tp); } else if (tp->snd_cwnd <= tp->snd_ssthresh) { /* Slow start. */ @@ -255,8 +250,6 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight) * we slow down. */ tp->snd_cwnd--; - tp->snd_ssthresh - = tcp_vegas_ssthresh(tp); } else if (diff < alpha) { /* We don't have enough extra packets * in the network, so speed up. diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 8f4158d7c9a6..7a1d1ce22e66 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -328,7 +328,7 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, if (unlikely(sk = skb_steal_sock(skb))) return sk; else - return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, + return __udp4_lib_lookup(dev_net(skb->dst->dev), iph->saddr, sport, iph->daddr, dport, inet_iif(skb), udptable); } @@ -1237,7 +1237,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, struct sock *sk; struct udphdr *uh; unsigned short ulen; - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = (struct rtable*)skb->dst; __be32 saddr, daddr; struct net *net = dev_net(skb->dev); diff --git a/trunk/net/ipv4/xfrm4_input.c b/trunk/net/ipv4/xfrm4_input.c index f9f922a0ba88..4ec2162a437e 100644 --- a/trunk/net/ipv4/xfrm4_input.c +++ b/trunk/net/ipv4/xfrm4_input.c @@ -23,7 +23,7 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb) static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) { - if (skb_dst(skb) == NULL) { + if (skb->dst == NULL) { const struct iphdr *iph = ip_hdr(skb); if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, diff --git a/trunk/net/ipv4/xfrm4_mode_tunnel.c b/trunk/net/ipv4/xfrm4_mode_tunnel.c index 3444f3b34eca..7135279f3f84 100644 --- a/trunk/net/ipv4/xfrm4_mode_tunnel.c +++ b/trunk/net/ipv4/xfrm4_mode_tunnel.c @@ -28,7 +28,7 @@ static inline void ipip_ecn_decapsulate(struct sk_buff *skb) */ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct iphdr *top_iph; int flags; @@ -41,7 +41,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) top_iph->ihl = 5; top_iph->version = 4; - top_iph->protocol = xfrm_af2proto(skb_dst(skb)->ops->family); + top_iph->protocol = xfrm_af2proto(skb->dst->ops->family); /* DS disclosed */ top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos, diff --git a/trunk/net/ipv4/xfrm4_output.c b/trunk/net/ipv4/xfrm4_output.c index c908bd99bcba..8c3180adddbf 100644 --- a/trunk/net/ipv4/xfrm4_output.c +++ b/trunk/net/ipv4/xfrm4_output.c @@ -29,7 +29,7 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb) if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df) goto out; - dst = skb_dst(skb); + dst = skb->dst; mtu = dst_mtu(dst); if (skb->len > mtu) { icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); @@ -72,7 +72,7 @@ EXPORT_SYMBOL(xfrm4_prepare_output); static int xfrm4_output_finish(struct sk_buff *skb) { #ifdef CONFIG_NETFILTER - if (!skb_dst(skb)->xfrm) { + if (!skb->dst->xfrm) { IPCB(skb)->flags |= IPSKB_REROUTED; return dst_output(skb); } @@ -87,6 +87,6 @@ static int xfrm4_output_finish(struct sk_buff *skb) int xfrm4_output(struct sk_buff *skb) { return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, - NULL, skb_dst(skb)->dev, xfrm4_output_finish, + NULL, skb->dst->dev, xfrm4_output_finish, !(IPCB(skb)->flags & IPSKB_REROUTED)); } diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index c3488372f12d..31938e5fb220 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -591,6 +591,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, { struct inet6_ifaddr *ifa = NULL; struct rt6_info *rt; + struct net *net = dev_net(idev->dev); int hash; int err = 0; int addr_type = ipv6_addr_type(addr); @@ -607,7 +608,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, goto out2; } - if (idev->cnf.disable_ipv6) { + if (idev->cnf.disable_ipv6 || net->ipv6.devconf_all->disable_ipv6) { err = -EACCES; goto out2; } @@ -1751,7 +1752,6 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) __u32 prefered_lft; int addr_type; struct inet6_dev *in6_dev; - struct net *net = dev_net(dev); pinfo = (struct prefix_info *) opt; @@ -1809,7 +1809,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) if (addrconf_finite_timeout(rt_expires)) rt_expires *= HZ; - rt = rt6_lookup(net, &pinfo->prefix, NULL, + rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, dev->ifindex, 1); if (rt && addrconf_is_prefix_route(rt)) { @@ -1846,6 +1846,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) struct inet6_ifaddr * ifp; struct in6_addr addr; int create = 0, update_lft = 0; + struct net *net = dev_net(dev); if (pinfo->prefix_len == 64) { memcpy(&addr, &pinfo->prefix, 8); @@ -3987,75 +3988,6 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table, return addrconf_fixup_forwarding(table, valp, val); } -static void dev_disable_change(struct inet6_dev *idev) -{ - if (!idev || !idev->dev) - return; - - if (idev->cnf.disable_ipv6) - addrconf_notify(NULL, NETDEV_DOWN, idev->dev); - else - addrconf_notify(NULL, NETDEV_UP, idev->dev); -} - -static void addrconf_disable_change(struct net *net, __s32 newf) -{ - struct net_device *dev; - struct inet6_dev *idev; - - read_lock(&dev_base_lock); - for_each_netdev(net, dev) { - rcu_read_lock(); - idev = __in6_dev_get(dev); - if (idev) { - int changed = (!idev->cnf.disable_ipv6) ^ (!newf); - idev->cnf.disable_ipv6 = newf; - if (changed) - dev_disable_change(idev); - } - rcu_read_unlock(); - } - read_unlock(&dev_base_lock); -} - -static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) -{ - struct net *net; - - net = (struct net *)table->extra2; - - if (p == &net->ipv6.devconf_dflt->disable_ipv6) - return 0; - - if (!rtnl_trylock()) - return restart_syscall(); - - if (p == &net->ipv6.devconf_all->disable_ipv6) { - __s32 newf = net->ipv6.devconf_all->disable_ipv6; - net->ipv6.devconf_dflt->disable_ipv6 = newf; - addrconf_disable_change(net, newf); - } else if ((!*p) ^ (!old)) - dev_disable_change((struct inet6_dev *)table->extra1); - - rtnl_unlock(); - return 0; -} - -static -int addrconf_sysctl_disable(ctl_table *ctl, int write, struct file * filp, - void __user *buffer, size_t *lenp, loff_t *ppos) -{ - int *valp = ctl->data; - int val = *valp; - int ret; - - ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); - - if (write) - ret = addrconf_disable_ipv6(ctl, valp, val); - return ret; -} - static struct addrconf_sysctl_table { struct ctl_table_header *sysctl_header; @@ -4293,8 +4225,7 @@ static struct addrconf_sysctl_table .data = &ipv6_devconf.disable_ipv6, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = addrconf_sysctl_disable, - .strategy = sysctl_intvec, + .proc_handler = proc_dointvec, }, { .ctl_name = CTL_UNNUMBERED, @@ -4415,10 +4346,6 @@ static int addrconf_init_net(struct net *net) dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); if (dflt == NULL) goto err_alloc_dflt; - } else { - /* these will be inherited by all namespaces */ - dflt->autoconf = ipv6_defaults.autoconf; - dflt->disable_ipv6 = ipv6_defaults.disable_ipv6; } net->ipv6.devconf_all = all; diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index 85b3d0036afd..b6215be0963f 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -72,21 +72,9 @@ MODULE_LICENSE("GPL"); static struct list_head inetsw6[SOCK_MAX]; static DEFINE_SPINLOCK(inetsw6_lock); -struct ipv6_params ipv6_defaults = { - .disable_ipv6 = 0, - .autoconf = 1, -}; - -static int disable_ipv6_mod = 0; - -module_param_named(disable, disable_ipv6_mod, int, 0444); -MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); - -module_param_named(disable_ipv6, ipv6_defaults.disable_ipv6, int, 0444); -MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces"); - -module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444); -MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces"); +static int disable_ipv6 = 0; +module_param_named(disable, disable_ipv6, int, 0); +MODULE_PARM_DESC(disable, "Disable IPv6 such that it is non-functional"); static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) { @@ -1050,7 +1038,7 @@ static int __init inet6_init(void) for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) INIT_LIST_HEAD(r); - if (disable_ipv6_mod) { + if (disable_ipv6) { printk(KERN_INFO "IPv6: Loaded, but administratively disabled, " "reboot required to enable\n"); @@ -1239,7 +1227,7 @@ module_init(inet6_init); static void __exit inet6_exit(void) { - if (disable_ipv6_mod) + if (disable_ipv6) return; /* First of all disallow new sockets creation. */ diff --git a/trunk/net/ipv6/exthdrs.c b/trunk/net/ipv6/exthdrs.c index 4aae658e5501..1c7f400a3cfe 100644 --- a/trunk/net/ipv6/exthdrs.c +++ b/trunk/net/ipv6/exthdrs.c @@ -277,7 +277,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || !pskb_may_pull(skb, (skb_transport_offset(skb) + ((skb_transport_header(skb)[1] + 1) << 3)))) { - IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; @@ -288,7 +288,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) dstbuf = opt->dst1; #endif - dst = dst_clone(skb_dst(skb)); + dst = dst_clone(skb->dst); if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { dst_release(dst); skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; @@ -333,7 +333,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || !pskb_may_pull(skb, (skb_transport_offset(skb) + ((skb_transport_header(skb)[1] + 1) << 3)))) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; @@ -343,7 +343,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || skb->pkt_type != PACKET_HOST) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; @@ -358,7 +358,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) * processed by own */ if (!addr) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; @@ -384,7 +384,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) goto unknown_rh; /* Silently discard invalid RTH type 2 */ if (hdr->hdrlen != 2 || hdr->segments_left != 1) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -1; @@ -403,7 +403,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) n = hdr->hdrlen >> 1; if (hdr->segments_left > n) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, ((&hdr->segments_left) - @@ -417,7 +417,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) if (skb_cloned(skb)) { /* the copy is a forwarded packet */ if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); return -1; @@ -440,13 +440,13 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, (xfrm_address_t *)&ipv6_hdr(skb)->saddr, IPPROTO_ROUTING) < 0) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; } - if (!ipv6_chk_home_addr(dev_net(skb_dst(skb)->dev), addr)) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) { + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; @@ -458,7 +458,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) } if (ipv6_addr_is_multicast(addr)) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); return -1; @@ -468,17 +468,17 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr); ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr); - skb_dst_drop(skb); + dst_release(xchg(&skb->dst, NULL)); ip6_route_input(skb); - if (skb_dst(skb)->error) { + if (skb->dst->error) { skb_push(skb, skb->data - skb_network_header(skb)); dst_input(skb); return -1; } - if (skb_dst(skb)->dev->flags&IFF_LOOPBACK) { + if (skb->dst->dev->flags&IFF_LOOPBACK) { if (ipv6_hdr(skb)->hop_limit <= 1) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0, skb->dev); @@ -494,7 +494,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb) return -1; unknown_rh: - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS); + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb_network_header(skb)); return -1; @@ -552,11 +552,11 @@ void ipv6_exthdrs_exit(void) **********************************/ /* - * Note: we cannot rely on skb_dst(skb) before we assign it in ip6_route_input(). + * Note: we cannot rely on skb->dst before we assign it in ip6_route_input(). */ static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb) { - return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev); + return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev); } /* Router Alert as of RFC 2711 */ @@ -581,7 +581,7 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) { const unsigned char *nh = skb_network_header(skb); u32 pkt_len; - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", diff --git a/trunk/net/ipv6/inet6_connection_sock.c b/trunk/net/ipv6/inet6_connection_sock.c index cc4797dd8325..3c3732d50c1a 100644 --- a/trunk/net/ipv6/inet6_connection_sock.c +++ b/trunk/net/ipv6/inet6_connection_sock.c @@ -228,7 +228,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) __inet6_csk_dst_store(sk, dst, NULL, NULL); } - skb_dst_set(skb, dst_clone(dst)); + skb->dst = dst_clone(dst); /* Restore final destination back after routing done */ ipv6_addr_copy(&fl.fl6_dst, &np->daddr); diff --git a/trunk/net/ipv6/ip6_input.c b/trunk/net/ipv6/ip6_input.c index c3a07d75b5f5..bc1a920c34a1 100644 --- a/trunk/net/ipv6/ip6_input.c +++ b/trunk/net/ipv6/ip6_input.c @@ -48,7 +48,7 @@ inline int ip6_rcv_finish( struct sk_buff *skb) { - if (skb_dst(skb) == NULL) + if (skb->dst == NULL) ip6_route_input(skb); return dst_input(skb); @@ -91,7 +91,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt * arrived via the sending interface (ethX), because of the * nature of scoping architecture. --yoshfuji */ - IP6CB(skb)->iif = skb_dst(skb) ? ip6_dst_idev(skb_dst(skb))->dev->ifindex : dev->ifindex; + IP6CB(skb)->iif = skb->dst ? ip6_dst_idev(skb->dst)->dev->ifindex : dev->ifindex; if (unlikely(!pskb_may_pull(skb, sizeof(*hdr)))) goto err; @@ -161,7 +161,7 @@ static int ip6_input_finish(struct sk_buff *skb) int nexthdr, raw; u8 hash; struct inet6_dev *idev; - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); /* * Parse extension headers @@ -169,7 +169,7 @@ static int ip6_input_finish(struct sk_buff *skb) rcu_read_lock(); resubmit: - idev = ip6_dst_idev(skb_dst(skb)); + idev = ip6_dst_idev(skb->dst); if (!pskb_pull(skb, skb_transport_offset(skb))) goto discard; nhoff = IP6CB(skb)->nhoff; @@ -242,8 +242,8 @@ int ip6_mc_input(struct sk_buff *skb) struct ipv6hdr *hdr; int deliver; - IP6_UPD_PO_STATS_BH(dev_net(skb_dst(skb)->dev), - ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INMCAST, + IP6_UPD_PO_STATS_BH(dev_net(skb->dst->dev), + ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCAST, skb->len); hdr = ipv6_hdr(skb); diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 7c76e3d18215..735a2bf4b5f1 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -78,7 +78,7 @@ int __ip6_local_out(struct sk_buff *skb) len = 0; ipv6_hdr(skb)->payload_len = htons(len); - return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, + return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); } @@ -96,7 +96,7 @@ EXPORT_SYMBOL_GPL(ip6_local_out); static int ip6_output_finish(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; if (dst->hh) return neigh_hh_output(dst->hh, skb); @@ -117,7 +117,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) __skb_pull(newskb, skb_network_offset(newskb)); newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; - WARN_ON(!skb_dst(newskb)); + WARN_ON(!newskb->dst); netif_rx(newskb); return 0; @@ -126,7 +126,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) static int ip6_output2(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct net_device *dev = dst->dev; skb->protocol = htons(ETH_P_IPV6); @@ -134,7 +134,7 @@ static int ip6_output2(struct sk_buff *skb) if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; - struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); + struct inet6_dev *idev = ip6_dst_idev(skb->dst); if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && ((mroute6_socket(dev_net(dev)) && @@ -172,21 +172,21 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb) struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? - skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); + skb->dst->dev->mtu : dst_mtu(skb->dst); } int ip6_output(struct sk_buff *skb) { - struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); + struct inet6_dev *idev = ip6_dst_idev(skb->dst); if (unlikely(idev->cnf.disable_ipv6)) { - IP6_INC_STATS(dev_net(skb_dst(skb)->dev), idev, + IP6_INC_STATS(dev_net(skb->dst->dev), idev, IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); return 0; } if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || - dst_allfrag(skb_dst(skb))) + dst_allfrag(skb->dst)) return ip6_fragment(skb, ip6_output2); else return ip6_output2(skb); @@ -202,7 +202,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, struct net *net = sock_net(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct in6_addr *first_hop = &fl->fl6_dst; - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct ipv6hdr *hdr; u8 proto = fl->proto; int seg_len = skb->len; @@ -222,7 +222,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, if (skb_headroom(skb) < head_room) { struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); if (skb2 == NULL) { - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); return -ENOBUFS; @@ -276,7 +276,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, mtu = dst_mtu(dst); if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { - IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_UPD_PO_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_OUT, skb->len); return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, dst_output); @@ -286,7 +286,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); kfree_skb(skb); return -EMSGSIZE; } @@ -416,7 +416,7 @@ static inline int ip6_forward_finish(struct sk_buff *skb) int ip6_forward(struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct ipv6hdr *hdr = ipv6_hdr(skb); struct inet6_skb_parm *opt = IP6CB(skb); struct net *net = dev_net(dst->dev); @@ -485,7 +485,7 @@ int ip6_forward(struct sk_buff *skb) IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); goto drop; } - dst = skb_dst(skb); + dst = skb->dst; /* IPv6 specs say nothing about it, but it is clear that we cannot send redirects to source routed frames. @@ -566,8 +566,8 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->pkt_type = from->pkt_type; to->priority = from->priority; to->protocol = from->protocol; - skb_dst_drop(to); - skb_dst_set(to, dst_clone(skb_dst(from))); + dst_release(to->dst); + to->dst = dst_clone(from->dst); to->dev = from->dev; to->mark = from->mark; @@ -624,7 +624,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) { struct sk_buff *frag; - struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); + struct rt6_info *rt = (struct rt6_info*)skb->dst; struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; struct ipv6hdr *tmp_hdr; struct frag_hdr *fh; @@ -632,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) __be32 frag_id = 0; int ptr, offset = 0, err=0; u8 *prevhdr, nexthdr = 0; - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); hlen = ip6_find_1stfragopt(skb, &prevhdr); nexthdr = *prevhdr; @@ -644,9 +644,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) * check should be redundant, but it's free.) */ if (!skb->local_df) { - skb->dev = skb_dst(skb)->dev; + skb->dev = skb->dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); kfree_skb(skb); return -EMSGSIZE; @@ -658,7 +658,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) } mtu -= hlen + sizeof(struct frag_hdr); - if (skb_has_frags(skb)) { + if (skb_shinfo(skb)->frag_list) { int first_len = skb_pagelen(skb); int truesizes = 0; @@ -667,7 +667,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb_cloned(skb)) goto slow_path; - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* Correct geometry. */ if (frag->len > mtu || ((frag->len & 7) && frag->next) || @@ -680,6 +680,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) BUG_ON(frag->sk); if (skb->sk) { + sock_hold(skb->sk); frag->sk = skb->sk; frag->destructor = sock_wfree; truesizes += frag->truesize; @@ -689,13 +690,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) err = 0; offset = 0; frag = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; /* BUILD HEADER */ *prevhdr = NEXTHDR_FRAGMENT; tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); if (!tmp_hdr) { - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); return -ENOMEM; } @@ -808,7 +809,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); err = -ENOMEM; goto fail; @@ -872,16 +873,16 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) if (err) goto fail; - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES); } - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGOKS); kfree_skb(skb); return err; fail: - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); kfree_skb(skb); return err; @@ -1515,10 +1516,10 @@ int ip6_push_pending_frames(struct sock *sk) skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; - skb_dst_set(skb, dst_clone(&rt->u.dst)); + skb->dst = dst_clone(&rt->u.dst); IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); if (proto == IPPROTO_ICMPV6) { - struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); + struct inet6_dev *idev = ip6_dst_idev(skb->dst); ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type); ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); @@ -1544,8 +1545,8 @@ void ip6_flush_pending_frames(struct sock *sk) struct sk_buff *skb; while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { - if (skb_dst(skb)) - IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb_dst(skb)), + if (skb->dst) + IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTDISCARDS); kfree_skb(skb); } diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index 404d16a97d5c..af256d47fd35 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -532,8 +532,8 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (!skb2) return 0; - skb_dst_drop(skb2); - + dst_release(skb2->dst); + skb2->dst = NULL; skb_pull(skb2, offset); skb_reset_network_header(skb2); eiph = ip_hdr(skb2); @@ -560,21 +560,21 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ip_rt_put(rt); goto out; } - skb_dst_set(skb2, (struct dst_entry *)rt); + skb2->dst = (struct dst_entry *)rt; } else { ip_rt_put(rt); if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || - skb_dst(skb2)->dev->type != ARPHRD_TUNNEL) + skb2->dst->dev->type != ARPHRD_TUNNEL) goto out; } /* change mtu on this route */ if (rel_type == ICMP_DEST_UNREACH && rel_code == ICMP_FRAG_NEEDED) { - if (rel_info > dst_mtu(skb_dst(skb2))) + if (rel_info > dst_mtu(skb2->dst)) goto out; - skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), rel_info); + skb2->dst->ops->update_pmtu(skb2->dst, rel_info); } icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); @@ -606,7 +606,8 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (!skb2) return 0; - skb_dst_drop(skb2); + dst_release(skb2->dst); + skb2->dst = NULL; skb_pull(skb2, offset); skb_reset_network_header(skb2); @@ -719,7 +720,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, skb->pkt_type = PACKET_HOST; memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); skb->dev = t->dev; - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; nf_reset(skb); dscp_ecn_decapsulate(t, ipv6h, skb); @@ -883,8 +885,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, } if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; - if (skb_dst(skb)) - skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + if (skb->dst) + skb->dst->ops->update_pmtu(skb->dst, mtu); if (skb->len > mtu) { *pmtu = mtu; err = -EMSGSIZE; @@ -908,8 +910,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, kfree_skb(skb); skb = new_skb; } - skb_dst_drop(skb); - skb_dst_set(skb, dst_clone(dst)); + dst_release(skb->dst); + skb->dst = dst_clone(dst); skb->transport_header = skb->network_header; diff --git a/trunk/net/ipv6/ip6mr.c b/trunk/net/ipv6/ip6mr.c index a35d8fc55b04..228be551e9c1 100644 --- a/trunk/net/ipv6/ip6mr.c +++ b/trunk/net/ipv6/ip6mr.c @@ -398,9 +398,10 @@ static int pim6_rcv(struct sk_buff *skb) skb->protocol = htons(ETH_P_IPV6); skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; - skb_dst_drop(skb); + dst_release(skb->dst); reg_dev->stats.rx_bytes += skb->len; reg_dev->stats.rx_packets++; + skb->dst = NULL; nf_reset(skb); netif_rx(skb); dev_put(reg_dev); @@ -848,7 +849,7 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi, ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); - skb_dst_set(skb, dst_clone(skb_dst(pkt))); + skb->dst = dst_clone(pkt->dst); skb->ip_summed = CHECKSUM_UNNECESSARY; } @@ -1486,7 +1487,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) static inline int ip6mr_forward2_finish(struct sk_buff *skb) { - IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTFORWDATAGRAMS); return dst_output(skb); } @@ -1531,8 +1532,8 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi) if (!dst) goto out_free; - skb_dst_drop(skb); - skb_dst_set(skb, dst); + dst_release(skb->dst); + skb->dst = dst; /* * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally @@ -1721,7 +1722,7 @@ int ip6mr_get_route(struct net *net, { int err; struct mfc6_cache *cache; - struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); + struct rt6_info *rt = (struct rt6_info *)skb->dst; read_lock(&mrt_lock); cache = ip6mr_cache_find(net, &rt->rt6i_src.addr, &rt->rt6i_dst.addr); diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index 4b264ed40a8c..4b48819a5b8d 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -1448,7 +1448,6 @@ static void mld_sendpack(struct sk_buff *skb) struct net *net = dev_net(skb->dev); int err; struct flowi fl; - struct dst_entry *dst; IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); @@ -1460,9 +1459,9 @@ static void mld_sendpack(struct sk_buff *skb) IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb), mldlen, 0)); - dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); + skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); - if (!dst) { + if (!skb->dst) { err = -ENOMEM; goto err_out; } @@ -1471,8 +1470,7 @@ static void mld_sendpack(struct sk_buff *skb) &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, skb->dev->ifindex); - err = xfrm_lookup(net, &dst, &fl, NULL, 0); - skb_dst_set(skb, dst); + err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); if (err) goto err_out; @@ -1777,7 +1775,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) IPV6_TLV_ROUTERALERT, 2, 0, 0, IPV6_TLV_PADN, 0 }; struct flowi fl; - struct dst_entry *dst; if (type == ICMPV6_MGM_REDUCTION) snd_addr = &in6addr_linklocal_allrouters; @@ -1831,8 +1828,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) idev = in6_dev_get(skb->dev); - dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); - if (!dst) { + skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr); + if (!skb->dst) { err = -ENOMEM; goto err_out; } @@ -1841,11 +1838,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, skb->dev->ifindex); - err = xfrm_lookup(net, &dst, &fl, NULL, 0); + err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0); if (err) goto err_out; - skb_dst_set(skb, dst); + err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, dst_output); out: diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 9eb68e92cc18..e09f12ee57cf 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -465,8 +465,8 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev, 1, &err); if (!skb) { ND_PRINTK0(KERN_ERR - "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n", - __func__, err); + "ICMPv6 ND: %s() failed to allocate an skb.\n", + __func__); return NULL; } @@ -530,7 +530,7 @@ void ndisc_send_skb(struct sk_buff *skb, return; } - skb_dst_set(skb, dst); + skb->dst = dst; idev = in6_dev_get(dst->dev); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); @@ -1562,8 +1562,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, 1, &err); if (buff == NULL) { ND_PRINTK0(KERN_ERR - "ICMPv6 Redirect: %s() failed to allocate an skb, err=%d.\n", - __func__, err); + "ICMPv6 Redirect: %s() failed to allocate an skb.\n", + __func__); goto release; } @@ -1612,7 +1612,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, len, IPPROTO_ICMPV6, csum_partial(icmph, len, 0)); - skb_dst_set(buff, dst); + buff->dst = dst; idev = in6_dev_get(dst->dev); IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, diff --git a/trunk/net/ipv6/netfilter.c b/trunk/net/ipv6/netfilter.c index d5ed92b14346..834cea69fb53 100644 --- a/trunk/net/ipv6/netfilter.c +++ b/trunk/net/ipv6/netfilter.c @@ -12,7 +12,7 @@ int ip6_route_me_harder(struct sk_buff *skb) { - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); struct ipv6hdr *iph = ipv6_hdr(skb); struct dst_entry *dst; struct flowi fl = { @@ -28,15 +28,9 @@ int ip6_route_me_harder(struct sk_buff *skb) #ifdef CONFIG_XFRM if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && - xfrm_decode_session(skb, &fl, AF_INET6) == 0) { - struct dst_entry *dst2 = skb_dst(skb); - - if (xfrm_lookup(net, &dst2, &fl, skb->sk, 0)) { - skb_dst_set(skb, NULL); + xfrm_decode_session(skb, &fl, AF_INET6) == 0) + if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0)) return -1; - } - skb_dst_set(skb, dst2); - } #endif if (dst->error) { @@ -47,9 +41,9 @@ int ip6_route_me_harder(struct sk_buff *skb) } /* Drop old route. */ - skb_dst_drop(skb); + dst_release(skb->dst); - skb_dst_set(skb, dst); + skb->dst = dst; return 0; } EXPORT_SYMBOL(ip6_route_me_harder); diff --git a/trunk/net/ipv6/netfilter/ip6t_REJECT.c b/trunk/net/ipv6/netfilter/ip6t_REJECT.c index 5a7f00cd15ce..5a2d0a41694a 100644 --- a/trunk/net/ipv6/netfilter/ip6t_REJECT.c +++ b/trunk/net/ipv6/netfilter/ip6t_REJECT.c @@ -112,7 +112,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) return; } - skb_dst_set(nskb, dst); + nskb->dst = dst; skb_reserve(nskb, hh_len + dst->header_len); diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index f3aba255ad9f..058a5e4a60c3 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -409,7 +409,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_shinfo(head)->frag_list) { struct sk_buff *clone; int i, plen = 0; @@ -420,7 +420,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) clone->next = head->next; head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); + skb_shinfo(head)->frag_list = NULL; for (i=0; inr_frags; i++) plen += skb_shinfo(head)->frags[i].size; clone->len = clone->data_len = head->data_len - plen; diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index 36a090d87a3d..e99307fba0b1 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -625,7 +625,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; - skb_dst_set(skb, dst_clone(&rt->u.dst)); + skb->dst = dst_clone(&rt->u.dst); skb_put(skb, length); skb_reset_network_header(skb); diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index 2642a41a8535..e9ac7a12f595 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -267,7 +267,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, struct sk_buff *prev, *next; struct net_device *dev; int offset, end; - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); if (fq->q.last_in & INET_FRAG_COMPLETE) goto err; @@ -277,7 +277,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); if ((unsigned int)end > IPV6_MAXPLEN) { - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, ((u8 *)&fhdr->frag_off - @@ -310,7 +310,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, /* RFC2460 says always send parameter problem in * this case. -DaveM */ - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, offsetof(struct ipv6hdr, payload_len)); @@ -434,7 +434,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, return -1; err: - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS); kfree_skb(skb); return -1; @@ -494,7 +494,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_shinfo(head)->frag_list) { struct sk_buff *clone; int i, plen = 0; @@ -503,7 +503,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, clone->next = head->next; head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); + skb_shinfo(head)->frag_list = NULL; for (i=0; inr_frags; i++) plen += skb_shinfo(head)->frags[i].size; clone->len = clone->data_len = head->data_len - plen; @@ -576,9 +576,9 @@ static int ipv6_frag_rcv(struct sk_buff *skb) struct frag_hdr *fhdr; struct frag_queue *fq; struct ipv6hdr *hdr = ipv6_hdr(skb); - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS); + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS); /* Jumbo payload inhibits frag. header */ if (hdr->payload_len==0) @@ -595,17 +595,17 @@ static int ipv6_frag_rcv(struct sk_buff *skb) /* It is not a fragmented frame */ skb->transport_header += sizeof(struct frag_hdr); IP6_INC_STATS_BH(net, - ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMOKS); + ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS); IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb); return 1; } if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh) - ip6_evictor(net, ip6_dst_idev(skb_dst(skb))); + ip6_evictor(net, ip6_dst_idev(skb->dst)); if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, - ip6_dst_idev(skb_dst(skb)))) != NULL) { + ip6_dst_idev(skb->dst))) != NULL) { int ret; spin_lock(&fq->q.lock); @@ -617,12 +617,12 @@ static int ipv6_frag_rcv(struct sk_buff *skb) return ret; } - IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMFAILS); + IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS); kfree_skb(skb); return -1; fail_hdr: - IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS); + IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb_network_header_len(skb)); return -1; } diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 658293ea05ba..032a5ec391c5 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -800,7 +800,7 @@ void ip6_route_input(struct sk_buff *skb) if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) flags |= RT6_LOOKUP_F_IFACE; - skb_dst_set(skb, fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input)); + skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input); } static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, @@ -911,7 +911,7 @@ static void ip6_link_failure(struct sk_buff *skb) icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev); - rt = (struct rt6_info *) skb_dst(skb); + rt = (struct rt6_info *) skb->dst; if (rt) { if (rt->rt6i_flags&RTF_CACHE) { dst_set_expires(&rt->u.dst, 0); @@ -1868,7 +1868,7 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg) static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes) { int type; - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; switch (ipstats_mib_noroutes) { case IPSTATS_MIB_INNOROUTES: type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); @@ -1895,7 +1895,7 @@ static int ip6_pkt_discard(struct sk_buff *skb) static int ip6_pkt_discard_out(struct sk_buff *skb) { - skb->dev = skb_dst(skb)->dev; + skb->dev = skb->dst->dev; return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); } @@ -1908,7 +1908,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb) static int ip6_pkt_prohibit_out(struct sk_buff *skb) { - skb->dev = skb_dst(skb)->dev; + skb->dev = skb->dst->dev; return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); } @@ -2366,7 +2366,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); - skb_dst_set(skb, &rt->u.dst); + skb->dst = &rt->u.dst; err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, RTM_NEWROUTE, NETLINK_CB(in_skb).pid, diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 68e52308e552..b3a59bd40f01 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -575,7 +575,8 @@ static int ipip6_rcv(struct sk_buff *skb) tunnel->dev->stats.rx_packets++; tunnel->dev->stats.rx_bytes += skb->len; skb->dev = tunnel->dev; - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; nf_reset(skb); ipip6_ecn_decapsulate(iph, skb); netif_rx(skb); @@ -637,8 +638,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (dev->priv_flags & IFF_ISATAP) { struct neighbour *neigh = NULL; - if (skb_dst(skb)) - neigh = skb_dst(skb)->neighbour; + if (skb->dst) + neigh = skb->dst->neighbour; if (neigh == NULL) { if (net_ratelimit()) @@ -662,8 +663,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (!dst) { struct neighbour *neigh = NULL; - if (skb_dst(skb)) - neigh = skb_dst(skb)->neighbour; + if (skb->dst) + neigh = skb->dst->neighbour; if (neigh == NULL) { if (net_ratelimit()) @@ -713,7 +714,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (tiph->frag_off) mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); else - mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; + mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; if (mtu < 68) { stats->collisions++; @@ -722,8 +723,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) } if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; - if (tunnel->parms.iph.daddr && skb_dst(skb)) - skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + if (tunnel->parms.iph.daddr && skb->dst) + skb->dst->ops->update_pmtu(skb->dst, mtu); if (skb->len > mtu) { icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); @@ -767,8 +768,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) skb_reset_network_header(skb); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); IPCB(skb)->flags = 0; - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* * Push down and install the IPIP header. diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 53b6a4192b16..ea37741062a9 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -981,10 +981,9 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, struct tcphdr *th = tcp_hdr(skb), *t1; struct sk_buff *buff; struct flowi fl; - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); struct sock *ctl_sk = net->ipv6.tcp_sk; unsigned int tot_len = sizeof(struct tcphdr); - struct dst_entry *dst; __be32 *topt; if (ts) @@ -1053,9 +1052,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, * Underlying function will use this to retrieve the network * namespace */ - if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { - if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { - skb_dst_set(buff, dst); + if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { + if (xfrm_lookup(net, &buff->dst, &fl, NULL, 0) >= 0) { ip6_xmit(ctl_sk, buff, &fl, NULL, 0); TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); if (rst) diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index fc333d854728..8905712cfbb8 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -177,9 +177,10 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, if (unlikely(sk = skb_steal_sock(skb))) return sk; - return __udp6_lib_lookup(dev_net(skb_dst(skb)->dev), &iph->saddr, sport, - &iph->daddr, dport, inet6_iif(skb), - udptable); + else + return __udp6_lib_lookup(dev_net(skb->dst->dev), &iph->saddr, sport, + &iph->daddr, dport, inet6_iif(skb), + udptable); } /* diff --git a/trunk/net/ipv6/xfrm6_mode_tunnel.c b/trunk/net/ipv6/xfrm6_mode_tunnel.c index 3927832227b9..e20529b4c825 100644 --- a/trunk/net/ipv6/xfrm6_mode_tunnel.c +++ b/trunk/net/ipv6/xfrm6_mode_tunnel.c @@ -31,7 +31,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) */ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct ipv6hdr *top_iph; int dsfield; @@ -45,7 +45,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl, sizeof(top_iph->flow_lbl)); - top_iph->nexthdr = xfrm_af2proto(skb_dst(skb)->ops->family); + top_iph->nexthdr = xfrm_af2proto(skb->dst->ops->family); dsfield = XFRM_MODE_SKB_CB(skb)->tos; dsfield = INET_ECN_encapsulate(dsfield, dsfield); diff --git a/trunk/net/ipv6/xfrm6_output.c b/trunk/net/ipv6/xfrm6_output.c index c4f4eef032a3..5ee5a031bc93 100644 --- a/trunk/net/ipv6/xfrm6_output.c +++ b/trunk/net/ipv6/xfrm6_output.c @@ -30,7 +30,7 @@ EXPORT_SYMBOL(xfrm6_find_1stfragopt); static int xfrm6_tunnel_check_size(struct sk_buff *skb) { int mtu, ret = 0; - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; mtu = dst_mtu(dst); if (mtu < IPV6_MIN_MTU) @@ -90,6 +90,6 @@ static int xfrm6_output_finish(struct sk_buff *skb) int xfrm6_output(struct sk_buff *skb) { - return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb_dst(skb)->dev, + return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dst->dev, xfrm6_output_finish); } diff --git a/trunk/net/irda/irlap_frame.c b/trunk/net/irda/irlap_frame.c index 7af2e74deda8..2562ebc1b22c 100644 --- a/trunk/net/irda/irlap_frame.c +++ b/trunk/net/irda/irlap_frame.c @@ -982,12 +982,17 @@ void irlap_resend_rejected_frames(struct irlap_cb *self, int command) { struct sk_buff *tx_skb; struct sk_buff *skb; + int count; IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == LAP_MAGIC, return;); + /* Initialize variables */ + count = skb_queue_len(&self->wx_list); + /* Resend unacknowledged frame(s) */ - skb_queue_walk(&self->wx_list, skb) { + skb = skb_peek(&self->wx_list); + while (skb != NULL) { irlap_wait_min_turn_around(self, &self->qos_tx); /* We copy the skb to be retransmitted since we will have to @@ -1006,12 +1011,21 @@ void irlap_resend_rejected_frames(struct irlap_cb *self, int command) /* * Set poll bit on the last frame retransmitted */ - if (skb_queue_is_last(&self->wx_list, skb)) + if (count-- == 1) tx_skb->data[1] |= PF_BIT; /* Set p/f bit */ else tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */ irlap_send_i_frame(self, tx_skb, command); + + /* + * If our skb is the last buffer in the list, then + * we are finished, if not, move to the next sk-buffer + */ + if (skb == skb_peek_tail(&self->wx_list)) + skb = NULL; + else + skb = skb->next; } #if 0 /* Not yet */ /* diff --git a/trunk/net/llc/llc_conn.c b/trunk/net/llc/llc_conn.c index c6bab39b018e..3477624a4906 100644 --- a/trunk/net/llc/llc_conn.c +++ b/trunk/net/llc/llc_conn.c @@ -79,6 +79,10 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) if (unlikely(!ev->ind_prim && !ev->cfm_prim)) { /* indicate or confirm not required */ + /* XXX this is not very pretty, perhaps we should store + * XXX indicate/confirm-needed state in the llc_conn_state_ev + * XXX control block of the SKB instead? -DaveM + */ if (!skb->next) goto out_kfree_skb; goto out_skb_put; diff --git a/trunk/net/mac80211/Kconfig b/trunk/net/mac80211/Kconfig index ba2643a43c73..9cbf545e95a2 100644 --- a/trunk/net/mac80211/Kconfig +++ b/trunk/net/mac80211/Kconfig @@ -1,19 +1,16 @@ config MAC80211 tristate "Generic IEEE 802.11 Networking Stack (mac80211)" - depends on CFG80211 select CRYPTO select CRYPTO_ECB select CRYPTO_ARC4 select CRYPTO_AES select CRC32 select WIRELESS_EXT + select CFG80211 ---help--- This option enables the hardware independent IEEE 802.11 networking stack. -comment "CFG80211 needs to be enabled for MAC80211" - depends on CFG80211=n - config MAC80211_DEFAULT_PS bool "enable powersave by default" depends on MAC80211 diff --git a/trunk/net/mac80211/agg-tx.c b/trunk/net/mac80211/agg-tx.c index 9e5762ad307d..43d00ffd3988 100644 --- a/trunk/net/mac80211/agg-tx.c +++ b/trunk/net/mac80211/agg-tx.c @@ -132,9 +132,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, state = &sta->ampdu_mlme.tid_state_tx[tid]; - if (*state == HT_AGG_STATE_OPERATIONAL) - sta->ampdu_mlme.addba_req_num[tid] = 0; - *state = HT_AGG_STATE_REQ_STOP_BA_MSK | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); @@ -340,7 +337,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) sta->ampdu_mlme.tid_tx[tid]->dialog_token, sta->ampdu_mlme.tid_tx[tid]->ssn, 0x40, 5000); - sta->ampdu_mlme.addba_req_num[tid]++; /* activate the timer for the recipient's addBA response */ sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = jiffies + ADDBA_RESP_INTERVAL; @@ -610,6 +606,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) *state = HT_AGG_STATE_IDLE; /* from now on packets are no longer put onto sta->pending */ + sta->ampdu_mlme.addba_req_num[tid] = 0; kfree(sta->ampdu_mlme.tid_tx[tid]); sta->ampdu_mlme.tid_tx[tid] = NULL; @@ -692,6 +689,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, sta->ampdu_mlme.addba_req_num[tid] = 0; } else { + sta->ampdu_mlme.addba_req_num[tid]++; ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); } spin_unlock_bh(&sta->lock); diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 3f47276caeb8..77e9ff5ec4f3 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -663,13 +663,6 @@ static void sta_apply_parameters(struct ieee80211_local *local, } spin_unlock_bh(&sta->lock); - /* - * cfg80211 validates this (1-2007) and allows setting the AID - * only when creating a new station entry - */ - if (params->aid) - sta->sta.aid = params->aid; - /* * FIXME: updating the following information is racy when this * function is called from ieee80211_change_station(). @@ -677,6 +670,12 @@ static void sta_apply_parameters(struct ieee80211_local *local, * maybe we should just reject attemps to change it. */ + if (params->aid) { + sta->sta.aid = params->aid; + if (sta->sta.aid > IEEE80211_MAX_AID) + sta->sta.aid = 0; /* XXX: should this be an error? */ + } + if (params->listen_interval >= 0) sta->listen_interval = params->listen_interval; @@ -1122,8 +1121,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, p.txop = params->txop; if (drv_conf_tx(local, params->queue, &p)) { printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), params->queue); + "parameters for queue %d\n", local->mdev->name, + params->queue); return -EINVAL; } @@ -1256,7 +1255,7 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL; ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len); - if (ret && ret != -EALREADY) + if (ret) return ret; if (req->use_mfp) { @@ -1334,53 +1333,6 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) return 0; } -static int ieee80211_set_tx_power(struct wiphy *wiphy, - enum tx_power_setting type, int dbm) -{ - struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_channel *chan = local->hw.conf.channel; - u32 changes = 0; - - switch (type) { - case TX_POWER_AUTOMATIC: - local->user_power_level = -1; - break; - case TX_POWER_LIMITED: - if (dbm < 0) - return -EINVAL; - local->user_power_level = dbm; - break; - case TX_POWER_FIXED: - if (dbm < 0) - return -EINVAL; - /* TODO: move to cfg80211 when it knows the channel */ - if (dbm > chan->max_power) - return -EINVAL; - local->user_power_level = dbm; - break; - } - - ieee80211_hw_config(local, changes); - - return 0; -} - -static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) -{ - struct ieee80211_local *local = wiphy_priv(wiphy); - - *dbm = local->hw.conf.power_level; - - return 0; -} - -static void ieee80211_rfkill_poll(struct wiphy *wiphy) -{ - struct ieee80211_local *local = wiphy_priv(wiphy); - - drv_rfkill_poll(local); -} - struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -1420,7 +1372,4 @@ struct cfg80211_ops mac80211_config_ops = { .join_ibss = ieee80211_join_ibss, .leave_ibss = ieee80211_leave_ibss, .set_wiphy_params = ieee80211_set_wiphy_params, - .set_tx_power = ieee80211_set_tx_power, - .get_tx_power = ieee80211_get_tx_power, - .rfkill_poll = ieee80211_rfkill_poll, }; diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h index b13446afd48f..3912b5334b9c 100644 --- a/trunk/net/mac80211/driver-ops.h +++ b/trunk/net/mac80211/driver-ops.h @@ -181,11 +181,4 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, sta, tid, ssn); return -EOPNOTSUPP; } - - -static inline void drv_rfkill_poll(struct ieee80211_local *local) -{ - if (local->ops->rfkill_poll) - local->ops->rfkill_poll(&local->hw); -} #endif /* __MAC80211_DRIVER_OPS */ diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 4dbc28964196..c088c46704a3 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -589,7 +589,6 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_AGGREGATION, IEEE80211_QUEUE_STOP_REASON_SUSPEND, IEEE80211_QUEUE_STOP_REASON_PENDING, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD, }; struct ieee80211_master_priv { @@ -1122,10 +1121,6 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, enum queue_stop_reason reason); void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, enum queue_stop_reason reason); -void ieee80211_add_pending_skb(struct ieee80211_local *local, - struct sk_buff *skb); -int ieee80211_add_pending_skbs(struct ieee80211_local *local, - struct sk_buff_head *skbs); void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index b7c8a4484298..8c9f1c722cdb 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -170,7 +170,7 @@ static int ieee80211_open(struct net_device *dev) goto err_del_bss; /* we're brought up, everything changes */ hw_reconf_flags = ~0; - ieee80211_led_radio(local, true); + ieee80211_led_radio(local, local->hw.conf.radio_enabled); } /* @@ -560,7 +560,7 @@ static int ieee80211_stop(struct net_device *dev) drv_stop(local); - ieee80211_led_radio(local, false); + ieee80211_led_radio(local, 0); flush_workqueue(local->hw.workqueue); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index 092a017b237e..6b7e92eaab47 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -289,8 +289,16 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, drv_bss_info_changed(local, &sdata->vif, &sdata->vif.bss_conf, changed); - /* DEPRECATED */ - local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int; + /* + * DEPRECATED + * + * ~changed is just there to not do this at resume time + */ + if (changed & BSS_CHANGED_BEACON_INT && ~changed) { + local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int; + ieee80211_hw_config(local, + _IEEE80211_CONF_CHANGE_BEACON_INTERVAL); + } } u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) @@ -369,12 +377,60 @@ static void ieee80211_tasklet_handler(unsigned long data) } } +/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to + * make a prepared TX frame (one that has been given to hw) to look like brand + * new IEEE 802.11 frame that is ready to go through TX processing again. + */ +static void ieee80211_remove_tx_extra(struct ieee80211_local *local, + struct ieee80211_key *key, + struct sk_buff *skb) +{ + unsigned int hdrlen, iv_len, mic_len; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + + if (!key) + goto no_key; + + switch (key->conf.alg) { + case ALG_WEP: + iv_len = WEP_IV_LEN; + mic_len = WEP_ICV_LEN; + break; + case ALG_TKIP: + iv_len = TKIP_IV_LEN; + mic_len = TKIP_ICV_LEN; + break; + case ALG_CCMP: + iv_len = CCMP_HDR_LEN; + mic_len = CCMP_MIC_LEN; + break; + default: + goto no_key; + } + + if (skb->len >= hdrlen + mic_len && + !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) + skb_trim(skb, skb->len - mic_len); + if (skb->len >= hdrlen + iv_len) { + memmove(skb->data + iv_len, skb->data, hdrlen); + hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len); + } + +no_key: + if (ieee80211_is_data_qos(hdr->frame_control)) { + hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data, + hdrlen - IEEE80211_QOS_CTL_LEN); + skb_pull(skb, IEEE80211_QOS_CTL_LEN); + } +} + static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, struct sta_info *sta, struct sk_buff *skb) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - sta->tx_filtered_count++; /* @@ -416,15 +472,16 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, */ if (test_sta_flags(sta, WLAN_STA_PS) && skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { + ieee80211_remove_tx_extra(local, sta->key, skb); skb_queue_tail(&sta->tx_filtered, skb); return; } - if (!test_sta_flags(sta, WLAN_STA_PS) && - !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { + if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { /* Software retry the packet once */ - info->flags |= IEEE80211_TX_INTFL_RETRIED; - ieee80211_add_pending_skb(local, skb); + skb->requeue = 1; + ieee80211_remove_tx_extra(local, sta->key, skb); + dev_queue_xmit(skb); return; } @@ -678,7 +735,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, * +-------------------------+ * */ - priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; + priv_size = ((sizeof(struct ieee80211_local) + + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) + + priv_data_len; wiphy = wiphy_new(&mac80211_config_ops, priv_size); @@ -695,7 +754,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.wiphy = wiphy; - local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); + local->hw.priv = (char *)local + + ((sizeof(struct ieee80211_local) + + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); BUG_ON(!ops->tx); BUG_ON(!ops->start); diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index d779c57a8220..509469cb9265 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -621,6 +621,9 @@ static void ieee80211_change_ps(struct ieee80211_local *local) struct ieee80211_conf *conf = &local->hw.conf; if (local->ps_sdata) { + if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) + return; + ieee80211_enable_ps(local, local->ps_sdata); } else if (conf->flags & IEEE80211_CONF_PS) { conf->flags &= ~IEEE80211_CONF_PS; @@ -650,9 +653,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) count++; } - if (count == 1 && found->u.mgd.powersave && - (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) && - !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { + if (count == 1 && found->u.mgd.powersave) { s32 beaconint_us; if (latency < 0) @@ -792,13 +793,13 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, #ifdef CONFIG_MAC80211_VERBOSE_DEBUG printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " "cWmin=%d cWmax=%d txop=%d\n", - wiphy_name(local->hw.wiphy), queue, aci, acm, - params.aifs, params.cw_min, params.cw_max, params.txop); + local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, + params.cw_max, params.txop); #endif if (drv_conf_tx(local, queue, ¶ms) && local->ops->conf_tx) printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), queue); + "parameters for queue %d\n", local->mdev->name, + queue); } } @@ -1321,11 +1322,6 @@ void ieee80211_beacon_loss_work(struct work_struct *work) #endif ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; - - mutex_lock(&sdata->local->iflist_mtx); - ieee80211_recalc_ps(sdata->local, -1); - mutex_unlock(&sdata->local->iflist_mtx); - ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, ifmgd->ssid_len, NULL, 0); @@ -1346,7 +1342,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - unsigned long last_rx; bool disassoc = false; /* TODO: start monitoring current AP signal quality and number of @@ -1363,21 +1358,17 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", sdata->dev->name, ifmgd->bssid); disassoc = true; - rcu_read_unlock(); - goto out; + goto unlock; } - last_rx = sta->last_rx; - rcu_read_unlock(); - if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && - time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) { + time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) { printk(KERN_DEBUG "%s: no probe response from AP %pM " "- disassociating\n", sdata->dev->name, ifmgd->bssid); disassoc = true; ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; - goto out; + goto unlock; } /* @@ -1396,29 +1387,26 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) } #endif ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&local->iflist_mtx); - ieee80211_recalc_ps(local, -1); - mutex_unlock(&local->iflist_mtx); ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, ifmgd->ssid_len, NULL, 0); mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); - goto out; + goto unlock; } - if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) { + if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) { ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&local->iflist_mtx); - ieee80211_recalc_ps(local, -1); - mutex_unlock(&local->iflist_mtx); ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, ifmgd->ssid_len, NULL, 0); } - out: if (!disassoc) mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL); - else + + unlock: + rcu_read_unlock(); + + if (disassoc) ieee80211_set_disassoc(sdata, true, true, WLAN_REASON_PREV_AUTH_NOT_VALID); } @@ -1901,12 +1889,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ieee80211_authenticate(sdata); } - if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { + if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&sdata->local->iflist_mtx); - ieee80211_recalc_ps(sdata->local, -1); - mutex_unlock(&sdata->local->iflist_mtx); - } } /* @@ -1964,9 +1948,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } #endif ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&local->iflist_mtx); - ieee80211_recalc_ps(local, -1); - mutex_unlock(&local->iflist_mtx); } ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); diff --git a/trunk/net/mac80211/rc80211_minstrel.c b/trunk/net/mac80211/rc80211_minstrel.c index b218b98fba7f..0a11515341ba 100644 --- a/trunk/net/mac80211/rc80211_minstrel.c +++ b/trunk/net/mac80211/rc80211_minstrel.c @@ -215,7 +215,7 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi) unsigned int sample_ndx; sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); mi->sample_idx++; - if ((int) mi->sample_idx > (mi->n_rates - 2)) { + if (mi->sample_idx > (mi->n_rates - 2)) { mi->sample_idx = 0; mi->sample_column++; if (mi->sample_column >= SAMPLE_COLUMNS) diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index de5bba7f910a..6a9b8e63a6bf 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -797,7 +797,8 @@ static int ap_sta_ps_end(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; - int sent, buffered; + struct sk_buff *skb; + int sent = 0; atomic_dec(&sdata->bss->num_sta_ps); @@ -813,16 +814,22 @@ static int ap_sta_ps_end(struct sta_info *sta) #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ /* Send all buffered frames to the station */ - sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); - buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); - sent += buffered; - local->total_ps_buffered -= buffered; - + while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { + sent++; + skb->requeue = 1; + dev_queue_xmit(skb); + } + while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { + local->total_ps_buffered--; + sent++; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " - "since STA not sleeping anymore\n", sdata->dev->name, - sta->sta.addr, sta->sta.aid, sent - buffered, buffered); + printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " + "since STA not sleeping anymore\n", sdata->dev->name, + sta->sta.addr, sta->sta.aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + skb->requeue = 1; + dev_queue_xmit(skb); + } return sent; } @@ -1328,7 +1335,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) * mac80211. That also explains the __skb_push() * below. */ - align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3; + align = (unsigned long)skb->data & 3; if (align) { if (WARN_ON(skb_headroom(skb) < 3)) { dev_kfree_skb(skb); diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index a360bceeba59..d5611d8fd0d6 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -44,15 +44,6 @@ * When the insertion fails (sta_info_insert()) returns non-zero), the * structure will have been freed by sta_info_insert()! * - * sta entries are added by mac80211 when you establish a link with a - * peer. This means different things for the different type of interfaces - * we support. For a regular station this mean we add the AP sta when we - * receive an assocation response from the AP. For IBSS this occurs when - * we receive a probe response or a beacon from target IBSS network. For - * WDS we add the sta for the peer imediately upon device open. When using - * AP mode we add stations for each respective station upon request from - * userspace through nl80211. - * * Because there are debugfs entries for each station, and adding those * must be able to sleep, it is also possible to "pin" a station entry, * that means it can be removed from the hash table but not be freed. diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 364222bfb10d..a910148b8228 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -400,7 +400,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) sta_info_set_tim_bit(sta); info->control.jiffies = jiffies; - info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; skb_queue_tail(&sta->ps_tx_buf, tx->skb); return TX_QUEUED; } @@ -421,7 +420,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) * frame filtering and keeps a station blacklist on its own * (e.g: p54), so that frames can be delivered unimpeded. * - * Note: It should be safe to disable the filter now. + * Note: It should be save to disable the filter now. * As, it is really unlikely that we still have any pending * frame for this station in the hw's buffers/fifos left, * that is not rejected with a unsuccessful tx_status yet. @@ -908,8 +907,9 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) * deal with packet injection down monitor interface * with Radiotap Header -- only called for monitor mode interface */ -static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, - struct sk_buff *skb) +static ieee80211_tx_result +__ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, + struct sk_buff *skb) { /* * this is the moment to interpret and discard the radiotap header that @@ -960,7 +960,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, * on transmission */ if (skb->len < (iterator.max_length + FCS_LEN)) - return false; + return TX_DROP; skb_trim(skb, skb->len - FCS_LEN); } @@ -982,7 +982,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, } if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ - return false; + return TX_DROP; /* * remove the radiotap header @@ -991,7 +991,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, */ skb_pull(skb, iterator.max_length); - return true; + return TX_CONTINUE; } /* @@ -1025,7 +1025,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, /* process and remove the injection radiotap header */ sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { - if (!__ieee80211_parse_tx_radiotap(tx, skb)) + if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) return TX_DROP; /* @@ -1238,6 +1238,7 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb, bool txpending) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct sta_info *sta; struct ieee80211_tx_data tx; ieee80211_tx_result res_prepare; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1269,6 +1270,7 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb, return; } + sta = tx.sta; tx.channel = local->hw.conf.channel; info->band = tx.channel->band; @@ -1415,8 +1417,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) } if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && - local->hw.conf.dynamic_ps_timeout > 0 && - !local->sw_scanning && !local->hw_scanning && local->ps_sdata) { + local->hw.conf.dynamic_ps_timeout > 0) { if (local->hw.conf.flags & IEEE80211_CONF_PS) { ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_QUEUE_STOP_REASON_PS); diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 66ce96a69f31..949d857debd8 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -341,52 +341,6 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) } EXPORT_SYMBOL(ieee80211_stop_queue); -void ieee80211_add_pending_skb(struct ieee80211_local *local, - struct sk_buff *skb) -{ - struct ieee80211_hw *hw = &local->hw; - unsigned long flags; - int queue = skb_get_queue_mapping(skb); - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING); - skb_queue_tail(&local->pending[queue], skb); - __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -} - -int ieee80211_add_pending_skbs(struct ieee80211_local *local, - struct sk_buff_head *skbs) -{ - struct ieee80211_hw *hw = &local->hw; - struct sk_buff *skb; - unsigned long flags; - int queue, ret = 0, i; - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - for (i = 0; i < hw->queues; i++) - __ieee80211_stop_queue(hw, i, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - - while ((skb = skb_dequeue(skbs))) { - ret++; - queue = skb_get_queue_mapping(skb); - skb_queue_tail(&local->pending[queue], skb); - } - - for (i = 0; i < hw->queues; i++) { - if (ret) - __ieee80211_stop_queue(hw, i, - IEEE80211_QUEUE_STOP_REASON_PENDING); - __ieee80211_wake_queue(hw, i, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - } - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - - return ret; -} - void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, enum queue_stop_reason reason) { @@ -703,15 +657,15 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) switch (queue) { case 3: /* AC_BK */ - qparam.cw_max = aCWmax; - qparam.cw_min = aCWmin; + qparam.cw_max = aCWmin; + qparam.cw_min = aCWmax; qparam.txop = 0; qparam.aifs = 7; break; default: /* never happens but let's not leave undefined */ case 2: /* AC_BE */ - qparam.cw_max = aCWmax; - qparam.cw_min = aCWmin; + qparam.cw_max = aCWmin; + qparam.cw_min = aCWmax; qparam.txop = 0; qparam.aifs = 3; break; @@ -1019,7 +973,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) if (local->open_count) { res = drv_start(local); - ieee80211_led_radio(local, true); + ieee80211_led_radio(local, hw->conf.radio_enabled); } /* add interfaces */ diff --git a/trunk/net/mac80211/wext.c b/trunk/net/mac80211/wext.c index d2d81b103341..a01154e127f0 100644 --- a/trunk/net/mac80211/wext.c +++ b/trunk/net/mac80211/wext.c @@ -306,6 +306,82 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev, return 0; } +static int ieee80211_ioctl_siwtxpower(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) +{ + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct ieee80211_channel* chan = local->hw.conf.channel; + bool reconf = false; + u32 reconf_flags = 0; + int new_power_level; + + if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) + return -EINVAL; + if (data->txpower.flags & IW_TXPOW_RANGE) + return -EINVAL; + if (!chan) + return -EINVAL; + + /* only change when not disabling */ + if (!data->txpower.disabled) { + if (data->txpower.fixed) { + if (data->txpower.value < 0) + return -EINVAL; + new_power_level = data->txpower.value; + /* + * Debatable, but we cannot do a fixed power + * level above the regulatory constraint. + * Use "iwconfig wlan0 txpower 15dBm" instead. + */ + if (new_power_level > chan->max_power) + return -EINVAL; + } else { + /* + * Automatic power level setting, max being the value + * passed in from userland. + */ + if (data->txpower.value < 0) + new_power_level = -1; + else + new_power_level = data->txpower.value; + } + + reconf = true; + + /* + * ieee80211_hw_config() will limit to the channel's + * max power and possibly power constraint from AP. + */ + local->user_power_level = new_power_level; + } + + if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { + local->hw.conf.radio_enabled = !(data->txpower.disabled); + reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED; + ieee80211_led_radio(local, local->hw.conf.radio_enabled); + } + + if (reconf || reconf_flags) + ieee80211_hw_config(local, reconf_flags); + + return 0; +} + +static int ieee80211_ioctl_giwtxpower(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) +{ + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + + data->txpower.fixed = 1; + data->txpower.disabled = !(local->hw.conf.radio_enabled); + data->txpower.value = local->hw.conf.power_level; + data->txpower.flags = IW_TXPOW_DBM; + + return 0; +} + static int ieee80211_ioctl_siwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, @@ -582,8 +658,8 @@ static const iw_handler ieee80211_handler[] = (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */ - (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */ + (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ + (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ diff --git a/trunk/net/mac80211/wme.c b/trunk/net/mac80211/wme.c index 116a923b14d6..694343b9102b 100644 --- a/trunk/net/mac80211/wme.c +++ b/trunk/net/mac80211/wme.c @@ -101,7 +101,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) * Now we know the 1d priority, fill in the QoS header if * there is one (and we haven't done this before). */ - if (ieee80211_is_data_qos(hdr->frame_control)) { + if (!skb->requeue && ieee80211_is_data_qos(hdr->frame_control)) { u8 *p = ieee80211_get_qos_ctl(hdr); u8 ack_policy = 0; tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; diff --git a/trunk/net/netfilter/ipvs/ip_vs_xmit.c b/trunk/net/netfilter/ipvs/ip_vs_xmit.c index 5874657af7f2..425ab144f15d 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_xmit.c +++ b/trunk/net/netfilter/ipvs/ip_vs_xmit.c @@ -260,8 +260,8 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, ip_send_check(ip_hdr(skb)); /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; @@ -324,8 +324,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, } /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; @@ -388,8 +388,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error_put; /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* mangle the packet */ if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) @@ -465,8 +465,8 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error_put; /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* mangle the packet */ if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) @@ -553,8 +553,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG_RL("ip_vs_tunnel_xmit(): mtu less than 68\n"); goto tx_error; } - if (skb_dst(skb)) - skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + if (skb->dst) + skb->dst->ops->update_pmtu(skb->dst, mtu); df |= (old_iph->frag_off & htons(IP_DF)); @@ -596,8 +596,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* * Push down and install the IPIP header. @@ -665,8 +665,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): mtu less than 1280\n"); goto tx_error; } - if (skb_dst(skb)) - skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); + if (skb->dst) + skb->dst->ops->update_pmtu(skb->dst, mtu); if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) { icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); @@ -702,8 +702,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* * Push down and install the IPIP header. @@ -775,8 +775,8 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, ip_send_check(ip_hdr(skb)); /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; @@ -828,8 +828,8 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, } /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; @@ -900,8 +900,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error_put; /* drop the old route when skb is not shared */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; ip_vs_nat_icmp(skb, pp, cp, 0); @@ -975,8 +975,8 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, goto tx_error_put; /* drop the old route when skb is not shared */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->u.dst); + dst_release(skb->dst); + skb->dst = &rt->u.dst; ip_vs_nat_icmp_v6(skb, pp, cp, 0); diff --git a/trunk/net/netfilter/nf_conntrack_netbios_ns.c b/trunk/net/netfilter/nf_conntrack_netbios_ns.c index 497b2224536f..8a3875e36ec2 100644 --- a/trunk/net/netfilter/nf_conntrack_netbios_ns.c +++ b/trunk/net/netfilter/nf_conntrack_netbios_ns.c @@ -48,7 +48,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, { struct nf_conntrack_expect *exp; struct iphdr *iph = ip_hdr(skb); - struct rtable *rt = skb_rtable(skb); + struct rtable *rt = skb->rtable; struct in_device *in_dev; __be32 mask = 0; diff --git a/trunk/net/netfilter/nf_conntrack_proto_dccp.c b/trunk/net/netfilter/nf_conntrack_proto_dccp.c index aee0d6bea309..11801c43c8cf 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_dccp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_dccp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static DEFINE_RWLOCK(dccp_lock); @@ -554,9 +553,6 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, ct->proto.dccp.state = new_state; write_unlock_bh(&dccp_lock); - if (new_state != old_state) - nf_conntrack_event_cache(IPCT_PROTOINFO, ct); - dn = dccp_pernet(net); nf_ct_refresh_acct(ct, ctinfo, skb, dn->dccp_timeout[new_state]); @@ -639,6 +635,8 @@ static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state); NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_ROLE, ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]); + NLA_PUT_BE64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ, + cpu_to_be64(ct->proto.dccp.handshake_seq)); nla_nest_end(skb, nest_parms); read_unlock_bh(&dccp_lock); return 0; @@ -651,6 +649,7 @@ static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla, static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = { [CTA_PROTOINFO_DCCP_STATE] = { .type = NLA_U8 }, [CTA_PROTOINFO_DCCP_ROLE] = { .type = NLA_U8 }, + [CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ] = { .type = NLA_U64 }, }; static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct) @@ -683,6 +682,10 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct) ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER; ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT; } + if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) { + ct->proto.dccp.handshake_seq = + be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ])); + } write_unlock_bh(&dccp_lock); return 0; } diff --git a/trunk/net/netfilter/nf_conntrack_proto_gre.c b/trunk/net/netfilter/nf_conntrack_proto_gre.c index a6d6ec320fbc..117b80112fcb 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_gre.c +++ b/trunk/net/netfilter/nf_conntrack_proto_gre.c @@ -176,7 +176,7 @@ static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple, static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) { - struct net *net = dev_net(skb->dev ? skb->dev : skb_dst(skb)->dev); + struct net *net = dev_net(skb->dev ? skb->dev : skb->dst->dev); const struct gre_hdr_pptp *pgrehdr; struct gre_hdr_pptp _pgrehdr; __be16 srckey; diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 97a6e93d742e..b5ccf2b4b2e7 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -634,14 +634,6 @@ static bool tcp_in_window(const struct nf_conn *ct, sender->td_end = end; sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED; } - if (tcph->ack) { - if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) { - sender->td_maxack = ack; - sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET; - } else if (after(ack, sender->td_maxack)) - sender->td_maxack = ack; - } - /* * Update receiver data. */ @@ -926,16 +918,6 @@ static int tcp_packet(struct nf_conn *ct, "nf_ct_tcp: invalid state "); return -NF_ACCEPT; case TCP_CONNTRACK_CLOSE: - if (index == TCP_RST_SET - && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) - && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) { - /* Invalid RST */ - write_unlock_bh(&tcp_lock); - if (LOG_INVALID(net, IPPROTO_TCP)) - nf_log_packet(pf, 0, skb, NULL, NULL, NULL, - "nf_ct_tcp: invalid RST "); - return -NF_ACCEPT; - } if (index == TCP_RST_SET && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status) && ct->proto.tcp.last_index == TCP_SYN_SET) diff --git a/trunk/net/netfilter/nfnetlink_log.c b/trunk/net/netfilter/nfnetlink_log.c index 66a6dd5c519a..fd326ac27ec8 100644 --- a/trunk/net/netfilter/nfnetlink_log.c +++ b/trunk/net/netfilter/nfnetlink_log.c @@ -581,12 +581,6 @@ nfulnl_log_packet(u_int8_t pf, + nla_total_size(sizeof(struct nfulnl_msg_packet_hw)) + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp)); - if (in && skb_mac_header_was_set(skb)) { - size += nla_total_size(skb->dev->hard_header_len) - + nla_total_size(sizeof(u_int16_t)) /* hwtype */ - + nla_total_size(sizeof(u_int16_t)); /* hwlen */ - } - spin_lock_bh(&inst->lock); if (inst->flags & NFULNL_CFG_F_SEQ) diff --git a/trunk/net/netfilter/nfnetlink_queue.c b/trunk/net/netfilter/nfnetlink_queue.c index 71daa0934b6c..8c860112ce05 100644 --- a/trunk/net/netfilter/nfnetlink_queue.c +++ b/trunk/net/netfilter/nfnetlink_queue.c @@ -1,6 +1,6 @@ /* * This is a module which is used for queueing packets and communicating with - * userspace via nfnetlink. + * userspace via nfetlink. * * (C) 2005 by Harald Welte * (C) 2007 by Patrick McHardy @@ -932,8 +932,6 @@ static void __exit nfnetlink_queue_fini(void) #endif nfnetlink_subsys_unregister(&nfqnl_subsys); netlink_unregister_notifier(&nfqnl_rtnl_notifier); - - rcu_barrier(); /* Wait for completion of call_rcu()'s */ } MODULE_DESCRIPTION("netfilter packet queue handler"); diff --git a/trunk/net/netfilter/xt_TCPMSS.c b/trunk/net/netfilter/xt_TCPMSS.c index eda64c1cb1e5..4f3b1f808795 100644 --- a/trunk/net/netfilter/xt_TCPMSS.c +++ b/trunk/net/netfilter/xt_TCPMSS.c @@ -73,11 +73,11 @@ tcpmss_mangle_packet(struct sk_buff *skb, } if (info->mss == XT_TCPMSS_CLAMP_PMTU) { - if (dst_mtu(skb_dst(skb)) <= minlen) { + if (dst_mtu(skb->dst) <= minlen) { if (net_ratelimit()) printk(KERN_ERR "xt_TCPMSS: " "unknown or invalid path-MTU (%u)\n", - dst_mtu(skb_dst(skb))); + dst_mtu(skb->dst)); return -1; } if (in_mtu <= minlen) { @@ -86,7 +86,7 @@ tcpmss_mangle_packet(struct sk_buff *skb, "invalid path-MTU (%u)\n", in_mtu); return -1; } - newmss = min(dst_mtu(skb_dst(skb)), in_mtu) - minlen; + newmss = min(dst_mtu(skb->dst), in_mtu) - minlen; } else newmss = info->mss; diff --git a/trunk/net/netfilter/xt_hashlimit.c b/trunk/net/netfilter/xt_hashlimit.c index 219dcdbe388c..a5b5369c30f9 100644 --- a/trunk/net/netfilter/xt_hashlimit.c +++ b/trunk/net/netfilter/xt_hashlimit.c @@ -926,7 +926,7 @@ static int dl_seq_show(struct seq_file *s, void *v) if (!hlist_empty(&htable->hash[*bucket])) { hlist_for_each_entry(ent, pos, &htable->hash[*bucket], node) if (dl_seq_real_show(ent, htable->family, s)) - return -1; + return 1; } return 0; } diff --git a/trunk/net/netfilter/xt_policy.c b/trunk/net/netfilter/xt_policy.c index 4cbfebda8fa1..328bd20ddd25 100644 --- a/trunk/net/netfilter/xt_policy.c +++ b/trunk/net/netfilter/xt_policy.c @@ -86,7 +86,7 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info, unsigned short family) { const struct xt_policy_elem *e; - const struct dst_entry *dst = skb_dst(skb); + const struct dst_entry *dst = skb->dst; int strict = info->flags & XT_POLICY_MATCH_STRICT; int i, pos; diff --git a/trunk/net/netfilter/xt_realm.c b/trunk/net/netfilter/xt_realm.c index 484d1689bfde..67419287bc7e 100644 --- a/trunk/net/netfilter/xt_realm.c +++ b/trunk/net/netfilter/xt_realm.c @@ -25,7 +25,7 @@ static bool realm_mt(const struct sk_buff *skb, const struct xt_match_param *par) { const struct xt_realm_info *info = par->matchinfo; - const struct dst_entry *dst = skb_dst(skb); + const struct dst_entry *dst = skb->dst; return (info->id == (dst->tclassid & info->mask)) ^ info->invert; } diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index 4f76e5552d8e..c7c5d524967e 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -372,7 +372,8 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct goto oom; /* drop any routing info */ - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; /* drop conntrack reference */ nf_reset(skb); @@ -620,7 +621,8 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet skb_set_owner_r(skb, sk); skb->dev = NULL; - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; /* drop conntrack reference */ nf_reset(skb); @@ -1580,9 +1582,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, break; case PACKET_MR_UNICAST: if (what > 0) - return dev_unicast_add(dev, i->addr); + return dev_unicast_add(dev, i->addr, i->alen); else - return dev_unicast_delete(dev, i->addr); + return dev_unicast_delete(dev, i->addr, i->alen); break; default:; } diff --git a/trunk/net/phonet/pep-gprs.c b/trunk/net/phonet/pep-gprs.c index 480839dfc560..4aa888584d20 100644 --- a/trunk/net/phonet/pep-gprs.c +++ b/trunk/net/phonet/pep-gprs.c @@ -115,10 +115,10 @@ static int gprs_recv(struct gprs_dev *gp, struct sk_buff *skb) rskb->truesize += rskb->len; /* Avoid nested fragments */ - skb_walk_frags(skb, fs) + for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next) flen += fs->len; skb->next = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; skb->len -= flen; skb->data_len -= flen; skb->truesize -= flen; @@ -212,9 +212,8 @@ static int gprs_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_bytes += len; } - netif_stop_queue(dev); - if (pep_writeable(sk)) - netif_wake_queue(dev); + if (!pep_writeable(sk)) + netif_stop_queue(dev); return 0; } diff --git a/trunk/net/phonet/pep.c b/trunk/net/phonet/pep.c index eef833ea6d7b..8ad2b5333881 100644 --- a/trunk/net/phonet/pep.c +++ b/trunk/net/phonet/pep.c @@ -940,10 +940,10 @@ int pep_write(struct sock *sk, struct sk_buff *skb) rskb->truesize += rskb->len; /* Avoid nested fragments */ - skb_walk_frags(skb, fs) + for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next) flen += fs->len; skb->next = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; skb->len -= flen; skb->data_len -= flen; skb->truesize -= flen; diff --git a/trunk/net/rfkill/Kconfig b/trunk/net/rfkill/Kconfig index eaf765876458..7f807b30cfbb 100644 --- a/trunk/net/rfkill/Kconfig +++ b/trunk/net/rfkill/Kconfig @@ -10,15 +10,22 @@ menuconfig RFKILL To compile this driver as a module, choose M here: the module will be called rfkill. +config RFKILL_INPUT + tristate "Input layer to RF switch connector" + depends on RFKILL && INPUT + help + Say Y here if you want kernel automatically toggle state + of RF switches on and off when user presses appropriate + button or a key on the keyboard. Without this module you + need a some kind of userspace application to control + state of the switches. + + To compile this driver as a module, choose M here: the + module will be called rfkill-input. + # LED trigger support config RFKILL_LEDS bool - depends on RFKILL - depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS + depends on RFKILL && LEDS_TRIGGERS default y -config RFKILL_INPUT - bool "RF switch input support" if EMBEDDED - depends on RFKILL - depends on INPUT = y || RFKILL = INPUT - default y if !EMBEDDED diff --git a/trunk/net/rfkill/Makefile b/trunk/net/rfkill/Makefile index 662105352691..b38c430be057 100644 --- a/trunk/net/rfkill/Makefile +++ b/trunk/net/rfkill/Makefile @@ -2,6 +2,5 @@ # Makefile for the RF switch subsystem. # -rfkill-y += core.o -rfkill-$(CONFIG_RFKILL_INPUT) += input.o -obj-$(CONFIG_RFKILL) += rfkill.o +obj-$(CONFIG_RFKILL) += rfkill.o +obj-$(CONFIG_RFKILL_INPUT) += rfkill-input.o diff --git a/trunk/net/rfkill/core.c b/trunk/net/rfkill/core.c deleted file mode 100644 index 4e68ab439d5d..000000000000 --- a/trunk/net/rfkill/core.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* - * Copyright (C) 2006 - 2007 Ivo van Doorn - * Copyright (C) 2007 Dmitry Torokhov - * Copyright 2009 Johannes Berg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rfkill.h" - -#define POLL_INTERVAL (5 * HZ) - -#define RFKILL_BLOCK_HW BIT(0) -#define RFKILL_BLOCK_SW BIT(1) -#define RFKILL_BLOCK_SW_PREV BIT(2) -#define RFKILL_BLOCK_ANY (RFKILL_BLOCK_HW |\ - RFKILL_BLOCK_SW |\ - RFKILL_BLOCK_SW_PREV) -#define RFKILL_BLOCK_SW_SETCALL BIT(31) - -struct rfkill { - spinlock_t lock; - - const char *name; - enum rfkill_type type; - - unsigned long state; - - u32 idx; - - bool registered; - bool suspended; - bool persistent; - - const struct rfkill_ops *ops; - void *data; - -#ifdef CONFIG_RFKILL_LEDS - struct led_trigger led_trigger; - const char *ledtrigname; -#endif - - struct device dev; - struct list_head node; - - struct delayed_work poll_work; - struct work_struct uevent_work; - struct work_struct sync_work; -}; -#define to_rfkill(d) container_of(d, struct rfkill, dev) - -struct rfkill_int_event { - struct list_head list; - struct rfkill_event ev; -}; - -struct rfkill_data { - struct list_head list; - struct list_head events; - struct mutex mtx; - wait_queue_head_t read_wait; - bool input_handler; -}; - - -MODULE_AUTHOR("Ivo van Doorn "); -MODULE_AUTHOR("Johannes Berg "); -MODULE_DESCRIPTION("RF switch support"); -MODULE_LICENSE("GPL"); - - -/* - * The locking here should be made much smarter, we currently have - * a bit of a stupid situation because drivers might want to register - * the rfkill struct under their own lock, and take this lock during - * rfkill method calls -- which will cause an AB-BA deadlock situation. - * - * To fix that, we need to rework this code here to be mostly lock-free - * and only use the mutex for list manipulations, not to protect the - * various other global variables. Then we can avoid holding the mutex - * around driver operations, and all is happy. - */ -static LIST_HEAD(rfkill_list); /* list of registered rf switches */ -static DEFINE_MUTEX(rfkill_global_mutex); -static LIST_HEAD(rfkill_fds); /* list of open fds of /dev/rfkill */ - -static unsigned int rfkill_default_state = 1; -module_param_named(default_state, rfkill_default_state, uint, 0444); -MODULE_PARM_DESC(default_state, - "Default initial state for all radio types, 0 = radio off"); - -static struct { - bool cur, sav; -} rfkill_global_states[NUM_RFKILL_TYPES]; - -static bool rfkill_epo_lock_active; - - -#ifdef CONFIG_RFKILL_LEDS -static void rfkill_led_trigger_event(struct rfkill *rfkill) -{ - struct led_trigger *trigger; - - if (!rfkill->registered) - return; - - trigger = &rfkill->led_trigger; - - if (rfkill->state & RFKILL_BLOCK_ANY) - led_trigger_event(trigger, LED_OFF); - else - led_trigger_event(trigger, LED_FULL); -} - -static void rfkill_led_trigger_activate(struct led_classdev *led) -{ - struct rfkill *rfkill; - - rfkill = container_of(led->trigger, struct rfkill, led_trigger); - - rfkill_led_trigger_event(rfkill); -} - -const char *rfkill_get_led_trigger_name(struct rfkill *rfkill) -{ - return rfkill->led_trigger.name; -} -EXPORT_SYMBOL(rfkill_get_led_trigger_name); - -void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name) -{ - BUG_ON(!rfkill); - - rfkill->ledtrigname = name; -} -EXPORT_SYMBOL(rfkill_set_led_trigger_name); - -static int rfkill_led_trigger_register(struct rfkill *rfkill) -{ - rfkill->led_trigger.name = rfkill->ledtrigname - ? : dev_name(&rfkill->dev); - rfkill->led_trigger.activate = rfkill_led_trigger_activate; - return led_trigger_register(&rfkill->led_trigger); -} - -static void rfkill_led_trigger_unregister(struct rfkill *rfkill) -{ - led_trigger_unregister(&rfkill->led_trigger); -} -#else -static void rfkill_led_trigger_event(struct rfkill *rfkill) -{ -} - -static inline int rfkill_led_trigger_register(struct rfkill *rfkill) -{ - return 0; -} - -static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill) -{ -} -#endif /* CONFIG_RFKILL_LEDS */ - -static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill, - enum rfkill_operation op) -{ - unsigned long flags; - - ev->idx = rfkill->idx; - ev->type = rfkill->type; - ev->op = op; - - spin_lock_irqsave(&rfkill->lock, flags); - ev->hard = !!(rfkill->state & RFKILL_BLOCK_HW); - ev->soft = !!(rfkill->state & (RFKILL_BLOCK_SW | - RFKILL_BLOCK_SW_PREV)); - spin_unlock_irqrestore(&rfkill->lock, flags); -} - -static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op) -{ - struct rfkill_data *data; - struct rfkill_int_event *ev; - - list_for_each_entry(data, &rfkill_fds, list) { - ev = kzalloc(sizeof(*ev), GFP_KERNEL); - if (!ev) - continue; - rfkill_fill_event(&ev->ev, rfkill, op); - mutex_lock(&data->mtx); - list_add_tail(&ev->list, &data->events); - mutex_unlock(&data->mtx); - wake_up_interruptible(&data->read_wait); - } -} - -static void rfkill_event(struct rfkill *rfkill) -{ - if (!rfkill->registered || rfkill->suspended) - return; - - kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); - - /* also send event to /dev/rfkill */ - rfkill_send_events(rfkill, RFKILL_OP_CHANGE); -} - -static bool __rfkill_set_hw_state(struct rfkill *rfkill, - bool blocked, bool *change) -{ - unsigned long flags; - bool prev, any; - - BUG_ON(!rfkill); - - spin_lock_irqsave(&rfkill->lock, flags); - prev = !!(rfkill->state & RFKILL_BLOCK_HW); - if (blocked) - rfkill->state |= RFKILL_BLOCK_HW; - else - rfkill->state &= ~RFKILL_BLOCK_HW; - *change = prev != blocked; - any = rfkill->state & RFKILL_BLOCK_ANY; - spin_unlock_irqrestore(&rfkill->lock, flags); - - rfkill_led_trigger_event(rfkill); - - return any; -} - -/** - * rfkill_set_block - wrapper for set_block method - * - * @rfkill: the rfkill struct to use - * @blocked: the new software state - * - * Calls the set_block method (when applicable) and handles notifications - * etc. as well. - */ -static void rfkill_set_block(struct rfkill *rfkill, bool blocked) -{ - unsigned long flags; - int err; - - /* - * Some platforms (...!) generate input events which affect the - * _hard_ kill state -- whenever something tries to change the - * current software state query the hardware state too. - */ - if (rfkill->ops->query) - rfkill->ops->query(rfkill, rfkill->data); - - spin_lock_irqsave(&rfkill->lock, flags); - if (rfkill->state & RFKILL_BLOCK_SW) - rfkill->state |= RFKILL_BLOCK_SW_PREV; - else - rfkill->state &= ~RFKILL_BLOCK_SW_PREV; - - if (blocked) - rfkill->state |= RFKILL_BLOCK_SW; - else - rfkill->state &= ~RFKILL_BLOCK_SW; - - rfkill->state |= RFKILL_BLOCK_SW_SETCALL; - spin_unlock_irqrestore(&rfkill->lock, flags); - - if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP)) - return; - - err = rfkill->ops->set_block(rfkill->data, blocked); - - spin_lock_irqsave(&rfkill->lock, flags); - if (err) { - /* - * Failed -- reset status to _prev, this may be different - * from what set set _PREV to earlier in this function - * if rfkill_set_sw_state was invoked. - */ - if (rfkill->state & RFKILL_BLOCK_SW_PREV) - rfkill->state |= RFKILL_BLOCK_SW; - else - rfkill->state &= ~RFKILL_BLOCK_SW; - } - rfkill->state &= ~RFKILL_BLOCK_SW_SETCALL; - rfkill->state &= ~RFKILL_BLOCK_SW_PREV; - spin_unlock_irqrestore(&rfkill->lock, flags); - - rfkill_led_trigger_event(rfkill); - rfkill_event(rfkill); -} - -#ifdef CONFIG_RFKILL_INPUT -static atomic_t rfkill_input_disabled = ATOMIC_INIT(0); - -/** - * __rfkill_switch_all - Toggle state of all switches of given type - * @type: type of interfaces to be affected - * @state: the new state - * - * This function sets the state of all switches of given type, - * unless a specific switch is claimed by userspace (in which case, - * that switch is left alone) or suspended. - * - * Caller must have acquired rfkill_global_mutex. - */ -static void __rfkill_switch_all(const enum rfkill_type type, bool blocked) -{ - struct rfkill *rfkill; - - rfkill_global_states[type].cur = blocked; - list_for_each_entry(rfkill, &rfkill_list, node) { - if (rfkill->type != type) - continue; - - rfkill_set_block(rfkill, blocked); - } -} - -/** - * rfkill_switch_all - Toggle state of all switches of given type - * @type: type of interfaces to be affected - * @state: the new state - * - * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state). - * Please refer to __rfkill_switch_all() for details. - * - * Does nothing if the EPO lock is active. - */ -void rfkill_switch_all(enum rfkill_type type, bool blocked) -{ - if (atomic_read(&rfkill_input_disabled)) - return; - - mutex_lock(&rfkill_global_mutex); - - if (!rfkill_epo_lock_active) - __rfkill_switch_all(type, blocked); - - mutex_unlock(&rfkill_global_mutex); -} - -/** - * rfkill_epo - emergency power off all transmitters - * - * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED, - * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex. - * - * The global state before the EPO is saved and can be restored later - * using rfkill_restore_states(). - */ -void rfkill_epo(void) -{ - struct rfkill *rfkill; - int i; - - if (atomic_read(&rfkill_input_disabled)) - return; - - mutex_lock(&rfkill_global_mutex); - - rfkill_epo_lock_active = true; - list_for_each_entry(rfkill, &rfkill_list, node) - rfkill_set_block(rfkill, true); - - for (i = 0; i < NUM_RFKILL_TYPES; i++) { - rfkill_global_states[i].sav = rfkill_global_states[i].cur; - rfkill_global_states[i].cur = true; - } - - mutex_unlock(&rfkill_global_mutex); -} - -/** - * rfkill_restore_states - restore global states - * - * Restore (and sync switches to) the global state from the - * states in rfkill_default_states. This can undo the effects of - * a call to rfkill_epo(). - */ -void rfkill_restore_states(void) -{ - int i; - - if (atomic_read(&rfkill_input_disabled)) - return; - - mutex_lock(&rfkill_global_mutex); - - rfkill_epo_lock_active = false; - for (i = 0; i < NUM_RFKILL_TYPES; i++) - __rfkill_switch_all(i, rfkill_global_states[i].sav); - mutex_unlock(&rfkill_global_mutex); -} - -/** - * rfkill_remove_epo_lock - unlock state changes - * - * Used by rfkill-input manually unlock state changes, when - * the EPO switch is deactivated. - */ -void rfkill_remove_epo_lock(void) -{ - if (atomic_read(&rfkill_input_disabled)) - return; - - mutex_lock(&rfkill_global_mutex); - rfkill_epo_lock_active = false; - mutex_unlock(&rfkill_global_mutex); -} - -/** - * rfkill_is_epo_lock_active - returns true EPO is active - * - * Returns 0 (false) if there is NOT an active EPO contidion, - * and 1 (true) if there is an active EPO contition, which - * locks all radios in one of the BLOCKED states. - * - * Can be called in atomic context. - */ -bool rfkill_is_epo_lock_active(void) -{ - return rfkill_epo_lock_active; -} - -/** - * rfkill_get_global_sw_state - returns global state for a type - * @type: the type to get the global state of - * - * Returns the current global state for a given wireless - * device type. - */ -bool rfkill_get_global_sw_state(const enum rfkill_type type) -{ - return rfkill_global_states[type].cur; -} -#endif - - -bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) -{ - bool ret, change; - - ret = __rfkill_set_hw_state(rfkill, blocked, &change); - - if (!rfkill->registered) - return ret; - - if (change) - schedule_work(&rfkill->uevent_work); - - return ret; -} -EXPORT_SYMBOL(rfkill_set_hw_state); - -static void __rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) -{ - u32 bit = RFKILL_BLOCK_SW; - - /* if in a ops->set_block right now, use other bit */ - if (rfkill->state & RFKILL_BLOCK_SW_SETCALL) - bit = RFKILL_BLOCK_SW_PREV; - - if (blocked) - rfkill->state |= bit; - else - rfkill->state &= ~bit; -} - -bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) -{ - unsigned long flags; - bool prev, hwblock; - - BUG_ON(!rfkill); - - spin_lock_irqsave(&rfkill->lock, flags); - prev = !!(rfkill->state & RFKILL_BLOCK_SW); - __rfkill_set_sw_state(rfkill, blocked); - hwblock = !!(rfkill->state & RFKILL_BLOCK_HW); - blocked = blocked || hwblock; - spin_unlock_irqrestore(&rfkill->lock, flags); - - if (!rfkill->registered) { - rfkill->persistent = true; - } else { - if (prev != blocked && !hwblock) - schedule_work(&rfkill->uevent_work); - - rfkill_led_trigger_event(rfkill); - } - - return blocked; -} -EXPORT_SYMBOL(rfkill_set_sw_state); - -void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) -{ - unsigned long flags; - bool swprev, hwprev; - - BUG_ON(!rfkill); - - spin_lock_irqsave(&rfkill->lock, flags); - - /* - * No need to care about prev/setblock ... this is for uevent only - * and that will get triggered by rfkill_set_block anyway. - */ - swprev = !!(rfkill->state & RFKILL_BLOCK_SW); - hwprev = !!(rfkill->state & RFKILL_BLOCK_HW); - __rfkill_set_sw_state(rfkill, sw); - - spin_unlock_irqrestore(&rfkill->lock, flags); - - if (!rfkill->registered) { - rfkill->persistent = true; - } else { - if (swprev != sw || hwprev != hw) - schedule_work(&rfkill->uevent_work); - - rfkill_led_trigger_event(rfkill); - } -} -EXPORT_SYMBOL(rfkill_set_states); - -static ssize_t rfkill_name_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct rfkill *rfkill = to_rfkill(dev); - - return sprintf(buf, "%s\n", rfkill->name); -} - -static const char *rfkill_get_type_str(enum rfkill_type type) -{ - switch (type) { - case RFKILL_TYPE_WLAN: - return "wlan"; - case RFKILL_TYPE_BLUETOOTH: - return "bluetooth"; - case RFKILL_TYPE_UWB: - return "ultrawideband"; - case RFKILL_TYPE_WIMAX: - return "wimax"; - case RFKILL_TYPE_WWAN: - return "wwan"; - default: - BUG(); - } - - BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1); -} - -static ssize_t rfkill_type_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct rfkill *rfkill = to_rfkill(dev); - - return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type)); -} - -static ssize_t rfkill_idx_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct rfkill *rfkill = to_rfkill(dev); - - return sprintf(buf, "%d\n", rfkill->idx); -} - -static u8 user_state_from_blocked(unsigned long state) -{ - if (state & RFKILL_BLOCK_HW) - return RFKILL_USER_STATE_HARD_BLOCKED; - if (state & RFKILL_BLOCK_SW) - return RFKILL_USER_STATE_SOFT_BLOCKED; - - return RFKILL_USER_STATE_UNBLOCKED; -} - -static ssize_t rfkill_state_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct rfkill *rfkill = to_rfkill(dev); - unsigned long flags; - u32 state; - - spin_lock_irqsave(&rfkill->lock, flags); - state = rfkill->state; - spin_unlock_irqrestore(&rfkill->lock, flags); - - return sprintf(buf, "%d\n", user_state_from_blocked(state)); -} - -static ssize_t rfkill_state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - /* - * The intention was that userspace can only take control over - * a given device when/if rfkill-input doesn't control it due - * to user_claim. Since user_claim is currently unsupported, - * we never support changing the state from userspace -- this - * can be implemented again later. - */ - - return -EPERM; -} - -static ssize_t rfkill_claim_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%d\n", 0); -} - -static ssize_t rfkill_claim_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - return -EOPNOTSUPP; -} - -static struct device_attribute rfkill_dev_attrs[] = { - __ATTR(name, S_IRUGO, rfkill_name_show, NULL), - __ATTR(type, S_IRUGO, rfkill_type_show, NULL), - __ATTR(index, S_IRUGO, rfkill_idx_show, NULL), - __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), - __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), - __ATTR_NULL -}; - -static void rfkill_release(struct device *dev) -{ - struct rfkill *rfkill = to_rfkill(dev); - - kfree(rfkill); -} - -static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct rfkill *rfkill = to_rfkill(dev); - unsigned long flags; - u32 state; - int error; - - error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name); - if (error) - return error; - error = add_uevent_var(env, "RFKILL_TYPE=%s", - rfkill_get_type_str(rfkill->type)); - if (error) - return error; - spin_lock_irqsave(&rfkill->lock, flags); - state = rfkill->state; - spin_unlock_irqrestore(&rfkill->lock, flags); - error = add_uevent_var(env, "RFKILL_STATE=%d", - user_state_from_blocked(state)); - return error; -} - -void rfkill_pause_polling(struct rfkill *rfkill) -{ - BUG_ON(!rfkill); - - if (!rfkill->ops->poll) - return; - - cancel_delayed_work_sync(&rfkill->poll_work); -} -EXPORT_SYMBOL(rfkill_pause_polling); - -void rfkill_resume_polling(struct rfkill *rfkill) -{ - BUG_ON(!rfkill); - - if (!rfkill->ops->poll) - return; - - schedule_work(&rfkill->poll_work.work); -} -EXPORT_SYMBOL(rfkill_resume_polling); - -static int rfkill_suspend(struct device *dev, pm_message_t state) -{ - struct rfkill *rfkill = to_rfkill(dev); - - rfkill_pause_polling(rfkill); - - rfkill->suspended = true; - - return 0; -} - -static int rfkill_resume(struct device *dev) -{ - struct rfkill *rfkill = to_rfkill(dev); - bool cur; - - cur = !!(rfkill->state & RFKILL_BLOCK_SW); - rfkill_set_block(rfkill, cur); - - rfkill->suspended = false; - - rfkill_resume_polling(rfkill); - - return 0; -} - -static struct class rfkill_class = { - .name = "rfkill", - .dev_release = rfkill_release, - .dev_attrs = rfkill_dev_attrs, - .dev_uevent = rfkill_dev_uevent, - .suspend = rfkill_suspend, - .resume = rfkill_resume, -}; - -bool rfkill_blocked(struct rfkill *rfkill) -{ - unsigned long flags; - u32 state; - - spin_lock_irqsave(&rfkill->lock, flags); - state = rfkill->state; - spin_unlock_irqrestore(&rfkill->lock, flags); - - return !!(state & RFKILL_BLOCK_ANY); -} -EXPORT_SYMBOL(rfkill_blocked); - - -struct rfkill * __must_check rfkill_alloc(const char *name, - struct device *parent, - const enum rfkill_type type, - const struct rfkill_ops *ops, - void *ops_data) -{ - struct rfkill *rfkill; - struct device *dev; - - if (WARN_ON(!ops)) - return NULL; - - if (WARN_ON(!ops->set_block)) - return NULL; - - if (WARN_ON(!name)) - return NULL; - - if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES)) - return NULL; - - rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL); - if (!rfkill) - return NULL; - - spin_lock_init(&rfkill->lock); - INIT_LIST_HEAD(&rfkill->node); - rfkill->type = type; - rfkill->name = name; - rfkill->ops = ops; - rfkill->data = ops_data; - - dev = &rfkill->dev; - dev->class = &rfkill_class; - dev->parent = parent; - device_initialize(dev); - - return rfkill; -} -EXPORT_SYMBOL(rfkill_alloc); - -static void rfkill_poll(struct work_struct *work) -{ - struct rfkill *rfkill; - - rfkill = container_of(work, struct rfkill, poll_work.work); - - /* - * Poll hardware state -- driver will use one of the - * rfkill_set{,_hw,_sw}_state functions and use its - * return value to update the current status. - */ - rfkill->ops->poll(rfkill, rfkill->data); - - schedule_delayed_work(&rfkill->poll_work, - round_jiffies_relative(POLL_INTERVAL)); -} - -static void rfkill_uevent_work(struct work_struct *work) -{ - struct rfkill *rfkill; - - rfkill = container_of(work, struct rfkill, uevent_work); - - mutex_lock(&rfkill_global_mutex); - rfkill_event(rfkill); - mutex_unlock(&rfkill_global_mutex); -} - -static void rfkill_sync_work(struct work_struct *work) -{ - struct rfkill *rfkill; - bool cur; - - rfkill = container_of(work, struct rfkill, sync_work); - - mutex_lock(&rfkill_global_mutex); - cur = rfkill_global_states[rfkill->type].cur; - rfkill_set_block(rfkill, cur); - mutex_unlock(&rfkill_global_mutex); -} - -int __must_check rfkill_register(struct rfkill *rfkill) -{ - static unsigned long rfkill_no; - struct device *dev = &rfkill->dev; - int error; - - BUG_ON(!rfkill); - - mutex_lock(&rfkill_global_mutex); - - if (rfkill->registered) { - error = -EALREADY; - goto unlock; - } - - rfkill->idx = rfkill_no; - dev_set_name(dev, "rfkill%lu", rfkill_no); - rfkill_no++; - - list_add_tail(&rfkill->node, &rfkill_list); - - error = device_add(dev); - if (error) - goto remove; - - error = rfkill_led_trigger_register(rfkill); - if (error) - goto devdel; - - rfkill->registered = true; - - INIT_DELAYED_WORK(&rfkill->poll_work, rfkill_poll); - INIT_WORK(&rfkill->uevent_work, rfkill_uevent_work); - INIT_WORK(&rfkill->sync_work, rfkill_sync_work); - - if (rfkill->ops->poll) - schedule_delayed_work(&rfkill->poll_work, - round_jiffies_relative(POLL_INTERVAL)); - - if (!rfkill->persistent || rfkill_epo_lock_active) { - schedule_work(&rfkill->sync_work); - } else { -#ifdef CONFIG_RFKILL_INPUT - bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW); - - if (!atomic_read(&rfkill_input_disabled)) - __rfkill_switch_all(rfkill->type, soft_blocked); -#endif - } - - rfkill_send_events(rfkill, RFKILL_OP_ADD); - - mutex_unlock(&rfkill_global_mutex); - return 0; - - devdel: - device_del(&rfkill->dev); - remove: - list_del_init(&rfkill->node); - unlock: - mutex_unlock(&rfkill_global_mutex); - return error; -} -EXPORT_SYMBOL(rfkill_register); - -void rfkill_unregister(struct rfkill *rfkill) -{ - BUG_ON(!rfkill); - - if (rfkill->ops->poll) - cancel_delayed_work_sync(&rfkill->poll_work); - - cancel_work_sync(&rfkill->uevent_work); - cancel_work_sync(&rfkill->sync_work); - - rfkill->registered = false; - - device_del(&rfkill->dev); - - mutex_lock(&rfkill_global_mutex); - rfkill_send_events(rfkill, RFKILL_OP_DEL); - list_del_init(&rfkill->node); - mutex_unlock(&rfkill_global_mutex); - - rfkill_led_trigger_unregister(rfkill); -} -EXPORT_SYMBOL(rfkill_unregister); - -void rfkill_destroy(struct rfkill *rfkill) -{ - if (rfkill) - put_device(&rfkill->dev); -} -EXPORT_SYMBOL(rfkill_destroy); - -static int rfkill_fop_open(struct inode *inode, struct file *file) -{ - struct rfkill_data *data; - struct rfkill *rfkill; - struct rfkill_int_event *ev, *tmp; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - INIT_LIST_HEAD(&data->events); - mutex_init(&data->mtx); - init_waitqueue_head(&data->read_wait); - - mutex_lock(&rfkill_global_mutex); - mutex_lock(&data->mtx); - /* - * start getting events from elsewhere but hold mtx to get - * startup events added first - */ - list_add(&data->list, &rfkill_fds); - - list_for_each_entry(rfkill, &rfkill_list, node) { - ev = kzalloc(sizeof(*ev), GFP_KERNEL); - if (!ev) - goto free; - rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD); - list_add_tail(&ev->list, &data->events); - } - mutex_unlock(&data->mtx); - mutex_unlock(&rfkill_global_mutex); - - file->private_data = data; - - return nonseekable_open(inode, file); - - free: - mutex_unlock(&data->mtx); - mutex_unlock(&rfkill_global_mutex); - mutex_destroy(&data->mtx); - list_for_each_entry_safe(ev, tmp, &data->events, list) - kfree(ev); - kfree(data); - return -ENOMEM; -} - -static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait) -{ - struct rfkill_data *data = file->private_data; - unsigned int res = POLLOUT | POLLWRNORM; - - poll_wait(file, &data->read_wait, wait); - - mutex_lock(&data->mtx); - if (!list_empty(&data->events)) - res = POLLIN | POLLRDNORM; - mutex_unlock(&data->mtx); - - return res; -} - -static bool rfkill_readable(struct rfkill_data *data) -{ - bool r; - - mutex_lock(&data->mtx); - r = !list_empty(&data->events); - mutex_unlock(&data->mtx); - - return r; -} - -static ssize_t rfkill_fop_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) -{ - struct rfkill_data *data = file->private_data; - struct rfkill_int_event *ev; - unsigned long sz; - int ret; - - mutex_lock(&data->mtx); - - while (list_empty(&data->events)) { - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - goto out; - } - mutex_unlock(&data->mtx); - ret = wait_event_interruptible(data->read_wait, - rfkill_readable(data)); - mutex_lock(&data->mtx); - - if (ret) - goto out; - } - - ev = list_first_entry(&data->events, struct rfkill_int_event, - list); - - sz = min_t(unsigned long, sizeof(ev->ev), count); - ret = sz; - if (copy_to_user(buf, &ev->ev, sz)) - ret = -EFAULT; - - list_del(&ev->list); - kfree(ev); - out: - mutex_unlock(&data->mtx); - return ret; -} - -static ssize_t rfkill_fop_write(struct file *file, const char __user *buf, - size_t count, loff_t *pos) -{ - struct rfkill *rfkill; - struct rfkill_event ev; - - /* we don't need the 'hard' variable but accept it */ - if (count < sizeof(ev) - 1) - return -EINVAL; - - if (copy_from_user(&ev, buf, sizeof(ev) - 1)) - return -EFAULT; - - if (ev.op != RFKILL_OP_CHANGE && ev.op != RFKILL_OP_CHANGE_ALL) - return -EINVAL; - - if (ev.type >= NUM_RFKILL_TYPES) - return -EINVAL; - - mutex_lock(&rfkill_global_mutex); - - if (ev.op == RFKILL_OP_CHANGE_ALL) { - if (ev.type == RFKILL_TYPE_ALL) { - enum rfkill_type i; - for (i = 0; i < NUM_RFKILL_TYPES; i++) - rfkill_global_states[i].cur = ev.soft; - } else { - rfkill_global_states[ev.type].cur = ev.soft; - } - } - - list_for_each_entry(rfkill, &rfkill_list, node) { - if (rfkill->idx != ev.idx && ev.op != RFKILL_OP_CHANGE_ALL) - continue; - - if (rfkill->type != ev.type && ev.type != RFKILL_TYPE_ALL) - continue; - - rfkill_set_block(rfkill, ev.soft); - } - mutex_unlock(&rfkill_global_mutex); - - return count; -} - -static int rfkill_fop_release(struct inode *inode, struct file *file) -{ - struct rfkill_data *data = file->private_data; - struct rfkill_int_event *ev, *tmp; - - mutex_lock(&rfkill_global_mutex); - list_del(&data->list); - mutex_unlock(&rfkill_global_mutex); - - mutex_destroy(&data->mtx); - list_for_each_entry_safe(ev, tmp, &data->events, list) - kfree(ev); - -#ifdef CONFIG_RFKILL_INPUT - if (data->input_handler) - if (atomic_dec_return(&rfkill_input_disabled) == 0) - printk(KERN_DEBUG "rfkill: input handler enabled\n"); -#endif - - kfree(data); - - return 0; -} - -#ifdef CONFIG_RFKILL_INPUT -static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct rfkill_data *data = file->private_data; - - if (_IOC_TYPE(cmd) != RFKILL_IOC_MAGIC) - return -ENOSYS; - - if (_IOC_NR(cmd) != RFKILL_IOC_NOINPUT) - return -ENOSYS; - - mutex_lock(&data->mtx); - - if (!data->input_handler) { - if (atomic_inc_return(&rfkill_input_disabled) == 1) - printk(KERN_DEBUG "rfkill: input handler disabled\n"); - data->input_handler = true; - } - - mutex_unlock(&data->mtx); - - return 0; -} -#endif - -static const struct file_operations rfkill_fops = { - .open = rfkill_fop_open, - .read = rfkill_fop_read, - .write = rfkill_fop_write, - .poll = rfkill_fop_poll, - .release = rfkill_fop_release, -#ifdef CONFIG_RFKILL_INPUT - .unlocked_ioctl = rfkill_fop_ioctl, - .compat_ioctl = rfkill_fop_ioctl, -#endif -}; - -static struct miscdevice rfkill_miscdev = { - .name = "rfkill", - .fops = &rfkill_fops, - .minor = MISC_DYNAMIC_MINOR, -}; - -static int __init rfkill_init(void) -{ - int error; - int i; - - for (i = 0; i < NUM_RFKILL_TYPES; i++) - rfkill_global_states[i].cur = !rfkill_default_state; - - error = class_register(&rfkill_class); - if (error) - goto out; - - error = misc_register(&rfkill_miscdev); - if (error) { - class_unregister(&rfkill_class); - goto out; - } - -#ifdef CONFIG_RFKILL_INPUT - error = rfkill_handler_init(); - if (error) { - misc_deregister(&rfkill_miscdev); - class_unregister(&rfkill_class); - goto out; - } -#endif - - out: - return error; -} -subsys_initcall(rfkill_init); - -static void __exit rfkill_exit(void) -{ -#ifdef CONFIG_RFKILL_INPUT - rfkill_handler_exit(); -#endif - misc_deregister(&rfkill_miscdev); - class_unregister(&rfkill_class); -} -module_exit(rfkill_exit); diff --git a/trunk/net/rfkill/input.c b/trunk/net/rfkill/input.c deleted file mode 100644 index a7295ad5f9cb..000000000000 --- a/trunk/net/rfkill/input.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Input layer to RF Kill interface connector - * - * Copyright (c) 2007 Dmitry Torokhov - * Copyright 2009 Johannes Berg - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * If you ever run into a situation in which you have a SW_ type rfkill - * input device, then you can revive code that was removed in the patch - * "rfkill-input: remove unused code". - */ - -#include -#include -#include -#include -#include -#include - -#include "rfkill.h" - -enum rfkill_input_master_mode { - RFKILL_INPUT_MASTER_UNLOCK = 0, - RFKILL_INPUT_MASTER_RESTORE = 1, - RFKILL_INPUT_MASTER_UNBLOCKALL = 2, - NUM_RFKILL_INPUT_MASTER_MODES -}; - -/* Delay (in ms) between consecutive switch ops */ -#define RFKILL_OPS_DELAY 200 - -static enum rfkill_input_master_mode rfkill_master_switch_mode = - RFKILL_INPUT_MASTER_UNBLOCKALL; -module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0); -MODULE_PARM_DESC(master_switch_mode, - "SW_RFKILL_ALL ON should: 0=do nothing (only unlock); 1=restore; 2=unblock all"); - -static spinlock_t rfkill_op_lock; -static bool rfkill_op_pending; -static unsigned long rfkill_sw_pending[BITS_TO_LONGS(NUM_RFKILL_TYPES)]; -static unsigned long rfkill_sw_state[BITS_TO_LONGS(NUM_RFKILL_TYPES)]; - -enum rfkill_sched_op { - RFKILL_GLOBAL_OP_EPO = 0, - RFKILL_GLOBAL_OP_RESTORE, - RFKILL_GLOBAL_OP_UNLOCK, - RFKILL_GLOBAL_OP_UNBLOCK, -}; - -static enum rfkill_sched_op rfkill_master_switch_op; -static enum rfkill_sched_op rfkill_op; - -static void __rfkill_handle_global_op(enum rfkill_sched_op op) -{ - unsigned int i; - - switch (op) { - case RFKILL_GLOBAL_OP_EPO: - rfkill_epo(); - break; - case RFKILL_GLOBAL_OP_RESTORE: - rfkill_restore_states(); - break; - case RFKILL_GLOBAL_OP_UNLOCK: - rfkill_remove_epo_lock(); - break; - case RFKILL_GLOBAL_OP_UNBLOCK: - rfkill_remove_epo_lock(); - for (i = 0; i < NUM_RFKILL_TYPES; i++) - rfkill_switch_all(i, false); - break; - default: - /* memory corruption or bug, fail safely */ - rfkill_epo(); - WARN(1, "Unknown requested operation %d! " - "rfkill Emergency Power Off activated\n", - op); - } -} - -static void __rfkill_handle_normal_op(const enum rfkill_type type, - const bool complement) -{ - bool blocked; - - blocked = rfkill_get_global_sw_state(type); - if (complement) - blocked = !blocked; - - rfkill_switch_all(type, blocked); -} - -static void rfkill_op_handler(struct work_struct *work) -{ - unsigned int i; - bool c; - - spin_lock_irq(&rfkill_op_lock); - do { - if (rfkill_op_pending) { - enum rfkill_sched_op op = rfkill_op; - rfkill_op_pending = false; - memset(rfkill_sw_pending, 0, - sizeof(rfkill_sw_pending)); - spin_unlock_irq(&rfkill_op_lock); - - __rfkill_handle_global_op(op); - - spin_lock_irq(&rfkill_op_lock); - - /* - * handle global ops first -- during unlocked period - * we might have gotten a new global op. - */ - if (rfkill_op_pending) - continue; - } - - if (rfkill_is_epo_lock_active()) - continue; - - for (i = 0; i < NUM_RFKILL_TYPES; i++) { - if (__test_and_clear_bit(i, rfkill_sw_pending)) { - c = __test_and_clear_bit(i, rfkill_sw_state); - spin_unlock_irq(&rfkill_op_lock); - - __rfkill_handle_normal_op(i, c); - - spin_lock_irq(&rfkill_op_lock); - } - } - } while (rfkill_op_pending); - spin_unlock_irq(&rfkill_op_lock); -} - -static DECLARE_DELAYED_WORK(rfkill_op_work, rfkill_op_handler); -static unsigned long rfkill_last_scheduled; - -static unsigned long rfkill_ratelimit(const unsigned long last) -{ - const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY); - return (time_after(jiffies, last + delay)) ? 0 : delay; -} - -static void rfkill_schedule_ratelimited(void) -{ - if (delayed_work_pending(&rfkill_op_work)) - return; - schedule_delayed_work(&rfkill_op_work, - rfkill_ratelimit(rfkill_last_scheduled)); - rfkill_last_scheduled = jiffies; -} - -static void rfkill_schedule_global_op(enum rfkill_sched_op op) -{ - unsigned long flags; - - spin_lock_irqsave(&rfkill_op_lock, flags); - rfkill_op = op; - rfkill_op_pending = true; - if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) { - /* bypass the limiter for EPO */ - cancel_delayed_work(&rfkill_op_work); - schedule_delayed_work(&rfkill_op_work, 0); - rfkill_last_scheduled = jiffies; - } else - rfkill_schedule_ratelimited(); - spin_unlock_irqrestore(&rfkill_op_lock, flags); -} - -static void rfkill_schedule_toggle(enum rfkill_type type) -{ - unsigned long flags; - - if (rfkill_is_epo_lock_active()) - return; - - spin_lock_irqsave(&rfkill_op_lock, flags); - if (!rfkill_op_pending) { - __set_bit(type, rfkill_sw_pending); - __change_bit(type, rfkill_sw_state); - rfkill_schedule_ratelimited(); - } - spin_unlock_irqrestore(&rfkill_op_lock, flags); -} - -static void rfkill_schedule_evsw_rfkillall(int state) -{ - if (state) - rfkill_schedule_global_op(rfkill_master_switch_op); - else - rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO); -} - -static void rfkill_event(struct input_handle *handle, unsigned int type, - unsigned int code, int data) -{ - if (type == EV_KEY && data == 1) { - switch (code) { - case KEY_WLAN: - rfkill_schedule_toggle(RFKILL_TYPE_WLAN); - break; - case KEY_BLUETOOTH: - rfkill_schedule_toggle(RFKILL_TYPE_BLUETOOTH); - break; - case KEY_UWB: - rfkill_schedule_toggle(RFKILL_TYPE_UWB); - break; - case KEY_WIMAX: - rfkill_schedule_toggle(RFKILL_TYPE_WIMAX); - break; - } - } else if (type == EV_SW && code == SW_RFKILL_ALL) - rfkill_schedule_evsw_rfkillall(data); -} - -static int rfkill_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "rfkill"; - - /* causes rfkill_start() to be called */ - error = input_register_handle(handle); - if (error) - goto err_free_handle; - - error = input_open_device(handle); - if (error) - goto err_unregister_handle; - - return 0; - - err_unregister_handle: - input_unregister_handle(handle); - err_free_handle: - kfree(handle); - return error; -} - -static void rfkill_start(struct input_handle *handle) -{ - /* - * Take event_lock to guard against configuration changes, we - * should be able to deal with concurrency with rfkill_event() - * just fine (which event_lock will also avoid). - */ - spin_lock_irq(&handle->dev->event_lock); - - if (test_bit(EV_SW, handle->dev->evbit) && - test_bit(SW_RFKILL_ALL, handle->dev->swbit)) - rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL, - handle->dev->sw)); - - spin_unlock_irq(&handle->dev->event_lock); -} - -static void rfkill_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id rfkill_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) }, - }, - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) }, - }, - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) }, - }, - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, - }, - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT, - .evbit = { BIT(EV_SW) }, - .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) }, - }, - { } -}; - -static struct input_handler rfkill_handler = { - .name = "rfkill", - .event = rfkill_event, - .connect = rfkill_connect, - .start = rfkill_start, - .disconnect = rfkill_disconnect, - .id_table = rfkill_ids, -}; - -int __init rfkill_handler_init(void) -{ - switch (rfkill_master_switch_mode) { - case RFKILL_INPUT_MASTER_UNBLOCKALL: - rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNBLOCK; - break; - case RFKILL_INPUT_MASTER_RESTORE: - rfkill_master_switch_op = RFKILL_GLOBAL_OP_RESTORE; - break; - case RFKILL_INPUT_MASTER_UNLOCK: - rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNLOCK; - break; - default: - return -EINVAL; - } - - spin_lock_init(&rfkill_op_lock); - - /* Avoid delay at first schedule */ - rfkill_last_scheduled = - jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1; - return input_register_handler(&rfkill_handler); -} - -void __exit rfkill_handler_exit(void) -{ - input_unregister_handler(&rfkill_handler); - cancel_delayed_work_sync(&rfkill_op_work); -} diff --git a/trunk/net/rfkill/rfkill-input.c b/trunk/net/rfkill/rfkill-input.c new file mode 100644 index 000000000000..60a34f3b5f65 --- /dev/null +++ b/trunk/net/rfkill/rfkill-input.c @@ -0,0 +1,390 @@ +/* + * Input layer to RF Kill interface connector + * + * Copyright (c) 2007 Dmitry Torokhov + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rfkill-input.h" + +MODULE_AUTHOR("Dmitry Torokhov "); +MODULE_DESCRIPTION("Input layer to RF switch connector"); +MODULE_LICENSE("GPL"); + +enum rfkill_input_master_mode { + RFKILL_INPUT_MASTER_DONOTHING = 0, + RFKILL_INPUT_MASTER_RESTORE = 1, + RFKILL_INPUT_MASTER_UNBLOCKALL = 2, + RFKILL_INPUT_MASTER_MAX, /* marker */ +}; + +/* Delay (in ms) between consecutive switch ops */ +#define RFKILL_OPS_DELAY 200 + +static enum rfkill_input_master_mode rfkill_master_switch_mode = + RFKILL_INPUT_MASTER_UNBLOCKALL; +module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0); +MODULE_PARM_DESC(master_switch_mode, + "SW_RFKILL_ALL ON should: 0=do nothing; 1=restore; 2=unblock all"); + +enum rfkill_global_sched_op { + RFKILL_GLOBAL_OP_EPO = 0, + RFKILL_GLOBAL_OP_RESTORE, + RFKILL_GLOBAL_OP_UNLOCK, + RFKILL_GLOBAL_OP_UNBLOCK, +}; + +struct rfkill_task { + struct delayed_work dwork; + + /* ensures that task is serialized */ + struct mutex mutex; + + /* protects everything below */ + spinlock_t lock; + + /* pending regular switch operations (1=pending) */ + unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; + + /* should the state be complemented (1=yes) */ + unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; + + bool global_op_pending; + enum rfkill_global_sched_op op; + + /* last time it was scheduled */ + unsigned long last_scheduled; +}; + +static void __rfkill_handle_global_op(enum rfkill_global_sched_op op) +{ + unsigned int i; + + switch (op) { + case RFKILL_GLOBAL_OP_EPO: + rfkill_epo(); + break; + case RFKILL_GLOBAL_OP_RESTORE: + rfkill_restore_states(); + break; + case RFKILL_GLOBAL_OP_UNLOCK: + rfkill_remove_epo_lock(); + break; + case RFKILL_GLOBAL_OP_UNBLOCK: + rfkill_remove_epo_lock(); + for (i = 0; i < RFKILL_TYPE_MAX; i++) + rfkill_switch_all(i, RFKILL_STATE_UNBLOCKED); + break; + default: + /* memory corruption or bug, fail safely */ + rfkill_epo(); + WARN(1, "Unknown requested operation %d! " + "rfkill Emergency Power Off activated\n", + op); + } +} + +static void __rfkill_handle_normal_op(const enum rfkill_type type, + const bool c) +{ + enum rfkill_state state; + + state = rfkill_get_global_state(type); + if (c) + state = rfkill_state_complement(state); + + rfkill_switch_all(type, state); +} + +static void rfkill_task_handler(struct work_struct *work) +{ + struct rfkill_task *task = container_of(work, + struct rfkill_task, dwork.work); + bool doit = true; + + mutex_lock(&task->mutex); + + spin_lock_irq(&task->lock); + while (doit) { + if (task->global_op_pending) { + enum rfkill_global_sched_op op = task->op; + task->global_op_pending = false; + memset(task->sw_pending, 0, sizeof(task->sw_pending)); + spin_unlock_irq(&task->lock); + + __rfkill_handle_global_op(op); + + /* make sure we do at least one pass with + * !task->global_op_pending */ + spin_lock_irq(&task->lock); + continue; + } else if (!rfkill_is_epo_lock_active()) { + unsigned int i = 0; + + while (!task->global_op_pending && + i < RFKILL_TYPE_MAX) { + if (test_and_clear_bit(i, task->sw_pending)) { + bool c; + c = test_and_clear_bit(i, + task->sw_togglestate); + spin_unlock_irq(&task->lock); + + __rfkill_handle_normal_op(i, c); + + spin_lock_irq(&task->lock); + } + i++; + } + } + doit = task->global_op_pending; + } + spin_unlock_irq(&task->lock); + + mutex_unlock(&task->mutex); +} + +static struct rfkill_task rfkill_task = { + .dwork = __DELAYED_WORK_INITIALIZER(rfkill_task.dwork, + rfkill_task_handler), + .mutex = __MUTEX_INITIALIZER(rfkill_task.mutex), + .lock = __SPIN_LOCK_UNLOCKED(rfkill_task.lock), +}; + +static unsigned long rfkill_ratelimit(const unsigned long last) +{ + const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY); + return (time_after(jiffies, last + delay)) ? 0 : delay; +} + +static void rfkill_schedule_ratelimited(void) +{ + if (!delayed_work_pending(&rfkill_task.dwork)) { + schedule_delayed_work(&rfkill_task.dwork, + rfkill_ratelimit(rfkill_task.last_scheduled)); + rfkill_task.last_scheduled = jiffies; + } +} + +static void rfkill_schedule_global_op(enum rfkill_global_sched_op op) +{ + unsigned long flags; + + spin_lock_irqsave(&rfkill_task.lock, flags); + rfkill_task.op = op; + rfkill_task.global_op_pending = true; + if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) { + /* bypass the limiter for EPO */ + cancel_delayed_work(&rfkill_task.dwork); + schedule_delayed_work(&rfkill_task.dwork, 0); + rfkill_task.last_scheduled = jiffies; + } else + rfkill_schedule_ratelimited(); + spin_unlock_irqrestore(&rfkill_task.lock, flags); +} + +static void rfkill_schedule_toggle(enum rfkill_type type) +{ + unsigned long flags; + + if (rfkill_is_epo_lock_active()) + return; + + spin_lock_irqsave(&rfkill_task.lock, flags); + if (!rfkill_task.global_op_pending) { + set_bit(type, rfkill_task.sw_pending); + change_bit(type, rfkill_task.sw_togglestate); + rfkill_schedule_ratelimited(); + } + spin_unlock_irqrestore(&rfkill_task.lock, flags); +} + +static void rfkill_schedule_evsw_rfkillall(int state) +{ + if (state) { + switch (rfkill_master_switch_mode) { + case RFKILL_INPUT_MASTER_UNBLOCKALL: + rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNBLOCK); + break; + case RFKILL_INPUT_MASTER_RESTORE: + rfkill_schedule_global_op(RFKILL_GLOBAL_OP_RESTORE); + break; + case RFKILL_INPUT_MASTER_DONOTHING: + rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNLOCK); + break; + default: + /* memory corruption or driver bug! fail safely */ + rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO); + WARN(1, "Unknown rfkill_master_switch_mode (%d), " + "driver bug or memory corruption detected!\n", + rfkill_master_switch_mode); + break; + } + } else + rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO); +} + +static void rfkill_event(struct input_handle *handle, unsigned int type, + unsigned int code, int data) +{ + if (type == EV_KEY && data == 1) { + enum rfkill_type t; + + switch (code) { + case KEY_WLAN: + t = RFKILL_TYPE_WLAN; + break; + case KEY_BLUETOOTH: + t = RFKILL_TYPE_BLUETOOTH; + break; + case KEY_UWB: + t = RFKILL_TYPE_UWB; + break; + case KEY_WIMAX: + t = RFKILL_TYPE_WIMAX; + break; + default: + return; + } + rfkill_schedule_toggle(t); + return; + } else if (type == EV_SW) { + switch (code) { + case SW_RFKILL_ALL: + rfkill_schedule_evsw_rfkillall(data); + return; + default: + return; + } + } +} + +static int rfkill_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *handle; + int error; + + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + if (!handle) + return -ENOMEM; + + handle->dev = dev; + handle->handler = handler; + handle->name = "rfkill"; + + /* causes rfkill_start() to be called */ + error = input_register_handle(handle); + if (error) + goto err_free_handle; + + error = input_open_device(handle); + if (error) + goto err_unregister_handle; + + return 0; + + err_unregister_handle: + input_unregister_handle(handle); + err_free_handle: + kfree(handle); + return error; +} + +static void rfkill_start(struct input_handle *handle) +{ + /* Take event_lock to guard against configuration changes, we + * should be able to deal with concurrency with rfkill_event() + * just fine (which event_lock will also avoid). */ + spin_lock_irq(&handle->dev->event_lock); + + if (test_bit(EV_SW, handle->dev->evbit)) { + if (test_bit(SW_RFKILL_ALL, handle->dev->swbit)) + rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL, + handle->dev->sw)); + /* add resync for further EV_SW events here */ + } + + spin_unlock_irq(&handle->dev->event_lock); +} + +static void rfkill_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + input_unregister_handle(handle); + kfree(handle); +} + +static const struct input_device_id rfkill_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT, + .evbit = { BIT(EV_SW) }, + .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) }, + }, + { } +}; + +static struct input_handler rfkill_handler = { + .event = rfkill_event, + .connect = rfkill_connect, + .disconnect = rfkill_disconnect, + .start = rfkill_start, + .name = "rfkill", + .id_table = rfkill_ids, +}; + +static int __init rfkill_handler_init(void) +{ + if (rfkill_master_switch_mode >= RFKILL_INPUT_MASTER_MAX) + return -EINVAL; + + /* + * The penalty to not doing this is a possible RFKILL_OPS_DELAY delay + * at the first use. Acceptable, but if we can avoid it, why not? + */ + rfkill_task.last_scheduled = + jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1; + return input_register_handler(&rfkill_handler); +} + +static void __exit rfkill_handler_exit(void) +{ + input_unregister_handler(&rfkill_handler); + cancel_delayed_work_sync(&rfkill_task.dwork); + rfkill_remove_epo_lock(); +} + +module_init(rfkill_handler_init); +module_exit(rfkill_handler_exit); diff --git a/trunk/net/rfkill/rfkill.h b/trunk/net/rfkill/rfkill-input.h similarity index 60% rename from trunk/net/rfkill/rfkill.h rename to trunk/net/rfkill/rfkill-input.h index d1117cb6e4de..fe8df6b5b935 100644 --- a/trunk/net/rfkill/rfkill.h +++ b/trunk/net/rfkill/rfkill-input.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2007 Ivo van Doorn - * Copyright 2009 Johannes Berg */ /* @@ -12,16 +11,11 @@ #ifndef __RFKILL_INPUT_H #define __RFKILL_INPUT_H -/* core code */ -void rfkill_switch_all(const enum rfkill_type type, bool blocked); +void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state); void rfkill_epo(void); void rfkill_restore_states(void); void rfkill_remove_epo_lock(void); bool rfkill_is_epo_lock_active(void); -bool rfkill_get_global_sw_state(const enum rfkill_type type); - -/* input handler */ -int rfkill_handler_init(void); -void rfkill_handler_exit(void); +enum rfkill_state rfkill_get_global_state(const enum rfkill_type type); #endif /* __RFKILL_INPUT_H */ diff --git a/trunk/net/rfkill/rfkill.c b/trunk/net/rfkill/rfkill.c new file mode 100644 index 000000000000..4f5a83183c95 --- /dev/null +++ b/trunk/net/rfkill/rfkill.c @@ -0,0 +1,855 @@ +/* + * Copyright (C) 2006 - 2007 Ivo van Doorn + * Copyright (C) 2007 Dmitry Torokhov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Get declaration of rfkill_switch_all() to shut up sparse. */ +#include "rfkill-input.h" + + +MODULE_AUTHOR("Ivo van Doorn "); +MODULE_VERSION("1.0"); +MODULE_DESCRIPTION("RF switch support"); +MODULE_LICENSE("GPL"); + +static LIST_HEAD(rfkill_list); /* list of registered rf switches */ +static DEFINE_MUTEX(rfkill_global_mutex); + +static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED; +module_param_named(default_state, rfkill_default_state, uint, 0444); +MODULE_PARM_DESC(default_state, + "Default initial state for all radio types, 0 = radio off"); + +struct rfkill_gsw_state { + enum rfkill_state current_state; + enum rfkill_state default_state; +}; + +static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX]; +static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; +static bool rfkill_epo_lock_active; + + +#ifdef CONFIG_RFKILL_LEDS +static void rfkill_led_trigger(struct rfkill *rfkill, + enum rfkill_state state) +{ + struct led_trigger *led = &rfkill->led_trigger; + + if (!led->name) + return; + if (state != RFKILL_STATE_UNBLOCKED) + led_trigger_event(led, LED_OFF); + else + led_trigger_event(led, LED_FULL); +} + +static void rfkill_led_trigger_activate(struct led_classdev *led) +{ + struct rfkill *rfkill = container_of(led->trigger, + struct rfkill, led_trigger); + + rfkill_led_trigger(rfkill, rfkill->state); +} +#else +static inline void rfkill_led_trigger(struct rfkill *rfkill, + enum rfkill_state state) +{ +} +#endif /* CONFIG_RFKILL_LEDS */ + +static void rfkill_uevent(struct rfkill *rfkill) +{ + kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); +} + +static void update_rfkill_state(struct rfkill *rfkill) +{ + enum rfkill_state newstate, oldstate; + + if (rfkill->get_state) { + mutex_lock(&rfkill->mutex); + if (!rfkill->get_state(rfkill->data, &newstate)) { + oldstate = rfkill->state; + rfkill->state = newstate; + if (oldstate != newstate) + rfkill_uevent(rfkill); + } + mutex_unlock(&rfkill->mutex); + } + rfkill_led_trigger(rfkill, rfkill->state); +} + +/** + * rfkill_toggle_radio - wrapper for toggle_radio hook + * @rfkill: the rfkill struct to use + * @force: calls toggle_radio even if cache says it is not needed, + * and also makes sure notifications of the state will be + * sent even if it didn't change + * @state: the new state to call toggle_radio() with + * + * Calls rfkill->toggle_radio, enforcing the API for toggle_radio + * calls and handling all the red tape such as issuing notifications + * if the call is successful. + * + * Suspended devices are not touched at all, and -EAGAIN is returned. + * + * Note that the @force parameter cannot override a (possibly cached) + * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of + * RFKILL_STATE_HARD_BLOCKED implements either get_state() or + * rfkill_force_state(), so the cache either is bypassed or valid. + * + * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED + * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to + * give the driver a hint that it should double-BLOCK the transmitter. + * + * Caller must have acquired rfkill->mutex. + */ +static int rfkill_toggle_radio(struct rfkill *rfkill, + enum rfkill_state state, + int force) +{ + int retval = 0; + enum rfkill_state oldstate, newstate; + + if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP)) + return -EBUSY; + + oldstate = rfkill->state; + + if (rfkill->get_state && !force && + !rfkill->get_state(rfkill->data, &newstate)) { + rfkill->state = newstate; + } + + switch (state) { + case RFKILL_STATE_HARD_BLOCKED: + /* typically happens when refreshing hardware state, + * such as on resume */ + state = RFKILL_STATE_SOFT_BLOCKED; + break; + case RFKILL_STATE_UNBLOCKED: + /* force can't override this, only rfkill_force_state() can */ + if (rfkill->state == RFKILL_STATE_HARD_BLOCKED) + return -EPERM; + break; + case RFKILL_STATE_SOFT_BLOCKED: + /* nothing to do, we want to give drivers the hint to double + * BLOCK even a transmitter that is already in state + * RFKILL_STATE_HARD_BLOCKED */ + break; + default: + WARN(1, KERN_WARNING + "rfkill: illegal state %d passed as parameter " + "to rfkill_toggle_radio\n", state); + return -EINVAL; + } + + if (force || state != rfkill->state) { + retval = rfkill->toggle_radio(rfkill->data, state); + /* never allow a HARD->SOFT downgrade! */ + if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED) + rfkill->state = state; + } + + if (force || rfkill->state != oldstate) + rfkill_uevent(rfkill); + + rfkill_led_trigger(rfkill, rfkill->state); + return retval; +} + +/** + * __rfkill_switch_all - Toggle state of all switches of given type + * @type: type of interfaces to be affected + * @state: the new state + * + * This function toggles the state of all switches of given type, + * unless a specific switch is claimed by userspace (in which case, + * that switch is left alone) or suspended. + * + * Caller must have acquired rfkill_global_mutex. + */ +static void __rfkill_switch_all(const enum rfkill_type type, + const enum rfkill_state state) +{ + struct rfkill *rfkill; + + if (WARN((state >= RFKILL_STATE_MAX || type >= RFKILL_TYPE_MAX), + KERN_WARNING + "rfkill: illegal state %d or type %d " + "passed as parameter to __rfkill_switch_all\n", + state, type)) + return; + + rfkill_global_states[type].current_state = state; + list_for_each_entry(rfkill, &rfkill_list, node) { + if (rfkill->type == type) { + mutex_lock(&rfkill->mutex); + rfkill_toggle_radio(rfkill, state, 0); + mutex_unlock(&rfkill->mutex); + rfkill_led_trigger(rfkill, rfkill->state); + } + } +} + +/** + * rfkill_switch_all - Toggle state of all switches of given type + * @type: type of interfaces to be affected + * @state: the new state + * + * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state). + * Please refer to __rfkill_switch_all() for details. + * + * Does nothing if the EPO lock is active. + */ +void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) +{ + mutex_lock(&rfkill_global_mutex); + if (!rfkill_epo_lock_active) + __rfkill_switch_all(type, state); + mutex_unlock(&rfkill_global_mutex); +} +EXPORT_SYMBOL(rfkill_switch_all); + +/** + * rfkill_epo - emergency power off all transmitters + * + * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED, + * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex. + * + * The global state before the EPO is saved and can be restored later + * using rfkill_restore_states(). + */ +void rfkill_epo(void) +{ + struct rfkill *rfkill; + int i; + + mutex_lock(&rfkill_global_mutex); + + rfkill_epo_lock_active = true; + list_for_each_entry(rfkill, &rfkill_list, node) { + mutex_lock(&rfkill->mutex); + rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); + mutex_unlock(&rfkill->mutex); + } + for (i = 0; i < RFKILL_TYPE_MAX; i++) { + rfkill_global_states[i].default_state = + rfkill_global_states[i].current_state; + rfkill_global_states[i].current_state = + RFKILL_STATE_SOFT_BLOCKED; + } + mutex_unlock(&rfkill_global_mutex); + rfkill_led_trigger(rfkill, rfkill->state); +} +EXPORT_SYMBOL_GPL(rfkill_epo); + +/** + * rfkill_restore_states - restore global states + * + * Restore (and sync switches to) the global state from the + * states in rfkill_default_states. This can undo the effects of + * a call to rfkill_epo(). + */ +void rfkill_restore_states(void) +{ + int i; + + mutex_lock(&rfkill_global_mutex); + + rfkill_epo_lock_active = false; + for (i = 0; i < RFKILL_TYPE_MAX; i++) + __rfkill_switch_all(i, rfkill_global_states[i].default_state); + mutex_unlock(&rfkill_global_mutex); +} +EXPORT_SYMBOL_GPL(rfkill_restore_states); + +/** + * rfkill_remove_epo_lock - unlock state changes + * + * Used by rfkill-input manually unlock state changes, when + * the EPO switch is deactivated. + */ +void rfkill_remove_epo_lock(void) +{ + mutex_lock(&rfkill_global_mutex); + rfkill_epo_lock_active = false; + mutex_unlock(&rfkill_global_mutex); +} +EXPORT_SYMBOL_GPL(rfkill_remove_epo_lock); + +/** + * rfkill_is_epo_lock_active - returns true EPO is active + * + * Returns 0 (false) if there is NOT an active EPO contidion, + * and 1 (true) if there is an active EPO contition, which + * locks all radios in one of the BLOCKED states. + * + * Can be called in atomic context. + */ +bool rfkill_is_epo_lock_active(void) +{ + return rfkill_epo_lock_active; +} +EXPORT_SYMBOL_GPL(rfkill_is_epo_lock_active); + +/** + * rfkill_get_global_state - returns global state for a type + * @type: the type to get the global state of + * + * Returns the current global state for a given wireless + * device type. + */ +enum rfkill_state rfkill_get_global_state(const enum rfkill_type type) +{ + return rfkill_global_states[type].current_state; +} +EXPORT_SYMBOL_GPL(rfkill_get_global_state); + +/** + * rfkill_force_state - Force the internal rfkill radio state + * @rfkill: pointer to the rfkill class to modify. + * @state: the current radio state the class should be forced to. + * + * This function updates the internal state of the radio cached + * by the rfkill class. It should be used when the driver gets + * a notification by the firmware/hardware of the current *real* + * state of the radio rfkill switch. + * + * Devices which are subject to external changes on their rfkill + * state (such as those caused by a hardware rfkill line) MUST + * have their driver arrange to call rfkill_force_state() as soon + * as possible after such a change. + * + * This function may not be called from an atomic context. + */ +int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) +{ + enum rfkill_state oldstate; + + BUG_ON(!rfkill); + if (WARN((state >= RFKILL_STATE_MAX), + KERN_WARNING + "rfkill: illegal state %d passed as parameter " + "to rfkill_force_state\n", state)) + return -EINVAL; + + mutex_lock(&rfkill->mutex); + + oldstate = rfkill->state; + rfkill->state = state; + + if (state != oldstate) + rfkill_uevent(rfkill); + + mutex_unlock(&rfkill->mutex); + rfkill_led_trigger(rfkill, rfkill->state); + + return 0; +} +EXPORT_SYMBOL(rfkill_force_state); + +static ssize_t rfkill_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct rfkill *rfkill = to_rfkill(dev); + + return sprintf(buf, "%s\n", rfkill->name); +} + +static const char *rfkill_get_type_str(enum rfkill_type type) +{ + switch (type) { + case RFKILL_TYPE_WLAN: + return "wlan"; + case RFKILL_TYPE_BLUETOOTH: + return "bluetooth"; + case RFKILL_TYPE_UWB: + return "ultrawideband"; + case RFKILL_TYPE_WIMAX: + return "wimax"; + case RFKILL_TYPE_WWAN: + return "wwan"; + default: + BUG(); + } +} + +static ssize_t rfkill_type_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct rfkill *rfkill = to_rfkill(dev); + + return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type)); +} + +static ssize_t rfkill_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct rfkill *rfkill = to_rfkill(dev); + + update_rfkill_state(rfkill); + return sprintf(buf, "%d\n", rfkill->state); +} + +static ssize_t rfkill_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rfkill *rfkill = to_rfkill(dev); + unsigned long state; + int error; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + error = strict_strtoul(buf, 0, &state); + if (error) + return error; + + /* RFKILL_STATE_HARD_BLOCKED is illegal here... */ + if (state != RFKILL_STATE_UNBLOCKED && + state != RFKILL_STATE_SOFT_BLOCKED) + return -EINVAL; + + error = mutex_lock_killable(&rfkill->mutex); + if (error) + return error; + + if (!rfkill_epo_lock_active) + error = rfkill_toggle_radio(rfkill, state, 0); + else + error = -EPERM; + + mutex_unlock(&rfkill->mutex); + + return error ? error : count; +} + +static ssize_t rfkill_claim_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", 0); +} + +static ssize_t rfkill_claim_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return -EOPNOTSUPP; +} + +static struct device_attribute rfkill_dev_attrs[] = { + __ATTR(name, S_IRUGO, rfkill_name_show, NULL), + __ATTR(type, S_IRUGO, rfkill_type_show, NULL), + __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), + __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), + __ATTR_NULL +}; + +static void rfkill_release(struct device *dev) +{ + struct rfkill *rfkill = to_rfkill(dev); + + kfree(rfkill); + module_put(THIS_MODULE); +} + +#ifdef CONFIG_PM +static int rfkill_suspend(struct device *dev, pm_message_t state) +{ + struct rfkill *rfkill = to_rfkill(dev); + + /* mark class device as suspended */ + if (dev->power.power_state.event != state.event) + dev->power.power_state = state; + + /* store state for the resume handler */ + rfkill->state_for_resume = rfkill->state; + + return 0; +} + +static int rfkill_resume(struct device *dev) +{ + struct rfkill *rfkill = to_rfkill(dev); + enum rfkill_state newstate; + + if (dev->power.power_state.event != PM_EVENT_ON) { + mutex_lock(&rfkill->mutex); + + dev->power.power_state.event = PM_EVENT_ON; + + /* + * rfkill->state could have been modified before we got + * called, and won't be updated by rfkill_toggle_radio() + * in force mode. Sync it FIRST. + */ + if (rfkill->get_state && + !rfkill->get_state(rfkill->data, &newstate)) + rfkill->state = newstate; + + /* + * If we are under EPO, kick transmitter offline, + * otherwise restore to pre-suspend state. + * + * Issue a notification in any case + */ + rfkill_toggle_radio(rfkill, + rfkill_epo_lock_active ? + RFKILL_STATE_SOFT_BLOCKED : + rfkill->state_for_resume, + 1); + + mutex_unlock(&rfkill->mutex); + rfkill_led_trigger(rfkill, rfkill->state); + } + + return 0; +} +#else +#define rfkill_suspend NULL +#define rfkill_resume NULL +#endif + +static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct rfkill *rfkill = to_rfkill(dev); + int error; + + error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name); + if (error) + return error; + error = add_uevent_var(env, "RFKILL_TYPE=%s", + rfkill_get_type_str(rfkill->type)); + if (error) + return error; + error = add_uevent_var(env, "RFKILL_STATE=%d", rfkill->state); + return error; +} + +static struct class rfkill_class = { + .name = "rfkill", + .dev_release = rfkill_release, + .dev_attrs = rfkill_dev_attrs, + .suspend = rfkill_suspend, + .resume = rfkill_resume, + .dev_uevent = rfkill_dev_uevent, +}; + +static int rfkill_check_duplicity(const struct rfkill *rfkill) +{ + struct rfkill *p; + unsigned long seen[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; + + memset(seen, 0, sizeof(seen)); + + list_for_each_entry(p, &rfkill_list, node) { + if (WARN((p == rfkill), KERN_WARNING + "rfkill: illegal attempt to register " + "an already registered rfkill struct\n")) + return -EEXIST; + set_bit(p->type, seen); + } + + /* 0: first switch of its kind */ + return (test_bit(rfkill->type, seen)) ? 1 : 0; +} + +static int rfkill_add_switch(struct rfkill *rfkill) +{ + int error; + + mutex_lock(&rfkill_global_mutex); + + error = rfkill_check_duplicity(rfkill); + if (error < 0) + goto unlock_out; + + if (!error) { + /* lock default after first use */ + set_bit(rfkill->type, rfkill_states_lockdflt); + rfkill_global_states[rfkill->type].current_state = + rfkill_global_states[rfkill->type].default_state; + } + + rfkill_toggle_radio(rfkill, + rfkill_global_states[rfkill->type].current_state, + 0); + + list_add_tail(&rfkill->node, &rfkill_list); + + error = 0; +unlock_out: + mutex_unlock(&rfkill_global_mutex); + + return error; +} + +static void rfkill_remove_switch(struct rfkill *rfkill) +{ + mutex_lock(&rfkill_global_mutex); + list_del_init(&rfkill->node); + mutex_unlock(&rfkill_global_mutex); + + mutex_lock(&rfkill->mutex); + rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); + mutex_unlock(&rfkill->mutex); +} + +/** + * rfkill_allocate - allocate memory for rfkill structure. + * @parent: device that has rf switch on it + * @type: type of the switch (RFKILL_TYPE_*) + * + * This function should be called by the network driver when it needs + * rfkill structure. Once the structure is allocated the driver should + * finish its initialization by setting the name, private data, enable_radio + * and disable_radio methods and then register it with rfkill_register(). + * + * NOTE: If registration fails the structure shoudl be freed by calling + * rfkill_free() otherwise rfkill_unregister() should be used. + */ +struct rfkill * __must_check rfkill_allocate(struct device *parent, + enum rfkill_type type) +{ + struct rfkill *rfkill; + struct device *dev; + + if (WARN((type >= RFKILL_TYPE_MAX), + KERN_WARNING + "rfkill: illegal type %d passed as parameter " + "to rfkill_allocate\n", type)) + return NULL; + + rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL); + if (!rfkill) + return NULL; + + mutex_init(&rfkill->mutex); + INIT_LIST_HEAD(&rfkill->node); + rfkill->type = type; + + dev = &rfkill->dev; + dev->class = &rfkill_class; + dev->parent = parent; + device_initialize(dev); + + __module_get(THIS_MODULE); + + return rfkill; +} +EXPORT_SYMBOL(rfkill_allocate); + +/** + * rfkill_free - Mark rfkill structure for deletion + * @rfkill: rfkill structure to be destroyed + * + * Decrements reference count of the rfkill structure so it is destroyed. + * Note that rfkill_free() should _not_ be called after rfkill_unregister(). + */ +void rfkill_free(struct rfkill *rfkill) +{ + if (rfkill) + put_device(&rfkill->dev); +} +EXPORT_SYMBOL(rfkill_free); + +static void rfkill_led_trigger_register(struct rfkill *rfkill) +{ +#ifdef CONFIG_RFKILL_LEDS + int error; + + if (!rfkill->led_trigger.name) + rfkill->led_trigger.name = dev_name(&rfkill->dev); + if (!rfkill->led_trigger.activate) + rfkill->led_trigger.activate = rfkill_led_trigger_activate; + error = led_trigger_register(&rfkill->led_trigger); + if (error) + rfkill->led_trigger.name = NULL; +#endif /* CONFIG_RFKILL_LEDS */ +} + +static void rfkill_led_trigger_unregister(struct rfkill *rfkill) +{ +#ifdef CONFIG_RFKILL_LEDS + if (rfkill->led_trigger.name) { + led_trigger_unregister(&rfkill->led_trigger); + rfkill->led_trigger.name = NULL; + } +#endif +} + +/** + * rfkill_register - Register a rfkill structure. + * @rfkill: rfkill structure to be registered + * + * This function should be called by the network driver when the rfkill + * structure needs to be registered. Immediately from registration the + * switch driver should be able to service calls to toggle_radio. + */ +int __must_check rfkill_register(struct rfkill *rfkill) +{ + static atomic_t rfkill_no = ATOMIC_INIT(0); + struct device *dev = &rfkill->dev; + int error; + + if (WARN((!rfkill || !rfkill->toggle_radio || + rfkill->type >= RFKILL_TYPE_MAX || + rfkill->state >= RFKILL_STATE_MAX), + KERN_WARNING + "rfkill: attempt to register a " + "badly initialized rfkill struct\n")) + return -EINVAL; + + dev_set_name(dev, "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1); + + rfkill_led_trigger_register(rfkill); + + error = rfkill_add_switch(rfkill); + if (error) { + rfkill_led_trigger_unregister(rfkill); + return error; + } + + error = device_add(dev); + if (error) { + rfkill_remove_switch(rfkill); + rfkill_led_trigger_unregister(rfkill); + return error; + } + + return 0; +} +EXPORT_SYMBOL(rfkill_register); + +/** + * rfkill_unregister - Unregister a rfkill structure. + * @rfkill: rfkill structure to be unregistered + * + * This function should be called by the network driver during device + * teardown to destroy rfkill structure. Note that rfkill_free() should + * _not_ be called after rfkill_unregister(). + */ +void rfkill_unregister(struct rfkill *rfkill) +{ + BUG_ON(!rfkill); + device_del(&rfkill->dev); + rfkill_remove_switch(rfkill); + rfkill_led_trigger_unregister(rfkill); + put_device(&rfkill->dev); +} +EXPORT_SYMBOL(rfkill_unregister); + +/** + * rfkill_set_default - set initial value for a switch type + * @type - the type of switch to set the default state of + * @state - the new default state for that group of switches + * + * Sets the initial state rfkill should use for a given type. + * The following initial states are allowed: RFKILL_STATE_SOFT_BLOCKED + * and RFKILL_STATE_UNBLOCKED. + * + * This function is meant to be used by platform drivers for platforms + * that can save switch state across power down/reboot. + * + * The default state for each switch type can be changed exactly once. + * After a switch of that type is registered, the default state cannot + * be changed anymore. This guards against multiple drivers it the + * same platform trying to set the initial switch default state, which + * is not allowed. + * + * Returns -EPERM if the state has already been set once or is in use, + * so drivers likely want to either ignore or at most printk(KERN_NOTICE) + * if this function returns -EPERM. + * + * Returns 0 if the new default state was set, or an error if it + * could not be set. + */ +int rfkill_set_default(enum rfkill_type type, enum rfkill_state state) +{ + int error; + + if (WARN((type >= RFKILL_TYPE_MAX || + (state != RFKILL_STATE_SOFT_BLOCKED && + state != RFKILL_STATE_UNBLOCKED)), + KERN_WARNING + "rfkill: illegal state %d or type %d passed as " + "parameter to rfkill_set_default\n", state, type)) + return -EINVAL; + + mutex_lock(&rfkill_global_mutex); + + if (!test_and_set_bit(type, rfkill_states_lockdflt)) { + rfkill_global_states[type].default_state = state; + rfkill_global_states[type].current_state = state; + error = 0; + } else + error = -EPERM; + + mutex_unlock(&rfkill_global_mutex); + return error; +} +EXPORT_SYMBOL_GPL(rfkill_set_default); + +/* + * Rfkill module initialization/deinitialization. + */ +static int __init rfkill_init(void) +{ + int error; + int i; + + /* RFKILL_STATE_HARD_BLOCKED is illegal here... */ + if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED && + rfkill_default_state != RFKILL_STATE_UNBLOCKED) + return -EINVAL; + + for (i = 0; i < RFKILL_TYPE_MAX; i++) + rfkill_global_states[i].default_state = rfkill_default_state; + + error = class_register(&rfkill_class); + if (error) { + printk(KERN_ERR "rfkill: unable to register rfkill class\n"); + return error; + } + + return 0; +} + +static void __exit rfkill_exit(void) +{ + class_unregister(&rfkill_class); +} + +subsys_initcall(rfkill_init); +module_exit(rfkill_exit); diff --git a/trunk/net/sched/cls_api.c b/trunk/net/sched/cls_api.c index 09cdcdfe7e91..0759f32e9dca 100644 --- a/trunk/net/sched/cls_api.c +++ b/trunk/net/sched/cls_api.c @@ -135,7 +135,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) unsigned long cl; unsigned long fh; int err; - int tp_created = 0; if (net != &init_net) return -EINVAL; @@ -267,7 +266,10 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) goto errout; } - tp_created = 1; + spin_lock_bh(root_lock); + tp->next = *back; + *back = tp; + spin_unlock_bh(root_lock); } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) goto errout; @@ -294,11 +296,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) switch (n->nlmsg_type) { case RTM_NEWTFILTER: err = -EEXIST; - if (n->nlmsg_flags & NLM_F_EXCL) { - if (tp_created) - tcf_destroy(tp); + if (n->nlmsg_flags & NLM_F_EXCL) goto errout; - } break; case RTM_DELTFILTER: err = tp->ops->delete(tp, fh); @@ -315,18 +314,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) } err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); - if (err == 0) { - if (tp_created) { - spin_lock_bh(root_lock); - tp->next = *back; - *back = tp; - spin_unlock_bh(root_lock); - } + if (err == 0) tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); - } else { - if (tp_created) - tcf_destroy(tp); - } errout: if (cl) diff --git a/trunk/net/sched/cls_cgroup.c b/trunk/net/sched/cls_cgroup.c index 0f815cc6a3db..1ab4542e61e0 100644 --- a/trunk/net/sched/cls_cgroup.c +++ b/trunk/net/sched/cls_cgroup.c @@ -98,7 +98,8 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res) { struct cls_cgroup_head *head = tp->root; - u32 classid; + struct cgroup_cls_state *cs; + int ret = 0; /* * Due to the nature of the classifier it is required to ignore all @@ -114,18 +115,17 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, return -1; rcu_read_lock(); - classid = task_cls_state(current)->classid; - rcu_read_unlock(); + cs = task_cls_state(current); + if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) { + res->classid = cs->classid; + res->class = 0; + ret = tcf_exts_exec(skb, &head->exts, res); + } else + ret = -1; - if (!classid) - return -1; - - if (!tcf_em_tree_match(skb, &head->ematches, NULL)) - return -1; + rcu_read_unlock(); - res->classid = classid; - res->class = 0; - return tcf_exts_exec(skb, &head->exts, res); + return ret; } static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) diff --git a/trunk/net/sched/cls_flow.c b/trunk/net/sched/cls_flow.c index 9402a7fd3785..0ef4e3065bcd 100644 --- a/trunk/net/sched/cls_flow.c +++ b/trunk/net/sched/cls_flow.c @@ -84,7 +84,7 @@ static u32 flow_get_dst(const struct sk_buff *skb) case htons(ETH_P_IPV6): return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); default: - return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; + return addr_fold(skb->dst) ^ (__force u16)skb->protocol; } } @@ -163,7 +163,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb) break; } default: - res = addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; + res = addr_fold(skb->dst) ^ (__force u16)skb->protocol; } return res; @@ -251,8 +251,8 @@ static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb) static u32 flow_get_rtclassid(const struct sk_buff *skb) { #ifdef CONFIG_NET_CLS_ROUTE - if (skb_dst(skb)) - return skb_dst(skb)->tclassid; + if (skb->dst) + return skb->dst->tclassid; #endif return 0; } diff --git a/trunk/net/sched/cls_route.c b/trunk/net/sched/cls_route.c index dd872d5383ef..bdf1f4172eef 100644 --- a/trunk/net/sched/cls_route.c +++ b/trunk/net/sched/cls_route.c @@ -137,7 +137,7 @@ static int route4_classify(struct sk_buff *skb, struct tcf_proto *tp, u32 id, h; int iif, dont_cache = 0; - if ((dst = skb_dst(skb)) == NULL) + if ((dst = skb->dst) == NULL) goto failure; id = dst->tclassid; diff --git a/trunk/net/sched/em_meta.c b/trunk/net/sched/em_meta.c index 266151ae85a3..fad596bf32d7 100644 --- a/trunk/net/sched/em_meta.c +++ b/trunk/net/sched/em_meta.c @@ -246,11 +246,11 @@ META_COLLECTOR(int_tcindex) META_COLLECTOR(int_rtclassid) { - if (unlikely(skb_dst(skb) == NULL)) + if (unlikely(skb->dst == NULL)) *err = -1; else #ifdef CONFIG_NET_CLS_ROUTE - dst->value = skb_dst(skb)->tclassid; + dst->value = skb->dst->tclassid; #else dst->value = 0; #endif @@ -258,10 +258,10 @@ META_COLLECTOR(int_rtclassid) META_COLLECTOR(int_rtiif) { - if (unlikely(skb_rtable(skb) == NULL)) + if (unlikely(skb->rtable == NULL)) *err = -1; else - dst->value = skb_rtable(skb)->fl.iif; + dst->value = skb->rtable->fl.iif; } /************************************************************************** diff --git a/trunk/net/sched/sch_hfsc.c b/trunk/net/sched/sch_hfsc.c index 362c2811b2df..5022f9c1f34b 100644 --- a/trunk/net/sched/sch_hfsc.c +++ b/trunk/net/sched/sch_hfsc.c @@ -372,7 +372,7 @@ cftree_update(struct hfsc_class *cl) * ism: (psched_us/byte) << ISM_SHIFT * dx: psched_us * - * The clock source resolution with ktime and PSCHED_SHIFT 10 is 1.024us. + * The clock source resolution with ktime is 1.024us. * * sm and ism are scaled in order to keep effective digits. * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective @@ -383,11 +383,9 @@ cftree_update(struct hfsc_class *cl) * bytes/1.024us 12.8e-3 128e-3 1280e-3 12800e-3 128000e-3 * * 1.024us/byte 78.125 7.8125 0.78125 0.078125 0.0078125 - * - * So, for PSCHED_SHIFT 10 we need: SM_SHIFT 20, ISM_SHIFT 18. */ -#define SM_SHIFT (30 - PSCHED_SHIFT) -#define ISM_SHIFT (8 + PSCHED_SHIFT) +#define SM_SHIFT 20 +#define ISM_SHIFT 18 #define SM_MASK ((1ULL << SM_SHIFT) - 1) #define ISM_MASK ((1ULL << ISM_SHIFT) - 1) diff --git a/trunk/net/sched/sch_sfq.c b/trunk/net/sched/sch_sfq.c index 8706920a6d45..33133d27b539 100644 --- a/trunk/net/sched/sch_sfq.c +++ b/trunk/net/sched/sch_sfq.c @@ -149,7 +149,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) break; } default: - h = (unsigned long)skb_dst(skb) ^ skb->protocol; + h = (unsigned long)skb->dst ^ skb->protocol; h2 = (unsigned long)skb->sk; } diff --git a/trunk/net/sched/sch_teql.c b/trunk/net/sched/sch_teql.c index cb1cb1e76b9a..a886496bdc3a 100644 --- a/trunk/net/sched/sch_teql.c +++ b/trunk/net/sched/sch_teql.c @@ -222,7 +222,7 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * { struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, 0); struct teql_sched_data *q = qdisc_priv(dev_queue->qdisc); - struct neighbour *mn = skb_dst(skb)->neighbour; + struct neighbour *mn = skb->dst->neighbour; struct neighbour *n = q->ncache; if (mn->tbl == NULL) @@ -262,8 +262,8 @@ static inline int teql_resolve(struct sk_buff *skb, return -ENODEV; if (dev->header_ops == NULL || - skb_dst(skb) == NULL || - skb_dst(skb)->neighbour == NULL) + skb->dst == NULL || + skb->dst->neighbour == NULL) return 0; return __teql_resolve(skb, skb_res, dev); } diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index 525864bf4f07..f4b23043b610 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -293,8 +293,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a * told otherwise. */ asoc->peer.ipv4_address = 1; - if (asoc->base.sk->sk_family == PF_INET6) - asoc->peer.ipv6_address = 1; + asoc->peer.ipv6_address = 1; INIT_LIST_HEAD(&asoc->asocs); asoc->autoclose = sp->autoclose; @@ -567,21 +566,6 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc, if (asoc->init_last_sent_to == peer) asoc->init_last_sent_to = NULL; - /* If we remove the transport an SHUTDOWN was last sent to, set it - * to NULL. Combined with the update of the retran path above, this - * will cause the next SHUTDOWN to be sent to the next available - * transport, maintaining the cycle. - */ - if (asoc->shutdown_last_sent_to == peer) - asoc->shutdown_last_sent_to = NULL; - - /* If we remove the transport an ASCONF was last sent to, set it to - * NULL. - */ - if (asoc->addip_last_asconf && - asoc->addip_last_asconf->transport == peer) - asoc->addip_last_asconf->transport = NULL; - asoc->peer.transport_count--; sctp_transport_free(peer); @@ -1284,21 +1268,49 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) ntohs(t->ipaddr.v4.sin_port)); } -/* Choose the transport for sending retransmit packet. */ -struct sctp_transport *sctp_assoc_choose_alter_transport( - struct sctp_association *asoc, struct sctp_transport *last_sent_to) +/* Choose the transport for sending a INIT packet. */ +struct sctp_transport *sctp_assoc_choose_init_transport( + struct sctp_association *asoc) +{ + struct sctp_transport *t; + + /* Use the retran path. If the last INIT was sent over the + * retran path, update the retran path and use it. + */ + if (!asoc->init_last_sent_to) { + t = asoc->peer.active_path; + } else { + if (asoc->init_last_sent_to == asoc->peer.retran_path) + sctp_assoc_update_retran_path(asoc); + t = asoc->peer.retran_path; + } + + SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" + " %p addr: ", + " port: %d\n", + asoc, + (&t->ipaddr), + ntohs(t->ipaddr.v4.sin_port)); + + return t; +} + +/* Choose the transport for sending a SHUTDOWN packet. */ +struct sctp_transport *sctp_assoc_choose_shutdown_transport( + struct sctp_association *asoc) { - /* If this is the first time packet is sent, use the active path, - * else use the retran path. If the last packet was sent over the + /* If this is the first time SHUTDOWN is sent, use the active path, + * else use the retran path. If the last SHUTDOWN was sent over the * retran path, update the retran path and use it. */ - if (!last_sent_to) + if (!asoc->shutdown_last_sent_to) return asoc->peer.active_path; else { - if (last_sent_to == asoc->peer.retran_path) + if (asoc->shutdown_last_sent_to == asoc->peer.retran_path) sctp_assoc_update_retran_path(asoc); return asoc->peer.retran_path; } + } /* Update the association's pmtu and frag_point by going through all the @@ -1470,10 +1482,6 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp) { int assoc_id; int error = 0; - - /* If the id is already assigned, keep it. */ - if (asoc->assoc_id) - return error; retry: if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp))) return -ENOMEM; diff --git a/trunk/net/sctp/input.c b/trunk/net/sctp/input.c index c0c973e67add..d2e98803ffe3 100644 --- a/trunk/net/sctp/input.c +++ b/trunk/net/sctp/input.c @@ -81,13 +81,13 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb); /* Calculate the SCTP checksum of an SCTP packet. */ static inline int sctp_rcv_checksum(struct sk_buff *skb) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; struct sctphdr *sh = sctp_hdr(skb); __le32 cmp = sh->checksum; - struct sk_buff *list; __le32 val; __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); - skb_walk_frags(skb, list) + for (; list; list = list->next) tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), tmp); diff --git a/trunk/net/sctp/output.c b/trunk/net/sctp/output.c index b76411444515..f0c91df59d4e 100644 --- a/trunk/net/sctp/output.c +++ b/trunk/net/sctp/output.c @@ -405,10 +405,10 @@ int sctp_packet_transmit(struct sctp_packet *packet) sctp_assoc_sync_pmtu(asoc); } } - dst = dst_clone(tp->dst); - skb_dst_set(nskb, dst); - if (dst) + nskb->dst = dst_clone(tp->dst); + if (!nskb->dst) goto no_route; + dst = nskb->dst; /* Build the SCTP header. */ sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index 79cbd47f4df7..8eb3e61cb701 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -393,7 +393,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr, return 0; /* Is this a broadcast address? */ - if (skb && skb_rtable(skb)->rt_flags & RTCF_BROADCAST) + if (skb && skb->rtable->rt_flags & RTCF_BROADCAST) return 0; return 1; @@ -572,7 +572,7 @@ static void sctp_v4_get_saddr(struct sctp_sock *sk, /* What interface did this skb arrive on? */ static int sctp_v4_skb_iif(const struct sk_buff *skb) { - return skb_rtable(skb)->rt_iif; + return skb->rtable->rt_iif; } /* Was this packet marked by Explicit Congestion Notification? */ @@ -848,8 +848,8 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", __func__, skb, skb->len, - &skb_rtable(skb)->rt_src, - &skb_rtable(skb)->rt_dst); + &skb->rtable->rt_src, + &skb->rtable->rt_dst); inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT; @@ -1370,8 +1370,6 @@ SCTP_STATIC __exit void sctp_exit(void) sctp_proc_exit(); cleanup_sctp_mibs(); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ - kmem_cache_destroy(sctp_chunk_cachep); kmem_cache_destroy(sctp_bucket_cachep); } diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index 61cc6075b0df..6851ee94e974 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -2864,19 +2864,19 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, switch (addr_param->v4.param_hdr.type) { case SCTP_PARAM_IPV6_ADDRESS: if (!asoc->peer.ipv6_address) - return SCTP_ERROR_DNS_FAILED; + return SCTP_ERROR_INV_PARAM; break; case SCTP_PARAM_IPV4_ADDRESS: if (!asoc->peer.ipv4_address) - return SCTP_ERROR_DNS_FAILED; + return SCTP_ERROR_INV_PARAM; break; default: - return SCTP_ERROR_DNS_FAILED; + return SCTP_ERROR_INV_PARAM; } af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); if (unlikely(!af)) - return SCTP_ERROR_DNS_FAILED; + return SCTP_ERROR_INV_PARAM; af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0); @@ -2886,7 +2886,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, * make sure we check for that) */ if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb)) - return SCTP_ERROR_DNS_FAILED; + return SCTP_ERROR_INV_PARAM; switch (asconf_param->param_hdr.type) { case SCTP_PARAM_ADD_IP: @@ -2954,12 +2954,12 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, peer = sctp_assoc_lookup_paddr(asoc, &addr); if (!peer) - return SCTP_ERROR_DNS_FAILED; + return SCTP_ERROR_INV_PARAM; sctp_assoc_set_primary(asoc, peer); break; default: - return SCTP_ERROR_UNKNOWN_PARAM; + return SCTP_ERROR_INV_PARAM; break; } @@ -3273,7 +3273,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, retval = 1; break; - case SCTP_ERROR_UNKNOWN_PARAM: + case SCTP_ERROR_INV_PARAM: /* Disable sending this type of asconf parameter in * future. */ diff --git a/trunk/net/sctp/sm_sideeffect.c b/trunk/net/sctp/sm_sideeffect.c index 86426aac1600..e2020eb2c8ca 100644 --- a/trunk/net/sctp/sm_sideeffect.c +++ b/trunk/net/sctp/sm_sideeffect.c @@ -686,8 +686,7 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, { struct sctp_transport *t; - t = sctp_assoc_choose_alter_transport(asoc, - asoc->shutdown_last_sent_to); + t = sctp_assoc_choose_shutdown_transport(asoc); asoc->shutdown_last_sent_to = t; asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto; chunk->transport = t; @@ -778,7 +777,7 @@ static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds, { struct sctp_transport *t; - t = sctp_assoc_choose_alter_transport(asoc, chunk->transport); + t = asoc->peer.active_path; asoc->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = t->rto; chunk->transport = t; } @@ -1380,8 +1379,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, case SCTP_CMD_INIT_CHOOSE_TRANSPORT: chunk = cmd->obj.ptr; - t = sctp_assoc_choose_alter_transport(asoc, - asoc->init_last_sent_to); + t = sctp_assoc_choose_init_transport(asoc); asoc->init_last_sent_to = t; chunk->transport = t; t->init_sent_count++; diff --git a/trunk/net/sctp/sm_statefuns.c b/trunk/net/sctp/sm_statefuns.c index 7288192f7df5..55a61aa69662 100644 --- a/trunk/net/sctp/sm_statefuns.c +++ b/trunk/net/sctp/sm_statefuns.c @@ -5432,13 +5432,9 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep, if (!reply) goto nomem; - /* Do some failure management (Section 8.2). - * If we remove the transport an SHUTDOWN was last sent to, don't - * do failure management. - */ - if (asoc->shutdown_last_sent_to) - sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, - SCTP_TRANSPORT(asoc->shutdown_last_sent_to)); + /* Do some failure management (Section 8.2). */ + sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, + SCTP_TRANSPORT(asoc->shutdown_last_sent_to)); /* Set the transport for the SHUTDOWN/ACK chunk and the timeout for * the T2-shutdown timer. @@ -5475,9 +5471,7 @@ sctp_disposition_t sctp_sf_t4_timer_expire( * detection on the appropriate destination address as defined in * RFC2960 [5] section 8.1 and 8.2. */ - if (transport) - sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, - SCTP_TRANSPORT(transport)); + sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport)); /* Reconfig T4 timer and transport. */ sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk)); diff --git a/trunk/net/sctp/sm_statetable.c b/trunk/net/sctp/sm_statetable.c index 6d9b3aafcc5d..5c8186d88c61 100644 --- a/trunk/net/sctp/sm_statetable.c +++ b/trunk/net/sctp/sm_statetable.c @@ -698,7 +698,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \ -} /* TYPE_SCTP_PRIMITIVE_ASCONF */ +} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ /* The primary index for this table is the primitive type. * The secondary index for this table is the state. diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 0f01e5d8a24f..5fb3a8c9792e 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -1100,15 +1100,6 @@ static int __sctp_connect(struct sock* sk, goto out_free; } - /* In case the user of sctp_connectx() wants an association - * id back, assign one now. - */ - if (assoc_id) { - err = sctp_assoc_set_id(asoc, GFP_KERNEL); - if (err < 0) - goto out_free; - } - err = sctp_primitive_ASSOCIATE(asoc, NULL); if (err < 0) { goto out_free; @@ -1129,7 +1120,7 @@ static int __sctp_connect(struct sock* sk, timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); err = sctp_wait_for_connect(asoc, &timeo); - if ((err == 0 || err == -EINPROGRESS) && assoc_id) + if (!err && assoc_id) *assoc_id = asoc->assoc_id; /* Don't free association on exit. */ @@ -1273,34 +1264,6 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, return assoc_id; } -/* - * New (hopefully final) interface for the API. The option buffer is used - * both for the returned association id and the addresses. - */ -SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, - char __user *optval, - int __user *optlen) -{ - sctp_assoc_t assoc_id = 0; - int err = 0; - - if (len < sizeof(assoc_id)) - return -EINVAL; - - err = __sctp_setsockopt_connectx(sk, - (struct sockaddr __user *)(optval + sizeof(assoc_id)), - len - sizeof(assoc_id), &assoc_id); - - if (err == 0 || err == -EINPROGRESS) { - if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) - return -EFAULT; - if (put_user(sizeof(assoc_id), optlen)) - return -EFAULT; - } - - return err; -} - /* API 3.1.4 close() - UDP Style Syntax * Applications use close() to perform graceful shutdown (as described in * Section 10.1 of [SCTP]) on ALL the associations currently represented @@ -1881,7 +1844,7 @@ static int sctp_skb_pull(struct sk_buff *skb, int len) len -= skb_len; __skb_pull(skb, skb_len); - skb_walk_frags(skb, list) { + for (list = skb_shinfo(skb)->frag_list; list; list = list->next) { rlen = sctp_skb_pull(list, len); skb->len -= (len-rlen); skb->data_len -= (len-rlen); @@ -5615,9 +5578,6 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, retval = sctp_getsockopt_local_addrs(sk, len, optval, optlen); break; - case SCTP_SOCKOPT_CONNECTX3: - retval = sctp_getsockopt_connectx3(sk, len, optval, optlen); - break; case SCTP_DEFAULT_SEND_PARAM: retval = sctp_getsockopt_default_send_param(sk, len, optval, optlen); @@ -6660,7 +6620,7 @@ static void sctp_sock_rfree_frag(struct sk_buff *skb) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) sctp_sock_rfree_frag(frag); done: @@ -6675,7 +6635,7 @@ static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) sctp_skb_set_owner_r_frag(frag, sk); done: diff --git a/trunk/net/sctp/sysctl.c b/trunk/net/sctp/sysctl.c index 63eabbc71298..f58e994e6852 100644 --- a/trunk/net/sctp/sysctl.c +++ b/trunk/net/sctp/sysctl.c @@ -49,8 +49,8 @@ static int zero = 0; static int one = 1; static int timer_max = 86400000; /* ms in one day */ static int int_max = INT_MAX; -static int sack_timer_min = 1; -static int sack_timer_max = 500; +static long sack_timer_min = 1; +static long sack_timer_max = 500; extern int sysctl_sctp_mem[3]; extern int sysctl_sctp_rmem[3]; @@ -223,7 +223,7 @@ static ctl_table sctp_table[] = { .ctl_name = NET_SCTP_SACK_TIMEOUT, .procname = "sack_timeout", .data = &sctp_sack_timeout, - .maxlen = sizeof(int), + .maxlen = sizeof(long), .mode = 0644, .proc_handler = proc_dointvec_minmax, .strategy = sysctl_intvec, diff --git a/trunk/net/sctp/ulpevent.c b/trunk/net/sctp/ulpevent.c index 8b3560fd876d..5f186ca550d7 100644 --- a/trunk/net/sctp/ulpevent.c +++ b/trunk/net/sctp/ulpevent.c @@ -976,8 +976,9 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, * In general, the skb passed from IP can have only 1 level of * fragments. But we allow multiple levels of fragments. */ - skb_walk_frags(skb, frag) + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc); + } } /* Do accounting for bytes just read by user and release the references to @@ -1002,7 +1003,7 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* NOTE: skb_shinfos are recursive. Although IP returns * skb's with only 1 level of fragments, SCTP reassembly can * increase the levels. @@ -1025,7 +1026,7 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* NOTE: skb_shinfos are recursive. Although IP returns * skb's with only 1 level of fragments, SCTP reassembly can * increase the levels. diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index 66d458fc6920..e630b38a6047 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -1548,7 +1548,6 @@ static void __exit exit_rpcsec_gss(void) { gss_svc_shutdown(); rpcauth_unregister(&authgss_ops); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ } MODULE_LICENSE("GPL"); diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index 6c2d61586551..e18596146013 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -918,7 +918,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) UDPX_INC_STATS_BH(sk, UDP_MIB_INDATAGRAMS); /* Something worked... */ - dst_confirm(skb_dst(skb)); + dst_confirm(skb->dst); xprt_adjust_cwnd(task, copied); xprt_update_rtt(task); diff --git a/trunk/net/wimax/Kconfig b/trunk/net/wimax/Kconfig index e4d97ab476d5..1b46747a5f5a 100644 --- a/trunk/net/wimax/Kconfig +++ b/trunk/net/wimax/Kconfig @@ -1,10 +1,23 @@ # # WiMAX LAN device configuration # +# Note the ugly 'depends on' on WIMAX: that disallows RFKILL to be a +# module if WIMAX is to be linked in. The WiMAX code is done in such a +# way that it doesn't require and explicit dependency on RFKILL in +# case an embedded system wants to rip it out. +# +# As well, enablement of the RFKILL code means we need the INPUT layer +# support to inject events coming from hw rfkill switches. That +# dependency could be killed if input.h provided appropriate means to +# work when input is disabled. + +comment "WiMAX Wireless Broadband support requires CONFIG_INPUT enabled" + depends on INPUT = n && RFKILL != n menuconfig WIMAX tristate "WiMAX Wireless Broadband support" - depends on RFKILL || !RFKILL + depends on (y && RFKILL != m) || m + depends on (INPUT && RFKILL != n) || RFKILL = n help Select to configure support for devices that provide diff --git a/trunk/net/wimax/Makefile b/trunk/net/wimax/Makefile index 8f1510d0cc2b..5b80b941c2c9 100644 --- a/trunk/net/wimax/Makefile +++ b/trunk/net/wimax/Makefile @@ -6,7 +6,6 @@ wimax-y := \ op-msg.o \ op-reset.o \ op-rfkill.o \ - op-state-get.o \ stack.o wimax-$(CONFIG_DEBUG_FS) += debugfs.o diff --git a/trunk/net/wimax/debug-levels.h b/trunk/net/wimax/debug-levels.h index 0975adba6b71..1c29123a3aa9 100644 --- a/trunk/net/wimax/debug-levels.h +++ b/trunk/net/wimax/debug-levels.h @@ -36,7 +36,6 @@ enum d_module { D_SUBMODULE_DECLARE(op_msg), D_SUBMODULE_DECLARE(op_reset), D_SUBMODULE_DECLARE(op_rfkill), - D_SUBMODULE_DECLARE(op_state_get), D_SUBMODULE_DECLARE(stack), }; diff --git a/trunk/net/wimax/debugfs.c b/trunk/net/wimax/debugfs.c index 6c9bedb7431e..94d216a46407 100644 --- a/trunk/net/wimax/debugfs.c +++ b/trunk/net/wimax/debugfs.c @@ -61,7 +61,6 @@ int wimax_debugfs_add(struct wimax_dev *wimax_dev) __debugfs_register("wimax_dl_", op_msg, dentry); __debugfs_register("wimax_dl_", op_reset, dentry); __debugfs_register("wimax_dl_", op_rfkill, dentry); - __debugfs_register("wimax_dl_", op_state_get, dentry); __debugfs_register("wimax_dl_", stack, dentry); result = 0; out: diff --git a/trunk/net/wimax/op-msg.c b/trunk/net/wimax/op-msg.c index d631a17186bc..9ad4d893a566 100644 --- a/trunk/net/wimax/op-msg.c +++ b/trunk/net/wimax/op-msg.c @@ -108,12 +108,6 @@ * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as * wimax_msg_send() depends on skb->data being placed at the * beginning of the user message. - * - * Unlike other WiMAX stack calls, this call can be used way early, - * even before wimax_dev_add() is called, as long as the - * wimax_dev->net_dev pointer is set to point to a proper - * net_dev. This is so that drivers can use it early in case they need - * to send stuff around or communicate with user space. */ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev, const char *pipe_name, @@ -121,7 +115,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev, gfp_t gfp_flags) { int result; - struct device *dev = wimax_dev_to_dev(wimax_dev); + struct device *dev = wimax_dev->net_dev->dev.parent; size_t msg_size; void *genl_msg; struct sk_buff *skb; @@ -167,6 +161,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev, error_new: nlmsg_free(skb); return ERR_PTR(result); + } EXPORT_SYMBOL_GPL(wimax_msg_alloc); @@ -261,16 +256,10 @@ EXPORT_SYMBOL_GPL(wimax_msg_len); * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as * wimax_msg_send() depends on skb->data being placed at the * beginning of the user message. - * - * Unlike other WiMAX stack calls, this call can be used way early, - * even before wimax_dev_add() is called, as long as the - * wimax_dev->net_dev pointer is set to point to a proper - * net_dev. This is so that drivers can use it early in case they need - * to send stuff around or communicate with user space. */ int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb) { - struct device *dev = wimax_dev_to_dev(wimax_dev); + struct device *dev = wimax_dev->net_dev->dev.parent; void *msg = skb->data; size_t size = skb->len; might_sleep(); diff --git a/trunk/net/wimax/op-rfkill.c b/trunk/net/wimax/op-rfkill.c index 70ef4df863b9..a3616e2ccb8a 100644 --- a/trunk/net/wimax/op-rfkill.c +++ b/trunk/net/wimax/op-rfkill.c @@ -29,8 +29,8 @@ * A non-polled generic rfkill device is embedded into the WiMAX * subsystem's representation of a device. * - * FIXME: Need polled support? Let drivers provide a poll routine - * and hand it to rfkill ops then? + * FIXME: Need polled support? use a timer or add the implementation + * to the stack. * * All device drivers have to do is after wimax_dev_init(), call * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update @@ -43,7 +43,7 @@ * wimax_rfkill() Kernel calling wimax_rfkill() * __wimax_rf_toggle_radio() * - * wimax_rfkill_set_radio_block() RF-Kill subsytem calling + * wimax_rfkill_toggle_radio() RF-Kill subsytem calling * __wimax_rf_toggle_radio() * * __wimax_rf_toggle_radio() @@ -65,11 +65,15 @@ #include #include #include +#include #include "wimax-internal.h" #define D_SUBMODULE op_rfkill #include "debug-levels.h" +#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) + + /** * wimax_report_rfkill_hw - Reports changes in the hardware RF switch * @@ -95,6 +99,7 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, int result; struct device *dev = wimax_dev_to_dev(wimax_dev); enum wimax_st wimax_state; + enum rfkill_state rfkill_state; d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); BUG_ON(state == WIMAX_RF_QUERY); @@ -107,16 +112,16 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, if (state != wimax_dev->rf_hw) { wimax_dev->rf_hw = state; + rfkill_state = state == WIMAX_RF_ON ? + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; if (wimax_dev->rf_hw == WIMAX_RF_ON && wimax_dev->rf_sw == WIMAX_RF_ON) wimax_state = WIMAX_ST_READY; else wimax_state = WIMAX_ST_RADIO_OFF; - - result = rfkill_set_hw_state(wimax_dev->rfkill, - state == WIMAX_RF_OFF); - __wimax_state_change(wimax_dev, wimax_state); + input_report_key(wimax_dev->rfkill_input, KEY_WIMAX, + rfkill_state); } error_not_ready: mutex_unlock(&wimax_dev->mutex); @@ -169,7 +174,6 @@ void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev, else wimax_state = WIMAX_ST_RADIO_OFF; __wimax_state_change(wimax_dev, wimax_state); - rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF); } error_not_ready: mutex_unlock(&wimax_dev->mutex); @@ -245,31 +249,36 @@ int __wimax_rf_toggle_radio(struct wimax_dev *wimax_dev, * * NOTE: This call will block until the operation is completed. */ -static int wimax_rfkill_set_radio_block(void *data, bool blocked) +static +int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state) { int result; struct wimax_dev *wimax_dev = data; struct device *dev = wimax_dev_to_dev(wimax_dev); enum wimax_rf_state rf_state; - d_fnstart(3, dev, "(wimax_dev %p blocked %u)\n", wimax_dev, blocked); - rf_state = WIMAX_RF_ON; - if (blocked) + d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); + switch (state) { + case RFKILL_STATE_SOFT_BLOCKED: rf_state = WIMAX_RF_OFF; + break; + case RFKILL_STATE_UNBLOCKED: + rf_state = WIMAX_RF_ON; + break; + default: + BUG(); + } mutex_lock(&wimax_dev->mutex); if (wimax_dev->state <= __WIMAX_ST_QUIESCING) - result = 0; + result = 0; /* just pretend it didn't happen */ else result = __wimax_rf_toggle_radio(wimax_dev, rf_state); mutex_unlock(&wimax_dev->mutex); - d_fnend(3, dev, "(wimax_dev %p blocked %u) = %d\n", - wimax_dev, blocked, result); + d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n", + wimax_dev, state, result); return result; } -static const struct rfkill_ops wimax_rfkill_ops = { - .set_block = wimax_rfkill_set_radio_block, -}; /** * wimax_rfkill - Set the software RF switch state for a WiMAX device @@ -313,7 +322,6 @@ int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state) result = __wimax_rf_toggle_radio(wimax_dev, state); if (result < 0) goto error; - rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF); break; case WIMAX_RF_QUERY: break; @@ -341,20 +349,40 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev) { int result; struct rfkill *rfkill; + struct input_dev *input_dev; struct device *dev = wimax_dev_to_dev(wimax_dev); d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); /* Initialize RF Kill */ result = -ENOMEM; - rfkill = rfkill_alloc(wimax_dev->name, dev, RFKILL_TYPE_WIMAX, - &wimax_rfkill_ops, wimax_dev); + rfkill = rfkill_allocate(dev, RFKILL_TYPE_WIMAX); if (rfkill == NULL) goto error_rfkill_allocate; - - d_printf(1, dev, "rfkill %p\n", rfkill); - wimax_dev->rfkill = rfkill; + rfkill->name = wimax_dev->name; + rfkill->state = RFKILL_STATE_UNBLOCKED; + rfkill->data = wimax_dev; + rfkill->toggle_radio = wimax_rfkill_toggle_radio; + + /* Initialize the input device for the hw key */ + input_dev = input_allocate_device(); + if (input_dev == NULL) + goto error_input_allocate; + wimax_dev->rfkill_input = input_dev; + d_printf(1, dev, "rfkill %p input %p\n", rfkill, input_dev); + + input_dev->name = wimax_dev->name; + /* FIXME: get a real device bus ID and stuff? do we care? */ + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0xffff; + input_dev->evbit[0] = BIT(EV_KEY); + set_bit(KEY_WIMAX, input_dev->keybit); + + /* Register both */ + result = input_register_device(wimax_dev->rfkill_input); + if (result < 0) + goto error_input_register; result = rfkill_register(wimax_dev->rfkill); if (result < 0) goto error_rfkill_register; @@ -366,8 +394,17 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev) d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev); return 0; + /* if rfkill_register() suceeds, can't use rfkill_free() any + * more, only rfkill_unregister() [it owns the refcount]; with + * the input device we have the same issue--hence the if. */ error_rfkill_register: - rfkill_destroy(wimax_dev->rfkill); + input_unregister_device(wimax_dev->rfkill_input); + wimax_dev->rfkill_input = NULL; +error_input_register: + if (wimax_dev->rfkill_input) + input_free_device(wimax_dev->rfkill_input); +error_input_allocate: + rfkill_free(wimax_dev->rfkill); error_rfkill_allocate: d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result); return result; @@ -386,12 +423,45 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev) { struct device *dev = wimax_dev_to_dev(wimax_dev); d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); - rfkill_unregister(wimax_dev->rfkill); - rfkill_destroy(wimax_dev->rfkill); + rfkill_unregister(wimax_dev->rfkill); /* frees */ + input_unregister_device(wimax_dev->rfkill_input); d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev); } +#else /* #ifdef CONFIG_RFKILL */ + +void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, + enum wimax_rf_state state) +{ +} +EXPORT_SYMBOL_GPL(wimax_report_rfkill_hw); + +void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev, + enum wimax_rf_state state) +{ +} +EXPORT_SYMBOL_GPL(wimax_report_rfkill_sw); + +int wimax_rfkill(struct wimax_dev *wimax_dev, + enum wimax_rf_state state) +{ + return WIMAX_RF_ON << 1 | WIMAX_RF_ON; +} +EXPORT_SYMBOL_GPL(wimax_rfkill); + +int wimax_rfkill_add(struct wimax_dev *wimax_dev) +{ + return 0; +} + +void wimax_rfkill_rm(struct wimax_dev *wimax_dev) +{ +} + +#endif /* #ifdef CONFIG_RFKILL */ + + /* * Exporting to user space over generic netlink * diff --git a/trunk/net/wimax/op-state-get.c b/trunk/net/wimax/op-state-get.c deleted file mode 100644 index a76b8fcb056d..000000000000 --- a/trunk/net/wimax/op-state-get.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Linux WiMAX - * Implement and export a method for getting a WiMAX device current state - * - * Copyright (C) 2009 Paulius Zaleckas - * - * Based on previous WiMAX core work by: - * Copyright (C) 2008 Intel Corporation - * Inaky Perez-Gonzalez - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include "wimax-internal.h" - -#define D_SUBMODULE op_state_get -#include "debug-levels.h" - - -static const -struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = { - [WIMAX_GNL_STGET_IFIDX] = { - .type = NLA_U32, - }, -}; - - -/* - * Exporting to user space over generic netlink - * - * Parse the state get command from user space, return a combination - * value that describe the current state. - * - * No attributes. - */ -static -int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info) -{ - int result, ifindex; - struct wimax_dev *wimax_dev; - struct device *dev; - - d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info); - result = -ENODEV; - if (info->attrs[WIMAX_GNL_STGET_IFIDX] == NULL) { - printk(KERN_ERR "WIMAX_GNL_OP_STATE_GET: can't find IFIDX " - "attribute\n"); - goto error_no_wimax_dev; - } - ifindex = nla_get_u32(info->attrs[WIMAX_GNL_STGET_IFIDX]); - wimax_dev = wimax_dev_get_by_genl_info(info, ifindex); - if (wimax_dev == NULL) - goto error_no_wimax_dev; - dev = wimax_dev_to_dev(wimax_dev); - /* Execute the operation and send the result back to user space */ - result = wimax_state_get(wimax_dev); - dev_put(wimax_dev->net_dev); -error_no_wimax_dev: - d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result); - return result; -} - - -struct genl_ops wimax_gnl_state_get = { - .cmd = WIMAX_GNL_OP_STATE_GET, - .flags = GENL_ADMIN_PERM, - .policy = wimax_gnl_state_get_policy, - .doit = wimax_gnl_doit_state_get, - .dumpit = NULL, -}; diff --git a/trunk/net/wimax/stack.c b/trunk/net/wimax/stack.c index 79fb7d7c640f..933e1422b09f 100644 --- a/trunk/net/wimax/stack.c +++ b/trunk/net/wimax/stack.c @@ -402,15 +402,13 @@ EXPORT_SYMBOL_GPL(wimax_dev_init); extern struct genl_ops wimax_gnl_msg_from_user, wimax_gnl_reset, - wimax_gnl_rfkill, - wimax_gnl_state_get; + wimax_gnl_rfkill; static struct genl_ops *wimax_gnl_ops[] = { &wimax_gnl_msg_from_user, &wimax_gnl_reset, &wimax_gnl_rfkill, - &wimax_gnl_state_get, }; @@ -535,7 +533,6 @@ struct d_level D_LEVEL[] = { D_SUBMODULE_DEFINE(op_msg), D_SUBMODULE_DEFINE(op_reset), D_SUBMODULE_DEFINE(op_rfkill), - D_SUBMODULE_DEFINE(op_state_get), D_SUBMODULE_DEFINE(stack), }; size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL); diff --git a/trunk/net/wireless/Kconfig b/trunk/net/wireless/Kconfig index 4428dd5e911d..45005497c634 100644 --- a/trunk/net/wireless/Kconfig +++ b/trunk/net/wireless/Kconfig @@ -1,6 +1,5 @@ config CFG80211 - tristate "Improved wireless configuration API" - depends on RFKILL || !RFKILL + tristate "Improved wireless configuration API" config CFG80211_REG_DEBUG bool "cfg80211 regulatory debugging" diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index d5850292b3df..a5dbea1da476 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include "nl80211.h" @@ -228,41 +227,6 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, return 0; } -static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) -{ - struct cfg80211_registered_device *drv = data; - - drv->ops->rfkill_poll(&drv->wiphy); -} - -static int cfg80211_rfkill_set_block(void *data, bool blocked) -{ - struct cfg80211_registered_device *drv = data; - struct wireless_dev *wdev; - - if (!blocked) - return 0; - - rtnl_lock(); - mutex_lock(&drv->devlist_mtx); - - list_for_each_entry(wdev, &drv->netdev_list, list) - dev_close(wdev->netdev); - - mutex_unlock(&drv->devlist_mtx); - rtnl_unlock(); - - return 0; -} - -static void cfg80211_rfkill_sync_work(struct work_struct *work) -{ - struct cfg80211_registered_device *drv; - - drv = container_of(work, struct cfg80211_registered_device, rfkill_sync); - cfg80211_rfkill_set_block(drv, rfkill_blocked(drv->rfkill)); -} - /* exported functions */ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) @@ -310,18 +274,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) drv->wiphy.dev.class = &ieee80211_class; drv->wiphy.dev.platform_data = drv; - drv->rfkill_ops.set_block = cfg80211_rfkill_set_block; - drv->rfkill = rfkill_alloc(dev_name(&drv->wiphy.dev), - &drv->wiphy.dev, RFKILL_TYPE_WLAN, - &drv->rfkill_ops, drv); - - if (!drv->rfkill) { - kfree(drv); - return NULL; - } - - INIT_WORK(&drv->rfkill_sync, cfg80211_rfkill_sync_work); - /* * Initialize wiphy parameters to IEEE 802.11 MIB default values. * Fragmentation and RTS threshold are disabled by default with the @@ -395,22 +347,16 @@ int wiphy_register(struct wiphy *wiphy) /* check and set up bitrates */ ieee80211_set_bitrate_flags(wiphy); - res = device_add(&drv->wiphy.dev); - if (res) - return res; - - res = rfkill_register(drv->rfkill); - if (res) - goto out_rm_dev; - mutex_lock(&cfg80211_mutex); /* set up regulatory info */ wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); - list_add(&drv->list, &cfg80211_drv_list); + res = device_add(&drv->wiphy.dev); + if (res) + goto out_unlock; - mutex_unlock(&cfg80211_mutex); + list_add(&drv->list, &cfg80211_drv_list); /* add to debugfs */ drv->wiphy.debugfsdir = @@ -432,39 +378,17 @@ int wiphy_register(struct wiphy *wiphy) cfg80211_debugfs_drv_add(drv); - return 0; - - out_rm_dev: - device_del(&drv->wiphy.dev); + res = 0; +out_unlock: + mutex_unlock(&cfg80211_mutex); return res; } EXPORT_SYMBOL(wiphy_register); -void wiphy_rfkill_start_polling(struct wiphy *wiphy) -{ - struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); - - if (!drv->ops->rfkill_poll) - return; - drv->rfkill_ops.poll = cfg80211_rfkill_poll; - rfkill_resume_polling(drv->rfkill); -} -EXPORT_SYMBOL(wiphy_rfkill_start_polling); - -void wiphy_rfkill_stop_polling(struct wiphy *wiphy) -{ - struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); - - rfkill_pause_polling(drv->rfkill); -} -EXPORT_SYMBOL(wiphy_rfkill_stop_polling); - void wiphy_unregister(struct wiphy *wiphy) { struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); - rfkill_unregister(drv->rfkill); - /* protect the device list */ mutex_lock(&cfg80211_mutex); @@ -501,7 +425,6 @@ EXPORT_SYMBOL(wiphy_unregister); void cfg80211_dev_free(struct cfg80211_registered_device *drv) { struct cfg80211_internal_bss *scan, *tmp; - rfkill_destroy(drv->rfkill); mutex_destroy(&drv->mtx); mutex_destroy(&drv->devlist_mtx); list_for_each_entry_safe(scan, tmp, &drv->bss_list, list) @@ -515,15 +438,6 @@ void wiphy_free(struct wiphy *wiphy) } EXPORT_SYMBOL(wiphy_free); -void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked) -{ - struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); - - if (rfkill_set_hw_state(drv->rfkill, blocked)) - schedule_work(&drv->rfkill_sync); -} -EXPORT_SYMBOL(wiphy_rfkill_set_hw_state); - static int cfg80211_netdev_notifier_call(struct notifier_block * nb, unsigned long state, void *ndev) @@ -532,7 +446,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, struct cfg80211_registered_device *rdev; if (!dev->ieee80211_ptr) - return NOTIFY_DONE; + return 0; rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); @@ -578,13 +492,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, } mutex_unlock(&rdev->devlist_mtx); break; - case NETDEV_PRE_UP: - if (rfkill_blocked(rdev->rfkill)) - return notifier_from_errno(-ERFKILL); - break; } - return NOTIFY_DONE; + return 0; } static struct notifier_block cfg80211_netdev_notifier = { diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h index bfa340c7abb5..ab512bcd8153 100644 --- a/trunk/net/wireless/core.h +++ b/trunk/net/wireless/core.h @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include #include "reg.h" @@ -26,11 +24,6 @@ struct cfg80211_registered_device { * any call is in progress */ struct mutex mtx; - /* rfkill support */ - struct rfkill_ops rfkill_ops; - struct rfkill *rfkill; - struct work_struct rfkill_sync; - /* ISO / IEC 3166 alpha2 for which this device is receiving * country IEs on, this can help disregard country IEs from APs * on the same alpha2 quickly. The alpha2 may differ from diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 24168560ebae..4b4d3c8a1aed 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1687,12 +1687,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) if (err) goto out_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { - err = -EINVAL; - goto out; - } - err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, ¶ms.vlan); if (err) goto out; @@ -1744,11 +1738,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); params.listen_interval = nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); - params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); - if (!params.aid || params.aid > IEEE80211_MAX_AID) - return -EINVAL; - if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) params.ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); @@ -3569,43 +3559,11 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); } -static int nl80211_add_scan_req(struct sk_buff *msg, - struct cfg80211_registered_device *rdev) -{ - struct cfg80211_scan_request *req = rdev->scan_req; - struct nlattr *nest; - int i; - - if (WARN_ON(!req)) - return 0; - - nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS); - if (!nest) - goto nla_put_failure; - for (i = 0; i < req->n_ssids; i++) - NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid); - nla_nest_end(msg, nest); - - nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); - if (!nest) - goto nla_put_failure; - for (i = 0; i < req->n_channels; i++) - NLA_PUT_U32(msg, i, req->channels[i]->center_freq); - nla_nest_end(msg, nest); - - if (req->ie) - NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie); - - return 0; - nla_put_failure: - return -ENOBUFS; -} - static int nl80211_send_scan_donemsg(struct sk_buff *msg, - struct cfg80211_registered_device *rdev, - struct net_device *netdev, - u32 pid, u32 seq, int flags, - u32 cmd) + struct cfg80211_registered_device *rdev, + struct net_device *netdev, + u32 pid, u32 seq, int flags, + u32 cmd) { void *hdr; @@ -3616,8 +3574,7 @@ static int nl80211_send_scan_donemsg(struct sk_buff *msg, NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); - /* ignore errors and send incomplete event anyway */ - nl80211_add_scan_req(msg, rdev); + /* XXX: we should probably bounce back the request? */ return genlmsg_end(msg, hdr); @@ -3871,7 +3828,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct sk_buff *msg; void *hdr; - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return; @@ -3895,7 +3852,7 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, return; } - genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC); + genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL); return; nla_put_failure: diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index 5e14371cda70..f87ac1df2df5 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -2129,12 +2129,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) * driver wanted to the wiphy to deal with conflicts */ - /* - * Userspace could have sent two replies with only - * one kernel request. - */ - if (request_wiphy->regd) - return -EALREADY; + BUG_ON(request_wiphy->regd); r = reg_copy_regd(&request_wiphy->regd, rd); if (r) @@ -2176,13 +2171,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) * the country IE rd with what CRDA believes that country should have */ - /* - * Userspace could have sent two replies with only - * one kernel request. By the second reply we would have - * already processed and consumed the country_ie_regdomain. - */ - if (!country_ie_regdomain) - return -EALREADY; + BUG_ON(!country_ie_regdomain); BUG_ON(rd == country_ie_regdomain); /* diff --git a/trunk/net/wireless/scan.c b/trunk/net/wireless/scan.c index e95b638b919f..df59440290e5 100644 --- a/trunk/net/wireless/scan.c +++ b/trunk/net/wireless/scan.c @@ -29,14 +29,13 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) goto out; WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); + wiphy_to_dev(request->wiphy)->scan_req = NULL; if (aborted) nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev); else nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev); - wiphy_to_dev(request->wiphy)->scan_req = NULL; - #ifdef CONFIG_WIRELESS_EXT if (!aborted) { memset(&wrqu, 0, sizeof(wrqu)); diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 25550692dda6..d072bff463aa 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -157,25 +157,26 @@ int cfg80211_validate_key_settings(struct key_params *params, int key_idx, params->cipher != WLAN_CIPHER_SUITE_WEP104) return -EINVAL; + /* TODO: add definitions for the lengths to linux/ieee80211.h */ switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: - if (params->key_len != WLAN_KEY_LEN_WEP40) + if (params->key_len != 5) return -EINVAL; break; case WLAN_CIPHER_SUITE_TKIP: - if (params->key_len != WLAN_KEY_LEN_TKIP) + if (params->key_len != 32) return -EINVAL; break; case WLAN_CIPHER_SUITE_CCMP: - if (params->key_len != WLAN_KEY_LEN_CCMP) + if (params->key_len != 16) return -EINVAL; break; case WLAN_CIPHER_SUITE_WEP104: - if (params->key_len != WLAN_KEY_LEN_WEP104) + if (params->key_len != 13) return -EINVAL; break; case WLAN_CIPHER_SUITE_AES_CMAC: - if (params->key_len != WLAN_KEY_LEN_AES_CMAC) + if (params->key_len != 16) return -EINVAL; break; default: @@ -258,7 +259,7 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) } EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); -static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) +int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) { int ae = meshhdr->flags & MESH_FLAGS_AE; /* 7.1.3.5a.2 */ diff --git a/trunk/net/wireless/wext-compat.c b/trunk/net/wireless/wext-compat.c index d030c5315672..711e00a0c9b5 100644 --- a/trunk/net/wireless/wext-compat.c +++ b/trunk/net/wireless/wext-compat.c @@ -744,86 +744,3 @@ int cfg80211_wext_giwencode(struct net_device *dev, return err; } EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); - -int cfg80211_wext_siwtxpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - enum tx_power_setting type; - int dbm = 0; - - if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) - return -EINVAL; - if (data->txpower.flags & IW_TXPOW_RANGE) - return -EINVAL; - - if (!rdev->ops->set_tx_power) - return -EOPNOTSUPP; - - /* only change when not disabling */ - if (!data->txpower.disabled) { - rfkill_set_sw_state(rdev->rfkill, false); - - if (data->txpower.fixed) { - /* - * wext doesn't support negative values, see - * below where it's for automatic - */ - if (data->txpower.value < 0) - return -EINVAL; - dbm = data->txpower.value; - type = TX_POWER_FIXED; - /* TODO: do regulatory check! */ - } else { - /* - * Automatic power level setting, max being the value - * passed in from userland. - */ - if (data->txpower.value < 0) { - type = TX_POWER_AUTOMATIC; - } else { - dbm = data->txpower.value; - type = TX_POWER_LIMITED; - } - } - } else { - rfkill_set_sw_state(rdev->rfkill, true); - schedule_work(&rdev->rfkill_sync); - return 0; - } - - return rdev->ops->set_tx_power(wdev->wiphy, type, dbm);; -} -EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower); - -int cfg80211_wext_giwtxpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - int err, val; - - if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) - return -EINVAL; - if (data->txpower.flags & IW_TXPOW_RANGE) - return -EINVAL; - - if (!rdev->ops->get_tx_power) - return -EOPNOTSUPP; - - err = rdev->ops->get_tx_power(wdev->wiphy, &val); - if (err) - return err; - - /* well... oh well */ - data->txpower.fixed = 1; - data->txpower.disabled = rfkill_blocked(rdev->rfkill); - data->txpower.value = val; - data->txpower.flags = IW_TXPOW_DBM; - - return 0; -} -EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower); diff --git a/trunk/net/xfrm/xfrm_algo.c b/trunk/net/xfrm/xfrm_algo.c index d31ccb487730..96036cf2216d 100644 --- a/trunk/net/xfrm/xfrm_algo.c +++ b/trunk/net/xfrm/xfrm_algo.c @@ -696,9 +696,8 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; - struct scatterlist sg; int err; + struct scatterlist sg; /* Checksum header. */ if (copy > 0) { @@ -743,24 +742,28 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - err = skb_icv_walk(frag_iter, desc, offset-start, - copy, icv_update); - if (unlikely(err)) - return err; - if ((len -= copy) == 0) - return 0; - offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + err = skb_icv_walk(list, desc, offset-start, + copy, icv_update); + if (unlikely(err)) + return err; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + start = end; } - start = end; } BUG_ON(len); return 0; diff --git a/trunk/net/xfrm/xfrm_input.c b/trunk/net/xfrm/xfrm_input.c index e0009c17d809..b4a13178fb40 100644 --- a/trunk/net/xfrm/xfrm_input.c +++ b/trunk/net/xfrm/xfrm_input.c @@ -251,7 +251,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) nf_reset(skb); if (decaps) { - skb_dst_drop(skb); + dst_release(skb->dst); + skb->dst = NULL; netif_rx(skb); return 0; } else { diff --git a/trunk/net/xfrm/xfrm_output.c b/trunk/net/xfrm/xfrm_output.c index b9fe13138c07..c235597ba8dd 100644 --- a/trunk/net/xfrm/xfrm_output.c +++ b/trunk/net/xfrm/xfrm_output.c @@ -22,7 +22,7 @@ static int xfrm_output2(struct sk_buff *skb); static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev) - skb_headroom(skb); int ntail = dst->dev->needed_tailroom - skb_tailroom(skb); @@ -39,7 +39,7 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb) static int xfrm_output_one(struct sk_buff *skb, int err) { - struct dst_entry *dst = skb_dst(skb); + struct dst_entry *dst = skb->dst; struct xfrm_state *x = dst->xfrm; struct net *net = xs_net(x); @@ -94,13 +94,12 @@ static int xfrm_output_one(struct sk_buff *skb, int err) goto error_nolock; } - dst = dst_pop(dst); - if (!dst) { + if (!(skb->dst = dst_pop(dst))) { XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR); err = -EHOSTUNREACH; goto error_nolock; } - skb_dst_set(skb, dst); + dst = skb->dst; x = dst->xfrm; } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); @@ -120,16 +119,16 @@ int xfrm_output_resume(struct sk_buff *skb, int err) while (likely((err = xfrm_output_one(skb, err)) == 0)) { nf_reset(skb); - err = skb_dst(skb)->ops->local_out(skb); + err = skb->dst->ops->local_out(skb); if (unlikely(err != 1)) goto out; - if (!skb_dst(skb)->xfrm) + if (!skb->dst->xfrm) return dst_output(skb); - err = nf_hook(skb_dst(skb)->ops->family, + err = nf_hook(skb->dst->ops->family, NF_INET_POST_ROUTING, skb, - NULL, skb_dst(skb)->dev, xfrm_output2); + NULL, skb->dst->dev, xfrm_output2); if (unlikely(err != 1)) goto out; } @@ -180,7 +179,7 @@ static int xfrm_output_gso(struct sk_buff *skb) int xfrm_output(struct sk_buff *skb) { - struct net *net = dev_net(skb_dst(skb)->dev); + struct net *net = dev_net(skb->dst->dev); int err; if (skb_is_gso(skb)) @@ -203,7 +202,7 @@ int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb) struct xfrm_mode *inner_mode; if (x->sel.family == AF_UNSPEC) inner_mode = xfrm_ip2inner_mode(x, - xfrm_af2proto(skb_dst(skb)->ops->family)); + xfrm_af2proto(skb->dst->ops->family)); else inner_mode = x->inner_mode; diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index cb81ca35b0d6..9c068ab3a834 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -2027,8 +2027,6 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) { struct net *net = dev_net(skb->dev); struct flowi fl; - struct dst_entry *dst; - int res; if (xfrm_decode_session(skb, &fl, family) < 0) { /* XXX: we should have something like FWDHDRERROR here. */ @@ -2036,11 +2034,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) return 0; } - dst = skb_dst(skb); - - res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0; - skb_dst_set(skb, dst); - return res; + return xfrm_lookup(net, &skb->dst, &fl, NULL, 0) == 0; } EXPORT_SYMBOL(__xfrm_route_forward); diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 4bfc6153ad4f..2fcad7c33eaf 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -4503,7 +4503,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, * when the packet is on it's final way out. * NOTE: there appear to be some IPv6 multicast cases where skb->dst * is NULL, in this case go ahead and apply access control. */ - if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL) + if (skb->dst != NULL && skb->dst->xfrm != NULL) return NF_ACCEPT; #endif secmark_active = selinux_secmark_enabled(); diff --git a/trunk/security/selinux/xfrm.c b/trunk/security/selinux/xfrm.c index 72b18452e1a1..c0eb72013d67 100644 --- a/trunk/security/selinux/xfrm.c +++ b/trunk/security/selinux/xfrm.c @@ -447,7 +447,7 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, struct dst_entry *dst; int rc = 0; - dst = skb_dst(skb); + dst = skb->dst; if (dst) { struct dst_entry *dst_test;