From b9475703eed20bb05f3d8216220986d99233e03b Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 26 Aug 2012 19:13:55 +0200 Subject: [PATCH] --- yaml --- r: 327772 b: refs/heads/master c: 5f2d04f1f9b52604fca6ee08a77972c0df67e082 h: refs/heads/master v: v3 --- [refs] | 2 +- .../bindings/net/mdio-mux-mmioreg.txt | 75 --- trunk/Documentation/networking/batman-adv.txt | 7 +- trunk/Documentation/networking/ip-sysctl.txt | 37 +- trunk/Documentation/networking/stmmac.txt | 5 + trunk/Makefile | 2 +- trunk/drivers/Makefile | 1 + trunk/drivers/acpi/acpica/tbxface.c | 1 - trunk/drivers/bcma/Kconfig | 4 +- trunk/drivers/bcma/bcma_private.h | 2 - trunk/drivers/bcma/driver_chipcommon_nflash.c | 28 +- trunk/drivers/bcma/driver_chipcommon_sflash.c | 123 +--- trunk/drivers/bcma/main.c | 17 - trunk/drivers/char/agp/intel-agp.h | 1 - trunk/drivers/char/agp/intel-gtt.c | 105 +-- trunk/drivers/gpu/drm/drm_modes.c | 3 + trunk/drivers/gpu/drm/drm_proc.c | 4 +- trunk/drivers/gpu/drm/i915/i915_gem.c | 8 +- trunk/drivers/gpu/drm/i915/i915_gem_gtt.c | 5 +- trunk/drivers/gpu/drm/i915/i915_reg.h | 1 - trunk/drivers/gpu/drm/i915/intel_crt.c | 36 +- trunk/drivers/gpu/drm/i915/intel_drv.h | 2 - trunk/drivers/gpu/drm/i915/intel_modes.c | 31 +- trunk/drivers/gpu/drm/i915/intel_pm.c | 15 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 1 - trunk/drivers/gpu/drm/radeon/atombios_crtc.c | 25 +- trunk/drivers/gpu/drm/radeon/r600_cs.c | 105 +-- trunk/drivers/gpu/drm/radeon/r600d.h | 17 - trunk/drivers/gpu/drm/radeon/radeon.h | 15 + .../drivers/gpu/drm/radeon/radeon_atombios.c | 2 +- .../gpu/drm/radeon/radeon_atpx_handler.c | 56 +- trunk/drivers/gpu/drm/radeon/radeon_bios.c | 138 +--- trunk/drivers/gpu/drm/radeon/radeon_drv.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_object.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_ring.c | 1 - trunk/drivers/gpu/drm/radeon/reg_srcs/r600 | 8 + trunk/drivers/gpu/drm/udl/udl_modeset.c | 3 +- trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 6 +- trunk/drivers/i2c/busses/i2c-diolan-u2c.c | 1 - trunk/drivers/i2c/busses/i2c-nomadik.c | 28 +- trunk/drivers/i2c/busses/i2c-omap.c | 2 +- trunk/drivers/i2c/busses/i2c-tegra.c | 2 +- trunk/drivers/{net => }/ieee802154/Kconfig | 0 trunk/drivers/{net => }/ieee802154/Makefile | 0 .../drivers/{net => }/ieee802154/at86rf230.c | 12 +- trunk/drivers/{net => }/ieee802154/fakehard.c | 1 + trunk/drivers/{net => }/ieee802154/fakelb.c | 0 trunk/drivers/net/Kconfig | 4 +- trunk/drivers/net/Makefile | 1 - trunk/drivers/net/bonding/bond_main.c | 31 +- .../net/can/sja1000/sja1000_platform.c | 4 +- trunk/drivers/net/can/softing/softing_fw.c | 7 +- .../net/ethernet/broadcom/bnx2x/bnx2x.h | 3 + .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 - .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 +- .../ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 + .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 18 +- trunk/drivers/net/ethernet/emulex/benet/be.h | 1 - .../net/ethernet/emulex/benet/be_cmds.c | 8 +- .../net/ethernet/emulex/benet/be_main.c | 24 +- trunk/drivers/net/ethernet/freescale/Kconfig | 7 - trunk/drivers/net/ethernet/freescale/Makefile | 1 - .../net/ethernet/freescale/fsl_pq_mdio.c | 549 ++++++++-------- .../net/ethernet/freescale/fsl_pq_mdio.h | 52 ++ .../drivers/net/ethernet/freescale/gianfar.c | 3 +- .../drivers/net/ethernet/freescale/ucc_geth.c | 1 + .../net/ethernet/freescale/xgmac_mdio.c | 274 -------- .../drivers/net/ethernet/intel/e1000e/82571.c | 4 +- .../drivers/net/ethernet/intel/e1000e/e1000.h | 1 - .../net/ethernet/intel/e1000e/ethtool.c | 3 +- .../net/ethernet/intel/e1000e/netdev.c | 67 +- .../net/ethernet/intel/ixgbevf/ixgbevf.h | 4 +- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 160 +---- trunk/drivers/net/ethernet/intel/ixgbevf/vf.c | 14 - trunk/drivers/net/ethernet/intel/ixgbevf/vf.h | 1 - trunk/drivers/net/ethernet/nvidia/forcedeth.c | 17 +- trunk/drivers/net/ethernet/realtek/r8169.c | 2 - trunk/drivers/net/ethernet/sfc/efx.c | 235 +++---- trunk/drivers/net/ethernet/sfc/ethtool.c | 8 +- .../drivers/net/ethernet/sfc/falcon_boards.c | 2 +- trunk/drivers/net/ethernet/sfc/net_driver.h | 49 +- trunk/drivers/net/ethernet/sfc/nic.c | 6 +- trunk/drivers/net/ethernet/sfc/tx.c | 621 +++++++++++------- .../net/ethernet/stmicro/stmmac/common.h | 5 - .../net/ethernet/stmicro/stmmac/descs.h | 6 - .../net/ethernet/stmicro/stmmac/descs_com.h | 5 - .../net/ethernet/stmicro/stmmac/dwmac100.h | 5 - .../net/ethernet/stmicro/stmmac/dwmac1000.h | 5 +- .../net/ethernet/stmicro/stmmac/dwmac_dma.h | 5 - .../drivers/net/ethernet/stmicro/stmmac/mmc.h | 5 - .../net/ethernet/stmicro/stmmac/mmc_core.c | 6 +- .../net/ethernet/stmicro/stmmac/stmmac.h | 5 - .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 11 +- .../net/ethernet/stmicro/stmmac/stmmac_pci.c | 1 + .../ethernet/stmicro/stmmac/stmmac_platform.c | 39 +- .../ethernet/stmicro/stmmac/stmmac_timer.h | 4 - .../drivers/net/ethernet/tundra/tsi108_eth.c | 1 + trunk/drivers/net/ethernet/wiznet/w5100.c | 3 +- trunk/drivers/net/ethernet/wiznet/w5300.c | 3 +- trunk/drivers/net/phy/Kconfig | 13 - trunk/drivers/net/phy/Makefile | 1 - trunk/drivers/net/phy/mdio-gpio.c | 132 ++-- trunk/drivers/net/phy/mdio-mux-mmioreg.c | 170 ----- trunk/drivers/net/team/team.c | 15 +- trunk/drivers/net/tun.c | 46 +- trunk/drivers/net/usb/cx82310_eth.c | 11 +- trunk/drivers/net/usb/sierra_net.c | 23 +- trunk/drivers/net/wimax/i2400m/driver.c | 3 +- trunk/drivers/net/wireless/adm8211.c | 4 +- trunk/drivers/net/wireless/airo.c | 48 +- trunk/drivers/net/wireless/at76c50x-usb.c | 4 +- trunk/drivers/net/wireless/ath/ath5k/eeprom.c | 2 +- trunk/drivers/net/wireless/ath/ath5k/eeprom.h | 1 - .../net/wireless/ath/ath5k/mac80211-ops.c | 3 +- trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 1 - trunk/drivers/net/wireless/ath/ath9k/htc.h | 1 - .../net/wireless/ath/ath9k/htc_drv_beacon.c | 2 +- .../net/wireless/ath/ath9k/htc_drv_main.c | 35 +- .../net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 5 +- trunk/drivers/net/wireless/ath/ath9k/xmit.c | 9 +- .../net/wireless/ath/carl9170/carl9170.h | 5 +- trunk/drivers/net/wireless/ath/carl9170/rx.c | 15 +- trunk/drivers/net/wireless/ath/carl9170/tx.c | 16 +- trunk/drivers/net/wireless/b43/main.c | 3 +- trunk/drivers/net/wireless/b43legacy/main.c | 1 - .../wireless/brcm80211/brcmsmac/mac80211_if.c | 9 +- trunk/drivers/net/wireless/ipw2x00/ipw2100.c | 3 +- .../drivers/net/wireless/iwlegacy/3945-mac.c | 12 +- .../drivers/net/wireless/iwlegacy/4965-mac.c | 26 +- trunk/drivers/net/wireless/iwlegacy/4965.h | 8 +- trunk/drivers/net/wireless/iwlwifi/dvm/agn.h | 13 +- .../net/wireless/iwlwifi/dvm/debugfs.c | 59 +- .../net/wireless/iwlwifi/dvm/mac80211.c | 8 +- trunk/drivers/net/wireless/iwlwifi/dvm/main.c | 24 +- trunk/drivers/net/wireless/iwlwifi/dvm/sta.c | 2 +- trunk/drivers/net/wireless/iwlwifi/dvm/tx.c | 18 +- trunk/drivers/net/wireless/iwlwifi/iwl-drv.c | 141 +--- trunk/drivers/net/wireless/iwlwifi/iwl-drv.h | 6 +- .../net/wireless/iwlwifi/iwl-op-mode.h | 3 +- .../drivers/net/wireless/iwlwifi/iwl-trans.h | 12 +- trunk/drivers/net/wireless/iwlwifi/pcie/drv.c | 6 - .../net/wireless/iwlwifi/pcie/internal.h | 3 +- trunk/drivers/net/wireless/iwlwifi/pcie/rx.c | 18 +- .../drivers/net/wireless/iwlwifi/pcie/trans.c | 58 +- trunk/drivers/net/wireless/iwlwifi/pcie/tx.c | 26 +- trunk/drivers/net/wireless/libertas_tf/main.c | 4 +- trunk/drivers/net/wireless/mac80211_hwsim.c | 8 +- trunk/drivers/net/wireless/mwl8k.c | 17 +- trunk/drivers/net/wireless/p54/lmac.h | 4 +- trunk/drivers/net/wireless/p54/main.c | 2 +- trunk/drivers/net/wireless/p54/txrx.c | 15 +- trunk/drivers/net/wireless/rt2x00/rt2x00.h | 4 +- trunk/drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +- trunk/drivers/net/wireless/rt2x00/rt2x00mac.c | 4 +- .../drivers/net/wireless/rt2x00/rt2x00queue.c | 20 +- .../net/wireless/rtl818x/rtl8180/dev.c | 6 +- .../net/wireless/rtl818x/rtl8187/dev.c | 6 +- trunk/drivers/net/wireless/rtlwifi/base.c | 3 +- trunk/drivers/net/wireless/rtlwifi/core.c | 8 +- trunk/drivers/net/wireless/rtlwifi/pci.c | 16 +- .../net/wireless/rtlwifi/rtl8192ce/trx.c | 5 +- .../net/wireless/rtlwifi/rtl8192ce/trx.h | 1 - .../net/wireless/rtlwifi/rtl8192cu/trx.c | 5 +- .../net/wireless/rtlwifi/rtl8192cu/trx.h | 4 +- .../net/wireless/rtlwifi/rtl8192de/trx.c | 5 +- .../net/wireless/rtlwifi/rtl8192de/trx.h | 1 - .../net/wireless/rtlwifi/rtl8192se/trx.c | 5 +- .../net/wireless/rtlwifi/rtl8192se/trx.h | 1 - trunk/drivers/net/wireless/rtlwifi/usb.c | 15 +- trunk/drivers/net/wireless/rtlwifi/wifi.h | 13 +- trunk/drivers/net/wireless/ti/wl1251/main.c | 4 +- trunk/drivers/net/wireless/ti/wlcore/main.c | 6 +- trunk/drivers/net/wireless/ti/wlcore/tx.c | 61 +- trunk/drivers/net/wireless/ti/wlcore/tx.h | 4 +- trunk/drivers/net/wireless/zd1211rw/zd_mac.c | 6 +- trunk/drivers/net/xen-netfront.c | 39 +- trunk/drivers/pwm/Kconfig | 31 +- trunk/drivers/pwm/core.c | 12 +- trunk/drivers/pwm/pwm-samsung.c | 1 - trunk/drivers/pwm/pwm-tegra.c | 4 +- trunk/drivers/pwm/pwm-tiecap.c | 4 +- trunk/drivers/pwm/pwm-tiehrpwm.c | 4 +- trunk/drivers/pwm/pwm-vt8500.c | 2 +- trunk/drivers/staging/winbond/wbusb.c | 4 +- trunk/drivers/target/target_core_pscsi.c | 9 +- trunk/drivers/target/target_core_transport.c | 15 +- trunk/drivers/target/tcm_fc/tcm_fc.h | 1 - trunk/drivers/target/tcm_fc/tfc_cmd.c | 8 +- trunk/drivers/target/tcm_fc/tfc_sess.c | 4 +- trunk/drivers/vfio/vfio.c | 19 +- trunk/drivers/vhost/tcm_vhost.c | 203 +++--- trunk/drivers/vhost/tcm_vhost.h | 12 +- trunk/drivers/video/console/fbcon.c | 3 - trunk/fs/ceph/debugfs.c | 1 - trunk/fs/ceph/inode.c | 15 +- trunk/fs/ceph/ioctl.c | 3 +- trunk/fs/eventpoll.c | 2 +- trunk/fs/namei.c | 8 +- trunk/fs/nfs/Makefile | 18 +- trunk/fs/nfs/client.c | 2 +- trunk/fs/nfs/idmap.c | 62 +- trunk/fs/nfs/nfs3proc.c | 2 +- trunk/fs/nfs/nfs4_fs.h | 3 - trunk/fs/nfs/nfs4client.c | 2 +- trunk/fs/nfs/nfs4proc.c | 76 +-- trunk/fs/nfs/nfs4super.c | 15 + trunk/fs/nfs/nfs4xdr.c | 26 +- trunk/fs/nfs/objlayout/objio_osd.c | 55 +- trunk/fs/nfs/pagelist.c | 2 - trunk/fs/nfs/pnfs.c | 39 +- trunk/fs/nfs/pnfs.h | 2 +- trunk/fs/nfs/super.c | 39 +- trunk/fs/nfs/write.c | 15 +- trunk/fs/seq_file.c | 4 - trunk/include/drm/drm_crtc.h | 2 + .../linux/bcma/bcma_driver_chipcommon.h | 26 - trunk/include/linux/bcma/bcma_regs.h | 2 - trunk/include/linux/if_vlan.h | 9 +- trunk/include/linux/inet_diag.h | 1 - trunk/include/linux/kref.h | 18 - trunk/include/linux/netdevice.h | 1 - trunk/include/linux/netlink.h | 1 - trunk/include/linux/nfs_page.h | 1 - trunk/include/linux/nfs_xdr.h | 1 - trunk/include/linux/nl80211.h | 30 +- trunk/include/linux/of_mdio.h | 33 - trunk/include/linux/pci_ids.h | 2 +- trunk/include/linux/rfkill.h | 31 - trunk/include/linux/seq_file.h | 14 - trunk/include/linux/snmp.h | 4 - trunk/include/linux/stmmac.h | 1 + trunk/include/linux/tcp.h | 45 +- trunk/include/net/ax25.h | 4 +- trunk/include/net/cfg80211.h | 40 +- trunk/include/net/ieee80211_radiotap.h | 11 - trunk/include/net/inet_frag.h | 2 + trunk/include/net/ip.h | 2 + trunk/include/net/ipv6.h | 5 +- trunk/include/net/mac80211.h | 87 +-- .../net/netfilter/nf_conntrack_ecache.h | 1 - trunk/include/net/netns/ipv4.h | 3 +- trunk/include/net/netns/packet.h | 2 +- trunk/include/net/request_sock.h | 49 +- trunk/include/net/sch_generic.h | 3 +- trunk/include/net/sock.h | 11 +- trunk/include/net/tcp.h | 83 +-- trunk/include/target/target_core_base.h | 2 + trunk/init/Kconfig | 19 + trunk/ipc/mqueue.c | 61 +- trunk/kernel/pid.c | 1 - trunk/kernel/pid_namespace.c | 2 - trunk/lib/nlattr.c | 4 - trunk/net/8021q/vlan_core.c | 6 - trunk/net/appletalk/atalk_proc.c | 3 +- trunk/net/atm/resources.c | 2 +- trunk/net/ax25/ax25_uid.c | 21 +- trunk/net/batman-adv/bat_iv_ogm.c | 96 ++- trunk/net/batman-adv/bridge_loop_avoidance.c | 214 ++---- trunk/net/batman-adv/bridge_loop_avoidance.h | 11 +- trunk/net/batman-adv/debugfs.c | 12 - trunk/net/batman-adv/gateway_client.c | 53 +- trunk/net/batman-adv/hard-interface.c | 13 +- trunk/net/batman-adv/main.c | 27 +- trunk/net/batman-adv/main.h | 29 +- trunk/net/batman-adv/packet.h | 35 +- trunk/net/batman-adv/routing.c | 85 +-- trunk/net/batman-adv/send.c | 8 +- trunk/net/batman-adv/soft-interface.c | 79 +-- trunk/net/batman-adv/soft-interface.h | 5 +- trunk/net/batman-adv/translation-table.c | 416 +++++------- trunk/net/batman-adv/translation-table.h | 4 +- trunk/net/batman-adv/types.h | 120 ++-- trunk/net/batman-adv/unicast.c | 16 +- trunk/net/batman-adv/vis.c | 144 ++-- trunk/net/batman-adv/vis.h | 2 +- trunk/net/ceph/ceph_common.c | 1 + trunk/net/ceph/debugfs.c | 4 - trunk/net/ceph/messenger.c | 11 +- trunk/net/ceph/mon_client.c | 51 +- trunk/net/core/dev.c | 24 +- trunk/net/core/fib_rules.c | 3 +- trunk/net/core/link_watch.c | 8 - trunk/net/core/netpoll.c | 13 +- trunk/net/core/request_sock.c | 95 --- trunk/net/core/scm.c | 31 +- trunk/net/core/sock.c | 12 +- trunk/net/decnet/af_decnet.c | 4 +- trunk/net/ieee802154/6lowpan.c | 53 +- trunk/net/ipv4/af_inet.c | 28 +- trunk/net/ipv4/devinet.c | 6 +- trunk/net/ipv4/fib_frontend.c | 7 +- trunk/net/ipv4/inet_connection_sock.c | 57 +- trunk/net/ipv4/inet_diag.c | 21 +- trunk/net/ipv4/ip_fragment.c | 8 +- trunk/net/ipv4/ip_output.c | 4 +- trunk/net/ipv4/ipmr.c | 14 +- trunk/net/ipv4/netfilter/nf_nat_sip.c | 5 +- trunk/net/ipv4/ping.c | 22 +- trunk/net/ipv4/proc.c | 4 - trunk/net/ipv4/raw.c | 4 +- trunk/net/ipv4/route.c | 11 +- trunk/net/ipv4/syncookies.c | 1 - trunk/net/ipv4/sysctl_net_ipv4.c | 87 +-- trunk/net/ipv4/tcp.c | 49 +- trunk/net/ipv4/tcp_fastopen.c | 83 +-- trunk/net/ipv4/tcp_input.c | 285 ++++---- trunk/net/ipv4/tcp_ipv4.c | 275 +------- trunk/net/ipv4/tcp_minisocks.c | 61 +- trunk/net/ipv4/tcp_output.c | 27 +- trunk/net/ipv4/tcp_timer.c | 39 +- trunk/net/ipv4/udp.c | 4 +- trunk/net/ipv4/udp_diag.c | 5 +- trunk/net/ipv6/addrconf.c | 35 +- trunk/net/ipv6/ip6_flowlabel.c | 47 +- trunk/net/ipv6/raw.c | 3 +- trunk/net/ipv6/syncookies.c | 1 - trunk/net/ipv6/tcp_ipv6.c | 11 +- trunk/net/ipv6/udp.c | 3 +- trunk/net/ipx/ipx_proc.c | 3 +- trunk/net/key/af_key.c | 2 +- trunk/net/l2tp/l2tp_core.c | 3 +- trunk/net/l2tp/l2tp_core.h | 1 - trunk/net/llc/llc_proc.c | 2 +- trunk/net/mac80211/aes_cmac.c | 6 +- trunk/net/mac80211/cfg.c | 66 +- trunk/net/mac80211/debugfs.c | 32 + trunk/net/mac80211/driver-ops.h | 11 +- trunk/net/mac80211/ibss.c | 15 +- trunk/net/mac80211/ieee80211_i.h | 30 +- trunk/net/mac80211/iface.c | 289 ++++---- trunk/net/mac80211/main.c | 21 +- trunk/net/mac80211/mesh.c | 28 +- trunk/net/mac80211/mesh.h | 3 - trunk/net/mac80211/mesh_hwmp.c | 2 + trunk/net/mac80211/mesh_pathtbl.c | 44 +- trunk/net/mac80211/mesh_plink.c | 38 +- trunk/net/mac80211/mlme.c | 240 +++---- trunk/net/mac80211/offchannel.c | 6 - trunk/net/mac80211/rate.h | 2 +- trunk/net/mac80211/rx.c | 58 +- trunk/net/mac80211/scan.c | 12 +- trunk/net/mac80211/status.c | 22 +- trunk/net/mac80211/trace.h | 11 +- trunk/net/mac80211/tx.c | 109 +-- trunk/net/mac80211/util.c | 57 +- trunk/net/netfilter/ipvs/ip_vs_ctl.c | 4 +- trunk/net/netfilter/nf_conntrack_core.c | 16 +- trunk/net/netfilter/nf_conntrack_netlink.c | 3 +- trunk/net/netfilter/nfnetlink_log.c | 20 +- trunk/net/netfilter/xt_LOG.c | 16 +- trunk/net/netfilter/xt_owner.c | 30 +- trunk/net/netfilter/xt_recent.c | 13 +- trunk/net/netlink/af_netlink.c | 10 +- trunk/net/openvswitch/flow.c | 10 +- trunk/net/packet/af_packet.c | 4 +- trunk/net/phonet/socket.c | 6 +- trunk/net/rfkill/core.c | 14 - trunk/net/sched/cls_api.c | 2 +- trunk/net/sched/cls_basic.c | 3 +- trunk/net/sched/cls_cgroup.c | 3 +- trunk/net/sched/cls_flow.c | 19 +- trunk/net/sched/cls_fw.c | 3 +- trunk/net/sched/cls_route.c | 3 +- trunk/net/sched/cls_rsvp.h | 3 +- trunk/net/sched/cls_tcindex.c | 3 +- trunk/net/sched/cls_u32.c | 3 +- trunk/net/sctp/proc.c | 6 +- trunk/net/unix/af_unix.c | 12 +- trunk/net/wireless/chan.c | 7 +- trunk/net/wireless/core.c | 53 +- trunk/net/wireless/mlme.c | 10 +- trunk/net/wireless/nl80211.c | 122 +--- trunk/net/wireless/radiotap.c | 2 - trunk/net/wireless/util.c | 36 +- 375 files changed, 3509 insertions(+), 6864 deletions(-) delete mode 100644 trunk/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt rename trunk/drivers/{net => }/ieee802154/Kconfig (100%) rename trunk/drivers/{net => }/ieee802154/Makefile (100%) rename trunk/drivers/{net => }/ieee802154/at86rf230.c (98%) rename trunk/drivers/{net => }/ieee802154/fakehard.c (99%) rename trunk/drivers/{net => }/ieee802154/fakelb.c (100%) create mode 100644 trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.h delete mode 100644 trunk/drivers/net/ethernet/freescale/xgmac_mdio.c delete mode 100644 trunk/drivers/net/phy/mdio-mux-mmioreg.c diff --git a/[refs] b/[refs] index ed872242a609..1e5b7bcf2e42 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 684bad1107571d35610a674c61b3544efb5a5b13 +refs/heads/master: 5f2d04f1f9b52604fca6ee08a77972c0df67e082 diff --git a/trunk/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt b/trunk/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt deleted file mode 100644 index 8516929c7251..000000000000 --- a/trunk/Documentation/devicetree/bindings/net/mdio-mux-mmioreg.txt +++ /dev/null @@ -1,75 +0,0 @@ -Properties for an MDIO bus multiplexer controlled by a memory-mapped device - -This is a special case of a MDIO bus multiplexer. A memory-mapped device, -like an FPGA, is used to control which child bus is connected. The mdio-mux -node must be a child of the memory-mapped device. The driver currently only -supports devices with eight-bit registers. - -Required properties in addition to the generic multiplexer properties: - -- compatible : string, must contain "mdio-mux-mmioreg" - -- reg : integer, contains the offset of the register that controls the bus - multiplexer. The size field in the 'reg' property is the size of - register, and must therefore be 1. - -- mux-mask : integer, contains an eight-bit mask that specifies which - bits in the register control the actual bus multiplexer. The - 'reg' property of each child mdio-mux node must be constrained by - this mask. - -Example: - -The FPGA node defines a memory-mapped FPGA with a register space of 0x30 bytes. -For the "EMI2" MDIO bus, register 9 (BRDCFG1) controls the mux on that bus. -A bitmask of 0x6 means that bits 1 and 2 (bit 0 is lsb) are the bits on -BRDCFG1 that control the actual mux. - - /* The FPGA node */ - fpga: board-control@3,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis"; - reg = <3 0 0x30>; - ranges = <0 3 0 0x30>; - - mdio-mux-emi2 { - compatible = "mdio-mux-mmioreg", "mdio-mux"; - mdio-parent-bus = <&xmdio0>; - #address-cells = <1>; - #size-cells = <0>; - reg = <9 1>; // BRDCFG1 - mux-mask = <0x6>; // EMI2 - - emi2_slot1: mdio@0 { // Slot 1 XAUI (FM2) - reg = <0>; - #address-cells = <1>; - #size-cells = <0>; - - phy_xgmii_slot1: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c45"; - reg = <4>; - }; - }; - - emi2_slot2: mdio@2 { // Slot 2 XAUI (FM1) - reg = <2>; - #address-cells = <1>; - #size-cells = <0>; - - phy_xgmii_slot2: ethernet-phy@4 { - compatible = "ethernet-phy-ieee802.3-c45"; - reg = <0>; - }; - }; - }; - }; - - /* The parent MDIO bus. */ - xmdio0: mdio@f1000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,fman-xmdio"; - reg = <0xf1000 0x1000>; - interrupts = <100 1 0 0>; - }; diff --git a/trunk/Documentation/networking/batman-adv.txt b/trunk/Documentation/networking/batman-adv.txt index a173d2a879f5..8f3ae4a6147e 100644 --- a/trunk/Documentation/networking/batman-adv.txt +++ b/trunk/Documentation/networking/batman-adv.txt @@ -75,10 +75,9 @@ folder: There is a special folder for debugging information: -# ls /sys/kernel/debug/batman_adv/bat0/ -# bla_backbone_table log transtable_global -# bla_claim_table originators transtable_local -# gateways socket vis_data +# ls /sys/kernel/debug/batman_adv/bat0/ +# bla_claim_table log socket transtable_local +# gateways originators transtable_global vis_data Some of the files contain all sort of status information regard- ing the mesh network. For example, you can view the table of diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index c7fc10724948..ca447b35b833 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -439,9 +439,7 @@ tcp_stdurg - BOOLEAN tcp_synack_retries - INTEGER Number of times SYNACKs for a passive TCP connection attempt will be retransmitted. Should not be higher than 255. Default value - is 5, which corresponds to 31seconds till the last retransmission - with the current initial RTO of 1second. With this the final timeout - for a passive TCP connection will happen after 63seconds. + is 5, which corresponds to ~180seconds. tcp_syncookies - BOOLEAN Only valid when the kernel was compiled with CONFIG_SYNCOOKIES @@ -467,37 +465,20 @@ tcp_syncookies - BOOLEAN tcp_fastopen - INTEGER Enable TCP Fast Open feature (draft-ietf-tcpm-fastopen) to send data in the opening SYN packet. To use this feature, the client application - must use sendmsg() or sendto() with MSG_FASTOPEN flag rather than - connect() to perform a TCP handshake automatically. - - The values (bitmap) are - 1: Enables sending data in the opening SYN on the client. - 2: Enables TCP Fast Open on the server side, i.e., allowing data in - a SYN packet to be accepted and passed to the application before - 3-way hand shake finishes. - 4: Send data in the opening SYN regardless of cookie availability and - without a cookie option. - 0x100: Accept SYN data w/o validating the cookie. - 0x200: Accept data-in-SYN w/o any cookie option present. - 0x400/0x800: Enable Fast Open on all listeners regardless of the - TCP_FASTOPEN socket option. The two different flags designate two - different ways of setting max_qlen without the TCP_FASTOPEN socket - option. + must not use connect(). Instead, it should use sendmsg() or sendto() + with MSG_FASTOPEN flag which performs a TCP handshake automatically. - Default: 0 - - Note that the client & server side Fast Open flags (1 and 2 - respectively) must be also enabled before the rest of flags can take - effect. + The values (bitmap) are: + 1: Enables sending data in the opening SYN on the client + 5: Enables sending data in the opening SYN on the client regardless + of cookie availability. - See include/net/tcp.h and the code for more details. + Default: 0 tcp_syn_retries - INTEGER Number of times initial SYNs for an active TCP connection attempt will be retransmitted. Should not be higher than 255. Default value - is 6, which corresponds to 63seconds till the last restransmission - with the current initial RTO of 1second. With this the final timeout - for an active TCP connection attempt will happen after 127seconds. + is 5, which corresponds to ~180seconds. tcp_timestamps - BOOLEAN Enable timestamps as defined in RFC1323. diff --git a/trunk/Documentation/networking/stmmac.txt b/trunk/Documentation/networking/stmmac.txt index ef9ee71b4d7f..c676b9cedbd0 100644 --- a/trunk/Documentation/networking/stmmac.txt +++ b/trunk/Documentation/networking/stmmac.txt @@ -173,6 +173,7 @@ Where: For MDIO bus The we have: struct stmmac_mdio_bus_data { + int bus_id; int (*phy_reset)(void *priv); unsigned int phy_mask; int *irqs; @@ -180,6 +181,7 @@ For MDIO bus The we have: }; Where: + o bus_id: bus identifier; o phy_reset: hook to reset the phy device attached to the bus. o phy_mask: phy mask passed when register the MDIO bus within the driver. o irqs: list of IRQs, one per PHY. @@ -228,6 +230,9 @@ there are two MAC cores: one MAC is for MDIO Bus/PHY emulation with fixed_link support. static struct stmmac_mdio_bus_data stmmac1_mdio_bus = { + .bus_id = 1, + | + |-> phy device on the bus_id 1 .phy_reset = phy_reset; | |-> function to provide the phy_reset on this board diff --git a/trunk/Makefile b/trunk/Makefile index 354026873b13..9cc77acfc881 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc2 NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index 1ecd1bfe5069..5b421840c48d 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -120,6 +120,7 @@ obj-$(CONFIG_VHOST_NET) += vhost/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ +obj-y += ieee802154/ #common clk code obj-y += clk/ diff --git a/trunk/drivers/acpi/acpica/tbxface.c b/trunk/drivers/acpi/acpica/tbxface.c index 29e51bc01383..ea4c6d52605a 100644 --- a/trunk/drivers/acpi/acpica/tbxface.c +++ b/trunk/drivers/acpi/acpica/tbxface.c @@ -387,7 +387,6 @@ acpi_get_table_with_size(char *signature, return (AE_NOT_FOUND); } -ACPI_EXPORT_SYMBOL(acpi_get_table_with_size) acpi_status acpi_get_table(char *signature, diff --git a/trunk/drivers/bcma/Kconfig b/trunk/drivers/bcma/Kconfig index a533af218368..06b3207adebd 100644 --- a/trunk/drivers/bcma/Kconfig +++ b/trunk/drivers/bcma/Kconfig @@ -48,12 +48,12 @@ config BCMA_DRIVER_MIPS config BCMA_SFLASH bool - depends on BCMA_DRIVER_MIPS + depends on BCMA_DRIVER_MIPS && BROKEN default y config BCMA_NFLASH bool - depends on BCMA_DRIVER_MIPS + depends on BCMA_DRIVER_MIPS && BROKEN default y config BCMA_DRIVER_GMAC_CMN diff --git a/trunk/drivers/bcma/bcma_private.h b/trunk/drivers/bcma/bcma_private.h index 169fc58427d3..3cf9cc923cd2 100644 --- a/trunk/drivers/bcma/bcma_private.h +++ b/trunk/drivers/bcma/bcma_private.h @@ -54,7 +54,6 @@ u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc); #ifdef CONFIG_BCMA_SFLASH /* driver_chipcommon_sflash.c */ int bcma_sflash_init(struct bcma_drv_cc *cc); -extern struct platform_device bcma_sflash_dev; #else static inline int bcma_sflash_init(struct bcma_drv_cc *cc) { @@ -66,7 +65,6 @@ static inline int bcma_sflash_init(struct bcma_drv_cc *cc) #ifdef CONFIG_BCMA_NFLASH /* driver_chipcommon_nflash.c */ int bcma_nflash_init(struct bcma_drv_cc *cc); -extern struct platform_device bcma_nflash_dev; #else static inline int bcma_nflash_init(struct bcma_drv_cc *cc) { diff --git a/trunk/drivers/bcma/driver_chipcommon_nflash.c b/trunk/drivers/bcma/driver_chipcommon_nflash.c index 9042781edec3..574d62435bc2 100644 --- a/trunk/drivers/bcma/driver_chipcommon_nflash.c +++ b/trunk/drivers/bcma/driver_chipcommon_nflash.c @@ -5,37 +5,15 @@ * Licensed under the GNU/GPL. See COPYING for details. */ -#include #include +#include +#include #include "bcma_private.h" -struct platform_device bcma_nflash_dev = { - .name = "bcma_nflash", - .num_resources = 0, -}; - /* Initialize NAND flash access */ int bcma_nflash_init(struct bcma_drv_cc *cc) { - struct bcma_bus *bus = cc->core->bus; - - if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && - cc->core->id.rev != 0x38) { - bcma_err(bus, "NAND flash on unsupported board!\n"); - return -ENOTSUPP; - } - - if (!(cc->capabilities & BCMA_CC_CAP_NFLASH)) { - bcma_err(bus, "NAND flash not present according to ChipCommon\n"); - return -ENODEV; - } - - cc->nflash.present = true; - - /* Prepare platform device, but don't register it yet. It's too early, - * malloc (required by device_private_init) is not available yet. */ - bcma_nflash_dev.dev.platform_data = &cc->nflash; - + bcma_err(cc->core->bus, "NAND flash support is broken\n"); return 0; } diff --git a/trunk/drivers/bcma/driver_chipcommon_sflash.c b/trunk/drivers/bcma/driver_chipcommon_sflash.c index 2c4eec2ca5a0..6e157a58a1d7 100644 --- a/trunk/drivers/bcma/driver_chipcommon_sflash.c +++ b/trunk/drivers/bcma/driver_chipcommon_sflash.c @@ -5,132 +5,15 @@ * Licensed under the GNU/GPL. See COPYING for details. */ -#include #include +#include +#include #include "bcma_private.h" -static struct resource bcma_sflash_resource = { - .name = "bcma_sflash", - .start = BCMA_SFLASH, - .end = 0, - .flags = IORESOURCE_MEM | IORESOURCE_READONLY, -}; - -struct platform_device bcma_sflash_dev = { - .name = "bcma_sflash", - .resource = &bcma_sflash_resource, - .num_resources = 1, -}; - -struct bcma_sflash_tbl_e { - char *name; - u32 id; - u32 blocksize; - u16 numblocks; -}; - -static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { - { "", 0x14, 0x10000, 32, }, - { 0 }, -}; - -static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = { - { 0 }, -}; - -static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = { - { 0 }, -}; - -static void bcma_sflash_cmd(struct bcma_drv_cc *cc, u32 opcode) -{ - int i; - bcma_cc_write32(cc, BCMA_CC_FLASHCTL, - BCMA_CC_FLASHCTL_START | opcode); - for (i = 0; i < 1000; i++) { - if (!(bcma_cc_read32(cc, BCMA_CC_FLASHCTL) & - BCMA_CC_FLASHCTL_BUSY)) - return; - cpu_relax(); - } - bcma_err(cc->core->bus, "SFLASH control command failed (timeout)!\n"); -} - /* Initialize serial flash access */ int bcma_sflash_init(struct bcma_drv_cc *cc) { - struct bcma_bus *bus = cc->core->bus; - struct bcma_sflash *sflash = &cc->sflash; - struct bcma_sflash_tbl_e *e; - u32 id, id2; - - switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { - case BCMA_CC_FLASHT_STSER: - bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_DP); - - bcma_cc_write32(cc, BCMA_CC_FLASHADDR, 0); - bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_RES); - id = bcma_cc_read32(cc, BCMA_CC_FLASHDATA); - - bcma_cc_write32(cc, BCMA_CC_FLASHADDR, 1); - bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_ST_RES); - id2 = bcma_cc_read32(cc, BCMA_CC_FLASHDATA); - - switch (id) { - case 0xbf: - for (e = bcma_sflash_sst_tbl; e->name; e++) { - if (e->id == id2) - break; - } - break; - default: - for (e = bcma_sflash_st_tbl; e->name; e++) { - if (e->id == id) - break; - } - break; - } - if (!e->name) { - bcma_err(bus, "Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n", id, id2); - return -ENOTSUPP; - } - - break; - case BCMA_CC_FLASHT_ATSER: - bcma_sflash_cmd(cc, BCMA_CC_FLASHCTL_AT_STATUS); - id = bcma_cc_read32(cc, BCMA_CC_FLASHDATA) & 0x3c; - - for (e = bcma_sflash_at_tbl; e->name; e++) { - if (e->id == id) - break; - } - if (!e->name) { - bcma_err(bus, "Unsupported Atmel serial flash (id: 0x%X)\n", id); - return -ENOTSUPP; - } - - break; - default: - bcma_err(bus, "Unsupported flash type\n"); - return -ENOTSUPP; - } - - sflash->window = BCMA_SFLASH; - sflash->blocksize = e->blocksize; - sflash->numblocks = e->numblocks; - sflash->size = sflash->blocksize * sflash->numblocks; - sflash->present = true; - - bcma_info(bus, "Found %s serial flash (size: %dKiB, blocksize: 0x%X, blocks: %d)\n", - e->name, sflash->size / 1024, sflash->blocksize, - sflash->numblocks); - - /* Prepare platform device, but don't register it yet. It's too early, - * malloc (required by device_private_init) is not available yet. */ - bcma_sflash_dev.resource[0].end = bcma_sflash_dev.resource[0].start + - sflash->size; - bcma_sflash_dev.dev.platform_data = sflash; - + bcma_err(cc->core->bus, "Serial flash support is broken\n"); return 0; } diff --git a/trunk/drivers/bcma/main.c b/trunk/drivers/bcma/main.c index a8f570d69075..758af9ccdef0 100644 --- a/trunk/drivers/bcma/main.c +++ b/trunk/drivers/bcma/main.c @@ -7,7 +7,6 @@ #include "bcma_private.h" #include -#include #include #include @@ -137,22 +136,6 @@ static int bcma_register_cores(struct bcma_bus *bus) dev_id++; } -#ifdef CONFIG_BCMA_SFLASH - if (bus->drv_cc.sflash.present) { - err = platform_device_register(&bcma_sflash_dev); - if (err) - bcma_err(bus, "Error registering serial flash\n"); - } -#endif - -#ifdef CONFIG_BCMA_NFLASH - if (bus->drv_cc.nflash.present) { - err = platform_device_register(&bcma_nflash_dev); - if (err) - bcma_err(bus, "Error registering NAND flash\n"); - } -#endif - return 0; } diff --git a/trunk/drivers/char/agp/intel-agp.h b/trunk/drivers/char/agp/intel-agp.h index 6ec0fff79bc2..6f007b6c240d 100644 --- a/trunk/drivers/char/agp/intel-agp.h +++ b/trunk/drivers/char/agp/intel-agp.h @@ -64,7 +64,6 @@ #define I830_PTE_SYSTEM_CACHED 0x00000006 /* GT PTE cache control fields */ #define GEN6_PTE_UNCACHED 0x00000002 -#define HSW_PTE_UNCACHED 0x00000000 #define GEN6_PTE_LLC 0x00000004 #define GEN6_PTE_LLC_MLC 0x00000006 #define GEN6_PTE_GFDT 0x00000008 diff --git a/trunk/drivers/char/agp/intel-gtt.c b/trunk/drivers/char/agp/intel-gtt.c index 58e32f7c3229..08fc5cbb13cd 100644 --- a/trunk/drivers/char/agp/intel-gtt.c +++ b/trunk/drivers/char/agp/intel-gtt.c @@ -1156,30 +1156,6 @@ static bool gen6_check_flags(unsigned int flags) return true; } -static void haswell_write_entry(dma_addr_t addr, unsigned int entry, - unsigned int flags) -{ - unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; - unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; - u32 pte_flags; - - if (type_mask == AGP_USER_MEMORY) - pte_flags = HSW_PTE_UNCACHED | I810_PTE_VALID; - else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { - pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; - if (gfdt) - pte_flags |= GEN6_PTE_GFDT; - } else { /* set 'normal'/'cached' to LLC by default */ - pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; - if (gfdt) - pte_flags |= GEN6_PTE_GFDT; - } - - /* gen6 has bit11-4 for physical addr bit39-32 */ - addr |= (addr >> 28) & 0xff0; - writel(addr | pte_flags, intel_private.gtt + entry); -} - static void gen6_write_entry(dma_addr_t addr, unsigned int entry, unsigned int flags) { @@ -1406,15 +1382,6 @@ static const struct intel_gtt_driver sandybridge_gtt_driver = { .check_flags = gen6_check_flags, .chipset_flush = i9xx_chipset_flush, }; -static const struct intel_gtt_driver haswell_gtt_driver = { - .gen = 6, - .setup = i9xx_setup, - .cleanup = gen6_cleanup, - .write_entry = haswell_write_entry, - .dma_mask_size = 40, - .check_flags = gen6_check_flags, - .chipset_flush = i9xx_chipset_flush, -}; static const struct intel_gtt_driver valleyview_gtt_driver = { .gen = 7, .setup = i9xx_setup, @@ -1532,77 +1499,77 @@ static const struct intel_gtt_driver_description { { PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG, "ValleyView", &valleyview_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG, - "Haswell", &haswell_gtt_driver }, + "Haswell", &sandybridge_gtt_driver }, { 0, NULL, NULL } }; diff --git a/trunk/drivers/gpu/drm/drm_modes.c b/trunk/drivers/gpu/drm/drm_modes.c index 28637c181b15..b7adb4a967fd 100644 --- a/trunk/drivers/gpu/drm/drm_modes.c +++ b/trunk/drivers/gpu/drm/drm_modes.c @@ -706,6 +706,9 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); + + p->crtc_hadjusted = false; + p->crtc_vadjusted = false; } EXPORT_SYMBOL(drm_mode_set_crtcinfo); diff --git a/trunk/drivers/gpu/drm/drm_proc.c b/trunk/drivers/gpu/drm/drm_proc.c index da457b18eaaf..371c695322d9 100644 --- a/trunk/drivers/gpu/drm/drm_proc.c +++ b/trunk/drivers/gpu/drm/drm_proc.c @@ -89,7 +89,7 @@ static const struct file_operations drm_proc_fops = { * Create a given set of proc files represented by an array of * gdm_proc_lists in the given root directory. */ -static int drm_proc_create_files(struct drm_info_list *files, int count, +int drm_proc_create_files(struct drm_info_list *files, int count, struct proc_dir_entry *root, struct drm_minor *minor) { struct drm_device *dev = minor->dev; @@ -172,7 +172,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, return 0; } -static int drm_proc_remove_files(struct drm_info_list *files, int count, +int drm_proc_remove_files(struct drm_info_list *files, int count, struct drm_minor *minor) { struct list_head *pos, *q; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 489e2b162b27..5c4657a54f97 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -2365,10 +2365,6 @@ int i915_gpu_idle(struct drm_device *dev) /* Flush everything onto the inactive list. */ for_each_ring(ring, dev_priv, i) { - ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); - if (ret) - return ret; - ret = i915_ring_idle(ring); if (ret) return ret; @@ -2376,6 +2372,10 @@ int i915_gpu_idle(struct drm_device *dev) /* Is the device fubar? */ if (WARN_ON(!list_empty(&ring->gpu_write_list))) return -EBUSY; + + ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); + if (ret) + return ret; } return 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c index d9a5372ec56f..ee9b68f6bc36 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -261,10 +261,7 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, pte_flags |= GEN6_PTE_CACHE_LLC; break; case I915_CACHE_NONE: - if (IS_HASWELL(dev)) - pte_flags |= HSW_PTE_UNCACHED; - else - pte_flags |= GEN6_PTE_UNCACHED; + pte_flags |= GEN6_PTE_UNCACHED; break; default: BUG(); diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 28725ce5b82c..acc99b21e0b6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -115,7 +115,6 @@ #define GEN6_PTE_VALID (1 << 0) #define GEN6_PTE_UNCACHED (1 << 1) -#define HSW_PTE_UNCACHED (0) #define GEN6_PTE_CACHE_LLC (2 << 1) #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) #define GEN6_PTE_CACHE_BITS (3 << 1) diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 23bdc8cd1458..7ed4a41c3965 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -326,36 +326,6 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) return ret; } -static struct edid *intel_crt_get_edid(struct drm_connector *connector, - struct i2c_adapter *i2c) -{ - struct edid *edid; - - edid = drm_get_edid(connector, i2c); - - if (!edid && !intel_gmbus_is_forced_bit(i2c)) { - DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n"); - intel_gmbus_force_bit(i2c, true); - edid = drm_get_edid(connector, i2c); - intel_gmbus_force_bit(i2c, false); - } - - return edid; -} - -/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */ -static int intel_crt_ddc_get_modes(struct drm_connector *connector, - struct i2c_adapter *adapter) -{ - struct edid *edid; - - edid = intel_crt_get_edid(connector, adapter); - if (!edid) - return 0; - - return intel_connector_update_modes(connector, edid); -} - static bool intel_crt_detect_ddc(struct drm_connector *connector) { struct intel_crt *crt = intel_attached_crt(connector); @@ -366,7 +336,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); - edid = intel_crt_get_edid(connector, i2c); + edid = drm_get_edid(connector, i2c); if (edid) { bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; @@ -574,13 +544,13 @@ static int intel_crt_get_modes(struct drm_connector *connector) struct i2c_adapter *i2c; i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); - ret = intel_crt_ddc_get_modes(connector, i2c); + ret = intel_ddc_get_modes(connector, i2c); if (ret || !IS_G4X(dev)) return ret; /* Try to probe digital port for output in DVI-I -> VGA mode. */ i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); - return intel_crt_ddc_get_modes(connector, i2c); + return intel_ddc_get_modes(connector, i2c); } static int intel_crt_set_property(struct drm_connector *connector, diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index cd54cf88a28f..132ab511b90c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -342,8 +342,6 @@ struct intel_fbc_work { int interval; }; -int intel_connector_update_modes(struct drm_connector *connector, - struct edid *edid); int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); extern void intel_attach_force_audio_property(struct drm_connector *connector); diff --git a/trunk/drivers/gpu/drm/i915/intel_modes.c b/trunk/drivers/gpu/drm/i915/intel_modes.c index 29b72593fbb2..45848b9b670b 100644 --- a/trunk/drivers/gpu/drm/i915/intel_modes.c +++ b/trunk/drivers/gpu/drm/i915/intel_modes.c @@ -32,25 +32,6 @@ #include "intel_drv.h" #include "i915_drv.h" -/** - * intel_connector_update_modes - update connector from edid - * @connector: DRM connector device to use - * @edid: previously read EDID information - */ -int intel_connector_update_modes(struct drm_connector *connector, - struct edid *edid) -{ - int ret; - - drm_mode_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - drm_edid_to_eld(connector, edid); - connector->display_info.raw_edid = NULL; - kfree(edid); - - return ret; -} - /** * intel_ddc_get_modes - get modelist from monitor * @connector: DRM connector device to use @@ -62,12 +43,18 @@ int intel_ddc_get_modes(struct drm_connector *connector, struct i2c_adapter *adapter) { struct edid *edid; + int ret = 0; edid = drm_get_edid(connector, adapter); - if (!edid) - return 0; + if (edid) { + drm_mode_connector_update_edid_property(connector, edid); + ret = drm_add_edid_modes(connector, edid); + drm_edid_to_eld(connector, edid); + connector->display_info.raw_edid = NULL; + kfree(edid); + } - return intel_connector_update_modes(connector, edid); + return ret; } static const struct drm_prop_enum_list force_audio_names[] = { diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index 1881c8c83f0e..58c07cdafb7e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -2441,10 +2441,17 @@ static void gen6_enable_rps(struct drm_device *dev) dev_priv->max_delay << 24 | dev_priv->min_delay << 16); - I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); - I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); - I915_WRITE(GEN6_RP_UP_EI, 66000); - I915_WRITE(GEN6_RP_DOWN_EI, 350000); + if (IS_HASWELL(dev)) { + I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); + I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); + I915_WRITE(GEN6_RP_UP_EI, 66000); + I915_WRITE(GEN6_RP_DOWN_EI, 350000); + } else { + I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); + I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); + I915_WRITE(GEN6_RP_UP_EI, 100000); + I915_WRITE(GEN6_RP_DOWN_EI, 5000000); + } I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); I915_WRITE(GEN6_RP_CONTROL, diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index d81bb0bf2885..d172e9873131 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -1692,7 +1692,6 @@ static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) edid = intel_sdvo_get_edid(connector); if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) has_audio = drm_detect_monitor_audio(edid); - kfree(edid); return has_audio; } diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index f4d4505fe831..c6fcb5b86a45 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -444,28 +444,11 @@ union atom_enable_ss { static void atombios_crtc_program_ss(struct radeon_device *rdev, int enable, int pll_id, - int crtc_id, struct radeon_atom_ss *ss) { - unsigned i; int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); union atom_enable_ss args; - if (!enable) { - for (i = 0; i < rdev->num_crtc; i++) { - if (rdev->mode_info.crtcs[i] && - rdev->mode_info.crtcs[i]->enabled && - i != crtc_id && - pll_id == rdev->mode_info.crtcs[i]->pll_id) { - /* one other crtc is using this pll don't turn - * off spread spectrum as it might turn off - * display on active crtc - */ - return; - } - } - } - memset(&args, 0, sizeof(args)); if (ASIC_IS_DCE5(rdev)) { @@ -1045,7 +1028,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, &ref_div, &post_div); - atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); + atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, encoder_mode, radeon_encoder->encoder_id, mode->clock, @@ -1068,7 +1051,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode ss.step = step_size; } - atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); + atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); } } @@ -1589,11 +1572,11 @@ void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev) ASIC_INTERNAL_SS_ON_DCPLL, rdev->clock.default_dispclk); if (ss_enabled) - atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss); + atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); /* XXX: DCE5, make sure voltage, dispclk is high enough */ atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); if (ss_enabled) - atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss); + atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); } } diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index ab74e6b149e7..3dab49cb1d4a 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -47,17 +47,13 @@ struct r600_cs_track { u32 npipes; /* value we track */ u32 sq_config; - u32 log_nsamples; u32 nsamples; u32 cb_color_base_last[8]; struct radeon_bo *cb_color_bo[8]; u64 cb_color_bo_mc[8]; - u64 cb_color_bo_offset[8]; - struct radeon_bo *cb_color_frag_bo[8]; - u64 cb_color_frag_offset[8]; - struct radeon_bo *cb_color_tile_bo[8]; - u64 cb_color_tile_offset[8]; - u32 cb_color_mask[8]; + u32 cb_color_bo_offset[8]; + struct radeon_bo *cb_color_frag_bo[8]; /* unused */ + struct radeon_bo *cb_color_tile_bo[8]; /* unused */ u32 cb_color_info[8]; u32 cb_color_view[8]; u32 cb_color_size_idx[8]; /* unused */ @@ -353,6 +349,10 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) unsigned array_mode; u32 format; + if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { + dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); + return -EINVAL; + } size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; format = G_0280A0_FORMAT(track->cb_color_info[i]); if (!r600_fmt_is_valid_color(format)) { @@ -420,8 +420,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) } /* check offset */ - tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * - r600_fmt_get_blocksize(format) * track->nsamples; + tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); switch (array_mode) { default: case V_0280A0_ARRAY_LINEAR_GENERAL: @@ -442,7 +441,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) * broken userspace. */ } else { - dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n", + dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", __func__, i, array_mode, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]), @@ -459,51 +458,6 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); ib[track->cb_color_size_idx[i]] = tmp; - - /* FMASK/CMASK */ - switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) { - case V_0280A0_TILE_DISABLE: - break; - case V_0280A0_FRAG_ENABLE: - if (track->nsamples > 1) { - uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]); - /* the tile size is 8x8, but the size is in units of bits. - * for bytes, do just * 8. */ - uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1); - - if (bytes + track->cb_color_frag_offset[i] > - radeon_bo_size(track->cb_color_frag_bo[i])) { - dev_warn(p->dev, "%s FMASK_TILE_MAX too large " - "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", - __func__, tile_max, bytes, - track->cb_color_frag_offset[i], - radeon_bo_size(track->cb_color_frag_bo[i])); - return -EINVAL; - } - } - /* fall through */ - case V_0280A0_CLEAR_ENABLE: - { - uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); - /* One block = 128x128 pixels, one 8x8 tile has 4 bits.. - * (128*128) / (8*8) / 2 = 128 bytes per block. */ - uint32_t bytes = (block_max + 1) * 128; - - if (bytes + track->cb_color_tile_offset[i] > - radeon_bo_size(track->cb_color_tile_bo[i])) { - dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large " - "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", - __func__, block_max, bytes, - track->cb_color_tile_offset[i], - radeon_bo_size(track->cb_color_tile_bo[i])); - return -EINVAL; - } - break; - } - default: - dev_warn(p->dev, "%s invalid tile mode\n", __func__); - return -EINVAL; - } return 0; } @@ -612,7 +566,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p) ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; - tmp = ntiles * bpe * 64 * nviews * track->nsamples; + tmp = ntiles * bpe * 64 * nviews; if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", array_mode, @@ -1277,7 +1231,6 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) break; case R_028C04_PA_SC_AA_CONFIG: tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); - track->log_nsamples = tmp; track->nsamples = 1 << tmp; track->cb_dirty = true; break; @@ -1359,21 +1312,16 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); return -EINVAL; } - track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; - track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; ib[idx] = track->cb_color_base_last[tmp]; + track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; } else { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); return -EINVAL; } - track->cb_color_frag_bo[tmp] = reloc->robj; - track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8; ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - } - if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { - track->cb_dirty = true; + track->cb_color_frag_bo[tmp] = reloc->robj; } break; case R_0280C0_CB_COLOR0_TILE: @@ -1390,35 +1338,16 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); return -EINVAL; } - track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; - track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; ib[idx] = track->cb_color_base_last[tmp]; + track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; } else { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); return -EINVAL; } - track->cb_color_tile_bo[tmp] = reloc->robj; - track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8; ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - } - if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { - track->cb_dirty = true; - } - break; - case R_028100_CB_COLOR0_MASK: - case R_028104_CB_COLOR1_MASK: - case R_028108_CB_COLOR2_MASK: - case R_02810C_CB_COLOR3_MASK: - case R_028110_CB_COLOR4_MASK: - case R_028114_CB_COLOR5_MASK: - case R_028118_CB_COLOR6_MASK: - case R_02811C_CB_COLOR7_MASK: - tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; - track->cb_color_mask[tmp] = ib[idx]; - if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { - track->cb_dirty = true; + track->cb_color_tile_bo[tmp] = reloc->robj; } break; case CB_COLOR0_BASE: @@ -1563,7 +1492,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level) } static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, - unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format, + unsigned w0, unsigned h0, unsigned d0, unsigned format, unsigned block_align, unsigned height_align, unsigned base_align, unsigned *l0_size, unsigned *mipmap_size) { @@ -1591,7 +1520,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, depth = r600_mip_minify(d0, i); - size = nbx * nby * blocksize * nsamples; + size = nbx * nby * blocksize; if (nfaces) size *= nfaces; else @@ -1743,7 +1672,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, nfaces = larray - barray + 1; } - r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format, + r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, pitch_align, height_align, base_align, &l0_size, &mipmap_size); /* using get ib will give us the offset into the texture bo */ diff --git a/trunk/drivers/gpu/drm/radeon/r600d.h b/trunk/drivers/gpu/drm/radeon/r600d.h index bdb69a63062f..fd328f4c3ea8 100644 --- a/trunk/drivers/gpu/drm/radeon/r600d.h +++ b/trunk/drivers/gpu/drm/radeon/r600d.h @@ -92,20 +92,6 @@ #define R_028094_CB_COLOR5_VIEW 0x028094 #define R_028098_CB_COLOR6_VIEW 0x028098 #define R_02809C_CB_COLOR7_VIEW 0x02809C -#define R_028100_CB_COLOR0_MASK 0x028100 -#define S_028100_CMASK_BLOCK_MAX(x) (((x) & 0xFFF) << 0) -#define G_028100_CMASK_BLOCK_MAX(x) (((x) >> 0) & 0xFFF) -#define C_028100_CMASK_BLOCK_MAX 0xFFFFF000 -#define S_028100_FMASK_TILE_MAX(x) (((x) & 0xFFFFF) << 12) -#define G_028100_FMASK_TILE_MAX(x) (((x) >> 12) & 0xFFFFF) -#define C_028100_FMASK_TILE_MAX 0x00000FFF -#define R_028104_CB_COLOR1_MASK 0x028104 -#define R_028108_CB_COLOR2_MASK 0x028108 -#define R_02810C_CB_COLOR3_MASK 0x02810C -#define R_028110_CB_COLOR4_MASK 0x028110 -#define R_028114_CB_COLOR5_MASK 0x028114 -#define R_028118_CB_COLOR6_MASK 0x028118 -#define R_02811C_CB_COLOR7_MASK 0x02811C #define CB_COLOR0_INFO 0x280a0 # define CB_FORMAT(x) ((x) << 2) # define CB_ARRAY_MODE(x) ((x) << 8) @@ -1414,9 +1400,6 @@ #define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) #define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) #define C_0280A0_TILE_MODE 0xFFF3FFFF -#define V_0280A0_TILE_DISABLE 0 -#define V_0280A0_CLEAR_ENABLE 1 -#define V_0280A0_FRAG_ENABLE 2 #define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20) #define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1) #define C_0280A0_BLEND_CLAMP 0xFFEFFFFF diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 59a15315ae9f..99304194a65c 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -142,6 +142,21 @@ struct radeon_device; /* * BIOS. */ +#define ATRM_BIOS_PAGE 4096 + +#if defined(CONFIG_VGA_SWITCHEROO) +bool radeon_atrm_supported(struct pci_dev *pdev); +int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); +#else +static inline bool radeon_atrm_supported(struct pci_dev *pdev) +{ + return false; +} + +static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ + return -EINVAL; +} +#endif bool radeon_get_bios(struct radeon_device *rdev); /* diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index d67d4f3eb6f4..f9c21f9d16bc 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -452,7 +452,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, } /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ - if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) && + if ((dev->pdev->device == 0x9802) && (dev->pdev->subsystem_vendor == 0x1734) && (dev->pdev->subsystem_device == 0x11bd)) { if (*connector_type == DRM_MODE_CONNECTOR_VGA) { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 2a2cf0b88a28..98724fcb0088 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -30,8 +30,57 @@ static struct radeon_atpx_priv { /* handle for device - and atpx */ acpi_handle dhandle; acpi_handle atpx_handle; + acpi_handle atrm_handle; } radeon_atpx_priv; +/* retrieve the ROM in 4k blocks */ +static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, + int offset, int len) +{ + acpi_status status; + union acpi_object atrm_arg_elements[2], *obj; + struct acpi_object_list atrm_arg; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; + + atrm_arg.count = 2; + atrm_arg.pointer = &atrm_arg_elements[0]; + + atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; + atrm_arg_elements[0].integer.value = offset; + + atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; + atrm_arg_elements[1].integer.value = len; + + status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); + if (ACPI_FAILURE(status)) { + printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); + return -ENODEV; + } + + obj = (union acpi_object *)buffer.pointer; + memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); + len = obj->buffer.length; + kfree(buffer.pointer); + return len; +} + +bool radeon_atrm_supported(struct pci_dev *pdev) +{ + /* get the discrete ROM only via ATRM */ + if (!radeon_atpx_priv.atpx_detected) + return false; + + if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) + return false; + return true; +} + + +int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) +{ + return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len); +} + static int radeon_atpx_get_version(acpi_handle handle) { acpi_status status; @@ -149,7 +198,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) { - acpi_handle dhandle, atpx_handle; + acpi_handle dhandle, atpx_handle, atrm_handle; acpi_status status; dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); @@ -160,8 +209,13 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) if (ACPI_FAILURE(status)) return false; + status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); + if (ACPI_FAILURE(status)) + return false; + radeon_atpx_priv.dhandle = dhandle; radeon_atpx_priv.atpx_handle = atpx_handle; + radeon_atpx_priv.atrm_handle = atrm_handle; return true; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c index d306cc8fdeaa..501f4881e5aa 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c @@ -32,7 +32,6 @@ #include #include -#include /* * BIOS. */ @@ -99,81 +98,16 @@ static bool radeon_read_bios(struct radeon_device *rdev) return true; } -#ifdef CONFIG_ACPI /* ATRM is used to get the BIOS on the discrete cards in * dual-gpu systems. */ -/* retrieve the ROM in 4k blocks */ -#define ATRM_BIOS_PAGE 4096 -/** - * radeon_atrm_call - fetch a chunk of the vbios - * - * @atrm_handle: acpi ATRM handle - * @bios: vbios image pointer - * @offset: offset of vbios image data to fetch - * @len: length of vbios image data to fetch - * - * Executes ATRM to fetch a chunk of the discrete - * vbios image on PX systems (all asics). - * Returns the length of the buffer fetched. - */ -static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, - int offset, int len) -{ - acpi_status status; - union acpi_object atrm_arg_elements[2], *obj; - struct acpi_object_list atrm_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; - - atrm_arg.count = 2; - atrm_arg.pointer = &atrm_arg_elements[0]; - - atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; - atrm_arg_elements[0].integer.value = offset; - - atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; - atrm_arg_elements[1].integer.value = len; - - status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); - if (ACPI_FAILURE(status)) { - printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); - return -ENODEV; - } - - obj = (union acpi_object *)buffer.pointer; - memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); - len = obj->buffer.length; - kfree(buffer.pointer); - return len; -} - static bool radeon_atrm_get_bios(struct radeon_device *rdev) { int ret; int size = 256 * 1024; int i; - struct pci_dev *pdev = NULL; - acpi_handle dhandle, atrm_handle; - acpi_status status; - bool found = false; - - /* ATRM is for the discrete card only */ - if (rdev->flags & RADEON_IS_IGP) - return false; - - while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { - dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); - if (!dhandle) - continue; - - status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); - if (!ACPI_FAILURE(status)) { - found = true; - break; - } - } - if (!found) + if (!radeon_atrm_supported(rdev->pdev)) return false; rdev->bios = kmalloc(size, GFP_KERNEL); @@ -183,10 +117,9 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) } for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { - ret = radeon_atrm_call(atrm_handle, - rdev->bios, - (i * ATRM_BIOS_PAGE), - ATRM_BIOS_PAGE); + ret = radeon_atrm_get_bios_chunk(rdev->bios, + (i * ATRM_BIOS_PAGE), + ATRM_BIOS_PAGE); if (ret < ATRM_BIOS_PAGE) break; } @@ -197,12 +130,6 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) } return true; } -#else -static inline bool radeon_atrm_get_bios(struct radeon_device *rdev) -{ - return false; -} -#endif static bool ni_read_disabled_bios(struct radeon_device *rdev) { @@ -549,61 +476,6 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) return legacy_read_disabled_bios(rdev); } -#ifdef CONFIG_ACPI -static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) -{ - bool ret = false; - struct acpi_table_header *hdr; - acpi_size tbl_size; - UEFI_ACPI_VFCT *vfct; - GOP_VBIOS_CONTENT *vbios; - VFCT_IMAGE_HEADER *vhdr; - - if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size))) - return false; - if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { - DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); - goto out_unmap; - } - - vfct = (UEFI_ACPI_VFCT *)hdr; - if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { - DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); - goto out_unmap; - } - - vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); - vhdr = &vbios->VbiosHeader; - DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", - vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction, - vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength); - - if (vhdr->PCIBus != rdev->pdev->bus->number || - vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) || - vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) || - vhdr->VendorID != rdev->pdev->vendor || - vhdr->DeviceID != rdev->pdev->device) { - DRM_INFO("ACPI VFCT table is not for this card\n"); - goto out_unmap; - }; - - if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { - DRM_ERROR("ACPI VFCT image truncated\n"); - goto out_unmap; - } - - rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); - ret = !!rdev->bios; - -out_unmap: - return ret; -} -#else -static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev) -{ - return false; -} -#endif bool radeon_get_bios(struct radeon_device *rdev) { @@ -611,8 +483,6 @@ bool radeon_get_bios(struct radeon_device *rdev) uint16_t tmp; r = radeon_atrm_get_bios(rdev); - if (r == false) - r = radeon_acpi_vfct_bios(rdev); if (r == false) r = igp_read_bios_from_vram(rdev); if (r == false) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 27d22d709c90..d7269f48d37c 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -62,10 +62,9 @@ * 2.18.0 - r600-eg: allow "invalid" DB formats * 2.19.0 - r600-eg: MSAA textures * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query - * 2.21.0 - r600-r700: FMASK and CMASK */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 21 +#define KMS_DRIVER_MINOR 20 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index 9024e7222839..1cb014b571ab 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -132,7 +132,6 @@ int radeon_bo_create(struct radeon_device *rdev, acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, sizeof(struct radeon_bo)); -retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) return -ENOMEM; @@ -146,6 +145,8 @@ int radeon_bo_create(struct radeon_device *rdev, bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); INIT_LIST_HEAD(&bo->va); + +retry: radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ down_read(&rdev->pm.mclk_lock); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ring.c b/trunk/drivers/gpu/drm/radeon/radeon_ring.c index 43c431a2686d..ec79b3750430 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ring.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ring.c @@ -706,7 +706,6 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig if (radeon_debugfs_ring_init(rdev, ring)) { DRM_ERROR("Failed to register debugfs file for rings !\n"); } - radeon_ring_lockup_update(ring); return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/r600 b/trunk/drivers/gpu/drm/radeon/reg_srcs/r600 index f93e45d869f4..5e659b034d9a 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/r600 @@ -744,6 +744,14 @@ r600 0x9400 0x00028C38 CB_CLRCMP_DST 0x00028C3C CB_CLRCMP_MSK 0x00028C34 CB_CLRCMP_SRC +0x00028100 CB_COLOR0_MASK +0x00028104 CB_COLOR1_MASK +0x00028108 CB_COLOR2_MASK +0x0002810C CB_COLOR3_MASK +0x00028110 CB_COLOR4_MASK +0x00028114 CB_COLOR5_MASK +0x00028118 CB_COLOR6_MASK +0x0002811C CB_COLOR7_MASK 0x00028808 CB_COLOR_CONTROL 0x0002842C CB_FOG_BLUE 0x00028428 CB_FOG_GREEN diff --git a/trunk/drivers/gpu/drm/udl/udl_modeset.c b/trunk/drivers/gpu/drm/udl/udl_modeset.c index 9159d48d1dfd..f5dd89e891de 100644 --- a/trunk/drivers/gpu/drm/udl/udl_modeset.c +++ b/trunk/drivers/gpu/drm/udl/udl_modeset.c @@ -354,7 +354,8 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, static void udl_crtc_disable(struct drm_crtc *crtc) { - udl_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); + + } static void udl_crtc_destroy(struct drm_crtc *crtc) diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index c50724bd30f6..6b0078ffa763 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1688,19 +1688,15 @@ int vmw_du_page_flip(struct drm_crtc *crtc, struct vmw_private *dev_priv = vmw_priv(crtc->dev); struct drm_framebuffer *old_fb = crtc->fb; struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); - struct drm_file *file_priv ; + struct drm_file *file_priv = event->base.file_priv; struct vmw_fence_obj *fence = NULL; struct drm_clip_rect clips; int ret; - if (event == NULL) - return -EINVAL; - /* require ScreenObject support for page flipping */ if (!dev_priv->sou_priv) return -ENOSYS; - file_priv = event->base.file_priv; if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) return -EINVAL; diff --git a/trunk/drivers/i2c/busses/i2c-diolan-u2c.c b/trunk/drivers/i2c/busses/i2c-diolan-u2c.c index dae3ddfe7619..aedb94f34bf7 100644 --- a/trunk/drivers/i2c/busses/i2c-diolan-u2c.c +++ b/trunk/drivers/i2c/busses/i2c-diolan-u2c.c @@ -405,7 +405,6 @@ static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, } } } - ret = num; abort: sret = diolan_i2c_stop(dev); if (sret < 0 && ret >= 0) diff --git a/trunk/drivers/i2c/busses/i2c-nomadik.c b/trunk/drivers/i2c/busses/i2c-nomadik.c index 61b00edacb08..5e6f1eed4f83 100644 --- a/trunk/drivers/i2c/busses/i2c-nomadik.c +++ b/trunk/drivers/i2c/busses/i2c-nomadik.c @@ -350,6 +350,10 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev) i2c_clk = clk_get_rate(dev->clk); + /* fallback to std. mode if machine has not provided it */ + if (dev->cfg.clk_freq == 0) + dev->cfg.clk_freq = 100000; + /* * The spec says, in case of std. mode the divider is * 2 whereas it is 3 for fast and fastplus mode of @@ -907,32 +911,20 @@ static const struct i2c_algorithm nmk_i2c_algo = { .functionality = nmk_i2c_functionality }; -static struct nmk_i2c_controller u8500_i2c = { - /* - * Slave data setup time; 250ns, 100ns, and 10ns, which - * is 14, 6 and 2 respectively for a 48Mhz i2c clock. - */ - .slsu = 0xe, - .tft = 1, /* Tx FIFO threshold */ - .rft = 8, /* Rx FIFO threshold */ - .clk_freq = 400000, /* fast mode operation */ - .timeout = 200, /* Slave response timeout(ms) */ - .sm = I2C_FREQ_MODE_FAST, -}; - static atomic_t adapter_id = ATOMIC_INIT(0); static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) { int ret = 0; - struct nmk_i2c_controller *pdata = adev->dev.platform_data; + struct nmk_i2c_controller *pdata = + adev->dev.platform_data; struct nmk_i2c_dev *dev; struct i2c_adapter *adap; - if (!pdata) - /* No i2c configuration found, using the default. */ - pdata = &u8500_i2c; - + if (!pdata) { + dev_warn(&adev->dev, "no platform data\n"); + return -ENODEV; + } dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL); if (!dev) { dev_err(&adev->dev, "cannot allocate memory\n"); diff --git a/trunk/drivers/i2c/busses/i2c-omap.c b/trunk/drivers/i2c/busses/i2c-omap.c index 5d19a49803c1..6849635b268a 100644 --- a/trunk/drivers/i2c/busses/i2c-omap.c +++ b/trunk/drivers/i2c/busses/i2c-omap.c @@ -584,7 +584,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) r = pm_runtime_get_sync(dev->dev); if (IS_ERR_VALUE(r)) - goto out; + return r; r = omap_i2c_wait_for_bb(dev); if (r < 0) diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index 9a08c57bc936..66eb53fac202 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -712,7 +712,7 @@ static int __devexit tegra_i2c_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int tegra_i2c_suspend(struct device *dev) { struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); diff --git a/trunk/drivers/net/ieee802154/Kconfig b/trunk/drivers/ieee802154/Kconfig similarity index 100% rename from trunk/drivers/net/ieee802154/Kconfig rename to trunk/drivers/ieee802154/Kconfig diff --git a/trunk/drivers/net/ieee802154/Makefile b/trunk/drivers/ieee802154/Makefile similarity index 100% rename from trunk/drivers/net/ieee802154/Makefile rename to trunk/drivers/ieee802154/Makefile diff --git a/trunk/drivers/net/ieee802154/at86rf230.c b/trunk/drivers/ieee802154/at86rf230.c similarity index 98% rename from trunk/drivers/net/ieee802154/at86rf230.c rename to trunk/drivers/ieee802154/at86rf230.c index ba753d87a32f..5d309408395d 100644 --- a/trunk/drivers/net/ieee802154/at86rf230.c +++ b/trunk/drivers/ieee802154/at86rf230.c @@ -952,7 +952,17 @@ static struct spi_driver at86rf230_driver = { .resume = at86rf230_resume, }; -module_spi_driver(at86rf230_driver); +static int __init at86rf230_init(void) +{ + return spi_register_driver(&at86rf230_driver); +} +module_init(at86rf230_init); + +static void __exit at86rf230_exit(void) +{ + spi_unregister_driver(&at86rf230_driver); +} +module_exit(at86rf230_exit); MODULE_DESCRIPTION("AT86RF230 Transceiver Driver"); MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/net/ieee802154/fakehard.c b/trunk/drivers/ieee802154/fakehard.c similarity index 99% rename from trunk/drivers/net/ieee802154/fakehard.c rename to trunk/drivers/ieee802154/fakehard.c index 7d39add7d467..73d453159408 100644 --- a/trunk/drivers/net/ieee802154/fakehard.c +++ b/trunk/drivers/ieee802154/fakehard.c @@ -446,3 +446,4 @@ static __exit void fake_exit(void) module_init(fake_init); module_exit(fake_exit); MODULE_LICENSE("GPL"); + diff --git a/trunk/drivers/net/ieee802154/fakelb.c b/trunk/drivers/ieee802154/fakelb.c similarity index 100% rename from trunk/drivers/net/ieee802154/fakelb.c rename to trunk/drivers/ieee802154/fakelb.c diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 707ab7bd4ea5..0c2bd806950e 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -107,6 +107,8 @@ config MII or internal device. It is safe to say Y or M here even if your ethernet card lacks MII. +source "drivers/ieee802154/Kconfig" + config IFB tristate "Intermediate Functional Block support" depends on NET_CLS_ACT @@ -288,8 +290,6 @@ source "drivers/net/wimax/Kconfig" source "drivers/net/wan/Kconfig" -source "drivers/net/ieee802154/Kconfig" - config XEN_NETDEV_FRONTEND tristate "Xen network device frontend driver" depends on XEN diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index b682a1de7be8..3d375ca128a6 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -53,7 +53,6 @@ obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o obj-$(CONFIG_WAN) += wan/ obj-$(CONFIG_WLAN) += wireless/ obj-$(CONFIG_WIMAX) += wimax/ -obj-$(CONFIG_IEEE802154) += ieee802154/ obj-$(CONFIG_VMXNET3) += vmxnet3/ obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 7858c58df4a3..b24ce257ac7b 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -2811,13 +2811,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work) arp_work.work); struct slave *slave, *oldcurrent; int do_failover = 0; - int delta_in_ticks, extra_ticks; + int delta_in_ticks; int i; read_lock(&bond->lock); delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); - extra_ticks = delta_in_ticks / 2; if (bond->slave_cnt == 0) goto re_arm; @@ -2840,10 +2839,10 @@ void bond_loadbalance_arp_mon(struct work_struct *work) if (slave->link != BOND_LINK_UP) { if (time_in_range(jiffies, trans_start - delta_in_ticks, - trans_start + delta_in_ticks + extra_ticks) && + trans_start + delta_in_ticks) && time_in_range(jiffies, slave->dev->last_rx - delta_in_ticks, - slave->dev->last_rx + delta_in_ticks + extra_ticks)) { + slave->dev->last_rx + delta_in_ticks)) { slave->link = BOND_LINK_UP; bond_set_active_slave(slave); @@ -2873,10 +2872,10 @@ void bond_loadbalance_arp_mon(struct work_struct *work) */ if (!time_in_range(jiffies, trans_start - delta_in_ticks, - trans_start + 2 * delta_in_ticks + extra_ticks) || + trans_start + 2 * delta_in_ticks) || !time_in_range(jiffies, slave->dev->last_rx - delta_in_ticks, - slave->dev->last_rx + 2 * delta_in_ticks + extra_ticks)) { + slave->dev->last_rx + 2 * delta_in_ticks)) { slave->link = BOND_LINK_DOWN; bond_set_backup_slave(slave); @@ -2934,14 +2933,6 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) struct slave *slave; int i, commit = 0; unsigned long trans_start; - int extra_ticks; - - /* All the time comparisons below need some extra time. Otherwise, on - * fast networks the ARP probe/reply may arrive within the same jiffy - * as it was sent. Then, the next time the ARP monitor is run, one - * arp_interval will already have passed in the comparisons. - */ - extra_ticks = delta_in_ticks / 2; bond_for_each_slave(bond, slave, i) { slave->new_link = BOND_LINK_NOCHANGE; @@ -2949,7 +2940,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) if (slave->link != BOND_LINK_UP) { if (time_in_range(jiffies, slave_last_rx(bond, slave) - delta_in_ticks, - slave_last_rx(bond, slave) + delta_in_ticks + extra_ticks)) { + slave_last_rx(bond, slave) + delta_in_ticks)) { slave->new_link = BOND_LINK_UP; commit++; @@ -2965,7 +2956,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) */ if (time_in_range(jiffies, slave->jiffies - delta_in_ticks, - slave->jiffies + 2 * delta_in_ticks + extra_ticks)) + slave->jiffies + 2 * delta_in_ticks)) continue; /* @@ -2985,7 +2976,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) !bond->current_arp_slave && !time_in_range(jiffies, slave_last_rx(bond, slave) - delta_in_ticks, - slave_last_rx(bond, slave) + 3 * delta_in_ticks + extra_ticks)) { + slave_last_rx(bond, slave) + 3 * delta_in_ticks)) { slave->new_link = BOND_LINK_DOWN; commit++; @@ -3001,10 +2992,10 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks) if (bond_is_active_slave(slave) && (!time_in_range(jiffies, trans_start - delta_in_ticks, - trans_start + 2 * delta_in_ticks + extra_ticks) || + trans_start + 2 * delta_in_ticks) || !time_in_range(jiffies, slave_last_rx(bond, slave) - delta_in_ticks, - slave_last_rx(bond, slave) + 2 * delta_in_ticks + extra_ticks))) { + slave_last_rx(bond, slave) + 2 * delta_in_ticks))) { slave->new_link = BOND_LINK_DOWN; commit++; @@ -3036,7 +3027,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) if ((!bond->curr_active_slave && time_in_range(jiffies, trans_start - delta_in_ticks, - trans_start + delta_in_ticks + delta_in_ticks / 2)) || + trans_start + delta_in_ticks)) || bond->curr_active_slave != slave) { slave->link = BOND_LINK_UP; if (bond->current_arp_slave) { diff --git a/trunk/drivers/net/can/sja1000/sja1000_platform.c b/trunk/drivers/net/can/sja1000/sja1000_platform.c index 662c5f7eb0c5..4f50145f6483 100644 --- a/trunk/drivers/net/can/sja1000/sja1000_platform.c +++ b/trunk/drivers/net/can/sja1000/sja1000_platform.c @@ -109,9 +109,7 @@ static int sp_probe(struct platform_device *pdev) priv = netdev_priv(dev); dev->irq = res_irq->start; - priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; - if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) - priv->irq_flags |= IRQF_SHARED; + priv->irq_flags = res_irq->flags & (IRQF_TRIGGER_MASK | IRQF_SHARED); priv->reg_base = addr; /* The CAN clock frequency is half the oscillator clock frequency */ priv->can.clock.freq = pdata->osc_freq / 2; diff --git a/trunk/drivers/net/can/softing/softing_fw.c b/trunk/drivers/net/can/softing/softing_fw.c index b595d3422b9f..310596175676 100644 --- a/trunk/drivers/net/can/softing/softing_fw.c +++ b/trunk/drivers/net/can/softing/softing_fw.c @@ -150,7 +150,7 @@ int softing_load_fw(const char *file, struct softing *card, const uint8_t *mem, *end, *dat; uint16_t type, len; uint32_t addr; - uint8_t *buf = NULL, *new_buf; + uint8_t *buf = NULL; int buflen = 0; int8_t type_end = 0; @@ -199,12 +199,11 @@ int softing_load_fw(const char *file, struct softing *card, if (len > buflen) { /* align buflen */ buflen = (len + (1024-1)) & ~(1024-1); - new_buf = krealloc(buf, buflen, GFP_KERNEL); - if (!new_buf) { + buf = krealloc(buf, buflen, GFP_KERNEL); + if (!buf) { ret = -ENOMEM; goto failed; } - buf = new_buf; } /* verify record data */ memcpy_fromio(buf, &dpram[addr + offset], len); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 6d1a24acb77e..463b9ec57d80 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1708,6 +1708,9 @@ struct bnx2x_func_init_params { continue; \ else +#define for_each_napi_rx_queue(bp, var) \ + for ((var) = 0; (var) < bp->num_napi_queues; (var)++) + /* Skip OOO FP */ #define for_each_tx_queue(bp, var) \ for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index af20c6ee2cd9..e879e19eb0d6 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2046,8 +2046,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) */ bnx2x_setup_tc(bp->dev, bp->max_cos); - /* Add all NAPI objects */ - bnx2x_add_all_napi(bp); bnx2x_napi_enable(bp); /* set pf load just before approaching the MCP */ @@ -2410,8 +2408,6 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Disable HW interrupts, NAPI */ bnx2x_netif_stop(bp, 1); - /* Delete all NAPI objects */ - bnx2x_del_all_napi(bp); /* Release IRQs */ bnx2x_free_irq(bp); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 21b553229ea4..dfa757e74296 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -792,7 +792,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) bp->num_napi_queues = bp->num_queues; /* Add NAPI objects */ - for_each_rx_queue(bp, i) + for_each_napi_rx_queue(bp, i) netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), bnx2x_poll, BNX2X_NAPI_WEIGHT); } @@ -801,7 +801,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp) { int i; - for_each_rx_queue(bp, i) + for_each_napi_rx_queue(bp, i) netif_napi_del(&bnx2x_fp(bp, i, napi)); } diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index c37a68d68090..fc4e0e3885b0 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -2888,9 +2888,11 @@ static void bnx2x_get_channels(struct net_device *dev, */ static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) { + bnx2x_del_all_napi(bp); bnx2x_disable_msi(bp); BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE; bnx2x_set_int_mode(bp); + bnx2x_add_all_napi(bp); } /** diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 21054987257a..02b5a343b195 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -8427,8 +8427,6 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) /* Disable HW interrupts, NAPI */ bnx2x_netif_stop(bp, 1); - /* Delete all NAPI objects */ - bnx2x_del_all_napi(bp); /* Release IRQs */ bnx2x_free_irq(bp); @@ -11231,12 +11229,10 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static void poll_bnx2x(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); - int i; - for_each_eth_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - napi_schedule(&bnx2x_fp(bp, fp->index, napi)); - } + disable_irq(bp->pdev->irq); + bnx2x_interrupt(bp->pdev->irq, dev); + enable_irq(bp->pdev->irq); } #endif @@ -11903,6 +11899,9 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, */ bnx2x_set_int_mode(bp); + /* Add all NAPI objects */ + bnx2x_add_all_napi(bp); + rc = register_netdev(dev); if (rc) { dev_err(&pdev->dev, "Cannot register net device\n"); @@ -11977,6 +11976,9 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) unregister_netdev(dev); + /* Delete all NAPI objects */ + bnx2x_del_all_napi(bp); + /* Power on: we can't let PCI layer write to us while we are in D3 */ bnx2x_set_power_state(bp, PCI_D0); @@ -12023,8 +12025,6 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) bnx2x_tx_disable(bp); bnx2x_netif_stop(bp, 0); - /* Delete all NAPI objects */ - bnx2x_del_all_napi(bp); del_timer_sync(&bp->timer); diff --git a/trunk/drivers/net/ethernet/emulex/benet/be.h b/trunk/drivers/net/ethernet/emulex/benet/be.h index 5b622993ff17..d266c86a53f7 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be.h +++ b/trunk/drivers/net/ethernet/emulex/benet/be.h @@ -110,7 +110,6 @@ static inline char *nic_name(struct pci_dev *pdev) #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) -#define MAX_VFS 30 /* Max VFs supported by BE3 FW */ #define FW_VER_LEN 32 struct be_dma_mem { diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c index 701b3e9a715b..7fac97b4bb59 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -120,7 +120,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter, if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { dev_warn(&adapter->pdev->dev, - "VF is not privileged to issue opcode %d-%d\n", + "opcode %d-%d is not permitted\n", opcode, subsystem); } else { extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & @@ -259,7 +259,7 @@ int be_process_mcc(struct be_adapter *adapter) int num = 0, status = 0; struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; - spin_lock(&adapter->mcc_cq_lock); + spin_lock_bh(&adapter->mcc_cq_lock); while ((compl = be_mcc_compl_get(adapter))) { if (compl->flags & CQE_FLAGS_ASYNC_MASK) { /* Interpret flags as an async trailer */ @@ -280,7 +280,7 @@ int be_process_mcc(struct be_adapter *adapter) if (num) be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); - spin_unlock(&adapter->mcc_cq_lock); + spin_unlock_bh(&adapter->mcc_cq_lock); return status; } @@ -295,9 +295,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) if (be_error(adapter)) return -EIO; - local_bh_disable(); status = be_process_mcc(adapter); - local_bh_enable(); if (atomic_read(&mcc_obj->q.used) == 0) break; diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 111dc8813f68..90a903d83d87 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -2176,7 +2176,8 @@ static uint be_num_rss_want(struct be_adapter *adapter) { u32 num = 0; if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) && - !sriov_want(adapter) && be_physfn(adapter)) { + !sriov_want(adapter) && be_physfn(adapter) && + !be_is_mc(adapter)) { num = (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS; num = min_t(u32, num, (u32)netif_get_num_default_rss_queues()); } @@ -2645,8 +2646,8 @@ static int be_vf_setup(struct be_adapter *adapter) } for_all_vfs(adapter, vf_cfg, vf) { - lnk_speed = 1000; - status = be_cmd_set_qos(adapter, lnk_speed, vf + 1); + status = be_cmd_link_status_query(adapter, NULL, &lnk_speed, + NULL, vf + 1); if (status) goto err; vf_cfg->tx_rate = lnk_speed * 10; @@ -2723,8 +2724,6 @@ static int be_get_config(struct be_adapter *adapter) if (pos) { pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF, &dev_num_vfs); - if (!lancer_chip(adapter)) - dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS); adapter->dev_num_vfs = dev_num_vfs; } return 0; @@ -3438,7 +3437,6 @@ static void be_ctrl_cleanup(struct be_adapter *adapter) if (mem->va) dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, mem->dma); - kfree(adapter->pmac_id); } static int be_ctrl_init(struct be_adapter *adapter) @@ -3475,12 +3473,6 @@ static int be_ctrl_init(struct be_adapter *adapter) } memset(rx_filter->va, 0, rx_filter->size); - /* primary mac needs 1 pmac entry */ - adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1, - sizeof(*adapter->pmac_id), GFP_KERNEL); - if (!adapter->pmac_id) - return -ENOMEM; - mutex_init(&adapter->mbox_lock); spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); @@ -3617,6 +3609,12 @@ static int be_get_initial_config(struct be_adapter *adapter) else adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT; + /* primary mac needs 1 pmac entry */ + adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1, + sizeof(u32), GFP_KERNEL); + if (!adapter->pmac_id) + return -ENOMEM; + status = be_cmd_get_cntl_attributes(adapter); if (status) return status; @@ -3765,9 +3763,7 @@ static void be_worker(struct work_struct *work) /* when interrupts are not yet enabled, just reap any pending * mcc completions */ if (!netif_running(adapter->netdev)) { - local_bh_disable(); be_process_mcc(adapter); - local_bh_enable(); goto reschedule; } diff --git a/trunk/drivers/net/ethernet/freescale/Kconfig b/trunk/drivers/net/ethernet/freescale/Kconfig index feff51664dcf..3574e1499dfc 100644 --- a/trunk/drivers/net/ethernet/freescale/Kconfig +++ b/trunk/drivers/net/ethernet/freescale/Kconfig @@ -62,13 +62,6 @@ config FSL_PQ_MDIO ---help--- This driver supports the MDIO bus used by the gianfar and UCC drivers. -config FSL_XGMAC_MDIO - tristate "Freescale XGMAC MDIO" - depends on FSL_SOC - select PHYLIB - ---help--- - This driver supports the MDIO bus on the Fman 10G Ethernet MACs. - config UCC_GETH tristate "Freescale QE Gigabit Ethernet" depends on QUICC_ENGINE diff --git a/trunk/drivers/net/ethernet/freescale/Makefile b/trunk/drivers/net/ethernet/freescale/Makefile index 3d1839afff65..1752488c9ee5 100644 --- a/trunk/drivers/net/ethernet/freescale/Makefile +++ b/trunk/drivers/net/ethernet/freescale/Makefile @@ -9,7 +9,6 @@ ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y) endif obj-$(CONFIG_FS_ENET) += fs_enet/ obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o -obj-$(CONFIG_FSL_XGMAC_MDIO) += xgmac_mdio.o obj-$(CONFIG_GIANFAR) += gianfar_driver.o obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o gianfar_driver-objs := gianfar.o \ diff --git a/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c index c93a05654b46..9527b28d70d1 100644 --- a/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -19,90 +19,54 @@ #include #include #include +#include #include +#include #include #include +#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include #include #include -#include +#include #include -#include /* for ucc_set_qe_mux_mii_mng() */ +#include +#include +#include #include "gianfar.h" - -#define MIIMIND_BUSY 0x00000001 -#define MIIMIND_NOTVALID 0x00000004 -#define MIIMCFG_INIT_VALUE 0x00000007 -#define MIIMCFG_RESET 0x80000000 - -#define MII_READ_COMMAND 0x00000001 - -struct fsl_pq_mii { - u32 miimcfg; /* MII management configuration reg */ - u32 miimcom; /* MII management command reg */ - u32 miimadd; /* MII management address reg */ - u32 miimcon; /* MII management control reg */ - u32 miimstat; /* MII management status reg */ - u32 miimind; /* MII management indication reg */ -}; - -struct fsl_pq_mdio { - u8 res1[16]; - u32 ieventm; /* MDIO Interrupt event register (for etsec2)*/ - u32 imaskm; /* MDIO Interrupt mask register (for etsec2)*/ - u8 res2[4]; - u32 emapm; /* MDIO Event mapping register (for etsec2)*/ - u8 res3[1280]; - struct fsl_pq_mii mii; - u8 res4[28]; - u32 utbipar; /* TBI phy address reg (only on UCC) */ - u8 res5[2728]; -} __packed; +#include "fsl_pq_mdio.h" /* Number of microseconds to wait for an MII register to respond */ #define MII_TIMEOUT 1000 struct fsl_pq_mdio_priv { void __iomem *map; - struct fsl_pq_mii __iomem *regs; - int irqs[PHY_MAX_ADDR]; -}; - -/* - * Per-device-type data. Each type of device tree node that we support gets - * one of these. - * - * @mii_offset: the offset of the MII registers within the memory map of the - * node. Some nodes define only the MII registers, and some define the whole - * MAC (which includes the MII registers). - * - * @get_tbipa: determines the address of the TBIPA register - * - * @ucc_configure: a special function for extra QE configuration - */ -struct fsl_pq_mdio_data { - unsigned int mii_offset; /* offset of the MII registers */ - uint32_t __iomem * (*get_tbipa)(void __iomem *p); - void (*ucc_configure)(phys_addr_t start, phys_addr_t end); + struct fsl_pq_mdio __iomem *regs; }; /* - * Write value to the PHY at mii_id at register regnum, on the bus attached - * to the local interface, which may be different from the generic mdio bus - * (tied to a single interface), waiting until the write is done before - * returning. This is helpful in programming interfaces like the TBI which - * control interfaces like onchip SERDES and are always tied to the local - * mdio pins, which may not be the same as system mdio bus, used for + * Write value to the PHY at mii_id at register regnum, + * on the bus attached to the local interface, which may be different from the + * generic mdio bus (tied to a single interface), waiting until the write is + * done before returning. This is helpful in programming interfaces like + * the TBI which control interfaces like onchip SERDES and are always tied to + * the local mdio pins, which may not be the same as system mdio bus, used for * controlling the external PHYs, for example. */ -static int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, - u16 value) +int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, + int regnum, u16 value) { - struct fsl_pq_mdio_priv *priv = bus->priv; - struct fsl_pq_mii __iomem *regs = priv->regs; u32 status; /* Set the PHY address and the register address we want to write */ @@ -119,21 +83,20 @@ static int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, } /* - * Read the bus for PHY at addr mii_id, register regnum, and return the value. - * Clears miimcom first. - * - * All PHY operation done on the bus attached to the local interface, which - * may be different from the generic mdio bus. This is helpful in programming - * interfaces like the TBI which, in turn, control interfaces like on-chip - * SERDES and are always tied to the local mdio pins, which may not be the + * Read the bus for PHY at addr mii_id, register regnum, and + * return the value. Clears miimcom first. All PHY operation + * done on the bus attached to the local interface, + * which may be different from the generic mdio bus + * This is helpful in programming interfaces like + * the TBI which, in turn, control interfaces like onchip SERDES + * and are always tied to the local mdio pins, which may not be the * same as system mdio bus, used for controlling the external PHYs, for eg. */ -static int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) +int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, + int mii_id, int regnum) { - struct fsl_pq_mdio_priv *priv = bus->priv; - struct fsl_pq_mii __iomem *regs = priv->regs; - u32 status; u16 value; + u32 status; /* Set the PHY address and the register address we want to read */ out_be32(®s->miimadd, (mii_id << 8) | regnum); @@ -152,15 +115,44 @@ static int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) /* Grab the value of the register from miimstat */ value = in_be32(®s->miimstat); - dev_dbg(&bus->dev, "read %04x from address %x/%x\n", value, mii_id, regnum); return value; } +static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus) +{ + struct fsl_pq_mdio_priv *priv = bus->priv; + + return priv->regs; +} + +/* + * Write value to the PHY at mii_id at register regnum, + * on the bus, waiting until the write is done before returning. + */ +int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) +{ + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); + + /* Write to the local MII regs */ + return fsl_pq_local_mdio_write(regs, mii_id, regnum, value); +} + +/* + * Read the bus for PHY at addr mii_id, register regnum, and + * return the value. Clears miimcom first. + */ +int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) +{ + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); + + /* Read the local MII regs */ + return fsl_pq_local_mdio_read(regs, mii_id, regnum); +} + /* Reset the MIIM registers, and wait for the bus to free */ static int fsl_pq_mdio_reset(struct mii_bus *bus) { - struct fsl_pq_mdio_priv *priv = bus->priv; - struct fsl_pq_mii __iomem *regs = priv->regs; + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); u32 status; mutex_lock(&bus->mdio_lock); @@ -178,291 +170,234 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus) mutex_unlock(&bus->mdio_lock); if (!status) { - dev_err(&bus->dev, "timeout waiting for MII bus\n"); + printk(KERN_ERR "%s: The MII Bus is stuck!\n", + bus->name); return -EBUSY; } return 0; } -#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) -/* - * This is mildly evil, but so is our hardware for doing this. - * Also, we have to cast back to struct gfar because of - * definition weirdness done in gianfar.h. - */ -static uint32_t __iomem *get_gfar_tbipa(void __iomem *p) +void fsl_pq_mdio_bus_name(char *name, struct device_node *np) { - struct gfar __iomem *enet_regs = p; + const u32 *addr; + u64 taddr = OF_BAD_ADDR; - return &enet_regs->tbipa; -} + addr = of_get_address(np, 0, NULL, NULL); + if (addr) + taddr = of_translate_address(np, addr); -/* - * Return the TBIPAR address for an eTSEC2 node - */ -static uint32_t __iomem *get_etsec_tbipa(void __iomem *p) -{ - return p; + snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name, + (unsigned long long)taddr); } -#endif +EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name); -#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) -/* - * Return the TBIPAR address for a QE MDIO node - */ -static uint32_t __iomem *get_ucc_tbipa(void __iomem *p) + +static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) { - struct fsl_pq_mdio __iomem *mdio = p; +#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) + struct gfar __iomem *enet_regs; - return &mdio->utbipar; + /* + * This is mildly evil, but so is our hardware for doing this. + * Also, we have to cast back to struct gfar because of + * definition weirdness done in gianfar.h. + */ + if(of_device_is_compatible(np, "fsl,gianfar-mdio") || + of_device_is_compatible(np, "fsl,gianfar-tbi") || + of_device_is_compatible(np, "gianfar")) { + enet_regs = (struct gfar __iomem *)regs; + return &enet_regs->tbipa; + } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || + of_device_is_compatible(np, "fsl,etsec2-tbi")) { + return of_iomap(np, 1); + } +#endif + return NULL; } -/* - * Find the UCC node that controls the given MDIO node - * - * For some reason, the QE MDIO nodes are not children of the UCC devices - * that control them. Therefore, we need to scan all UCC nodes looking for - * the one that encompases the given MDIO node. We do this by comparing - * physical addresses. The 'start' and 'end' addresses of the MDIO node are - * passed, and the correct UCC node will cover the entire address range. - * - * This assumes that there is only one QE MDIO node in the entire device tree. - */ -static void ucc_configure(phys_addr_t start, phys_addr_t end) + +static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) { - static bool found_mii_master; +#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) struct device_node *np = NULL; - - if (found_mii_master) - return; + int err = 0; for_each_compatible_node(np, NULL, "ucc_geth") { - struct resource res; - const uint32_t *iprop; - uint32_t id; - int ret; - - ret = of_address_to_resource(np, 0, &res); - if (ret < 0) { - pr_debug("fsl-pq-mdio: no address range in node %s\n", - np->full_name); - continue; - } + struct resource tempres; - /* if our mdio regs fall within this UCC regs range */ - if ((start < res.start) || (end > res.end)) + err = of_address_to_resource(np, 0, &tempres); + if (err) continue; - iprop = of_get_property(np, "cell-index", NULL); - if (!iprop) { - iprop = of_get_property(np, "device-id", NULL); - if (!iprop) { - pr_debug("fsl-pq-mdio: no UCC ID in node %s\n", - np->full_name); - continue; + /* if our mdio regs fall within this UCC regs range */ + if ((start >= tempres.start) && (end <= tempres.end)) { + /* Find the id of the UCC */ + const u32 *id; + + id = of_get_property(np, "cell-index", NULL); + if (!id) { + id = of_get_property(np, "device-id", NULL); + if (!id) + continue; } - } - id = be32_to_cpup(iprop); + *ucc_id = *id; - /* - * cell-index and device-id for QE nodes are - * numbered from 1, not 0. - */ - if (ucc_set_qe_mux_mii_mng(id - 1) < 0) { - pr_debug("fsl-pq-mdio: invalid UCC ID in node %s\n", - np->full_name); - continue; + return 0; } - - pr_debug("fsl-pq-mdio: setting node UCC%u to MII master\n", id); - found_mii_master = true; } -} - -#endif -static struct of_device_id fsl_pq_mdio_match[] = { -#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) - { - .compatible = "fsl,gianfar-tbi", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = 0, - .get_tbipa = get_gfar_tbipa, - }, - }, - { - .compatible = "fsl,gianfar-mdio", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = 0, - .get_tbipa = get_gfar_tbipa, - }, - }, - { - .type = "mdio", - .compatible = "gianfar", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = offsetof(struct fsl_pq_mdio, mii), - .get_tbipa = get_gfar_tbipa, - }, - }, - { - .compatible = "fsl,etsec2-tbi", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = offsetof(struct fsl_pq_mdio, mii), - .get_tbipa = get_etsec_tbipa, - }, - }, - { - .compatible = "fsl,etsec2-mdio", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = offsetof(struct fsl_pq_mdio, mii), - .get_tbipa = get_etsec_tbipa, - }, - }, -#endif -#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) - { - .compatible = "fsl,ucc-mdio", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = 0, - .get_tbipa = get_ucc_tbipa, - .ucc_configure = ucc_configure, - }, - }, - { - /* Legacy UCC MDIO node */ - .type = "mdio", - .compatible = "ucc_geth_phy", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = 0, - .get_tbipa = get_ucc_tbipa, - .ucc_configure = ucc_configure, - }, - }, + if (err) + return err; + else + return -EINVAL; +#else + return -ENODEV; #endif - /* No Kconfig option for Fman support yet */ - { - .compatible = "fsl,fman-mdio", - .data = &(struct fsl_pq_mdio_data) { - .mii_offset = 0, - /* Fman TBI operations are handled elsewhere */ - }, - }, - - {}, -}; -MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); +} -static int fsl_pq_mdio_probe(struct platform_device *pdev) +static int fsl_pq_mdio_probe(struct platform_device *ofdev) { - const struct of_device_id *id = - of_match_device(fsl_pq_mdio_match, &pdev->dev); - const struct fsl_pq_mdio_data *data = id->data; - struct device_node *np = pdev->dev.of_node; - struct resource res; + struct device_node *np = ofdev->dev.of_node; struct device_node *tbi; struct fsl_pq_mdio_priv *priv; + struct fsl_pq_mdio __iomem *regs = NULL; + void __iomem *map; + u32 __iomem *tbipa; struct mii_bus *new_bus; + int tbiaddr = -1; + const u32 *addrp; + u64 addr = 0, size = 0; int err; - dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible); - - new_bus = mdiobus_alloc_size(sizeof(*priv)); - if (!new_bus) + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = new_bus->priv; + new_bus = mdiobus_alloc(); + if (!new_bus) { + err = -ENOMEM; + goto err_free_priv; + } + new_bus->name = "Freescale PowerQUICC MII Bus", - new_bus->read = &fsl_pq_mdio_read; - new_bus->write = &fsl_pq_mdio_write; - new_bus->reset = &fsl_pq_mdio_reset; - new_bus->irq = priv->irqs; - - err = of_address_to_resource(np, 0, &res); - if (err < 0) { - dev_err(&pdev->dev, "could not obtain address information\n"); - goto error; + new_bus->read = &fsl_pq_mdio_read, + new_bus->write = &fsl_pq_mdio_write, + new_bus->reset = &fsl_pq_mdio_reset, + new_bus->priv = priv; + fsl_pq_mdio_bus_name(new_bus->id, np); + + addrp = of_get_address(np, 0, &size, NULL); + if (!addrp) { + err = -EINVAL; + goto err_free_bus; } - snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s@%llx", np->name, - (unsigned long long)res.start); + /* Set the PHY base address */ + addr = of_translate_address(np, addrp); + if (addr == OF_BAD_ADDR) { + err = -EINVAL; + goto err_free_bus; + } - priv->map = of_iomap(np, 0); - if (!priv->map) { + map = ioremap(addr, size); + if (!map) { err = -ENOMEM; - goto error; + goto err_free_bus; } + priv->map = map; - /* - * Some device tree nodes represent only the MII registers, and - * others represent the MAC and MII registers. The 'mii_offset' field - * contains the offset of the MII registers inside the mapped register - * space. - */ - if (data->mii_offset > resource_size(&res)) { - dev_err(&pdev->dev, "invalid register map\n"); - err = -EINVAL; - goto error; + if (of_device_is_compatible(np, "fsl,gianfar-mdio") || + of_device_is_compatible(np, "fsl,gianfar-tbi") || + of_device_is_compatible(np, "fsl,ucc-mdio") || + of_device_is_compatible(np, "ucc_geth_phy")) + map -= offsetof(struct fsl_pq_mdio, miimcfg); + regs = map; + priv->regs = regs; + + new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); + + if (NULL == new_bus->irq) { + err = -ENOMEM; + goto err_unmap_regs; } - priv->regs = priv->map + data->mii_offset; - new_bus->parent = &pdev->dev; - dev_set_drvdata(&pdev->dev, new_bus); + new_bus->parent = &ofdev->dev; + dev_set_drvdata(&ofdev->dev, new_bus); + + if (of_device_is_compatible(np, "fsl,gianfar-mdio") || + of_device_is_compatible(np, "fsl,gianfar-tbi") || + of_device_is_compatible(np, "fsl,etsec2-mdio") || + of_device_is_compatible(np, "fsl,etsec2-tbi") || + of_device_is_compatible(np, "gianfar")) { + tbipa = get_gfar_tbipa(regs, np); + if (!tbipa) { + err = -EINVAL; + goto err_free_irqs; + } + } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || + of_device_is_compatible(np, "ucc_geth_phy")) { + u32 id; + static u32 mii_mng_master; - if (data->get_tbipa) { - for_each_child_of_node(np, tbi) { - if (strcmp(tbi->type, "tbi-phy") == 0) { - dev_dbg(&pdev->dev, "found TBI PHY node %s\n", - strrchr(tbi->full_name, '/') + 1); - break; - } + 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); } + } else { + err = -ENODEV; + goto err_free_irqs; + } - if (tbi) { - const u32 *prop = of_get_property(tbi, "reg", NULL); - uint32_t __iomem *tbipa; + for_each_child_of_node(np, tbi) { + if (!strncmp(tbi->type, "tbi-phy", 8)) + break; + } - if (!prop) { - dev_err(&pdev->dev, - "missing 'reg' property in node %s\n", - tbi->full_name); - err = -EBUSY; - goto error; - } + if (tbi) { + const u32 *prop = of_get_property(tbi, "reg", NULL); - tbipa = data->get_tbipa(priv->map); + if (prop) + tbiaddr = *prop; - out_be32(tbipa, be32_to_cpup(prop)); + if (tbiaddr == -1) { + err = -EBUSY; + goto err_free_irqs; + } else { + out_be32(tbipa, tbiaddr); } } - if (data->ucc_configure) - data->ucc_configure(res.start, res.end); - err = of_mdiobus_register(new_bus, np); if (err) { - dev_err(&pdev->dev, "cannot register %s as MDIO bus\n", - new_bus->name); - goto error; + printk (KERN_ERR "%s: Cannot register as MDIO bus\n", + new_bus->name); + goto err_free_irqs; } return 0; -error: - if (priv->map) - iounmap(priv->map); - +err_free_irqs: + kfree(new_bus->irq); +err_unmap_regs: + iounmap(priv->map); +err_free_bus: kfree(new_bus); - +err_free_priv: + kfree(priv); return err; } -static int fsl_pq_mdio_remove(struct platform_device *pdev) +static int fsl_pq_mdio_remove(struct platform_device *ofdev) { - struct device *device = &pdev->dev; + struct device *device = &ofdev->dev; struct mii_bus *bus = dev_get_drvdata(device); struct fsl_pq_mdio_priv *priv = bus->priv; @@ -471,11 +406,41 @@ static int fsl_pq_mdio_remove(struct platform_device *pdev) dev_set_drvdata(device, NULL); iounmap(priv->map); + bus->priv = NULL; mdiobus_free(bus); + kfree(priv); return 0; } +static struct of_device_id fsl_pq_mdio_match[] = { + { + .type = "mdio", + .compatible = "ucc_geth_phy", + }, + { + .type = "mdio", + .compatible = "gianfar", + }, + { + .compatible = "fsl,ucc-mdio", + }, + { + .compatible = "fsl,gianfar-tbi", + }, + { + .compatible = "fsl,gianfar-mdio", + }, + { + .compatible = "fsl,etsec2-tbi", + }, + { + .compatible = "fsl,etsec2-mdio", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match); + static struct platform_driver fsl_pq_mdio_driver = { .driver = { .name = "fsl-pq_mdio", diff --git a/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.h b/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.h new file mode 100644 index 000000000000..bd17a2a0139b --- /dev/null +++ b/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.h @@ -0,0 +1,52 @@ +/* + * Freescale PowerQUICC MDIO Driver -- MII Management Bus Implementation + * Driver for the MDIO bus controller on Freescale PowerQUICC processors + * + * Author: Andy Fleming + * Modifier: Sandeep Gopalpet + * + * Copyright 2002-2004, 2008-2009 Freescale Semiconductor, Inc. + * + * 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. + * + */ +#ifndef __FSL_PQ_MDIO_H +#define __FSL_PQ_MDIO_H + +#define MIIMIND_BUSY 0x00000001 +#define MIIMIND_NOTVALID 0x00000004 +#define MIIMCFG_INIT_VALUE 0x00000007 +#define MIIMCFG_RESET 0x80000000 + +#define MII_READ_COMMAND 0x00000001 + +struct fsl_pq_mdio { + u8 res1[16]; + u32 ieventm; /* MDIO Interrupt event register (for etsec2)*/ + u32 imaskm; /* MDIO Interrupt mask register (for etsec2)*/ + u8 res2[4]; + u32 emapm; /* MDIO Event mapping register (for etsec2)*/ + u8 res3[1280]; + u32 miimcfg; /* MII management configuration reg */ + u32 miimcom; /* MII management command reg */ + u32 miimadd; /* MII management address reg */ + u32 miimcon; /* MII management control reg */ + u32 miimstat; /* MII management status reg */ + u32 miimind; /* MII management indication reg */ + u8 reserved[28]; /* Space holder */ + u32 utbipar; /* TBI phy address reg (only on UCC) */ + u8 res4[2728]; +} __packed; + +int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum); +int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value); +int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id, + int regnum, u16 value); +int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum); +int __init fsl_pq_mdio_init(void); +void fsl_pq_mdio_exit(void); +void fsl_pq_mdio_bus_name(char *name, struct device_node *np); +#endif /* FSL_PQ_MDIO_H */ diff --git a/trunk/drivers/net/ethernet/freescale/gianfar.c b/trunk/drivers/net/ethernet/freescale/gianfar.c index 4d5b58ce1298..4605f7246687 100644 --- a/trunk/drivers/net/ethernet/freescale/gianfar.c +++ b/trunk/drivers/net/ethernet/freescale/gianfar.c @@ -100,6 +100,7 @@ #include #include "gianfar.h" +#include "fsl_pq_mdio.h" #define TX_TIMEOUT (1*HZ) @@ -1040,7 +1041,7 @@ static int gfar_probe(struct platform_device *ofdev) if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - dev->features |= NETIF_F_HW_VLAN_RX; + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; } if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { diff --git a/trunk/drivers/net/ethernet/freescale/ucc_geth.c b/trunk/drivers/net/ethernet/freescale/ucc_geth.c index 164288439220..21c6574c5f15 100644 --- a/trunk/drivers/net/ethernet/freescale/ucc_geth.c +++ b/trunk/drivers/net/ethernet/freescale/ucc_geth.c @@ -42,6 +42,7 @@ #include #include "ucc_geth.h" +#include "fsl_pq_mdio.h" #undef DEBUG diff --git a/trunk/drivers/net/ethernet/freescale/xgmac_mdio.c b/trunk/drivers/net/ethernet/freescale/xgmac_mdio.c deleted file mode 100644 index 1afb5ea2a984..000000000000 --- a/trunk/drivers/net/ethernet/freescale/xgmac_mdio.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * QorIQ 10G MDIO Controller - * - * Copyright 2012 Freescale Semiconductor, Inc. - * - * Authors: Andy Fleming - * Timur Tabi - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* Number of microseconds to wait for a register to respond */ -#define TIMEOUT 1000 - -struct tgec_mdio_controller { - __be32 reserved[12]; - __be32 mdio_stat; /* MDIO configuration and status */ - __be32 mdio_ctl; /* MDIO control */ - __be32 mdio_data; /* MDIO data */ - __be32 mdio_addr; /* MDIO address */ -} __packed; - -#define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8) -#define MDIO_STAT_BSY (1 << 0) -#define MDIO_STAT_RD_ER (1 << 1) -#define MDIO_CTL_DEV_ADDR(x) (x & 0x1f) -#define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5) -#define MDIO_CTL_PRE_DIS (1 << 10) -#define MDIO_CTL_SCAN_EN (1 << 11) -#define MDIO_CTL_POST_INC (1 << 14) -#define MDIO_CTL_READ (1 << 15) - -#define MDIO_DATA(x) (x & 0xffff) -#define MDIO_DATA_BSY (1 << 31) - -/* - * Wait untill the MDIO bus is free - */ -static int xgmac_wait_until_free(struct device *dev, - struct tgec_mdio_controller __iomem *regs) -{ - uint32_t status; - - /* Wait till the bus is free */ - status = spin_event_timeout( - !((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY), TIMEOUT, 0); - if (!status) { - dev_err(dev, "timeout waiting for bus to be free\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* - * Wait till the MDIO read or write operation is complete - */ -static int xgmac_wait_until_done(struct device *dev, - struct tgec_mdio_controller __iomem *regs) -{ - uint32_t status; - - /* Wait till the MDIO write is complete */ - status = spin_event_timeout( - !((in_be32(®s->mdio_data)) & MDIO_DATA_BSY), TIMEOUT, 0); - if (!status) { - dev_err(dev, "timeout waiting for operation to complete\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* - * Write value to the PHY for this device to the register at regnum,waiting - * until the write is done before it returns. All PHY configuration has to be - * done through the TSEC1 MIIM regs. - */ -static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value) -{ - struct tgec_mdio_controller __iomem *regs = bus->priv; - uint16_t dev_addr = regnum >> 16; - int ret; - - /* Setup the MII Mgmt clock speed */ - out_be32(®s->mdio_stat, MDIO_STAT_CLKDIV(100)); - - ret = xgmac_wait_until_free(&bus->dev, regs); - if (ret) - return ret; - - /* Set the port and dev addr */ - out_be32(®s->mdio_ctl, - MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr)); - - /* Set the register address */ - out_be32(®s->mdio_addr, regnum & 0xffff); - - ret = xgmac_wait_until_free(&bus->dev, regs); - if (ret) - return ret; - - /* Write the value to the register */ - out_be32(®s->mdio_data, MDIO_DATA(value)); - - ret = xgmac_wait_until_done(&bus->dev, regs); - if (ret) - return ret; - - return 0; -} - -/* - * Reads from register regnum in the PHY for device dev, returning the value. - * Clears miimcom first. All PHY configuration has to be done through the - * TSEC1 MIIM regs. - */ -static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum) -{ - struct tgec_mdio_controller __iomem *regs = bus->priv; - uint16_t dev_addr = regnum >> 16; - uint32_t mdio_ctl; - uint16_t value; - int ret; - - /* Setup the MII Mgmt clock speed */ - out_be32(®s->mdio_stat, MDIO_STAT_CLKDIV(100)); - - ret = xgmac_wait_until_free(&bus->dev, regs); - if (ret) - return ret; - - /* Set the Port and Device Addrs */ - mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr); - out_be32(®s->mdio_ctl, mdio_ctl); - - /* Set the register address */ - out_be32(®s->mdio_addr, regnum & 0xffff); - - ret = xgmac_wait_until_free(&bus->dev, regs); - if (ret) - return ret; - - /* Initiate the read */ - out_be32(®s->mdio_ctl, mdio_ctl | MDIO_CTL_READ); - - ret = xgmac_wait_until_done(&bus->dev, regs); - if (ret) - return ret; - - /* Return all Fs if nothing was there */ - if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER) { - dev_err(&bus->dev, "MDIO read error\n"); - return 0xffff; - } - - value = in_be32(®s->mdio_data) & 0xffff; - dev_dbg(&bus->dev, "read %04x\n", value); - - return value; -} - -/* Reset the MIIM registers, and wait for the bus to free */ -static int xgmac_mdio_reset(struct mii_bus *bus) -{ - struct tgec_mdio_controller __iomem *regs = bus->priv; - int ret; - - mutex_lock(&bus->mdio_lock); - - /* Setup the MII Mgmt clock speed */ - out_be32(®s->mdio_stat, MDIO_STAT_CLKDIV(100)); - - ret = xgmac_wait_until_free(&bus->dev, regs); - - mutex_unlock(&bus->mdio_lock); - - return ret; -} - -static int __devinit xgmac_mdio_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct mii_bus *bus; - struct resource res; - int ret; - - ret = of_address_to_resource(np, 0, &res); - if (ret) { - dev_err(&pdev->dev, "could not obtain address\n"); - return ret; - } - - bus = mdiobus_alloc_size(PHY_MAX_ADDR * sizeof(int)); - if (!bus) - return -ENOMEM; - - bus->name = "Freescale XGMAC MDIO Bus"; - bus->read = xgmac_mdio_read; - bus->write = xgmac_mdio_write; - bus->reset = xgmac_mdio_reset; - bus->irq = bus->priv; - bus->parent = &pdev->dev; - snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start); - - /* Set the PHY base address */ - bus->priv = of_iomap(np, 0); - if (!bus->priv) { - ret = -ENOMEM; - goto err_ioremap; - } - - ret = of_mdiobus_register(bus, np); - if (ret) { - dev_err(&pdev->dev, "cannot register MDIO bus\n"); - goto err_registration; - } - - dev_set_drvdata(&pdev->dev, bus); - - return 0; - -err_registration: - iounmap(bus->priv); - -err_ioremap: - mdiobus_free(bus); - - return ret; -} - -static int __devexit xgmac_mdio_remove(struct platform_device *pdev) -{ - struct mii_bus *bus = dev_get_drvdata(&pdev->dev); - - mdiobus_unregister(bus); - iounmap(bus->priv); - mdiobus_free(bus); - - return 0; -} - -static struct of_device_id xgmac_mdio_match[] = { - { - .compatible = "fsl,fman-xmdio", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, xgmac_mdio_match); - -static struct platform_driver xgmac_mdio_driver = { - .driver = { - .name = "fsl-fman_xmdio", - .of_match_table = xgmac_mdio_match, - }, - .probe = xgmac_mdio_probe, - .remove = xgmac_mdio_remove, -}; - -module_platform_driver(xgmac_mdio_driver); - -MODULE_DESCRIPTION("Freescale QorIQ 10G MDIO Controller"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/82571.c b/trunk/drivers/net/ethernet/intel/e1000e/82571.c index c98586408005..080c89093feb 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/82571.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/82571.c @@ -653,7 +653,7 @@ static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw) **/ static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active) { - u32 data = er32(POEMB); + u16 data = er32(POEMB); if (active) data |= E1000_PHY_CTRL_D0A_LPLU; @@ -677,7 +677,7 @@ static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active) **/ static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active) { - u32 data = er32(POEMB); + u16 data = er32(POEMB); if (!active) { data &= ~E1000_PHY_CTRL_NOND0A_LPLU; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/e1000.h b/trunk/drivers/net/ethernet/intel/e1000e/e1000.h index cb3356c9af80..cd153326c3cf 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/e1000.h @@ -310,7 +310,6 @@ struct e1000_adapter { */ struct e1000_ring *tx_ring /* One per active queue */ ____cacheline_aligned_in_smp; - u32 tx_fifo_limit; struct napi_struct napi; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c index c11ac2756667..2e76f06720fd 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1942,8 +1942,7 @@ static int e1000_set_coalesce(struct net_device *netdev, return -EINVAL; if (ec->rx_coalesce_usecs == 4) { - adapter->itr_setting = 4; - adapter->itr = adapter->itr_setting; + adapter->itr = adapter->itr_setting = 4; } else if (ec->rx_coalesce_usecs <= 3) { adapter->itr = 20000; adapter->itr_setting = ec->rx_coalesce_usecs; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 121990cab144..46c3b1f9ff89 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -56,7 +56,7 @@ #define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "2.1.4" DRV_EXTRAVERSION +#define DRV_VERSION "2.0.0" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -3446,7 +3446,7 @@ void e1000e_reset(struct e1000_adapter *adapter) /* * if short on Rx space, Rx wins and must trump Tx - * adjustment + * adjustment or use Early Receive if available */ if (pba < min_rx_space) pba = min_rx_space; @@ -3516,15 +3516,6 @@ void e1000e_reset(struct e1000_adapter *adapter) break; } - /* - * Alignment of Tx data is on an arbitrary byte boundary with the - * maximum size per Tx descriptor limited only to the transmit - * allocation of the packet buffer minus 96 bytes with an upper - * limit of 24KB due to receive synchronization limitations. - */ - adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96, - 24 << 10); - /* * Disable Adaptive Interrupt Moderation if 2 full packets cannot * fit in receive buffer. @@ -3755,10 +3746,6 @@ static irqreturn_t e1000_intr_msi_test(int irq, void *data) e_dbg("icr is %08X\n", icr); if (icr & E1000_ICR_RXSEQ) { adapter->flags &= ~FLAG_MSI_TEST_FAILED; - /* - * Force memory writes to complete before acknowledging the - * interrupt is handled. - */ wmb(); } @@ -3800,10 +3787,6 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) goto msi_test_failed; } - /* - * Force memory writes to complete before enabling and firing an - * interrupt. - */ wmb(); e1000_irq_enable(adapter); @@ -3815,7 +3798,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) e1000_irq_disable(adapter); - rmb(); /* read flags after interrupt has been fired */ + rmb(); if (adapter->flags & FLAG_MSI_TEST_FAILED) { adapter->int_mode = E1000E_INT_MODE_LEGACY; @@ -4678,7 +4661,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) struct e1000_buffer *buffer_info; unsigned int i; u32 cmd_length = 0; - u16 ipcse = 0, mss; + u16 ipcse = 0, tucse, mss; u8 ipcss, ipcso, tucss, tucso, hdr_len; if (!skb_is_gso(skb)) @@ -4712,6 +4695,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data; tucss = skb_transport_offset(skb); tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data; + tucse = 0; cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); @@ -4725,7 +4709,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse); context_desc->upper_setup.tcp_fields.tucss = tucss; context_desc->upper_setup.tcp_fields.tucso = tucso; - context_desc->upper_setup.tcp_fields.tucse = 0; + context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse); context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss); context_desc->tcp_seg_setup.fields.hdr_len = hdr_len; context_desc->cmd_and_length = cpu_to_le32(cmd_length); @@ -4801,9 +4785,12 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) return 1; } +#define E1000_MAX_PER_TXD 8192 +#define E1000_MAX_TXD_PWR 12 + static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, unsigned int first, unsigned int max_per_txd, - unsigned int nr_frags) + unsigned int nr_frags, unsigned int mss) { struct e1000_adapter *adapter = tx_ring->adapter; struct pci_dev *pdev = adapter->pdev; @@ -5036,19 +5023,20 @@ static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) { - BUG_ON(size > tx_ring->count); - if (e1000_desc_unused(tx_ring) >= size) return 0; return __e1000_maybe_stop_tx(tx_ring, size); } +#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1) static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_ring *tx_ring = adapter->tx_ring; unsigned int first; + unsigned int max_per_txd = E1000_MAX_PER_TXD; + unsigned int max_txd_pwr = E1000_MAX_TXD_PWR; unsigned int tx_flags = 0; unsigned int len = skb_headlen(skb); unsigned int nr_frags; @@ -5068,8 +5056,18 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, } mss = skb_shinfo(skb)->gso_size; + /* + * The controller does a simple calculation to + * make sure there is enough room in the FIFO before + * initiating the DMA for each buffer. The calc is: + * 4 = ceil(buffer len/mss). To make sure we don't + * overrun the FIFO, adjust the max buffer len if mss + * drops. + */ if (mss) { u8 hdr_len; + max_per_txd = min(mss << 2, max_per_txd); + max_txd_pwr = fls(max_per_txd) - 1; /* * TSO Workaround for 82571/2/3 Controllers -- if skb->data @@ -5099,12 +5097,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, count++; count++; - count += DIV_ROUND_UP(len, adapter->tx_fifo_limit); + count += TXD_USE_COUNT(len, max_txd_pwr); nr_frags = skb_shinfo(skb)->nr_frags; for (f = 0; f < nr_frags; f++) - count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]), - adapter->tx_fifo_limit); + count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), + max_txd_pwr); if (adapter->hw.mac.tx_pkt_filtering) e1000_transfer_dhcp_info(adapter, skb); @@ -5146,18 +5144,15 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, tx_flags |= E1000_TX_FLAGS_NO_FCS; /* if count is 0 then mapping error has occurred */ - count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit, - nr_frags); + count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss); if (count) { skb_tx_timestamp(skb); netdev_sent_queue(netdev, skb->len); e1000_tx_queue(tx_ring, tx_flags, count); /* Make sure there is space in the ring for the next send. */ - e1000_maybe_stop_tx(tx_ring, - (MAX_SKB_FRAGS * - DIV_ROUND_UP(PAGE_SIZE, - adapter->tx_fifo_limit) + 2)); + e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2); + } else { dev_kfree_skb_any(skb); tx_ring->buffer_info[first].time_stamp = 0; @@ -6332,8 +6327,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->hw.phy.autoneg_advertised = 0x2f; /* ring size defaults */ - adapter->rx_ring->count = E1000_DEFAULT_RXD; - adapter->tx_ring->count = E1000_DEFAULT_TXD; + adapter->rx_ring->count = 256; + adapter->tx_ring->count = 256; /* * Initial Wake on LAN setting - If APM wake is enabled in diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index eb26fda63c99..98cadb0c4dab 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -101,9 +101,7 @@ struct ixgbevf_ring { /* Supported Rx Buffer Sizes */ #define IXGBEVF_RXBUFFER_256 256 /* Used for packet split */ -#define IXGBEVF_RXBUFFER_3K 3072 -#define IXGBEVF_RXBUFFER_7K 7168 -#define IXGBEVF_RXBUFFER_15K 15360 +#define IXGBEVF_RXBUFFER_2048 2048 #define IXGBEVF_MAX_RXBUFFER 16384 /* largest size for single descriptor */ #define IXGBEVF_RX_HDR_SIZE IXGBEVF_RXBUFFER_256 diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index a5d9cc5bb257..60ef64587412 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -1057,44 +1057,13 @@ static void ixgbevf_configure_srrctl(struct ixgbevf_adapter *adapter, int index) srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; - srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >> - IXGBE_SRRCTL_BSIZEPKT_SHIFT; - - IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl); -} - -static void ixgbevf_set_rx_buffer_len(struct ixgbevf_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - int i; - u16 rx_buf_len; - - /* notify the PF of our intent to use this size of frame */ - ixgbevf_rlpml_set_vf(hw, max_frame); - - /* PF will allow an extra 4 bytes past for vlan tagged frames */ - max_frame += VLAN_HLEN; - - /* - * Make best use of allocation by using all but 1K of a - * power of 2 allocation that will be used for skb->head. - */ - if ((hw->mac.type == ixgbe_mac_X540_vf) && - (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE)) - rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; - else if (max_frame <= IXGBEVF_RXBUFFER_3K) - rx_buf_len = IXGBEVF_RXBUFFER_3K; - else if (max_frame <= IXGBEVF_RXBUFFER_7K) - rx_buf_len = IXGBEVF_RXBUFFER_7K; - else if (max_frame <= IXGBEVF_RXBUFFER_15K) - rx_buf_len = IXGBEVF_RXBUFFER_15K; + if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE) + srrctl |= IXGBEVF_RXBUFFER_2048 >> + IXGBE_SRRCTL_BSIZEPKT_SHIFT; else - rx_buf_len = IXGBEVF_MAX_RXBUFFER; - - for (i = 0; i < adapter->num_rx_queues; i++) - adapter->rx_ring[i].rx_buf_len = rx_buf_len; + srrctl |= rx_ring->rx_buf_len >> + IXGBE_SRRCTL_BSIZEPKT_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(index), srrctl); } /** @@ -1107,14 +1076,18 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) { u64 rdba; struct ixgbe_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; int i, j; u32 rdlen; + int rx_buf_len; /* PSRTYPE must be initialized in 82599 */ IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, 0); - - /* set_rx_buffer_len must be called before ring initialization */ - ixgbevf_set_rx_buffer_len(adapter); + if (netdev->mtu <= ETH_DATA_LEN) + rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; + else + rx_buf_len = ALIGN(max_frame, 1024); rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc); /* Setup the HW Rx Head and Tail Descriptor Pointers and @@ -1130,6 +1103,7 @@ static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_VFRDT(j), 0); adapter->rx_ring[i].head = IXGBE_VFRDH(j); adapter->rx_ring[i].tail = IXGBE_VFRDT(j); + adapter->rx_ring[i].rx_buf_len = rx_buf_len; ixgbevf_configure_srrctl(adapter, j); } @@ -1341,6 +1315,7 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) int i, j = 0; int num_rx_rings = adapter->num_rx_queues; u32 txdctl, rxdctl; + u32 msg[2]; for (i = 0; i < adapter->num_tx_queues; i++) { j = adapter->tx_ring[i].reg_idx; @@ -1381,6 +1356,10 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) hw->mac.ops.set_rar(hw, 0, hw->mac.perm_addr, 0); } + msg[0] = IXGBE_VF_SET_LPE; + msg[1] = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + hw->mbx.ops.write_posted(hw, msg, 2); + spin_unlock(&adapter->mbx_lock); clear_bit(__IXGBEVF_DOWN, &adapter->state); @@ -1887,22 +1866,6 @@ static int ixgbevf_init_interrupt_scheme(struct ixgbevf_adapter *adapter) return err; } -/** - * ixgbevf_clear_interrupt_scheme - Clear the current interrupt scheme settings - * @adapter: board private structure to clear interrupt scheme on - * - * We go through and clear interrupt specific resources and reset the structure - * to pre-load conditions - **/ -static void ixgbevf_clear_interrupt_scheme(struct ixgbevf_adapter *adapter) -{ - adapter->num_tx_queues = 0; - adapter->num_rx_queues = 0; - - ixgbevf_free_q_vectors(adapter); - ixgbevf_reset_interrupt_capability(adapter); -} - /** * ixgbevf_sw_init - Initialize general software structures * (struct ixgbevf_adapter) @@ -2897,8 +2860,10 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p) static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) { struct ixgbevf_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; + u32 msg[2]; if (adapter->hw.mac.type == ixgbe_mac_X540_vf) max_possible_frame = IXGBE_MAX_JUMBO_FRAME_SIZE; @@ -2912,91 +2877,35 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) /* must set new MTU before calling down or up */ netdev->mtu = new_mtu; + if (!netif_running(netdev)) { + msg[0] = IXGBE_VF_SET_LPE; + msg[1] = max_frame; + hw->mbx.ops.write_posted(hw, msg, 2); + } + if (netif_running(netdev)) ixgbevf_reinit_locked(adapter); return 0; } -static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state) +static void ixgbevf_shutdown(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct ixgbevf_adapter *adapter = netdev_priv(netdev); -#ifdef CONFIG_PM - int retval = 0; -#endif netif_device_detach(netdev); if (netif_running(netdev)) { - rtnl_lock(); ixgbevf_down(adapter); ixgbevf_free_irq(adapter); ixgbevf_free_all_tx_resources(adapter); ixgbevf_free_all_rx_resources(adapter); - rtnl_unlock(); } - ixgbevf_clear_interrupt_scheme(adapter); - -#ifdef CONFIG_PM - retval = pci_save_state(pdev); - if (retval) - return retval; - -#endif - pci_disable_device(pdev); - - return 0; -} - -#ifdef CONFIG_PM -static int ixgbevf_resume(struct pci_dev *pdev) -{ - struct ixgbevf_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; - u32 err; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - /* - * pci_restore_state clears dev->state_saved so call - * pci_save_state to restore it. - */ pci_save_state(pdev); - err = pci_enable_device_mem(pdev); - if (err) { - dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n"); - return err; - } - pci_set_master(pdev); - - rtnl_lock(); - err = ixgbevf_init_interrupt_scheme(adapter); - rtnl_unlock(); - if (err) { - dev_err(&pdev->dev, "Cannot initialize interrupts\n"); - return err; - } - - ixgbevf_reset(adapter); - - if (netif_running(netdev)) { - err = ixgbevf_open(netdev); - if (err) - return err; - } - - netif_device_attach(netdev); - - return err; -} - -#endif /* CONFIG_PM */ -static void ixgbevf_shutdown(struct pci_dev *pdev) -{ - ixgbevf_suspend(pdev, PMSG_SUSPEND); + pci_disable_device(pdev); } static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, @@ -3037,7 +2946,7 @@ static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, return stats; } -static const struct net_device_ops ixgbevf_netdev_ops = { +static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = ixgbevf_open, .ndo_stop = ixgbevf_close, .ndo_start_xmit = ixgbevf_xmit_frame, @@ -3053,7 +2962,7 @@ static const struct net_device_ops ixgbevf_netdev_ops = { static void ixgbevf_assign_netdev_ops(struct net_device *dev) { - dev->netdev_ops = &ixgbevf_netdev_ops; + dev->netdev_ops = &ixgbe_netdev_ops; ixgbevf_set_ethtool_ops(dev); dev->watchdog_timeo = 5 * HZ; } @@ -3222,7 +3131,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, return 0; err_register: - ixgbevf_clear_interrupt_scheme(adapter); err_sw_init: ixgbevf_reset_interrupt_capability(adapter); iounmap(hw->hw_addr); @@ -3260,7 +3168,6 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev) if (netdev->reg_state == NETREG_REGISTERED) unregister_netdev(netdev); - ixgbevf_clear_interrupt_scheme(adapter); ixgbevf_reset_interrupt_capability(adapter); iounmap(adapter->hw.hw_addr); @@ -3360,11 +3267,6 @@ static struct pci_driver ixgbevf_driver = { .id_table = ixgbevf_pci_tbl, .probe = ixgbevf_probe, .remove = __devexit_p(ixgbevf_remove), -#ifdef CONFIG_PM - /* Power Management Hooks */ - .suspend = ixgbevf_suspend, - .resume = ixgbevf_resume, -#endif .shutdown = ixgbevf_shutdown, .err_handler = &ixgbevf_err_handler }; diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c index 3d555a10f592..ec89b86f7ca4 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -419,20 +419,6 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw, return 0; } -/** - * ixgbevf_rlpml_set_vf - Set the maximum receive packet length - * @hw: pointer to the HW structure - * @max_size: value to assign to max frame size - **/ -void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) -{ - u32 msgbuf[2]; - - msgbuf[0] = IXGBE_VF_SET_LPE; - msgbuf[1] = max_size; - ixgbevf_write_msg_read_ack(hw, msgbuf, 2); -} - static const struct ixgbe_mac_operations ixgbevf_mac_ops = { .init_hw = ixgbevf_init_hw_vf, .reset_hw = ixgbevf_reset_hw_vf, diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h index 07fd87688e35..25c951daee5d 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/vf.h @@ -170,6 +170,5 @@ struct ixgbevf_info { const struct ixgbe_mac_operations *mac_ops; }; -void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size); #endif /* __IXGBE_VF_H__ */ diff --git a/trunk/drivers/net/ethernet/nvidia/forcedeth.c b/trunk/drivers/net/ethernet/nvidia/forcedeth.c index 876beceaf2d7..f45def01a98e 100644 --- a/trunk/drivers/net/ethernet/nvidia/forcedeth.c +++ b/trunk/drivers/net/ethernet/nvidia/forcedeth.c @@ -3409,7 +3409,7 @@ static int nv_update_linkspeed(struct net_device *dev) pause_flags = 0; /* setup pause frame */ - if (netif_running(dev) && (np->duplex != 0)) { + if (np->duplex != 0) { if (np->autoneg && np->pause_flags & NV_PAUSEFRAME_AUTONEG) { adv_pause = adv & (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); lpa_pause = lpa & (LPA_PAUSE_CAP | LPA_PAUSE_ASYM); @@ -4435,7 +4435,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void regs->version = FORCEDETH_REGS_VER; spin_lock_irq(&np->lock); - for (i = 0; i < np->register_size/sizeof(u32); i++) + for (i = 0; i <= np->register_size/sizeof(u32); i++) rbuf[i] = readl(base + i*sizeof(u32)); spin_unlock_irq(&np->lock); } @@ -5455,7 +5455,6 @@ static int nv_close(struct net_device *dev) netif_stop_queue(dev); spin_lock_irq(&np->lock); - nv_update_pause(dev, 0); /* otherwise stop_tx bricks NIC */ nv_stop_rxtx(dev); nv_txrx_reset(dev); @@ -5905,19 +5904,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i goto out_error; } - netif_carrier_off(dev); - - /* Some NICs freeze when TX pause is enabled while NIC is - * down, and this stays across warm reboots. The sequence - * below should be enough to recover from that state. - */ - nv_update_pause(dev, 0); - nv_start_tx(dev); - nv_stop_tx(dev); - if (id->driver_data & DEV_HAS_VLAN) nv_vlan_mode(dev, dev->features); + netif_carrier_off(dev); + dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 0c96604e6246..b47d5b35024e 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -287,8 +287,6 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, - { PCI_VENDOR_ID_DLINK, 0x4300, - PCI_VENDOR_ID_DLINK, 0x4b10, 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, diff --git a/trunk/drivers/net/ethernet/sfc/efx.c b/trunk/drivers/net/ethernet/sfc/efx.c index a606db43c5ba..65a8d49106a4 100644 --- a/trunk/drivers/net/ethernet/sfc/efx.c +++ b/trunk/drivers/net/ethernet/sfc/efx.c @@ -202,21 +202,11 @@ static void efx_stop_all(struct efx_nic *efx); #define EFX_ASSERT_RESET_SERIALISED(efx) \ do { \ - if ((efx->state == STATE_READY) || \ + if ((efx->state == STATE_RUNNING) || \ (efx->state == STATE_DISABLED)) \ ASSERT_RTNL(); \ } while (0) -static int efx_check_disabled(struct efx_nic *efx) -{ - if (efx->state == STATE_DISABLED) { - netif_err(efx, drv, efx->net_dev, - "device is disabled due to earlier errors\n"); - return -EIO; - } - return 0; -} - /************************************************************************** * * Event queue processing @@ -640,16 +630,6 @@ static void efx_start_datapath(struct efx_nic *efx) efx->rx_buffer_order = get_order(efx->rx_buffer_len + sizeof(struct efx_rx_page_state)); - /* We must keep at least one descriptor in a TX ring empty. - * We could avoid this when the queue size does not exactly - * match the hardware ring size, but it's not that important. - * Therefore we stop the queue when one more skb might fill - * the ring completely. We wake it when half way back to - * empty. - */ - efx->txq_stop_thresh = efx->txq_entries - efx_tx_max_skb_descs(efx); - efx->txq_wake_thresh = efx->txq_stop_thresh / 2; - /* Initialise the channels */ efx_for_each_channel(channel, efx) { efx_for_each_channel_tx_queue(tx_queue, channel) @@ -750,11 +730,7 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel; u32 old_rxq_entries, old_txq_entries; unsigned i, next_buffer_table = 0; - int rc; - - rc = efx_check_disabled(efx); - if (rc) - return rc; + int rc = 0; /* Not all channels should be reallocated. We must avoid * reallocating their buffer table entries. @@ -1389,8 +1365,6 @@ static void efx_start_interrupts(struct efx_nic *efx, bool may_keep_eventq) { struct efx_channel *channel; - BUG_ON(efx->state == STATE_DISABLED); - if (efx->legacy_irq) efx->legacy_irq_enabled = true; efx_nic_enable_interrupts(efx); @@ -1408,9 +1382,6 @@ static void efx_stop_interrupts(struct efx_nic *efx, bool may_keep_eventq) { struct efx_channel *channel; - if (efx->state == STATE_DISABLED) - return; - efx_mcdi_mode_poll(efx); efx_nic_disable_interrupts(efx); @@ -1562,21 +1533,22 @@ static int efx_probe_all(struct efx_nic *efx) return rc; } -/* If the interface is supposed to be running but is not, start - * the hardware and software data path, regular activity for the port - * (MAC statistics, link polling, etc.) and schedule the port to be - * reconfigured. Interrupts must already be enabled. This function - * is safe to call multiple times, so long as the NIC is not disabled. - * Requires the RTNL lock. +/* Called after previous invocation(s) of efx_stop_all, restarts the port, + * kernel transmit queues and NAPI processing, and ensures that the port is + * scheduled to be reconfigured. This function is safe to call multiple + * times when the NIC is in any state. */ static void efx_start_all(struct efx_nic *efx) { EFX_ASSERT_RESET_SERIALISED(efx); - BUG_ON(efx->state == STATE_DISABLED); /* Check that it is appropriate to restart the interface. All * of these flags are safe to read under just the rtnl lock */ - if (efx->port_enabled || !netif_running(efx->net_dev)) + if (efx->port_enabled) + return; + if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) + return; + if (!netif_running(efx->net_dev)) return; efx_start_port(efx); @@ -1610,11 +1582,11 @@ static void efx_flush_all(struct efx_nic *efx) cancel_work_sync(&efx->mac_work); } -/* Quiesce the hardware and software data path, and regular activity - * for the port without bringing the link down. Safe to call multiple - * times with the NIC in almost any state, but interrupts should be - * enabled. Requires the RTNL lock. - */ +/* Quiesce hardware and software without bringing the link down. + * Safe to call multiple times, when the nic and interface is in any + * state. The caller is guaranteed to subsequently be in a position + * to modify any hardware and software state they see fit without + * taking locks. */ static void efx_stop_all(struct efx_nic *efx) { EFX_ASSERT_RESET_SERIALISED(efx); @@ -1767,6 +1739,8 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) struct efx_nic *efx = netdev_priv(net_dev); struct mii_ioctl_data *data = if_mii(ifr); + EFX_ASSERT_RESET_SERIALISED(efx); + /* Convert phy_id from older PRTAD/DEVAD format */ if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) && (data->phy_id & 0xfc00) == 0x0400) @@ -1846,14 +1820,13 @@ static void efx_netpoll(struct net_device *net_dev) static int efx_net_open(struct net_device *net_dev) { struct efx_nic *efx = netdev_priv(net_dev); - int rc; + EFX_ASSERT_RESET_SERIALISED(efx); netif_dbg(efx, ifup, efx->net_dev, "opening device on CPU %d\n", raw_smp_processor_id()); - rc = efx_check_disabled(efx); - if (rc) - return rc; + if (efx->state == STATE_DISABLED) + return -EIO; if (efx->phy_mode & PHY_MODE_SPECIAL) return -EBUSY; if (efx_mcdi_poll_reboot(efx) && efx_reset(efx, RESET_TYPE_ALL)) @@ -1879,8 +1852,10 @@ static int efx_net_stop(struct net_device *net_dev) netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n", raw_smp_processor_id()); - /* Stop the device and flush all the channels */ - efx_stop_all(efx); + if (efx->state != STATE_DISABLED) { + /* Stop the device and flush all the channels */ + efx_stop_all(efx); + } return 0; } @@ -1940,11 +1915,9 @@ static void efx_watchdog(struct net_device *net_dev) static int efx_change_mtu(struct net_device *net_dev, int new_mtu) { struct efx_nic *efx = netdev_priv(net_dev); - int rc; - rc = efx_check_disabled(efx); - if (rc) - return rc; + EFX_ASSERT_RESET_SERIALISED(efx); + if (new_mtu > EFX_MAX_MTU) return -EINVAL; @@ -1953,6 +1926,8 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu); mutex_lock(&efx->mac_lock); + /* Reconfigure the MAC before enabling the dma queues so that + * the RX buffers don't overflow */ net_dev->mtu = new_mtu; efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); @@ -1967,6 +1942,8 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) struct sockaddr *addr = data; char *new_addr = addr->sa_data; + EFX_ASSERT_RESET_SERIALISED(efx); + if (!is_valid_ether_addr(new_addr)) { netif_err(efx, drv, efx->net_dev, "invalid ethernet MAC address requested: %pM\n", @@ -2102,27 +2079,11 @@ static int efx_register_netdev(struct efx_nic *efx) rtnl_lock(); - /* Enable resets to be scheduled and check whether any were - * already requested. If so, the NIC is probably hosed so we - * abort. - */ - efx->state = STATE_READY; - smp_mb(); /* ensure we change state before checking reset_pending */ - if (efx->reset_pending) { - netif_err(efx, probe, efx->net_dev, - "aborting probe due to scheduled reset\n"); - rc = -EIO; - goto fail_locked; - } - rc = dev_alloc_name(net_dev, net_dev->name); if (rc < 0) goto fail_locked; efx_update_name(efx); - /* Always start with carrier off; PHY events will detect the link */ - netif_carrier_off(net_dev); - rc = register_netdevice(net_dev); if (rc) goto fail_locked; @@ -2133,6 +2094,9 @@ static int efx_register_netdev(struct efx_nic *efx) efx_init_tx_queue_core_txq(tx_queue); } + /* Always start with carrier off; PHY events will detect the link */ + netif_carrier_off(net_dev); + rtnl_unlock(); rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type); @@ -2144,14 +2108,14 @@ static int efx_register_netdev(struct efx_nic *efx) return 0; -fail_registered: - rtnl_lock(); - unregister_netdevice(net_dev); fail_locked: - efx->state = STATE_UNINIT; rtnl_unlock(); netif_err(efx, drv, efx->net_dev, "could not register net dev\n"); return rc; + +fail_registered: + unregister_netdev(net_dev); + return rc; } static void efx_unregister_netdev(struct efx_nic *efx) @@ -2174,11 +2138,7 @@ static void efx_unregister_netdev(struct efx_nic *efx) strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); - - rtnl_lock(); - unregister_netdevice(efx->net_dev); - efx->state = STATE_UNINIT; - rtnl_unlock(); + unregister_netdev(efx->net_dev); } /************************************************************************** @@ -2194,9 +2154,9 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method) EFX_ASSERT_RESET_SERIALISED(efx); efx_stop_all(efx); - efx_stop_interrupts(efx, false); - mutex_lock(&efx->mac_lock); + + efx_stop_interrupts(efx, false); if (efx->port_initialized && method != RESET_TYPE_INVISIBLE) efx->phy_op->fini(efx); efx->type->fini(efx); @@ -2316,15 +2276,16 @@ static void efx_reset_work(struct work_struct *data) if (!pending) return; - rtnl_lock(); - - /* We checked the state in efx_schedule_reset() but it may - * have changed by now. Now that we have the RTNL lock, - * it cannot change again. - */ - if (efx->state == STATE_READY) - (void)efx_reset(efx, fls(pending) - 1); + /* If we're not RUNNING then don't reset. Leave the reset_pending + * flags set so that efx_pci_probe_main will be retried */ + if (efx->state != STATE_RUNNING) { + netif_info(efx, drv, efx->net_dev, + "scheduled reset quenched. NIC not RUNNING\n"); + return; + } + rtnl_lock(); + (void)efx_reset(efx, fls(pending) - 1); rtnl_unlock(); } @@ -2350,13 +2311,6 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) } set_bit(method, &efx->reset_pending); - smp_mb(); /* ensure we change reset_pending before checking state */ - - /* If we're not READY then just leave the flags set as the cue - * to abort probing or reschedule the reset later. - */ - if (ACCESS_ONCE(efx->state) != STATE_READY) - return; /* efx_process_channel() will no longer read events once a * reset is scheduled. So switch back to poll'd MCDI completions. */ @@ -2422,12 +2376,13 @@ static const struct efx_phy_operations efx_dummy_phy_operations = { /* This zeroes out and then fills in the invariants in a struct * efx_nic (including all sub-structures). */ -static int efx_init_struct(struct efx_nic *efx, +static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type, struct pci_dev *pci_dev, struct net_device *net_dev) { int i; /* Initialise common structures */ + memset(efx, 0, sizeof(*efx)); spin_lock_init(&efx->biu_lock); #ifdef CONFIG_SFC_MTD INIT_LIST_HEAD(&efx->mtd_list); @@ -2437,7 +2392,7 @@ static int efx_init_struct(struct efx_nic *efx, INIT_DELAYED_WORK(&efx->selftest_work, efx_selftest_async_work); efx->pci_dev = pci_dev; efx->msg_enable = debug; - efx->state = STATE_UNINIT; + efx->state = STATE_INIT; strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); efx->net_dev = net_dev; @@ -2454,6 +2409,8 @@ static int efx_init_struct(struct efx_nic *efx, goto fail; } + efx->type = type; + EFX_BUG_ON_PARANOID(efx->type->phys_addr_channels > EFX_MAX_CHANNELS); /* Higher numbered interrupt modes are less capable! */ @@ -2498,12 +2455,6 @@ static void efx_fini_struct(struct efx_nic *efx) */ static void efx_pci_remove_main(struct efx_nic *efx) { - /* Flush reset_work. It can no longer be scheduled since we - * are not READY. - */ - BUG_ON(efx->state == STATE_READY); - cancel_work_sync(&efx->reset_work); - #ifdef CONFIG_RFS_ACCEL free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap); efx->net_dev->rx_cpu_rmap = NULL; @@ -2529,15 +2480,24 @@ static void efx_pci_remove(struct pci_dev *pci_dev) /* Mark the NIC as fini, then stop the interface */ rtnl_lock(); + efx->state = STATE_FINI; dev_close(efx->net_dev); - efx_stop_interrupts(efx, false); + + /* Allow any queued efx_resets() to complete */ rtnl_unlock(); + efx_stop_interrupts(efx, false); efx_sriov_fini(efx); efx_unregister_netdev(efx); efx_mtd_remove(efx); + /* Wait for any scheduled resets to complete. No more will be + * scheduled from this point because efx_stop_all() has been + * called, we are no longer registered with driverlink, and + * the net_device's have been removed. */ + cancel_work_sync(&efx->reset_work); + efx_pci_remove_main(efx); efx_fini_io(efx); @@ -2657,6 +2617,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) static int __devinit efx_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *entry) { + const struct efx_nic_type *type = (const struct efx_nic_type *) entry->driver_data; struct net_device *net_dev; struct efx_nic *efx; int rc; @@ -2666,12 +2627,10 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, EFX_MAX_RX_QUEUES); if (!net_dev) return -ENOMEM; - efx = netdev_priv(net_dev); - efx->type = (const struct efx_nic_type *) entry->driver_data; - net_dev->features |= (efx->type->offload_features | NETIF_F_SG | + net_dev->features |= (type->offload_features | NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_RXCSUM); - if (efx->type->offload_features & NETIF_F_V6_CSUM) + if (type->offload_features & NETIF_F_V6_CSUM) net_dev->features |= NETIF_F_TSO6; /* Mask for features that also apply to VLAN devices */ net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG | @@ -2679,9 +2638,10 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, NETIF_F_RXCSUM); /* All offloads can be toggled */ net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA; + efx = netdev_priv(net_dev); pci_set_drvdata(pci_dev, efx); SET_NETDEV_DEV(net_dev, &pci_dev->dev); - rc = efx_init_struct(efx, pci_dev, net_dev); + rc = efx_init_struct(efx, type, pci_dev, net_dev); if (rc) goto fail1; @@ -2696,9 +2656,28 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, goto fail2; rc = efx_pci_probe_main(efx); + + /* Serialise against efx_reset(). No more resets will be + * scheduled since efx_stop_all() has been called, and we have + * not and never have been registered. + */ + cancel_work_sync(&efx->reset_work); + if (rc) goto fail3; + /* If there was a scheduled reset during probe, the NIC is + * probably hosed anyway. + */ + if (efx->reset_pending) { + rc = -EIO; + goto fail4; + } + + /* Switch to the running state before we expose the device to the OS, + * so that dev_open()|efx_start_all() will actually start the device */ + efx->state = STATE_RUNNING; + rc = efx_register_netdev(efx); if (rc) goto fail4; @@ -2738,18 +2717,12 @@ static int efx_pm_freeze(struct device *dev) { struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); - rtnl_lock(); + efx->state = STATE_FINI; - if (efx->state != STATE_DISABLED) { - efx->state = STATE_UNINIT; - - netif_device_detach(efx->net_dev); - - efx_stop_all(efx); - efx_stop_interrupts(efx, false); - } + netif_device_detach(efx->net_dev); - rtnl_unlock(); + efx_stop_all(efx); + efx_stop_interrupts(efx, false); return 0; } @@ -2758,25 +2731,21 @@ static int efx_pm_thaw(struct device *dev) { struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); - rtnl_lock(); + efx->state = STATE_INIT; - if (efx->state != STATE_DISABLED) { - efx_start_interrupts(efx, false); - - mutex_lock(&efx->mac_lock); - efx->phy_op->reconfigure(efx); - mutex_unlock(&efx->mac_lock); + efx_start_interrupts(efx, false); - efx_start_all(efx); + mutex_lock(&efx->mac_lock); + efx->phy_op->reconfigure(efx); + mutex_unlock(&efx->mac_lock); - netif_device_attach(efx->net_dev); + efx_start_all(efx); - efx->state = STATE_READY; + netif_device_attach(efx->net_dev); - efx->type->resume_wol(efx); - } + efx->state = STATE_RUNNING; - rtnl_unlock(); + efx->type->resume_wol(efx); /* Reschedule any quenched resets scheduled during efx_pm_freeze() */ queue_work(reset_workqueue, &efx->reset_work); diff --git a/trunk/drivers/net/ethernet/sfc/ethtool.c b/trunk/drivers/net/ethernet/sfc/ethtool.c index f8e7e204981f..8cba2df82b18 100644 --- a/trunk/drivers/net/ethernet/sfc/ethtool.c +++ b/trunk/drivers/net/ethernet/sfc/ethtool.c @@ -529,7 +529,9 @@ static void efx_ethtool_self_test(struct net_device *net_dev, if (!efx_tests) goto fail; - if (efx->state != STATE_READY) { + + ASSERT_RTNL(); + if (efx->state != STATE_RUNNING) { rc = -EIO; goto fail1; } @@ -861,8 +863,8 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx, &ip_entry->ip4dst, &ip_entry->pdst); if (rc != 0) { rc = efx_filter_get_ipv4_full( - &spec, &proto, &ip_entry->ip4dst, &ip_entry->pdst, - &ip_entry->ip4src, &ip_entry->psrc); + &spec, &proto, &ip_entry->ip4src, &ip_entry->psrc, + &ip_entry->ip4dst, &ip_entry->pdst); EFX_WARN_ON_PARANOID(rc); ip_mask->ip4src = ~0; ip_mask->psrc = ~0; diff --git a/trunk/drivers/net/ethernet/sfc/falcon_boards.c b/trunk/drivers/net/ethernet/sfc/falcon_boards.c index ec1e99d0dcad..8687a6c3db0d 100644 --- a/trunk/drivers/net/ethernet/sfc/falcon_boards.c +++ b/trunk/drivers/net/ethernet/sfc/falcon_boards.c @@ -380,7 +380,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev, new_mode = PHY_MODE_SPECIAL; if (!((old_mode ^ new_mode) & PHY_MODE_SPECIAL)) { err = 0; - } else if (efx->state != STATE_READY || netif_running(efx->net_dev)) { + } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { err = -EBUSY; } else { /* Reset the PHY, reconfigure the MAC and enable/disable diff --git a/trunk/drivers/net/ethernet/sfc/net_driver.h b/trunk/drivers/net/ethernet/sfc/net_driver.h index 7ab1232494ef..cd9c0a989692 100644 --- a/trunk/drivers/net/ethernet/sfc/net_driver.h +++ b/trunk/drivers/net/ethernet/sfc/net_driver.h @@ -91,31 +91,29 @@ struct efx_special_buffer { }; /** - * struct efx_tx_buffer - buffer state for a TX descriptor - * @skb: When @flags & %EFX_TX_BUF_SKB, the associated socket buffer to be - * freed when descriptor completes - * @heap_buf: When @flags & %EFX_TX_BUF_HEAP, the associated heap buffer to be - * freed when descriptor completes. + * struct efx_tx_buffer - An Efx TX buffer + * @skb: The associated socket buffer. + * Set only on the final fragment of a packet; %NULL for all other + * fragments. When this fragment completes, then we can free this + * skb. + * @tsoh: The associated TSO header structure, or %NULL if this + * buffer is not a TSO header. * @dma_addr: DMA address of the fragment. - * @flags: Flags for allocation and DMA mapping type * @len: Length of this fragment. * This field is zero when the queue slot is empty. + * @continuation: True if this fragment is not the end of a packet. + * @unmap_single: True if dma_unmap_single should be used. * @unmap_len: Length of this fragment to unmap */ struct efx_tx_buffer { - union { - const struct sk_buff *skb; - void *heap_buf; - }; + const struct sk_buff *skb; + struct efx_tso_header *tsoh; dma_addr_t dma_addr; - unsigned short flags; unsigned short len; + bool continuation; + bool unmap_single; unsigned short unmap_len; }; -#define EFX_TX_BUF_CONT 1 /* not last descriptor of packet */ -#define EFX_TX_BUF_SKB 2 /* buffer is last part of skb */ -#define EFX_TX_BUF_HEAP 4 /* buffer was allocated with kmalloc() */ -#define EFX_TX_BUF_MAP_SINGLE 8 /* buffer was mapped with dma_map_single() */ /** * struct efx_tx_queue - An Efx TX queue @@ -135,7 +133,6 @@ struct efx_tx_buffer { * @channel: The associated channel * @core_txq: The networking core TX queue structure * @buffer: The software buffer ring - * @tsoh_page: Array of pages of TSO header buffers * @txd: The hardware descriptor ring * @ptr_mask: The size of the ring minus 1. * @initialised: Has hardware queue been initialised? @@ -159,6 +156,9 @@ struct efx_tx_buffer { * variable indicates that the queue is full. This is to * avoid cache-line ping-pong between the xmit path and the * completion path. + * @tso_headers_free: A list of TSO headers allocated for this TX queue + * that are not in use, and so available for new TSO sends. The list + * is protected by the TX queue lock. * @tso_bursts: Number of times TSO xmit invoked by kernel * @tso_long_headers: Number of packets with headers too long for standard * blocks @@ -175,7 +175,6 @@ struct efx_tx_queue { struct efx_channel *channel; struct netdev_queue *core_txq; struct efx_tx_buffer *buffer; - struct efx_buffer *tsoh_page; struct efx_special_buffer txd; unsigned int ptr_mask; bool initialised; @@ -188,6 +187,7 @@ struct efx_tx_queue { unsigned int insert_count ____cacheline_aligned_in_smp; unsigned int write_count; unsigned int old_read_count; + struct efx_tso_header *tso_headers_free; unsigned int tso_bursts; unsigned int tso_long_headers; unsigned int tso_packets; @@ -430,9 +430,11 @@ enum efx_int_mode { #define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI) enum nic_state { - STATE_UNINIT = 0, /* device being probed/removed or is frozen */ - STATE_READY = 1, /* hardware ready and netdev registered */ - STATE_DISABLED = 2, /* device disabled due to hardware errors */ + STATE_INIT = 0, + STATE_RUNNING = 1, + STATE_FINI = 2, + STATE_DISABLED = 3, + STATE_MAX, }; /* @@ -652,7 +654,7 @@ struct vfdi_status; * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues * @irq_rx_moderation: IRQ moderation time for RX event queues * @msg_enable: Log message enable flags - * @state: Device state number (%STATE_*). Serialised by the rtnl_lock. + * @state: Device state flag. Serialised by the rtnl_lock. * @reset_pending: Bitmask for pending resets * @tx_queue: TX DMA queues * @rx_queue: RX DMA queues @@ -662,8 +664,6 @@ struct vfdi_status; * should be allocated for this NIC * @rxq_entries: Size of receive queues requested by user. * @txq_entries: Size of transmit queues requested by user. - * @txq_stop_thresh: TX queue fill level at or above which we stop it. - * @txq_wake_thresh: TX queue fill level at or below which we wake it. * @tx_dc_base: Base qword address in SRAM of TX queue descriptor caches * @rx_dc_base: Base qword address in SRAM of RX queue descriptor caches * @sram_lim_qw: Qword address limit of SRAM @@ -774,9 +774,6 @@ struct efx_nic { unsigned rxq_entries; unsigned txq_entries; - unsigned int txq_stop_thresh; - unsigned int txq_wake_thresh; - unsigned tx_dc_base; unsigned rx_dc_base; unsigned sram_lim_qw; diff --git a/trunk/drivers/net/ethernet/sfc/nic.c b/trunk/drivers/net/ethernet/sfc/nic.c index cdff40b65729..326d799762d6 100644 --- a/trunk/drivers/net/ethernet/sfc/nic.c +++ b/trunk/drivers/net/ethernet/sfc/nic.c @@ -298,7 +298,7 @@ efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) /************************************************************************** * * Generic buffer handling - * These buffers are used for interrupt status, MAC stats, etc. + * These buffers are used for interrupt status and MAC stats * **************************************************************************/ @@ -401,10 +401,8 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) ++tx_queue->write_count; /* Create TX descriptor ring entry */ - BUILD_BUG_ON(EFX_TX_BUF_CONT != 1); EFX_POPULATE_QWORD_4(*txd, - FSF_AZ_TX_KER_CONT, - buffer->flags & EFX_TX_BUF_CONT, + FSF_AZ_TX_KER_CONT, buffer->continuation, FSF_AZ_TX_KER_BYTE_COUNT, buffer->len, FSF_AZ_TX_KER_BUF_REGION, 0, FSF_AZ_TX_KER_BUF_ADDR, buffer->dma_addr); diff --git a/trunk/drivers/net/ethernet/sfc/tx.c b/trunk/drivers/net/ethernet/sfc/tx.c index ebca75ed78dc..18713436b443 100644 --- a/trunk/drivers/net/ethernet/sfc/tx.c +++ b/trunk/drivers/net/ethernet/sfc/tx.c @@ -22,6 +22,14 @@ #include "nic.h" #include "workarounds.h" +/* + * TX descriptor ring full threshold + * + * The tx_queue descriptor ring fill-level must fall below this value + * before we restart the netif queue + */ +#define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u) + static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, struct efx_tx_buffer *buffer, unsigned int *pkts_compl, @@ -31,32 +39,67 @@ static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, struct device *dma_dev = &tx_queue->efx->pci_dev->dev; dma_addr_t unmap_addr = (buffer->dma_addr + buffer->len - buffer->unmap_len); - if (buffer->flags & EFX_TX_BUF_MAP_SINGLE) + if (buffer->unmap_single) dma_unmap_single(dma_dev, unmap_addr, buffer->unmap_len, DMA_TO_DEVICE); else dma_unmap_page(dma_dev, unmap_addr, buffer->unmap_len, DMA_TO_DEVICE); buffer->unmap_len = 0; + buffer->unmap_single = false; } - if (buffer->flags & EFX_TX_BUF_SKB) { + if (buffer->skb) { (*pkts_compl)++; (*bytes_compl) += buffer->skb->len; dev_kfree_skb_any((struct sk_buff *) buffer->skb); + buffer->skb = NULL; netif_vdbg(tx_queue->efx, tx_done, tx_queue->efx->net_dev, "TX queue %d transmission id %x complete\n", tx_queue->queue, tx_queue->read_count); - } else if (buffer->flags & EFX_TX_BUF_HEAP) { - kfree(buffer->heap_buf); } - - buffer->len = 0; - buffer->flags = 0; } +/** + * struct efx_tso_header - a DMA mapped buffer for packet headers + * @next: Linked list of free ones. + * The list is protected by the TX queue lock. + * @dma_unmap_len: Length to unmap for an oversize buffer, or 0. + * @dma_addr: The DMA address of the header below. + * + * This controls the memory used for a TSO header. Use TSOH_DATA() + * to find the packet header data. Use TSOH_SIZE() to calculate the + * total size required for a given packet header length. TSO headers + * in the free list are exactly %TSOH_STD_SIZE bytes in size. + */ +struct efx_tso_header { + union { + struct efx_tso_header *next; + size_t unmap_len; + }; + dma_addr_t dma_addr; +}; + static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb); +static void efx_fini_tso(struct efx_tx_queue *tx_queue); +static void efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, + struct efx_tso_header *tsoh); + +static void efx_tsoh_free(struct efx_tx_queue *tx_queue, + struct efx_tx_buffer *buffer) +{ + if (buffer->tsoh) { + if (likely(!buffer->tsoh->unmap_len)) { + buffer->tsoh->next = tx_queue->tso_headers_free; + tx_queue->tso_headers_free = buffer->tsoh; + } else { + efx_tsoh_heap_free(tx_queue, buffer->tsoh); + } + buffer->tsoh = NULL; + } +} + static inline unsigned efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr) @@ -95,56 +138,6 @@ unsigned int efx_tx_max_skb_descs(struct efx_nic *efx) return max_descs; } -/* Get partner of a TX queue, seen as part of the same net core queue */ -static struct efx_tx_queue *efx_tx_queue_partner(struct efx_tx_queue *tx_queue) -{ - if (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD) - return tx_queue - EFX_TXQ_TYPE_OFFLOAD; - else - return tx_queue + EFX_TXQ_TYPE_OFFLOAD; -} - -static void efx_tx_maybe_stop_queue(struct efx_tx_queue *txq1) -{ - /* We need to consider both queues that the net core sees as one */ - struct efx_tx_queue *txq2 = efx_tx_queue_partner(txq1); - struct efx_nic *efx = txq1->efx; - unsigned int fill_level; - - fill_level = max(txq1->insert_count - txq1->old_read_count, - txq2->insert_count - txq2->old_read_count); - if (likely(fill_level < efx->txq_stop_thresh)) - return; - - /* We used the stale old_read_count above, which gives us a - * pessimistic estimate of the fill level (which may even - * validly be >= efx->txq_entries). Now try again using - * read_count (more likely to be a cache miss). - * - * If we read read_count and then conditionally stop the - * queue, it is possible for the completion path to race with - * us and complete all outstanding descriptors in the middle, - * after which there will be no more completions to wake it. - * Therefore we stop the queue first, then read read_count - * (with a memory barrier to ensure the ordering), then - * restart the queue if the fill level turns out to be low - * enough. - */ - netif_tx_stop_queue(txq1->core_txq); - smp_mb(); - txq1->old_read_count = ACCESS_ONCE(txq1->read_count); - txq2->old_read_count = ACCESS_ONCE(txq2->read_count); - - fill_level = max(txq1->insert_count - txq1->old_read_count, - txq2->insert_count - txq2->old_read_count); - EFX_BUG_ON_PARANOID(fill_level >= efx->txq_entries); - if (likely(fill_level < efx->txq_stop_thresh)) { - smp_mb(); - if (likely(!efx->loopback_selftest)) - netif_tx_start_queue(txq1->core_txq); - } -} - /* * Add a socket buffer to a TX queue * @@ -158,7 +151,7 @@ static void efx_tx_maybe_stop_queue(struct efx_tx_queue *txq1) * This function is split out from efx_hard_start_xmit to allow the * loopback test to direct packets via specific TX queues. * - * Returns NETDEV_TX_OK. + * Returns NETDEV_TX_OK or NETDEV_TX_BUSY * You must hold netif_tx_lock() to call this function. */ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) @@ -167,11 +160,12 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) struct device *dma_dev = &efx->pci_dev->dev; struct efx_tx_buffer *buffer; skb_frag_t *fragment; - unsigned int len, unmap_len = 0, insert_ptr; + unsigned int len, unmap_len = 0, fill_level, insert_ptr; dma_addr_t dma_addr, unmap_addr = 0; unsigned int dma_len; - unsigned short dma_flags; - int i = 0; + bool unmap_single; + int q_space, i = 0; + netdev_tx_t rc = NETDEV_TX_OK; EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count); @@ -189,11 +183,14 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) return NETDEV_TX_OK; } + fill_level = tx_queue->insert_count - tx_queue->old_read_count; + q_space = efx->txq_entries - 1 - fill_level; + /* Map for DMA. Use dma_map_single rather than dma_map_page * since this is more efficient on machines with sparse * memory. */ - dma_flags = EFX_TX_BUF_MAP_SINGLE; + unmap_single = true; dma_addr = dma_map_single(dma_dev, skb->data, len, PCI_DMA_TODEVICE); /* Process all fragments */ @@ -208,10 +205,39 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) /* Add to TX queue, splitting across DMA boundaries */ do { + if (unlikely(q_space-- <= 0)) { + /* It might be that completions have + * happened since the xmit path last + * checked. Update the xmit path's + * copy of read_count. + */ + netif_tx_stop_queue(tx_queue->core_txq); + /* This memory barrier protects the + * change of queue state from the access + * of read_count. */ + smp_mb(); + tx_queue->old_read_count = + ACCESS_ONCE(tx_queue->read_count); + fill_level = (tx_queue->insert_count + - tx_queue->old_read_count); + q_space = efx->txq_entries - 1 - fill_level; + if (unlikely(q_space-- <= 0)) { + rc = NETDEV_TX_BUSY; + goto unwind; + } + smp_mb(); + if (likely(!efx->loopback_selftest)) + netif_tx_start_queue( + tx_queue->core_txq); + } + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; - EFX_BUG_ON_PARANOID(buffer->flags); + efx_tsoh_free(tx_queue, buffer); + EFX_BUG_ON_PARANOID(buffer->tsoh); + EFX_BUG_ON_PARANOID(buffer->skb); EFX_BUG_ON_PARANOID(buffer->len); + EFX_BUG_ON_PARANOID(!buffer->continuation); EFX_BUG_ON_PARANOID(buffer->unmap_len); dma_len = efx_max_tx_len(efx, dma_addr); @@ -221,14 +247,13 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) /* Fill out per descriptor fields */ buffer->len = dma_len; buffer->dma_addr = dma_addr; - buffer->flags = EFX_TX_BUF_CONT; len -= dma_len; dma_addr += dma_len; ++tx_queue->insert_count; } while (len); /* Transfer ownership of the unmapping to the final buffer */ - buffer->flags = EFX_TX_BUF_CONT | dma_flags; + buffer->unmap_single = unmap_single; buffer->unmap_len = unmap_len; unmap_len = 0; @@ -239,22 +264,20 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) len = skb_frag_size(fragment); i++; /* Map for DMA */ - dma_flags = 0; + unmap_single = false; dma_addr = skb_frag_dma_map(dma_dev, fragment, 0, len, DMA_TO_DEVICE); } /* Transfer ownership of the skb to the final buffer */ buffer->skb = skb; - buffer->flags = EFX_TX_BUF_SKB | dma_flags; + buffer->continuation = false; netdev_tx_sent_queue(tx_queue->core_txq, skb->len); /* Pass off to hardware */ efx_nic_push_buffers(tx_queue); - efx_tx_maybe_stop_queue(tx_queue); - return NETDEV_TX_OK; dma_err: @@ -266,6 +289,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) /* Mark the packet as transmitted, and free the SKB ourselves */ dev_kfree_skb_any(skb); + unwind: /* Work backwards until we hit the original insert pointer value */ while (tx_queue->insert_count != tx_queue->write_count) { unsigned int pkts_compl = 0, bytes_compl = 0; @@ -273,11 +297,12 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl); + buffer->len = 0; } /* Free the fragment we were mid-way through pushing */ if (unmap_len) { - if (dma_flags & EFX_TX_BUF_MAP_SINGLE) + if (unmap_single) dma_unmap_single(dma_dev, unmap_addr, unmap_len, DMA_TO_DEVICE); else @@ -285,7 +310,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) DMA_TO_DEVICE); } - return NETDEV_TX_OK; + return rc; } /* Remove packets from the TX queue @@ -315,6 +340,8 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, } efx_dequeue_buffer(tx_queue, buffer, pkts_compl, bytes_compl); + buffer->continuation = true; + buffer->len = 0; ++tx_queue->read_count; read_ptr = tx_queue->read_count & tx_queue->ptr_mask; @@ -423,7 +450,6 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) { unsigned fill_level; struct efx_nic *efx = tx_queue->efx; - struct efx_tx_queue *txq2; unsigned int pkts_compl = 0, bytes_compl = 0; EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask); @@ -431,18 +457,15 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) efx_dequeue_buffers(tx_queue, index, &pkts_compl, &bytes_compl); netdev_tx_completed_queue(tx_queue->core_txq, pkts_compl, bytes_compl); - /* See if we need to restart the netif queue. This memory - * barrier ensures that we write read_count (inside - * efx_dequeue_buffers()) before reading the queue status. - */ + /* See if we need to restart the netif queue. This barrier + * separates the update of read_count from the test of the + * queue state. */ smp_mb(); if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) && likely(efx->port_enabled) && likely(netif_device_present(efx->net_dev))) { - txq2 = efx_tx_queue_partner(tx_queue); - fill_level = max(tx_queue->insert_count - tx_queue->read_count, - txq2->insert_count - txq2->read_count); - if (fill_level <= efx->txq_wake_thresh) + fill_level = tx_queue->insert_count - tx_queue->read_count; + if (fill_level < EFX_TXQ_THRESHOLD(efx)) netif_tx_wake_queue(tx_queue->core_txq); } @@ -457,26 +480,11 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) } } -/* Size of page-based TSO header buffers. Larger blocks must be - * allocated from the heap. - */ -#define TSOH_STD_SIZE 128 -#define TSOH_PER_PAGE (PAGE_SIZE / TSOH_STD_SIZE) - -/* At most half the descriptors in the queue at any time will refer to - * a TSO header buffer, since they must always be followed by a - * payload descriptor referring to an skb. - */ -static unsigned int efx_tsoh_page_count(struct efx_tx_queue *tx_queue) -{ - return DIV_ROUND_UP(tx_queue->ptr_mask + 1, 2 * TSOH_PER_PAGE); -} - int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; unsigned int entries; - int rc; + int i, rc; /* Create the smallest power-of-two aligned ring */ entries = max(roundup_pow_of_two(efx->txq_entries), EFX_MIN_DMAQ_SIZE); @@ -492,28 +500,17 @@ int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) GFP_KERNEL); if (!tx_queue->buffer) return -ENOMEM; - - if (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD) { - tx_queue->tsoh_page = - kcalloc(efx_tsoh_page_count(tx_queue), - sizeof(tx_queue->tsoh_page[0]), GFP_KERNEL); - if (!tx_queue->tsoh_page) { - rc = -ENOMEM; - goto fail1; - } - } + for (i = 0; i <= tx_queue->ptr_mask; ++i) + tx_queue->buffer[i].continuation = true; /* Allocate hardware ring */ rc = efx_nic_probe_tx(tx_queue); if (rc) - goto fail2; + goto fail; return 0; -fail2: - kfree(tx_queue->tsoh_page); - tx_queue->tsoh_page = NULL; -fail1: + fail: kfree(tx_queue->buffer); tx_queue->buffer = NULL; return rc; @@ -549,6 +546,8 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue) unsigned int pkts_compl = 0, bytes_compl = 0; buffer = &tx_queue->buffer[tx_queue->read_count & tx_queue->ptr_mask]; efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl); + buffer->continuation = true; + buffer->len = 0; ++tx_queue->read_count; } @@ -569,12 +568,13 @@ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue) efx_nic_fini_tx(tx_queue); efx_release_tx_buffers(tx_queue); + + /* Free up TSO header cache */ + efx_fini_tso(tx_queue); } void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) { - int i; - if (!tx_queue->buffer) return; @@ -582,14 +582,6 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) "destroying TX queue %d\n", tx_queue->queue); efx_nic_remove_tx(tx_queue); - if (tx_queue->tsoh_page) { - for (i = 0; i < efx_tsoh_page_count(tx_queue); i++) - efx_nic_free_buffer(tx_queue->efx, - &tx_queue->tsoh_page[i]); - kfree(tx_queue->tsoh_page); - tx_queue->tsoh_page = NULL; - } - kfree(tx_queue->buffer); tx_queue->buffer = NULL; } @@ -612,7 +604,22 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) #define TSOH_OFFSET NET_IP_ALIGN #endif +#define TSOH_BUFFER(tsoh) ((u8 *)(tsoh + 1) + TSOH_OFFSET) + +/* Total size of struct efx_tso_header, buffer and padding */ +#define TSOH_SIZE(hdr_len) \ + (sizeof(struct efx_tso_header) + TSOH_OFFSET + hdr_len) + +/* Size of blocks on free list. Larger blocks must be allocated from + * the heap. + */ +#define TSOH_STD_SIZE 128 + #define PTR_DIFF(p1, p2) ((u8 *)(p1) - (u8 *)(p2)) +#define ETH_HDR_LEN(skb) (skb_network_header(skb) - (skb)->data) +#define SKB_TCP_OFF(skb) PTR_DIFF(tcp_hdr(skb), (skb)->data) +#define SKB_IPV4_OFF(skb) PTR_DIFF(ip_hdr(skb), (skb)->data) +#define SKB_IPV6_OFF(skb) PTR_DIFF(ipv6_hdr(skb), (skb)->data) /** * struct tso_state - TSO state for an SKB @@ -624,12 +631,10 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) * @in_len: Remaining length in current SKB fragment * @unmap_len: Length of SKB fragment * @unmap_addr: DMA address of SKB fragment - * @dma_flags: TX buffer flags for DMA mapping - %EFX_TX_BUF_MAP_SINGLE or 0 + * @unmap_single: DMA single vs page mapping flag * @protocol: Network protocol (after any VLAN header) - * @ip_off: Offset of IP header - * @tcp_off: Offset of TCP header * @header_len: Number of bytes of header - * @ip_base_len: IPv4 tot_len or IPv6 payload_len, before TCP payload + * @full_packet_size: Number of bytes to put in each outgoing segment * * The state used during segmentation. It is put into this data structure * just to make it easy to pass into inline functions. @@ -646,13 +651,11 @@ struct tso_state { unsigned in_len; unsigned unmap_len; dma_addr_t unmap_addr; - unsigned short dma_flags; + bool unmap_single; __be16 protocol; - unsigned int ip_off; - unsigned int tcp_off; unsigned header_len; - unsigned int ip_base_len; + int full_packet_size; }; @@ -684,43 +687,91 @@ static __be16 efx_tso_check_protocol(struct sk_buff *skb) return protocol; } -static u8 *efx_tsoh_get_buffer(struct efx_tx_queue *tx_queue, - struct efx_tx_buffer *buffer, unsigned int len) + +/* + * Allocate a page worth of efx_tso_header structures, and string them + * into the tx_queue->tso_headers_free linked list. Return 0 or -ENOMEM. + */ +static int efx_tsoh_block_alloc(struct efx_tx_queue *tx_queue) { - u8 *result; + struct device *dma_dev = &tx_queue->efx->pci_dev->dev; + struct efx_tso_header *tsoh; + dma_addr_t dma_addr; + u8 *base_kva, *kva; - EFX_BUG_ON_PARANOID(buffer->len); - EFX_BUG_ON_PARANOID(buffer->flags); - EFX_BUG_ON_PARANOID(buffer->unmap_len); + base_kva = dma_alloc_coherent(dma_dev, PAGE_SIZE, &dma_addr, GFP_ATOMIC); + if (base_kva == NULL) { + netif_err(tx_queue->efx, tx_err, tx_queue->efx->net_dev, + "Unable to allocate page for TSO headers\n"); + return -ENOMEM; + } - if (likely(len <= TSOH_STD_SIZE - TSOH_OFFSET)) { - unsigned index = - (tx_queue->insert_count & tx_queue->ptr_mask) / 2; - struct efx_buffer *page_buf = - &tx_queue->tsoh_page[index / TSOH_PER_PAGE]; - unsigned offset = - TSOH_STD_SIZE * (index % TSOH_PER_PAGE) + TSOH_OFFSET; - - if (unlikely(!page_buf->addr) && - efx_nic_alloc_buffer(tx_queue->efx, page_buf, PAGE_SIZE)) - return NULL; - - result = (u8 *)page_buf->addr + offset; - buffer->dma_addr = page_buf->dma_addr + offset; - buffer->flags = EFX_TX_BUF_CONT; - } else { - tx_queue->tso_long_headers++; + /* dma_alloc_coherent() allocates pages. */ + EFX_BUG_ON_PARANOID(dma_addr & (PAGE_SIZE - 1u)); - buffer->heap_buf = kmalloc(TSOH_OFFSET + len, GFP_ATOMIC); - if (unlikely(!buffer->heap_buf)) - return NULL; - result = (u8 *)buffer->heap_buf + TSOH_OFFSET; - buffer->flags = EFX_TX_BUF_CONT | EFX_TX_BUF_HEAP; + for (kva = base_kva; kva < base_kva + PAGE_SIZE; kva += TSOH_STD_SIZE) { + tsoh = (struct efx_tso_header *)kva; + tsoh->dma_addr = dma_addr + (TSOH_BUFFER(tsoh) - base_kva); + tsoh->next = tx_queue->tso_headers_free; + tx_queue->tso_headers_free = tsoh; } - buffer->len = len; + return 0; +} - return result; + +/* Free up a TSO header, and all others in the same page. */ +static void efx_tsoh_block_free(struct efx_tx_queue *tx_queue, + struct efx_tso_header *tsoh, + struct device *dma_dev) +{ + struct efx_tso_header **p; + unsigned long base_kva; + dma_addr_t base_dma; + + base_kva = (unsigned long)tsoh & PAGE_MASK; + base_dma = tsoh->dma_addr & PAGE_MASK; + + p = &tx_queue->tso_headers_free; + while (*p != NULL) { + if (((unsigned long)*p & PAGE_MASK) == base_kva) + *p = (*p)->next; + else + p = &(*p)->next; + } + + dma_free_coherent(dma_dev, PAGE_SIZE, (void *)base_kva, base_dma); +} + +static struct efx_tso_header * +efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len) +{ + struct efx_tso_header *tsoh; + + tsoh = kmalloc(TSOH_SIZE(header_len), GFP_ATOMIC | GFP_DMA); + if (unlikely(!tsoh)) + return NULL; + + tsoh->dma_addr = dma_map_single(&tx_queue->efx->pci_dev->dev, + TSOH_BUFFER(tsoh), header_len, + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(&tx_queue->efx->pci_dev->dev, + tsoh->dma_addr))) { + kfree(tsoh); + return NULL; + } + + tsoh->unmap_len = header_len; + return tsoh; +} + +static void +efx_tsoh_heap_free(struct efx_tx_queue *tx_queue, struct efx_tso_header *tsoh) +{ + dma_unmap_single(&tx_queue->efx->pci_dev->dev, + tsoh->dma_addr, tsoh->unmap_len, + DMA_TO_DEVICE); + kfree(tsoh); } /** @@ -730,19 +781,47 @@ static u8 *efx_tsoh_get_buffer(struct efx_tx_queue *tx_queue, * @len: Length of fragment * @final_buffer: The final buffer inserted into the queue * - * Push descriptors onto the TX queue. + * Push descriptors onto the TX queue. Return 0 on success or 1 if + * @tx_queue full. */ -static void efx_tx_queue_insert(struct efx_tx_queue *tx_queue, - dma_addr_t dma_addr, unsigned len, - struct efx_tx_buffer **final_buffer) +static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, + dma_addr_t dma_addr, unsigned len, + struct efx_tx_buffer **final_buffer) { struct efx_tx_buffer *buffer; struct efx_nic *efx = tx_queue->efx; - unsigned dma_len, insert_ptr; + unsigned dma_len, fill_level, insert_ptr; + int q_space; EFX_BUG_ON_PARANOID(len <= 0); + fill_level = tx_queue->insert_count - tx_queue->old_read_count; + /* -1 as there is no way to represent all descriptors used */ + q_space = efx->txq_entries - 1 - fill_level; + while (1) { + if (unlikely(q_space-- <= 0)) { + /* It might be that completions have happened + * since the xmit path last checked. Update + * the xmit path's copy of read_count. + */ + netif_tx_stop_queue(tx_queue->core_txq); + /* This memory barrier protects the change of + * queue state from the access of read_count. */ + smp_mb(); + tx_queue->old_read_count = + ACCESS_ONCE(tx_queue->read_count); + fill_level = (tx_queue->insert_count + - tx_queue->old_read_count); + q_space = efx->txq_entries - 1 - fill_level; + if (unlikely(q_space-- <= 0)) { + *final_buffer = NULL; + return 1; + } + smp_mb(); + netif_tx_start_queue(tx_queue->core_txq); + } + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; ++tx_queue->insert_count; @@ -751,9 +830,12 @@ static void efx_tx_queue_insert(struct efx_tx_queue *tx_queue, tx_queue->read_count >= efx->txq_entries); + efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->len); EFX_BUG_ON_PARANOID(buffer->unmap_len); - EFX_BUG_ON_PARANOID(buffer->flags); + EFX_BUG_ON_PARANOID(buffer->skb); + EFX_BUG_ON_PARANOID(!buffer->continuation); + EFX_BUG_ON_PARANOID(buffer->tsoh); buffer->dma_addr = dma_addr; @@ -763,8 +845,7 @@ static void efx_tx_queue_insert(struct efx_tx_queue *tx_queue, if (dma_len >= len) break; - buffer->len = dma_len; - buffer->flags = EFX_TX_BUF_CONT; + buffer->len = dma_len; /* Don't set the other members */ dma_addr += dma_len; len -= dma_len; } @@ -772,6 +853,7 @@ static void efx_tx_queue_insert(struct efx_tx_queue *tx_queue, EFX_BUG_ON_PARANOID(!len); buffer->len = len; *final_buffer = buffer; + return 0; } @@ -782,42 +864,54 @@ static void efx_tx_queue_insert(struct efx_tx_queue *tx_queue, * a single fragment, and we know it doesn't cross a page boundary. It * also allows us to not worry about end-of-packet etc. */ -static int efx_tso_put_header(struct efx_tx_queue *tx_queue, - struct efx_tx_buffer *buffer, u8 *header) +static void efx_tso_put_header(struct efx_tx_queue *tx_queue, + struct efx_tso_header *tsoh, unsigned len) { - if (unlikely(buffer->flags & EFX_TX_BUF_HEAP)) { - buffer->dma_addr = dma_map_single(&tx_queue->efx->pci_dev->dev, - header, buffer->len, - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(&tx_queue->efx->pci_dev->dev, - buffer->dma_addr))) { - kfree(buffer->heap_buf); - buffer->len = 0; - buffer->flags = 0; - return -ENOMEM; - } - buffer->unmap_len = buffer->len; - buffer->flags |= EFX_TX_BUF_MAP_SINGLE; - } + struct efx_tx_buffer *buffer; + + buffer = &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask]; + efx_tsoh_free(tx_queue, buffer); + EFX_BUG_ON_PARANOID(buffer->len); + EFX_BUG_ON_PARANOID(buffer->unmap_len); + EFX_BUG_ON_PARANOID(buffer->skb); + EFX_BUG_ON_PARANOID(!buffer->continuation); + EFX_BUG_ON_PARANOID(buffer->tsoh); + buffer->len = len; + buffer->dma_addr = tsoh->dma_addr; + buffer->tsoh = tsoh; ++tx_queue->insert_count; - return 0; } -/* Remove buffers put into a tx_queue. None of the buffers must have - * an skb attached. - */ +/* Remove descriptors put into a tx_queue. */ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) { struct efx_tx_buffer *buffer; + dma_addr_t unmap_addr; /* Work backwards until we hit the original insert pointer value */ while (tx_queue->insert_count != tx_queue->write_count) { --tx_queue->insert_count; buffer = &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask]; - efx_dequeue_buffer(tx_queue, buffer, NULL, NULL); + efx_tsoh_free(tx_queue, buffer); + EFX_BUG_ON_PARANOID(buffer->skb); + if (buffer->unmap_len) { + unmap_addr = (buffer->dma_addr + buffer->len - + buffer->unmap_len); + if (buffer->unmap_single) + dma_unmap_single(&tx_queue->efx->pci_dev->dev, + unmap_addr, buffer->unmap_len, + DMA_TO_DEVICE); + else + dma_unmap_page(&tx_queue->efx->pci_dev->dev, + unmap_addr, buffer->unmap_len, + DMA_TO_DEVICE); + buffer->unmap_len = 0; + } + buffer->len = 0; + buffer->continuation = true; } } @@ -825,16 +919,17 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) /* Parse the SKB header and initialise state. */ static void tso_start(struct tso_state *st, const struct sk_buff *skb) { - st->ip_off = skb_network_header(skb) - skb->data; - st->tcp_off = skb_transport_header(skb) - skb->data; - st->header_len = st->tcp_off + (tcp_hdr(skb)->doff << 2u); - if (st->protocol == htons(ETH_P_IP)) { - st->ip_base_len = st->header_len - st->ip_off; + /* All ethernet/IP/TCP headers combined size is TCP header size + * plus offset of TCP header relative to start of packet. + */ + st->header_len = ((tcp_hdr(skb)->doff << 2u) + + PTR_DIFF(tcp_hdr(skb), skb->data)); + st->full_packet_size = st->header_len + skb_shinfo(skb)->gso_size; + + if (st->protocol == htons(ETH_P_IP)) st->ipv4_id = ntohs(ip_hdr(skb)->id); - } else { - st->ip_base_len = st->header_len - st->tcp_off; + else st->ipv4_id = 0; - } st->seqnum = ntohl(tcp_hdr(skb)->seq); EFX_BUG_ON_PARANOID(tcp_hdr(skb)->urg); @@ -843,7 +938,7 @@ static void tso_start(struct tso_state *st, const struct sk_buff *skb) st->out_len = skb->len - st->header_len; st->unmap_len = 0; - st->dma_flags = 0; + st->unmap_single = false; } static int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, @@ -852,7 +947,7 @@ static int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, st->unmap_addr = skb_frag_dma_map(&efx->pci_dev->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); if (likely(!dma_mapping_error(&efx->pci_dev->dev, st->unmap_addr))) { - st->dma_flags = 0; + st->unmap_single = false; st->unmap_len = skb_frag_size(frag); st->in_len = skb_frag_size(frag); st->dma_addr = st->unmap_addr; @@ -870,7 +965,7 @@ static int tso_get_head_fragment(struct tso_state *st, struct efx_nic *efx, st->unmap_addr = dma_map_single(&efx->pci_dev->dev, skb->data + hl, len, DMA_TO_DEVICE); if (likely(!dma_mapping_error(&efx->pci_dev->dev, st->unmap_addr))) { - st->dma_flags = EFX_TX_BUF_MAP_SINGLE; + st->unmap_single = true; st->unmap_len = len; st->in_len = len; st->dma_addr = st->unmap_addr; @@ -887,19 +982,20 @@ static int tso_get_head_fragment(struct tso_state *st, struct efx_nic *efx, * @st: TSO state * * Form descriptors for the current fragment, until we reach the end - * of fragment or end-of-packet. + * of fragment or end-of-packet. Return 0 on success, 1 if not enough + * space in @tx_queue. */ -static void tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, - const struct sk_buff *skb, - struct tso_state *st) +static int tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, + const struct sk_buff *skb, + struct tso_state *st) { struct efx_tx_buffer *buffer; - int n; + int n, end_of_packet, rc; if (st->in_len == 0) - return; + return 0; if (st->packet_space == 0) - return; + return 0; EFX_BUG_ON_PARANOID(st->in_len <= 0); EFX_BUG_ON_PARANOID(st->packet_space <= 0); @@ -910,24 +1006,25 @@ static void tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, st->out_len -= n; st->in_len -= n; - efx_tx_queue_insert(tx_queue, st->dma_addr, n, &buffer); + rc = efx_tx_queue_insert(tx_queue, st->dma_addr, n, &buffer); + if (likely(rc == 0)) { + if (st->out_len == 0) + /* Transfer ownership of the skb */ + buffer->skb = skb; - if (st->out_len == 0) { - /* Transfer ownership of the skb */ - buffer->skb = skb; - buffer->flags = EFX_TX_BUF_SKB; - } else if (st->packet_space != 0) { - buffer->flags = EFX_TX_BUF_CONT; - } + end_of_packet = st->out_len == 0 || st->packet_space == 0; + buffer->continuation = !end_of_packet; - if (st->in_len == 0) { - /* Transfer ownership of the DMA mapping */ - buffer->unmap_len = st->unmap_len; - buffer->flags |= st->dma_flags; - st->unmap_len = 0; + if (st->in_len == 0) { + /* Transfer ownership of the DMA mapping */ + buffer->unmap_len = st->unmap_len; + buffer->unmap_single = st->unmap_single; + st->unmap_len = 0; + } } st->dma_addr += n; + return rc; } @@ -938,25 +1035,36 @@ static void tso_fill_packet_with_fragment(struct efx_tx_queue *tx_queue, * @st: TSO state * * Generate a new header and prepare for the new packet. Return 0 on - * success, or -%ENOMEM if failed to alloc header. + * success, or -1 if failed to alloc header. */ static int tso_start_new_packet(struct efx_tx_queue *tx_queue, const struct sk_buff *skb, struct tso_state *st) { - struct efx_tx_buffer *buffer = - &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask]; + struct efx_tso_header *tsoh; struct tcphdr *tsoh_th; unsigned ip_length; u8 *header; - int rc; - /* Allocate and insert a DMA-mapped header buffer. */ - header = efx_tsoh_get_buffer(tx_queue, buffer, st->header_len); - if (!header) - return -ENOMEM; + /* Allocate a DMA-mapped header buffer. */ + if (likely(TSOH_SIZE(st->header_len) <= TSOH_STD_SIZE)) { + if (tx_queue->tso_headers_free == NULL) { + if (efx_tsoh_block_alloc(tx_queue)) + return -1; + } + EFX_BUG_ON_PARANOID(!tx_queue->tso_headers_free); + tsoh = tx_queue->tso_headers_free; + tx_queue->tso_headers_free = tsoh->next; + tsoh->unmap_len = 0; + } else { + tx_queue->tso_long_headers++; + tsoh = efx_tsoh_heap_alloc(tx_queue, st->header_len); + if (unlikely(!tsoh)) + return -1; + } - tsoh_th = (struct tcphdr *)(header + st->tcp_off); + header = TSOH_BUFFER(tsoh); + tsoh_th = (struct tcphdr *)(header + SKB_TCP_OFF(skb)); /* Copy and update the headers. */ memcpy(header, skb->data, st->header_len); @@ -965,19 +1073,19 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue, st->seqnum += skb_shinfo(skb)->gso_size; if (st->out_len > skb_shinfo(skb)->gso_size) { /* This packet will not finish the TSO burst. */ - st->packet_space = skb_shinfo(skb)->gso_size; + ip_length = st->full_packet_size - ETH_HDR_LEN(skb); tsoh_th->fin = 0; tsoh_th->psh = 0; } else { /* This packet will be the last in the TSO burst. */ - st->packet_space = st->out_len; + ip_length = st->header_len - ETH_HDR_LEN(skb) + st->out_len; tsoh_th->fin = tcp_hdr(skb)->fin; tsoh_th->psh = tcp_hdr(skb)->psh; } - ip_length = st->ip_base_len + st->packet_space; if (st->protocol == htons(ETH_P_IP)) { - struct iphdr *tsoh_iph = (struct iphdr *)(header + st->ip_off); + struct iphdr *tsoh_iph = + (struct iphdr *)(header + SKB_IPV4_OFF(skb)); tsoh_iph->tot_len = htons(ip_length); @@ -986,17 +1094,17 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue, st->ipv4_id++; } else { struct ipv6hdr *tsoh_iph = - (struct ipv6hdr *)(header + st->ip_off); + (struct ipv6hdr *)(header + SKB_IPV6_OFF(skb)); - tsoh_iph->payload_len = htons(ip_length); + tsoh_iph->payload_len = htons(ip_length - sizeof(*tsoh_iph)); } - rc = efx_tso_put_header(tx_queue, buffer, header); - if (unlikely(rc)) - return rc; - + st->packet_space = skb_shinfo(skb)->gso_size; ++tx_queue->tso_packets; + /* Form a descriptor for this header. */ + efx_tso_put_header(tx_queue, tsoh, st->header_len); + return 0; } @@ -1010,13 +1118,13 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue, * * Add socket buffer @skb to @tx_queue, doing TSO or return != 0 if * @skb was not enqueued. In all cases @skb is consumed. Return - * %NETDEV_TX_OK. + * %NETDEV_TX_OK or %NETDEV_TX_BUSY. */ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb) { struct efx_nic *efx = tx_queue->efx; - int frag_i, rc; + int frag_i, rc, rc2 = NETDEV_TX_OK; struct tso_state state; /* Find the packet protocol and sanity-check it */ @@ -1048,7 +1156,11 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, goto mem_err; while (1) { - tso_fill_packet_with_fragment(tx_queue, skb, &state); + rc = tso_fill_packet_with_fragment(tx_queue, skb, &state); + if (unlikely(rc)) { + rc2 = NETDEV_TX_BUSY; + goto unwind; + } /* Move onto the next fragment? */ if (state.in_len == 0) { @@ -1072,8 +1184,6 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, /* Pass off to hardware */ efx_nic_push_buffers(tx_queue); - efx_tx_maybe_stop_queue(tx_queue); - tx_queue->tso_bursts++; return NETDEV_TX_OK; @@ -1082,9 +1192,10 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, "Out of memory for TSO headers, or DMA mapping error\n"); dev_kfree_skb_any(skb); + unwind: /* Free the DMA mapping we were in the process of writing out */ if (state.unmap_len) { - if (state.dma_flags & EFX_TX_BUF_MAP_SINGLE) + if (state.unmap_single) dma_unmap_single(&efx->pci_dev->dev, state.unmap_addr, state.unmap_len, DMA_TO_DEVICE); else @@ -1093,5 +1204,25 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, } efx_enqueue_unwind(tx_queue); - return NETDEV_TX_OK; + return rc2; +} + + +/* + * Free up all TSO datastructures associated with tx_queue. This + * routine should be called only once the tx_queue is both empty and + * will no longer be used. + */ +static void efx_fini_tso(struct efx_tx_queue *tx_queue) +{ + unsigned i; + + if (tx_queue->buffer) { + for (i = 0; i <= tx_queue->ptr_mask; ++i) + efx_tsoh_free(tx_queue, &tx_queue->buffer[i]); + } + + while (tx_queue->tso_headers_free != NULL) + efx_tsoh_block_free(tx_queue, tx_queue->tso_headers_free, + &tx_queue->efx->pci_dev->dev); } diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/common.h b/trunk/drivers/net/ethernet/stmicro/stmmac/common.h index 719be3912aa9..e2d083228f3a 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/common.h @@ -22,9 +22,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __COMMON_H__ -#define __COMMON_H__ - #include #include #include @@ -369,5 +366,3 @@ extern void stmmac_set_mac(void __iomem *ioaddr, bool enable); extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); extern const struct stmmac_ring_mode_ops ring_mode_ops; - -#endif /* __COMMON_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/descs.h b/trunk/drivers/net/ethernet/stmicro/stmmac/descs.h index 223adf95fd03..9820ec842cc0 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/descs.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/descs.h @@ -20,10 +20,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ - -#ifndef __DESCS_H__ -#define __DESCS_H__ - struct dma_desc { /* Receive descriptor */ union { @@ -170,5 +166,3 @@ enum tdes_csum_insertion { * is not calculated */ cic_full = 3, /* IP header and pseudoheader */ }; - -#endif /* __DESCS_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/trunk/drivers/net/ethernet/stmicro/stmmac/descs_com.h index 7ee9499a6e38..dd8d6e19dff6 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/descs_com.h @@ -27,9 +27,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __DESC_COM_H__ -#define __DESC_COM_H__ - #if defined(CONFIG_STMMAC_RING) static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end) { @@ -127,5 +124,3 @@ static inline void norm_set_tx_desc_len(struct dma_desc *p, int len) p->des01.tx.buffer1_size = len; } #endif - -#endif /* __DESC_COM_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100.h index 2ec6aeae349e..7c6d857a9cc7 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac100.h @@ -22,9 +22,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __DWMAC100_H__ -#define __DWMAC100_H__ - #include #include "common.h" @@ -122,5 +119,3 @@ enum ttc_control { #define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ extern const struct stmmac_dma_ops dwmac100_dma_ops; - -#endif /* __DWMAC100_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 0e4cacedc1f0..f90fcb5f9573 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -19,8 +19,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __DWMAC1000_H__ -#define __DWMAC1000_H__ #include #include "common.h" @@ -231,7 +229,6 @@ enum rtc_control { #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 /* Synopsys Core versions */ -#define DWMAC_CORE_3_40 0x34 +#define DWMAC_CORE_3_40 34 extern const struct stmmac_dma_ops dwmac1000_dma_ops; -#endif /* __DWMAC1000_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index e49c9a0fd6ff..e678ce39d014 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -22,9 +22,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __DWMAC_DMA_H__ -#define __DWMAC_DMA_H__ - /* DMA CRS Control and Status Register Mapping */ #define DMA_BUS_MODE 0x00001000 /* Bus Mode */ #define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */ @@ -112,5 +109,3 @@ extern void dwmac_dma_start_rx(void __iomem *ioaddr); extern void dwmac_dma_stop_rx(void __iomem *ioaddr); extern int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x); - -#endif /* __DWMAC_DMA_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc.h b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc.h index 67995ef25251..a38352024cb8 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc.h @@ -22,9 +22,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __MMC_H__ -#define __MMC_H__ - /* MMC control register */ /* When set, all counter are reset */ #define MMC_CNTRL_COUNTER_RESET 0x1 @@ -132,5 +129,3 @@ struct stmmac_counters { extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode); extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr); extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); - -#endif /* __MMC_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index 0c74a702d461..c07cfe989f6e 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -33,7 +33,7 @@ #define MMC_TX_INTR 0x00000108 /* MMC TX Interrupt */ #define MMC_RX_INTR_MASK 0x0000010c /* MMC Interrupt Mask */ #define MMC_TX_INTR_MASK 0x00000110 /* MMC Interrupt Mask */ -#define MMC_DEFAULT_MASK 0xffffffff +#define MMC_DEFAUL_MASK 0xffffffff /* MMC TX counter registers */ @@ -147,8 +147,8 @@ void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode) /* To mask all all interrupts.*/ void dwmac_mmc_intr_all_mask(void __iomem *ioaddr) { - writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK); - writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK); + writel(MMC_DEFAUL_MASK, ioaddr + MMC_RX_INTR_MASK); + writel(MMC_DEFAUL_MASK, ioaddr + MMC_TX_INTR_MASK); } /* This reads the MAC core counters (if actaully supported). diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h index e872e1da3137..f2d3665430ad 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -20,9 +20,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __STMMAC_H__ -#define __STMMAC_H__ - #define STMMAC_RESOURCE_NAME "stmmaceth" #define DRV_MODULE_VERSION "March_2012" @@ -169,5 +166,3 @@ static inline void stmmac_unregister_pci(void) { } #endif /* CONFIG_STMMAC_PCI */ - -#endif /* __STMMAC_H__ */ diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index 0376a5e6b2bf..ade108232048 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -177,7 +177,7 @@ int stmmac_mdio_register(struct net_device *ndev) new_bus->write = &stmmac_mdio_write; new_bus->reset = &stmmac_mdio_reset; snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", - new_bus->name, priv->plat->bus_id); + new_bus->name, mdio_bus_data->bus_id); new_bus->priv = ndev; new_bus->irq = irqlist; new_bus->phy_mask = mdio_bus_data->phy_mask; @@ -213,10 +213,12 @@ int stmmac_mdio_register(struct net_device *ndev) * and no PHY number was provided to the MAC, * use the one probed here. */ - if (priv->plat->phy_addr == -1) + if ((priv->plat->bus_id == mdio_bus_data->bus_id) && + (priv->plat->phy_addr == -1)) priv->plat->phy_addr = addr; - act = (priv->plat->phy_addr == addr); + act = (priv->plat->bus_id == mdio_bus_data->bus_id) && + (priv->plat->phy_addr == addr); switch (phydev->irq) { case PHY_POLL: irq_str = "POLL"; @@ -256,9 +258,6 @@ int stmmac_mdio_unregister(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - if (!priv->mii) - return 0; - mdiobus_unregister(priv->mii); priv->mii->priv = NULL; mdiobus_free(priv->mii); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index 1f069b0f6af5..13afb8edfadc 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -40,6 +40,7 @@ static void stmmac_default_data(void) plat_dat.has_gmac = 1; plat_dat.force_sf_dma_mode = 1; + mdio_data.bus_id = 1; mdio_data.phy_reset = NULL; mdio_data.phy_mask = 0; plat_dat.mdio_bus_data = &mdio_data; diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index ed112b55ae7f..b93245c11995 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -78,7 +78,6 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; - struct device *dev = &pdev->dev; void __iomem *addr = NULL; struct stmmac_priv *priv = NULL; struct plat_stmmacenet_data *plat_dat = NULL; @@ -88,10 +87,18 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) if (!res) return -ENODEV; - addr = devm_request_and_ioremap(dev, res); + if (!request_mem_region(res->start, resource_size(res), pdev->name)) { + pr_err("%s: ERROR: memory allocation failed" + "cannot get the I/O addr 0x%x\n", + __func__, (unsigned int)res->start); + return -EBUSY; + } + + addr = ioremap(res->start, resource_size(res)); if (!addr) { pr_err("%s: ERROR: memory mapping failed", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto out_release_region; } if (pdev->dev.of_node) { @@ -100,13 +107,14 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) GFP_KERNEL); if (!plat_dat) { pr_err("%s: ERROR: no memory", __func__); - return -ENOMEM; + ret = -ENOMEM; + goto out_unmap; } ret = stmmac_probe_config_dt(pdev, plat_dat, &mac); if (ret) { pr_err("%s: main dt probe failed", __func__); - return ret; + goto out_unmap; } } else { plat_dat = pdev->dev.platform_data; @@ -116,13 +124,13 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) if (plat_dat->init) { ret = plat_dat->init(pdev); if (unlikely(ret)) - return ret; + goto out_unmap; } priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr); if (!priv) { pr_err("%s: main driver probe failed", __func__); - return -ENODEV; + goto out_unmap; } /* Get MAC address if available (DT) */ @@ -134,7 +142,8 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) if (priv->dev->irq == -ENXIO) { pr_err("%s: ERROR: MAC IRQ configuration " "information not found\n", __func__); - return -ENXIO; + ret = -ENXIO; + goto out_unmap; } /* @@ -156,6 +165,15 @@ static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) pr_debug("STMMAC platform driver registration completed"); return 0; + +out_unmap: + iounmap(addr); + platform_set_drvdata(pdev, NULL); + +out_release_region: + release_mem_region(res->start, resource_size(res)); + + return ret; } /** @@ -168,6 +186,7 @@ static int stmmac_pltfr_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(ndev); + struct resource *res; int ret = stmmac_dvr_remove(ndev); if (priv->plat->exit) @@ -175,6 +194,10 @@ static int stmmac_pltfr_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); + iounmap((void __force __iomem *)priv->ioaddr); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); + return ret; } diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h index aea9b14cdfbe..6863590d184b 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h @@ -21,8 +21,6 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#ifndef __STMMAC_TIMER_H__ -#define __STMMAC_TIMER_H__ struct stmmac_timer { void (*timer_start) (unsigned int new_freq); @@ -42,5 +40,3 @@ void stmmac_schedule(struct net_device *dev); extern int tmu2_register_user(void *fnt, void *data); extern void tmu2_unregister_user(void); #endif - -#endif /* __STMMAC_TIMER_H__ */ diff --git a/trunk/drivers/net/ethernet/tundra/tsi108_eth.c b/trunk/drivers/net/ethernet/tundra/tsi108_eth.c index 8fa947a2d929..277c93e9ff4d 100644 --- a/trunk/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/trunk/drivers/net/ethernet/tundra/tsi108_eth.c @@ -1358,6 +1358,7 @@ static int tsi108_open(struct net_device *dev) break; } + data->rxskbs[i] = skb; data->rxskbs[i] = skb; data->rxring[i].buf0 = virt_to_phys(data->rxskbs[i]->data); data->rxring[i].misc = TSI108_RX_OWN | TSI108_RX_INT; diff --git a/trunk/drivers/net/ethernet/wiznet/w5100.c b/trunk/drivers/net/ethernet/wiznet/w5100.c index 2c08bf6e7bf3..a5826a3111a6 100644 --- a/trunk/drivers/net/ethernet/wiznet/w5100.c +++ b/trunk/drivers/net/ethernet/wiznet/w5100.c @@ -637,7 +637,8 @@ static int __devinit w5100_hw_probe(struct platform_device *pdev) if (data && is_valid_ether_addr(data->mac_addr)) { memcpy(ndev->dev_addr, data->mac_addr, ETH_ALEN); } else { - eth_hw_addr_random(ndev); + eth_random_addr(ndev->dev_addr); + ndev->addr_assign_type |= NET_ADDR_RANDOM; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/trunk/drivers/net/ethernet/wiznet/w5300.c b/trunk/drivers/net/ethernet/wiznet/w5300.c index 88943d90c765..bdd8891c215a 100644 --- a/trunk/drivers/net/ethernet/wiznet/w5300.c +++ b/trunk/drivers/net/ethernet/wiznet/w5300.c @@ -557,7 +557,8 @@ static int __devinit w5300_hw_probe(struct platform_device *pdev) if (data && is_valid_ether_addr(data->mac_addr)) { memcpy(ndev->dev_addr, data->mac_addr, ETH_ALEN); } else { - eth_hw_addr_random(ndev); + eth_random_addr(ndev->dev_addr); + ndev->addr_assign_type |= NET_ADDR_RANDOM; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/trunk/drivers/net/phy/Kconfig b/trunk/drivers/net/phy/Kconfig index 983bbf4d5ef6..3090dc65a6f1 100644 --- a/trunk/drivers/net/phy/Kconfig +++ b/trunk/drivers/net/phy/Kconfig @@ -159,19 +159,6 @@ config MDIO_BUS_MUX_GPIO several child MDIO busses to a parent bus. Child bus selection is under the control of GPIO lines. -config MDIO_BUS_MUX_MMIOREG - tristate "Support for MMIO device-controlled MDIO bus multiplexers" - depends on OF_MDIO - select MDIO_BUS_MUX - help - This module provides a driver for MDIO bus multiplexers that - are controlled via a simple memory-mapped device, like an FPGA. - The multiplexer connects one of several child MDIO busses to a - parent bus. Child bus selection is under the control of one of - the FPGA's registers. - - Currently, only 8-bit registers are supported. - endif # PHYLIB config MICREL_KS8995MA diff --git a/trunk/drivers/net/phy/Makefile b/trunk/drivers/net/phy/Makefile index 426674debae4..6d2dc6c94f2e 100644 --- a/trunk/drivers/net/phy/Makefile +++ b/trunk/drivers/net/phy/Makefile @@ -28,4 +28,3 @@ obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o obj-$(CONFIG_AMD_PHY) += amd.o obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o -obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o diff --git a/trunk/drivers/net/phy/mdio-gpio.c b/trunk/drivers/net/phy/mdio-gpio.c index 899274f2f9b1..7189adf54bd1 100644 --- a/trunk/drivers/net/phy/mdio-gpio.c +++ b/trunk/drivers/net/phy/mdio-gpio.c @@ -28,38 +28,17 @@ #include #include +#ifdef CONFIG_OF_GPIO #include #include +#include +#endif struct mdio_gpio_info { struct mdiobb_ctrl ctrl; int mdc, mdio; }; -static void *mdio_gpio_of_get_data(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct mdio_gpio_platform_data *pdata; - int ret; - - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return NULL; - - ret = of_get_gpio(np, 0); - if (ret < 0) - return NULL; - - pdata->mdc = ret; - - ret = of_get_gpio(np, 1); - if (ret < 0) - return NULL; - pdata->mdio = ret; - - return pdata; -} - static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) { struct mdio_gpio_info *bitbang = @@ -183,15 +162,10 @@ static void __devexit mdio_gpio_bus_destroy(struct device *dev) static int __devinit mdio_gpio_probe(struct platform_device *pdev) { - struct mdio_gpio_platform_data *pdata; + struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data; struct mii_bus *new_bus; int ret; - if (pdev->dev.of_node) - pdata = mdio_gpio_of_get_data(pdev); - else - pdata = pdev->dev.platform_data; - if (!pdata) return -ENODEV; @@ -199,11 +173,7 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev) if (!new_bus) return -ENODEV; - if (pdev->dev.of_node) - ret = of_mdiobus_register(new_bus, pdev->dev.of_node); - else - ret = mdiobus_register(new_bus); - + ret = mdiobus_register(new_bus); if (ret) mdio_gpio_bus_deinit(&pdev->dev); @@ -217,30 +187,112 @@ static int __devexit mdio_gpio_remove(struct platform_device *pdev) return 0; } -static struct of_device_id mdio_gpio_of_match[] = { - { .compatible = "virtual,mdio-gpio", }, - { /* sentinel */ } +#ifdef CONFIG_OF_GPIO + +static int __devinit mdio_ofgpio_probe(struct platform_device *ofdev) +{ + struct mdio_gpio_platform_data *pdata; + struct mii_bus *new_bus; + int ret; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + ret = of_get_gpio(ofdev->dev.of_node, 0); + if (ret < 0) + goto out_free; + pdata->mdc = ret; + + ret = of_get_gpio(ofdev->dev.of_node, 1); + if (ret < 0) + goto out_free; + pdata->mdio = ret; + + new_bus = mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc); + if (!new_bus) + goto out_free; + + ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); + if (ret) + mdio_gpio_bus_deinit(&ofdev->dev); + + return ret; + +out_free: + kfree(pdata); + return -ENODEV; +} + +static int __devexit mdio_ofgpio_remove(struct platform_device *ofdev) +{ + mdio_gpio_bus_destroy(&ofdev->dev); + kfree(ofdev->dev.platform_data); + + return 0; +} + +static struct of_device_id mdio_ofgpio_match[] = { + { + .compatible = "virtual,mdio-gpio", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, mdio_ofgpio_match); + +static struct platform_driver mdio_ofgpio_driver = { + .driver = { + .name = "mdio-ofgpio", + .owner = THIS_MODULE, + .of_match_table = mdio_ofgpio_match, + }, + .probe = mdio_ofgpio_probe, + .remove = __devexit_p(mdio_ofgpio_remove), }; +static inline int __init mdio_ofgpio_init(void) +{ + return platform_driver_register(&mdio_ofgpio_driver); +} + +static inline void mdio_ofgpio_exit(void) +{ + platform_driver_unregister(&mdio_ofgpio_driver); +} +#else +static inline int __init mdio_ofgpio_init(void) { return 0; } +static inline void mdio_ofgpio_exit(void) { } +#endif /* CONFIG_OF_GPIO */ + static struct platform_driver mdio_gpio_driver = { .probe = mdio_gpio_probe, .remove = __devexit_p(mdio_gpio_remove), .driver = { .name = "mdio-gpio", .owner = THIS_MODULE, - .of_match_table = mdio_gpio_of_match, }, }; static int __init mdio_gpio_init(void) { - return platform_driver_register(&mdio_gpio_driver); + int ret; + + ret = mdio_ofgpio_init(); + if (ret) + return ret; + + ret = platform_driver_register(&mdio_gpio_driver); + if (ret) + mdio_ofgpio_exit(); + + return ret; } module_init(mdio_gpio_init); static void __exit mdio_gpio_exit(void) { platform_driver_unregister(&mdio_gpio_driver); + mdio_ofgpio_exit(); } module_exit(mdio_gpio_exit); diff --git a/trunk/drivers/net/phy/mdio-mux-mmioreg.c b/trunk/drivers/net/phy/mdio-mux-mmioreg.c deleted file mode 100644 index 098239a98b19..000000000000 --- a/trunk/drivers/net/phy/mdio-mux-mmioreg.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Simple memory-mapped device MDIO MUX driver - * - * Author: Timur Tabi - * - * Copyright 2012 Freescale Semiconductor, Inc. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include - -struct mdio_mux_mmioreg_state { - void *mux_handle; - phys_addr_t phys; - uint8_t mask; -}; - -/* - * MDIO multiplexing switch function - * - * This function is called by the mdio-mux layer when it thinks the mdio bus - * multiplexer needs to switch. - * - * 'current_child' is the current value of the mux register (masked via - * s->mask). - * - * 'desired_child' is the value of the 'reg' property of the target child MDIO - * node. - * - * The first time this function is called, current_child == -1. - * - * If current_child == desired_child, then the mux is already set to the - * correct bus. - */ -static int mdio_mux_mmioreg_switch_fn(int current_child, int desired_child, - void *data) -{ - struct mdio_mux_mmioreg_state *s = data; - - if (current_child ^ desired_child) { - void *p = ioremap(s->phys, 1); - uint8_t x, y; - - if (!p) - return -ENOMEM; - - x = ioread8(p); - y = (x & ~s->mask) | desired_child; - if (x != y) { - iowrite8((x & ~s->mask) | desired_child, p); - pr_debug("%s: %02x -> %02x\n", __func__, x, y); - } - - iounmap(p); - } - - return 0; -} - -static int __devinit mdio_mux_mmioreg_probe(struct platform_device *pdev) -{ - struct device_node *np2, *np = pdev->dev.of_node; - struct mdio_mux_mmioreg_state *s; - struct resource res; - const __be32 *iprop; - int len, ret; - - dev_dbg(&pdev->dev, "probing node %s\n", np->full_name); - - s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL); - if (!s) - return -ENOMEM; - - ret = of_address_to_resource(np, 0, &res); - if (ret) { - dev_err(&pdev->dev, "could not obtain memory map for node %s\n", - np->full_name); - return ret; - } - s->phys = res.start; - - if (resource_size(&res) != sizeof(uint8_t)) { - dev_err(&pdev->dev, "only 8-bit registers are supported\n"); - return -EINVAL; - } - - iprop = of_get_property(np, "mux-mask", &len); - if (!iprop || len != sizeof(uint32_t)) { - dev_err(&pdev->dev, "missing or invalid mux-mask property\n"); - return -ENODEV; - } - if (be32_to_cpup(iprop) > 255) { - dev_err(&pdev->dev, "only 8-bit registers are supported\n"); - return -EINVAL; - } - s->mask = be32_to_cpup(iprop); - - /* - * Verify that the 'reg' property of each child MDIO bus does not - * set any bits outside of the 'mask'. - */ - for_each_available_child_of_node(np, np2) { - iprop = of_get_property(np2, "reg", &len); - if (!iprop || len != sizeof(uint32_t)) { - dev_err(&pdev->dev, "mdio-mux child node %s is " - "missing a 'reg' property\n", np2->full_name); - return -ENODEV; - } - if (be32_to_cpup(iprop) & ~s->mask) { - dev_err(&pdev->dev, "mdio-mux child node %s has " - "a 'reg' value with unmasked bits\n", - np2->full_name); - return -ENODEV; - } - } - - ret = mdio_mux_init(&pdev->dev, mdio_mux_mmioreg_switch_fn, - &s->mux_handle, s); - if (ret) { - dev_err(&pdev->dev, "failed to register mdio-mux bus %s\n", - np->full_name); - return ret; - } - - pdev->dev.platform_data = s; - - return 0; -} - -static int __devexit mdio_mux_mmioreg_remove(struct platform_device *pdev) -{ - struct mdio_mux_mmioreg_state *s = dev_get_platdata(&pdev->dev); - - mdio_mux_uninit(s->mux_handle); - - return 0; -} - -static struct of_device_id mdio_mux_mmioreg_match[] = { - { - .compatible = "mdio-mux-mmioreg", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, mdio_mux_mmioreg_match); - -static struct platform_driver mdio_mux_mmioreg_driver = { - .driver = { - .name = "mdio-mux-mmioreg", - .owner = THIS_MODULE, - .of_match_table = mdio_mux_mmioreg_match, - }, - .probe = mdio_mux_mmioreg_probe, - .remove = __devexit_p(mdio_mux_mmioreg_remove), -}; - -module_platform_driver(mdio_mux_mmioreg_driver); - -MODULE_AUTHOR("Timur Tabi "); -MODULE_DESCRIPTION("Memory-mapped device MDIO MUX driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/net/team/team.c b/trunk/drivers/net/team/team.c index b4f67b55ef79..c8a3f108dc94 100644 --- a/trunk/drivers/net/team/team.c +++ b/trunk/drivers/net/team/team.c @@ -989,13 +989,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev) return -EBUSY; } - if (port_dev->features & NETIF_F_VLAN_CHALLENGED && - vlan_uses_dev(dev)) { - netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n", - portname); - return -EPERM; - } - err = team_dev_type_check_change(dev, port_dev); if (err) return err; @@ -2493,7 +2486,7 @@ static void __team_options_change_check(struct team *team) list_add_tail(&opt_inst->tmp_list, &sel_opt_inst_list); } err = team_nl_send_event_options_get(team, &sel_opt_inst_list); - if (err && err != -ESRCH) + if (err) netdev_warn(team->dev, "Failed to send options change via netlink (err %d)\n", err); } @@ -2524,9 +2517,9 @@ static void __team_port_change_check(struct team_port *port, bool linkup) send_event: err = team_nl_send_event_port_list_get(port->team); - if (err && err != -ESRCH) - netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink (err %d)\n", - port->dev->name, err); + if (err) + netdev_warn(port->team->dev, "Failed to send port change of device %s via netlink\n", + port->dev->name); } diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 498dc0d4ba5e..3a16d4fdaa05 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -120,8 +120,8 @@ struct tun_sock; struct tun_struct { struct tun_file *tfile; unsigned int flags; - kuid_t owner; - kgid_t group; + uid_t owner; + gid_t group; struct net_device *dev; netdev_features_t set_features; @@ -1031,8 +1031,8 @@ static void tun_setup(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); - tun->owner = INVALID_UID; - tun->group = INVALID_GID; + tun->owner = -1; + tun->group = -1; dev->ethtool_ops = &tun_ethtool_ops; dev->destructor = tun_free_netdev; @@ -1155,20 +1155,14 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, char *buf) { struct tun_struct *tun = netdev_priv(to_net_dev(dev)); - return uid_valid(tun->owner)? - sprintf(buf, "%u\n", - from_kuid_munged(current_user_ns(), tun->owner)): - sprintf(buf, "-1\n"); + return sprintf(buf, "%d\n", tun->owner); } static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, char *buf) { struct tun_struct *tun = netdev_priv(to_net_dev(dev)); - return gid_valid(tun->group) ? - sprintf(buf, "%u\n", - from_kgid_munged(current_user_ns(), tun->group)): - sprintf(buf, "-1\n"); + return sprintf(buf, "%d\n", tun->group); } static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); @@ -1195,8 +1189,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) else return -EINVAL; - if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || - (gid_valid(tun->group) && !in_egroup_p(tun->group))) && + if (((tun->owner != -1 && cred->euid != tun->owner) || + (tun->group != -1 && !in_egroup_p(tun->group))) && !capable(CAP_NET_ADMIN)) return -EPERM; err = security_tun_dev_attach(tun->socket.sk); @@ -1380,8 +1374,6 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, void __user* argp = (void __user*)arg; struct sock_fprog fprog; struct ifreq ifr; - kuid_t owner; - kgid_t group; int sndbuf; int vnet_hdr_sz; int ret; @@ -1455,26 +1447,16 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, case TUNSETOWNER: /* Set owner of the device */ - owner = make_kuid(current_user_ns(), arg); - if (!uid_valid(owner)) { - ret = -EINVAL; - break; - } - tun->owner = owner; - tun_debug(KERN_INFO, tun, "owner set to %d\n", - from_kuid(&init_user_ns, tun->owner)); + tun->owner = (uid_t) arg; + + tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); break; case TUNSETGROUP: /* Set group of the device */ - group = make_kgid(current_user_ns(), arg); - if (!gid_valid(group)) { - ret = -EINVAL; - break; - } - tun->group = group; - tun_debug(KERN_INFO, tun, "group set to %d\n", - from_kgid(&init_user_ns, tun->group)); + tun->group= (gid_t) arg; + + tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); break; case TUNSETLINK: diff --git a/trunk/drivers/net/usb/cx82310_eth.c b/trunk/drivers/net/usb/cx82310_eth.c index 1e207f086b75..49ab45e17fe8 100644 --- a/trunk/drivers/net/usb/cx82310_eth.c +++ b/trunk/drivers/net/usb/cx82310_eth.c @@ -302,9 +302,18 @@ static const struct driver_info cx82310_info = { .tx_fixup = cx82310_tx_fixup, }; +#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_DEV_INFO, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bDeviceClass = (cl), \ + .bDeviceSubClass = (sc), \ + .bDeviceProtocol = (pr) + static const struct usb_device_id products[] = { { - USB_DEVICE_AND_INTERFACE_INFO(0x0572, 0xcb01, 0xff, 0, 0), + USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0), .driver_info = (unsigned long) &cx82310_info }, { }, diff --git a/trunk/drivers/net/usb/sierra_net.c b/trunk/drivers/net/usb/sierra_net.c index 7ae70e9489d5..7be49ea60b6d 100644 --- a/trunk/drivers/net/usb/sierra_net.c +++ b/trunk/drivers/net/usb/sierra_net.c @@ -68,8 +68,9 @@ static atomic_t iface_counter = ATOMIC_INIT(0); */ #define SIERRA_NET_USBCTL_BUF_LEN 1024 -/* Overriding the default usbnet rx_urb_size */ -#define SIERRA_NET_RX_URB_SIZE (8 * 1024) +struct sierra_net_info_data { + u16 rx_urb_size; +}; /* Private data structure */ struct sierra_net_data { @@ -559,7 +560,7 @@ static void sierra_net_defer_kevent(struct usbnet *dev, int work) /* * Sync Retransmit Timer Handler. On expiry, kick the work queue */ -static void sierra_sync_timer(unsigned long syncdata) +void sierra_sync_timer(unsigned long syncdata) { struct usbnet *dev = (struct usbnet *)syncdata; @@ -677,6 +678,9 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = { 0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00}; + struct sierra_net_info_data *data = + (struct sierra_net_info_data *)dev->driver_info->data; + dev_dbg(&dev->udev->dev, "%s", __func__); ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; @@ -721,9 +725,9 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) sierra_net_set_ctx_index(priv, 0); /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */ - dev->rx_urb_size = SIERRA_NET_RX_URB_SIZE; + dev->rx_urb_size = data->rx_urb_size; if (dev->udev->speed != USB_SPEED_HIGH) - dev->rx_urb_size = min_t(size_t, 4096, SIERRA_NET_RX_URB_SIZE); + dev->rx_urb_size = min_t(size_t, 4096, data->rx_urb_size); dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN; dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; @@ -862,8 +866,8 @@ static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb) } /* ---------------------------- Transmit data path ----------------------*/ -static struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, - struct sk_buff *skb, gfp_t flags) +struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + gfp_t flags) { struct sierra_net_data *priv = sierra_net_get_private(dev); u16 len; @@ -914,6 +918,10 @@ static struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, return NULL; } +static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { + .rx_urb_size = 8 * 1024, +}; + static const struct driver_info sierra_net_info_direct_ip = { .description = "Sierra Wireless USB-to-WWAN Modem", .flags = FLAG_WWAN | FLAG_SEND_ZLP, @@ -922,6 +930,7 @@ static const struct driver_info sierra_net_info_direct_ip = { .status = sierra_net_status, .rx_fixup = sierra_net_rx_fixup, .tx_fixup = sierra_net_tx_fixup, + .data = (unsigned long)&sierra_net_info_data_direct_ip, }; #define DIRECT_IP_DEVICE(vend, prod) \ diff --git a/trunk/drivers/net/wimax/i2400m/driver.c b/trunk/drivers/net/wimax/i2400m/driver.c index 9c34d2fccfac..025426132754 100644 --- a/trunk/drivers/net/wimax/i2400m/driver.c +++ b/trunk/drivers/net/wimax/i2400m/driver.c @@ -222,6 +222,7 @@ int i2400m_check_mac_addr(struct i2400m *i2400m) struct sk_buff *skb; const struct i2400m_tlv_detailed_device_info *ddi; struct net_device *net_dev = i2400m->wimax_dev.net_dev; + const unsigned char zeromac[ETH_ALEN] = { 0 }; d_fnstart(3, dev, "(i2400m %p)\n", i2400m); skb = i2400m_get_device_info(i2400m); @@ -243,7 +244,7 @@ int i2400m_check_mac_addr(struct i2400m *i2400m) "to that of boot mode's\n"); dev_warn(dev, "device reports %pM\n", ddi->mac_address); dev_warn(dev, "boot mode reported %pM\n", net_dev->perm_addr); - if (is_zero_ether_addr(ddi->mac_address)) + if (!memcmp(zeromac, ddi->mac_address, sizeof(zeromac))) dev_err(dev, "device reports an invalid MAC address, " "not updating\n"); else { diff --git a/trunk/drivers/net/wireless/adm8211.c b/trunk/drivers/net/wireless/adm8211.c index 154a4965be4f..689a71c1af71 100644 --- a/trunk/drivers/net/wireless/adm8211.c +++ b/trunk/drivers/net/wireless/adm8211.c @@ -1661,9 +1661,7 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, } /* Put adm8211_tx_hdr on skb and transmit */ -static void adm8211_tx(struct ieee80211_hw *dev, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct adm8211_tx_hdr *txhdr; size_t payload_len, hdrlen; diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index c586f78c307f..f9f15bb3f03a 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -232,10 +232,8 @@ static int adhoc; static int probe = 1; -static kuid_t proc_kuid; static int proc_uid /* = 0 */; -static kgid_t proc_kgid; static int proc_gid /* = 0 */; static int airo_perm = 0555; @@ -4501,79 +4499,78 @@ struct proc_data { static int setup_proc_entry( struct net_device *dev, struct airo_info *apriv ) { struct proc_dir_entry *entry; - /* First setup the device directory */ strcpy(apriv->proc_name,dev->name); apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, airo_entry); if (!apriv->proc_entry) goto fail; - apriv->proc_entry->uid = proc_kuid; - apriv->proc_entry->gid = proc_kgid; + apriv->proc_entry->uid = proc_uid; + apriv->proc_entry->gid = proc_gid; /* Setup the StatsDelta */ entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, apriv->proc_entry, &proc_statsdelta_ops, dev); if (!entry) goto fail_stats_delta; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; /* Setup the Stats */ entry = proc_create_data("Stats", S_IRUGO & proc_perm, apriv->proc_entry, &proc_stats_ops, dev); if (!entry) goto fail_stats; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; /* Setup the Status */ entry = proc_create_data("Status", S_IRUGO & proc_perm, apriv->proc_entry, &proc_status_ops, dev); if (!entry) goto fail_status; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; /* Setup the Config */ entry = proc_create_data("Config", proc_perm, apriv->proc_entry, &proc_config_ops, dev); if (!entry) goto fail_config; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; /* Setup the SSID */ entry = proc_create_data("SSID", proc_perm, apriv->proc_entry, &proc_SSID_ops, dev); if (!entry) goto fail_ssid; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; /* Setup the APList */ entry = proc_create_data("APList", proc_perm, apriv->proc_entry, &proc_APList_ops, dev); if (!entry) goto fail_aplist; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; /* Setup the BSSList */ entry = proc_create_data("BSSList", proc_perm, apriv->proc_entry, &proc_BSSList_ops, dev); if (!entry) goto fail_bsslist; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; /* Setup the WepKey */ entry = proc_create_data("WepKey", proc_perm, apriv->proc_entry, &proc_wepkey_ops, dev); if (!entry) goto fail_wepkey; - entry->uid = proc_kuid; - entry->gid = proc_kgid; + entry->uid = proc_uid; + entry->gid = proc_gid; return 0; @@ -5700,16 +5697,11 @@ static int __init airo_init_module( void ) { int i; - proc_kuid = make_kuid(&init_user_ns, proc_uid); - proc_kgid = make_kgid(&init_user_ns, proc_gid); - if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid)) - return -EINVAL; - airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); if (airo_entry) { - airo_entry->uid = proc_kuid; - airo_entry->gid = proc_kgid; + airo_entry->uid = proc_uid; + airo_entry->gid = proc_gid; } for (i = 0; i < 4 && io[i] && irq[i]; i++) { diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index e361afed99ff..88b8d64c90f1 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -1726,9 +1726,7 @@ static void at76_mac80211_tx_callback(struct urb *urb) ieee80211_wake_queues(priv->hw); } -static void at76_mac80211_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct at76_priv *priv = hw->priv; struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; diff --git a/trunk/drivers/net/wireless/ath/ath5k/eeprom.c b/trunk/drivers/net/wireless/ath/ath5k/eeprom.c index b7e0258887e7..4026c906cc7b 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/trunk/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1482,7 +1482,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) case AR5K_EEPROM_MODE_11A: offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); rate_pcal_info = ee->ee_rate_tpwr_a; - ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN; + ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; break; case AR5K_EEPROM_MODE_11B: offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); diff --git a/trunk/drivers/net/wireless/ath/ath5k/eeprom.h b/trunk/drivers/net/wireless/ath/ath5k/eeprom.h index 94a9bbea6874..dc2bcfeadeb4 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/trunk/drivers/net/wireless/ath/ath5k/eeprom.h @@ -182,7 +182,6 @@ #define AR5K_EEPROM_EEP_DELTA 10 #define AR5K_EEPROM_N_MODES 3 #define AR5K_EEPROM_N_5GHZ_CHAN 10 -#define AR5K_EEPROM_N_5GHZ_RATE_CHAN 8 #define AR5K_EEPROM_N_2GHZ_CHAN 3 #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 #define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 diff --git a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c index df61a09adb6d..384e67af73bc 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/trunk/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -55,8 +55,7 @@ \********************/ static void -ath5k_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, - struct sk_buff *skb) +ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ath5k_hw *ah = hw->priv; u16 qnum = skb_get_queue_mapping(skb); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 7373e4b92c92..b09285c36c4a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -280,7 +280,6 @@ struct ath_tx_control { struct ath_txq *txq; struct ath_node *an; u8 paprd; - struct ieee80211_sta *sta; }; #define ATH_TX_ERROR 0x01 diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc.h b/trunk/drivers/net/wireless/ath/ath9k/htc.h index b30596fcf73a..936e920fb88e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/htc.h @@ -542,7 +542,6 @@ void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv); int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, - struct ieee80211_sta *sta, struct sk_buff *skb, u8 slot, bool is_cab); void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index f42d2eb6af99..77d541feb910 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -326,7 +326,7 @@ static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv, goto next; } - ret = ath9k_htc_tx_start(priv, NULL, skb, tx_slot, true); + ret = ath9k_htc_tx_start(priv, skb, tx_slot, true); if (ret != 0) { ath9k_htc_tx_clear_slot(priv, tx_slot); dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c index c32f6e3ffb18..c785129692ff 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -856,9 +856,7 @@ void ath9k_htc_ani_work(struct work_struct *work) /* mac80211 Callbacks */ /**********************/ -static void ath9k_htc_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ieee80211_hdr *hdr; struct ath9k_htc_priv *priv = hw->priv; @@ -885,7 +883,7 @@ static void ath9k_htc_tx(struct ieee80211_hw *hw, goto fail_tx; } - ret = ath9k_htc_tx_start(priv, control->sta, skb, slot, false); + ret = ath9k_htc_tx_start(priv, skb, slot, false); if (ret != 0) { ath_dbg(common, XMIT, "Tx failed\n"); goto clear_slot; @@ -1333,34 +1331,6 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, return ret; } -static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, u32 changed) -{ - struct ath9k_htc_priv *priv = hw->priv; - struct ath_common *common = ath9k_hw_common(priv->ah); - struct ath9k_htc_target_rate trate; - - mutex_lock(&priv->mutex); - ath9k_htc_ps_wakeup(priv); - - if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { - memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); - ath9k_htc_setup_rate(priv, sta, &trate); - if (!ath9k_htc_send_rate_cmd(priv, &trate)) - ath_dbg(common, CONFIG, - "Supported rates for sta: %pM updated, rate caps: 0x%X\n", - sta->addr, be32_to_cpu(trate.capflags)); - else - ath_dbg(common, CONFIG, - "Unable to update supported rates for sta: %pM\n", - sta->addr); - } - - ath9k_htc_ps_restore(priv); - mutex_unlock(&priv->mutex); -} - static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) @@ -1788,7 +1758,6 @@ struct ieee80211_ops ath9k_htc_ops = { .sta_add = ath9k_htc_sta_add, .sta_remove = ath9k_htc_sta_remove, .conf_tx = ath9k_htc_conf_tx, - .sta_rc_update = ath9k_htc_sta_rc_update, .bss_info_changed = ath9k_htc_bss_info_changed, .set_key = ath9k_htc_set_key, .get_tsf = ath9k_htc_get_tsf, diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 06cdcb772d78..47e61d0da33b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -333,12 +333,12 @@ static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv, } int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, - struct ieee80211_sta *sta, struct sk_buff *skb, u8 slot, bool is_cab) { struct ieee80211_hdr *hdr; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_vif *vif = tx_info->control.vif; struct ath9k_htc_sta *ista; struct ath9k_htc_vif *avp = NULL; diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 8a2b04d5922f..a22df749b8db 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -696,9 +696,7 @@ static int ath9k_start(struct ieee80211_hw *hw) return r; } -static void ath9k_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -758,7 +756,6 @@ static void ath9k_tx(struct ieee80211_hw *hw, memset(&txctl, 0, sizeof(struct ath_tx_control)); txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; - txctl.sta = control->sta; ath_dbg(common, XMIT, "transmitting packet, skb: %p\n", skb); diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index ef91f6cc2d79..2c9da6b2ecb1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -1773,12 +1773,11 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, TX_STAT_INC(txq->axq_qnum, queued); } -static void setup_frame_info(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct sk_buff *skb, +static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, int framelen) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; const struct ieee80211_rate *rate; @@ -1936,7 +1935,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_sta *sta = txctl->sta; + struct ieee80211_sta *sta = info->control.sta; struct ieee80211_vif *vif = info->control.vif; struct ath_softc *sc = hw->priv; struct ath_txq *txq = txctl->txq; @@ -1980,7 +1979,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, !ieee80211_is_data(hdr->frame_control)) info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; - setup_frame_info(hw, sta, skb, frmlen); + setup_frame_info(hw, skb, frmlen); /* * At this point, the vif, hw_key and sta pointers in the tx control diff --git a/trunk/drivers/net/wireless/ath/carl9170/carl9170.h b/trunk/drivers/net/wireless/ath/carl9170/carl9170.h index 2aa4a59c72c8..376be11161c0 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/trunk/drivers/net/wireless/ath/carl9170/carl9170.h @@ -425,7 +425,6 @@ struct ar9170 { bool rx_has_plcp; struct sk_buff *rx_failover; int rx_failover_missing; - u32 ampdu_ref; /* FIFO for collecting outstanding BlockAckRequest */ struct list_head bar_list[__AR9170_NUM_TXQ]; @@ -578,9 +577,7 @@ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); /* TX */ -void carl9170_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb); +void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); void carl9170_tx_janitor(struct work_struct *work); void carl9170_tx_process_status(struct ar9170 *ar, const struct carl9170_rsp *cmd); diff --git a/trunk/drivers/net/wireless/ath/carl9170/rx.c b/trunk/drivers/net/wireless/ath/carl9170/rx.c index a0b723078547..b813f43061f5 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/rx.c +++ b/trunk/drivers/net/wireless/ath/carl9170/rx.c @@ -624,8 +624,7 @@ static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len) #undef TID_CHECK } -static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms, - struct ieee80211_rx_status *rx_status) +static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms) { __le16 fc; @@ -638,9 +637,6 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms, return true; } - rx_status->flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN; - rx_status->ampdu_reference = ar->ampdu_ref; - /* * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts * certain frame types can be part of an aMPDU. @@ -689,15 +685,12 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (unlikely(len < sizeof(*mac))) goto drop; - memset(&status, 0, sizeof(status)); - mpdu_len = len - sizeof(*mac); mac = (void *)(buf + mpdu_len); mac_status = mac->status; switch (mac_status & AR9170_RX_STATUS_MPDU) { case AR9170_RX_STATUS_MPDU_FIRST: - ar->ampdu_ref++; /* Aggregated MPDUs start with an PLCP header */ if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { head = (void *) buf; @@ -728,13 +721,12 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) break; case AR9170_RX_STATUS_MPDU_LAST: - status.flag |= RX_FLAG_AMPDU_IS_LAST; - /* * The last frame of an A-MPDU has an extra tail * which does contain the phy status of the whole * aggregate. */ + if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { mpdu_len -= sizeof(struct ar9170_rx_phystatus); phy = (void *)(buf + mpdu_len); @@ -782,10 +774,11 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN))) goto drop; + memset(&status, 0, sizeof(status)); if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) goto drop; - if (!carl9170_ampdu_check(ar, buf, mac_status, &status)) + if (!carl9170_ampdu_check(ar, buf, mac_status)) goto drop; if (phy) diff --git a/trunk/drivers/net/wireless/ath/carl9170/tx.c b/trunk/drivers/net/wireless/ath/carl9170/tx.c index 84377cf580e0..6a8681407a1d 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/tx.c +++ b/trunk/drivers/net/wireless/ath/carl9170/tx.c @@ -867,15 +867,14 @@ static bool carl9170_tx_cts_check(struct ar9170 *ar, return false; } -static int carl9170_tx_prepare(struct ar9170 *ar, - struct ieee80211_sta *sta, - struct sk_buff *skb) +static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) { struct ieee80211_hdr *hdr; struct _carl9170_tx_superframe *txc; struct carl9170_vif_info *cvif; struct ieee80211_tx_info *info; struct ieee80211_tx_rate *txrate; + struct ieee80211_sta *sta; struct carl9170_tx_info *arinfo; unsigned int hw_queue; int i; @@ -911,6 +910,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar, else cvif = NULL; + sta = info->control.sta; + txc = (void *)skb_push(skb, sizeof(*txc)); memset(txc, 0, sizeof(*txc)); @@ -1456,21 +1457,20 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, return false; } -void carl9170_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct ar9170 *ar = hw->priv; struct ieee80211_tx_info *info; - struct ieee80211_sta *sta = control->sta; + struct ieee80211_sta *sta; bool run; if (unlikely(!IS_STARTED(ar))) goto err_free; info = IEEE80211_SKB_CB(skb); + sta = info->control.sta; - if (unlikely(carl9170_tx_prepare(ar, sta, skb))) + if (unlikely(carl9170_tx_prepare(ar, skb))) goto err_free; carl9170_tx_accounting(ar, skb); diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 73730e94e0ac..d97a95b1addb 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -3412,8 +3412,7 @@ static void b43_tx_work(struct work_struct *work) } static void b43_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) + struct sk_buff *skb) { struct b43_wl *wl = hw_to_b43_wl(hw); diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index 291cdf654088..3ea1a85d38d1 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -2492,7 +2492,6 @@ static void b43legacy_tx_work(struct work_struct *work) } static void b43legacy_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, struct sk_buff *skb) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 718da8d6d658..1c70defba6c3 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -267,9 +267,7 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br) } } -static void brcms_ops_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct brcms_info *wl = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -281,7 +279,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw, goto done; } brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); - tx_info->rate_driver_data[0] = control->sta; + tx_info->rate_driver_data[0] = tx_info->control.sta; done: spin_unlock_bh(&wl->lock); } @@ -1237,9 +1235,6 @@ uint brcms_reset(struct brcms_info *wl) /* dpc will not be rescheduled */ wl->resched = false; - /* inform publicly that interface is down */ - wl->pub->up = false; - return 0; } diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index 83324b321652..95aa8e1683ec 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -2042,8 +2042,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) return; } len = ETH_ALEN; - ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, bssid, - &len); + ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); if (ret) { IPW_DEBUG_INFO("failed querying ordinals at line %d\n", __LINE__); diff --git a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c index e252acb9c862..faec40467208 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c @@ -460,9 +460,7 @@ il3945_build_tx_cmd_basic(struct il_priv *il, struct il_device_cmd *cmd, * start C_TX command process */ static int -il3945_tx_skb(struct il_priv *il, - struct ieee80211_sta *sta, - struct sk_buff *skb) +il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -514,7 +512,7 @@ il3945_tx_skb(struct il_priv *il, hdr_len = ieee80211_hdrlen(fc); /* Find idx into station table for destination station */ - sta_id = il_sta_id_or_broadcast(il, sta); + sta_id = il_sta_id_or_broadcast(il, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); goto drop; @@ -2861,9 +2859,7 @@ il3945_mac_stop(struct ieee80211_hw *hw) } static void -il3945_mac_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct il_priv *il = hw->priv; @@ -2872,7 +2868,7 @@ il3945_mac_tx(struct ieee80211_hw *hw, D_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); - if (il3945_tx_skb(il, control->sta, skb)) + if (il3945_tx_skb(il, skb)) dev_kfree_skb_any(skb); D_MAC80211("leave\n"); diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index eac4dc8bc879..34f61a0581a2 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -1526,11 +1526,8 @@ il4965_tx_cmd_build_basic(struct il_priv *il, struct sk_buff *skb, } static void -il4965_tx_cmd_build_rate(struct il_priv *il, - struct il_tx_cmd *tx_cmd, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - __le16 fc) +il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, __le16 fc) { const u8 rts_retry_limit = 60; u32 rate_flags; @@ -1564,7 +1561,9 @@ il4965_tx_cmd_build_rate(struct il_priv *il, rate_idx = info->control.rates[0].idx; if ((info->control.rates[0].flags & IEEE80211_TX_RC_MCS) || rate_idx < 0 || rate_idx > RATE_COUNT_LEGACY) - rate_idx = rate_lowest_index(&il->bands[info->band], sta); + rate_idx = + rate_lowest_index(&il->bands[info->band], + info->control.sta); /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ if (info->band == IEEE80211_BAND_5GHZ) rate_idx += IL_FIRST_OFDM_RATE; @@ -1631,12 +1630,11 @@ il4965_tx_cmd_build_hwcrypto(struct il_priv *il, struct ieee80211_tx_info *info, * start C_TX command process */ int -il4965_tx_skb(struct il_priv *il, - struct ieee80211_sta *sta, - struct sk_buff *skb) +il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = info->control.sta; struct il_station_priv *sta_priv = NULL; struct il_tx_queue *txq; struct il_queue *q; @@ -1682,7 +1680,7 @@ il4965_tx_skb(struct il_priv *il, sta_id = il->hw_params.bcast_id; else { /* Find idx into station table for destination station */ - sta_id = il_sta_id_or_broadcast(il, sta); + sta_id = il_sta_id_or_broadcast(il, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -1788,7 +1786,7 @@ il4965_tx_skb(struct il_priv *il, /* TODO need this for burst mode later on */ il4965_tx_cmd_build_basic(il, skb, tx_cmd, info, hdr, sta_id); - il4965_tx_cmd_build_rate(il, tx_cmd, info, sta, fc); + il4965_tx_cmd_build_rate(il, tx_cmd, info, fc); il_update_stats(il, true, fc, len); /* @@ -5830,9 +5828,7 @@ il4965_mac_stop(struct ieee80211_hw *hw) } void -il4965_mac_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct il_priv *il = hw->priv; @@ -5841,7 +5837,7 @@ il4965_mac_tx(struct ieee80211_hw *hw, D_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); - if (il4965_tx_skb(il, control->sta, skb)) + if (il4965_tx_skb(il, skb)) dev_kfree_skb_any(skb); D_MACDUMP("leave\n"); diff --git a/trunk/drivers/net/wireless/iwlegacy/4965.h b/trunk/drivers/net/wireless/iwlegacy/4965.h index 2d092f328547..1db677689cfe 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965.h +++ b/trunk/drivers/net/wireless/iwlegacy/4965.h @@ -78,9 +78,7 @@ int il4965_hw_txq_attach_buf_to_tfd(struct il_priv *il, struct il_tx_queue *txq, int il4965_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq); void il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags, struct ieee80211_tx_info *info); -int il4965_tx_skb(struct il_priv *il, - struct ieee80211_sta *sta, - struct sk_buff *skb); +int il4965_tx_skb(struct il_priv *il, struct sk_buff *skb); int il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 * ssn); int il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif, @@ -165,9 +163,7 @@ void il4965_eeprom_release_semaphore(struct il_priv *il); int il4965_eeprom_check_version(struct il_priv *il); /* mac80211 handlers (for 4965) */ -void il4965_mac_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb); +void il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); int il4965_mac_start(struct ieee80211_hw *hw); void il4965_mac_stop(struct ieee80211_hw *hw); void il4965_configure_filter(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h b/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h index 75e12f29d9eb..9bb16bdf6d26 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -201,9 +201,7 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); /* tx */ -int iwlagn_tx_skb(struct iwl_priv *priv, - struct ieee80211_sta *sta, - struct sk_buff *skb); +int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 *ssn); int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, @@ -487,13 +485,16 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state) } #ifdef CONFIG_IWLWIFI_DEBUGFS -int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir); +int iwl_dbgfs_register(struct iwl_priv *priv, const char *name); +void iwl_dbgfs_unregister(struct iwl_priv *priv); #else -static inline int iwl_dbgfs_register(struct iwl_priv *priv, - struct dentry *dbgfs_dir) +static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) { return 0; } +static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) +{ +} #endif /* CONFIG_IWLWIFI_DEBUGFS */ #ifdef CONFIG_IWLWIFI_DEBUG diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 1a98fa3ab06d..46782f1102ac 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -124,9 +124,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, const struct fw_img *img; size_t bufsz; - if (!iwl_is_ready_rf(priv)) - return -EAGAIN; - /* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { priv->dbgfs_sram_offset = 0x800000; @@ -2352,19 +2349,24 @@ DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); * Create the debugfs files and directories * */ -int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) +int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) { - struct dentry *dir_data, *dir_rf, *dir_debug; + struct dentry *phyd = priv->hw->wiphy->debugfsdir; + struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug; + + dir_drv = debugfs_create_dir(name, phyd); + if (!dir_drv) + return -ENOMEM; - priv->debugfs_dir = dbgfs_dir; + priv->debugfs_dir = dir_drv; - dir_data = debugfs_create_dir("data", dbgfs_dir); + dir_data = debugfs_create_dir("data", dir_drv); if (!dir_data) goto err; - dir_rf = debugfs_create_dir("rf", dbgfs_dir); + dir_rf = debugfs_create_dir("rf", dir_drv); if (!dir_rf) goto err; - dir_debug = debugfs_create_dir("debug", dbgfs_dir); + dir_debug = debugfs_create_dir("debug", dir_drv); if (!dir_debug) goto err; @@ -2410,30 +2412,25 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) /* Calibrations disabled/enabled status*/ DEBUGFS_ADD_FILE(calib_disabled, dir_rf, S_IWUSR | S_IRUSR); - /* - * Create a symlink with mac80211. This is not very robust, as it does - * not remove the symlink created. The implicit assumption is that - * when the opmode exits, mac80211 will also exit, and will remove - * this symlink as part of its cleanup. - */ - if (priv->mac80211_registered) { - char buf[100]; - struct dentry *mac80211_dir, *dev_dir, *root_dir; - - dev_dir = dbgfs_dir->d_parent; - root_dir = dev_dir->d_parent; - mac80211_dir = priv->hw->wiphy->debugfsdir; - - snprintf(buf, 100, "../../%s/%s", root_dir->d_name.name, - dev_dir->d_name.name); - - if (!debugfs_create_symlink("iwlwifi", mac80211_dir, buf)) - goto err; - } - + if (iwl_trans_dbgfs_register(priv->trans, dir_debug)) + goto err; return 0; err: - IWL_ERR(priv, "failed to create the dvm debugfs entries\n"); + IWL_ERR(priv, "Can't create the debugfs directory\n"); + iwl_dbgfs_unregister(priv); return -ENOMEM; } + +/** + * Remove the debugfs files and directories + * + */ +void iwl_dbgfs_unregister(struct iwl_priv *priv) +{ + if (!priv->debugfs_dir) + return; + + debugfs_remove_recursive(priv->debugfs_dir); + priv->debugfs_dir = NULL; +} diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c index ff8162d4c454..a5f7bce96325 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -195,7 +195,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ARRAY_SIZE(iwlagn_iface_combinations_dualmode); } - hw->wiphy->max_remain_on_channel_duration = 500; + hw->wiphy->max_remain_on_channel_duration = 1000; hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | @@ -511,16 +511,14 @@ static void iwlagn_mac_set_wakeup(struct ieee80211_hw *hw, bool enabled) } #endif -static void iwlagn_mac_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); - if (iwlagn_tx_skb(priv, control->sta, skb)) + if (iwlagn_tx_skb(priv, skb)) dev_kfree_skb_any(skb); } diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c index 7ff3f1430678..84d3db5aa506 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c @@ -862,8 +862,7 @@ void iwl_down(struct iwl_priv *priv) * No race since we hold the mutex here and a new one * can't come in at this time. */ - if (priv->ucode_loaded && priv->cur_ucode != IWL_UCODE_INIT) - ieee80211_remain_on_channel_expired(priv->hw); + ieee80211_remain_on_channel_expired(priv->hw); exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); @@ -995,11 +994,7 @@ static void iwl_bg_restart(struct work_struct *data) iwlagn_prepare_restart(priv); mutex_unlock(&priv->mutex); iwl_cancel_deferred_work(priv); - if (priv->mac80211_registered) - ieee80211_restart_hw(priv->hw); - else - IWL_ERR(priv, - "Cannot request restart before registrating with mac80211"); + ieee80211_restart_hw(priv->hw); } else { WARN_ON(1); } @@ -1227,8 +1222,7 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, - const struct iwl_fw *fw, - struct dentry *dbgfs_dir) + const struct iwl_fw *fw) { struct iwl_priv *priv; struct ieee80211_hw *hw; @@ -1472,17 +1466,13 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, if (iwlagn_mac_setup_register(priv, &fw->ucode_capa)) goto out_destroy_workqueue; - if (iwl_dbgfs_register(priv, dbgfs_dir)) - goto out_mac80211_unregister; + if (iwl_dbgfs_register(priv, DRV_NAME)) + IWL_ERR(priv, + "failed to create debugfs files. Ignoring error\n"); return op_mode; -out_mac80211_unregister: - iwlagn_mac_unregister(priv); out_destroy_workqueue: - iwl_tt_exit(priv); - iwl_testmode_free(priv); - iwl_cancel_deferred_work(priv); destroy_workqueue(priv->workqueue); priv->workqueue = NULL; iwl_uninit_drv(priv); @@ -1503,6 +1493,8 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); + iwl_dbgfs_unregister(priv); + iwl_testmode_free(priv); iwlagn_mac_unregister(priv); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c b/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c index fe36a38f3505..b29b798f7550 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/sta.c @@ -150,7 +150,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); if (!(flags & CMD_ASYNC)) { - cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD; + cmd.flags |= CMD_WANT_SKB; might_sleep(); } diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c index f5ca73a89870..5971a23aa47d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -127,7 +127,6 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, struct iwl_tx_cmd *tx_cmd, struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, __le16 fc) { u32 rate_flags; @@ -188,7 +187,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) rate_idx = rate_lowest_index( - &priv->eeprom_data->bands[info->band], sta); + &priv->eeprom_data->bands[info->band], + info->control.sta); /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ if (info->band == IEEE80211_BAND_5GHZ) rate_idx += IWL_FIRST_OFDM_RATE; @@ -291,9 +291,7 @@ static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context, /* * start REPLY_TX command process */ -int iwlagn_tx_skb(struct iwl_priv *priv, - struct ieee80211_sta *sta, - struct sk_buff *skb) +int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -347,7 +345,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, sta_id = ctx->bcast_sta_id; else { /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(ctx, sta); + sta_id = iwl_sta_id_or_broadcast(ctx, info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -357,8 +355,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); - if (sta) - sta_priv = (void *)sta->drv_priv; + if (info->control.sta) + sta_priv = (void *)info->control.sta->drv_priv; if (sta_priv && sta_priv->asleep && (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) { @@ -399,7 +397,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, /* TODO need this for burst mode later on */ iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); - iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, sta, fc); + iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc); memset(&info->status, 0, sizeof(info->status)); @@ -433,7 +431,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, * only. Check this here. */ if (WARN_ONCE(tid_data->agg.state != IWL_AGG_ON && - tid_data->agg.state != IWL_AGG_OFF, + tid_data->agg.state != IWL_AGG_OFF, "Tx while agg.state = %d", tid_data->agg.state)) goto drop_unlock_sta; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c index 48d6d44c16d0..cc41cfaedfbd 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -101,10 +101,6 @@ MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); -#ifdef CONFIG_IWLWIFI_DEBUGFS -static struct dentry *iwl_dbgfs_root; -#endif - /** * struct iwl_drv - drv common data * @list: list of drv structures using this opmode @@ -130,12 +126,6 @@ struct iwl_drv { char firmware_name[25]; /* name of firmware file to load */ struct completion request_firmware_complete; - -#ifdef CONFIG_IWLWIFI_DEBUGFS - struct dentry *dbgfs_drv; - struct dentry *dbgfs_trans; - struct dentry *dbgfs_op_mode; -#endif }; #define DVM_OP_MODE 0 @@ -204,8 +194,7 @@ static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, return 0; } -static void iwl_req_fw_callback(const struct firmware *ucode_raw, - void *context); +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); #define UCODE_EXPERIMENTAL_INDEX 100 #define UCODE_EXPERIMENTAL_TAG "exp" @@ -242,7 +231,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, drv->trans->dev, - GFP_KERNEL, drv, iwl_req_fw_callback); + GFP_KERNEL, drv, iwl_ucode_callback); } struct fw_img_parsing { @@ -770,57 +759,13 @@ static int validate_sec_sizes(struct iwl_drv *drv, return 0; } -static struct iwl_op_mode * -_iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) -{ - const struct iwl_op_mode_ops *ops = op->ops; - struct dentry *dbgfs_dir = NULL; - struct iwl_op_mode *op_mode = NULL; - -#ifdef CONFIG_IWLWIFI_DEBUGFS - drv->dbgfs_op_mode = debugfs_create_dir(op->name, - drv->dbgfs_drv); - if (!drv->dbgfs_op_mode) { - IWL_ERR(drv, - "failed to create opmode debugfs directory\n"); - return op_mode; - } - dbgfs_dir = drv->dbgfs_op_mode; -#endif - - op_mode = ops->start(drv->trans, drv->cfg, &drv->fw, dbgfs_dir); - -#ifdef CONFIG_IWLWIFI_DEBUGFS - if (!op_mode) { - debugfs_remove_recursive(drv->dbgfs_op_mode); - drv->dbgfs_op_mode = NULL; - } -#endif - - return op_mode; -} - -static void _iwl_op_mode_stop(struct iwl_drv *drv) -{ - /* op_mode can be NULL if its start failed */ - if (drv->op_mode) { - iwl_op_mode_stop(drv->op_mode); - drv->op_mode = NULL; - -#ifdef CONFIG_IWLWIFI_DEBUGFS - debugfs_remove_recursive(drv->dbgfs_op_mode); - drv->dbgfs_op_mode = NULL; -#endif - } -} - /** - * iwl_req_fw_callback - callback when firmware was loaded + * iwl_ucode_callback - callback when firmware was loaded * * If loaded successfully, copies the firmware into buffers * for the card to fetch (via DMA). */ -static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) { struct iwl_drv *drv = context; struct iwl_fw *fw = &drv->fw; @@ -963,7 +908,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) list_add_tail(&drv->list, &op->drv); if (op->ops) { - drv->op_mode = _iwl_op_mode_start(drv, op); + const struct iwl_op_mode_ops *ops = op->ops; + drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw); if (!drv->op_mode) { mutex_unlock(&iwlwifi_opmode_table_mtx); @@ -1023,43 +969,14 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, init_completion(&drv->request_firmware_complete); INIT_LIST_HEAD(&drv->list); -#ifdef CONFIG_IWLWIFI_DEBUGFS - /* Create the device debugfs entries. */ - drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev), - iwl_dbgfs_root); - - if (!drv->dbgfs_drv) { - IWL_ERR(drv, "failed to create debugfs directory\n"); - goto err_free_drv; - } - - /* Create transport layer debugfs dir */ - drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); - - if (!drv->trans->dbgfs_dir) { - IWL_ERR(drv, "failed to create transport debugfs directory\n"); - goto err_free_dbgfs; - } -#endif - ret = iwl_request_firmware(drv, true); if (ret) { IWL_ERR(trans, "Couldn't request the fw\n"); - goto err_fw; + kfree(drv); + drv = NULL; } - return drv; - -err_fw: -#ifdef CONFIG_IWLWIFI_DEBUGFS -err_free_dbgfs: - debugfs_remove_recursive(drv->dbgfs_drv); -err_free_drv: -#endif - kfree(drv); - drv = NULL; - return drv; } @@ -1067,7 +984,9 @@ void iwl_drv_stop(struct iwl_drv *drv) { wait_for_completion(&drv->request_firmware_complete); - _iwl_op_mode_stop(drv); + /* op_mode can be NULL if its start failed */ + if (drv->op_mode) + iwl_op_mode_stop(drv->op_mode); iwl_dealloc_ucode(drv); @@ -1081,10 +1000,6 @@ void iwl_drv_stop(struct iwl_drv *drv) list_del(&drv->list); mutex_unlock(&iwlwifi_opmode_table_mtx); -#ifdef CONFIG_IWLWIFI_DEBUGFS - debugfs_remove_recursive(drv->dbgfs_drv); -#endif - kfree(drv); } @@ -1107,18 +1022,15 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) { int i; struct iwl_drv *drv; - struct iwlwifi_opmode_table *op; mutex_lock(&iwlwifi_opmode_table_mtx); for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { - op = &iwlwifi_opmode_table[i]; - if (strcmp(op->name, name)) + if (strcmp(iwlwifi_opmode_table[i].name, name)) continue; - op->ops = ops; - /* TODO: need to handle exceptional case */ - list_for_each_entry(drv, &op->drv, list) - drv->op_mode = _iwl_op_mode_start(drv, op); - + iwlwifi_opmode_table[i].ops = ops; + list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) + drv->op_mode = ops->start(drv->trans, drv->cfg, + &drv->fw); mutex_unlock(&iwlwifi_opmode_table_mtx); return 0; } @@ -1139,9 +1051,12 @@ void iwl_opmode_deregister(const char *name) iwlwifi_opmode_table[i].ops = NULL; /* call the stop routine for all devices */ - list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) - _iwl_op_mode_stop(drv); - + list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) { + if (drv->op_mode) { + iwl_op_mode_stop(drv->op_mode); + drv->op_mode = NULL; + } + } mutex_unlock(&iwlwifi_opmode_table_mtx); return; } @@ -1161,14 +1076,6 @@ static int __init iwl_drv_init(void) pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); pr_info(DRV_COPYRIGHT "\n"); -#ifdef CONFIG_IWLWIFI_DEBUGFS - /* Create the root of iwlwifi debugfs subsystem. */ - iwl_dbgfs_root = debugfs_create_dir(DRV_NAME, NULL); - - if (!iwl_dbgfs_root) - return -EFAULT; -#endif - return iwl_pci_register_driver(); } module_init(iwl_drv_init); @@ -1176,10 +1083,6 @@ module_init(iwl_drv_init); static void __exit iwl_drv_exit(void) { iwl_pci_unregister_driver(); - -#ifdef CONFIG_IWLWIFI_DEBUGFS - debugfs_remove_recursive(iwl_dbgfs_root); -#endif } module_exit(iwl_drv_exit); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.h b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.h index 285de5f68c05..2cbf137b25bf 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -90,9 +90,9 @@ * 4) The bus specific component configures the bus * 5) The bus specific component calls to the drv bus agnostic part * (iwl_drv_start) - * 6) iwl_drv_start fetches the fw ASYNC, iwl_req_fw_callback - * 7) iwl_req_fw_callback parses the fw file - * 8) iwl_req_fw_callback starts the wifi implementation to matches the fw + * 6) iwl_drv_start fetches the fw ASYNC, iwl_ucode_callback + * 7) iwl_ucode_callback parses the fw file + * 8) iwl_ucode_callback starts the wifi implementation to matches the fw */ struct iwl_drv; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/trunk/drivers/net/wireless/iwlwifi/iwl-op-mode.h index c8d9b9517468..64886f95664f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -134,8 +134,7 @@ struct iwl_cfg; struct iwl_op_mode_ops { struct iwl_op_mode *(*start)(struct iwl_trans *trans, const struct iwl_cfg *cfg, - const struct iwl_fw *fw, - struct dentry *dbgfs_dir); + const struct iwl_fw *fw); void (*stop)(struct iwl_op_mode *op_mode); int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h index ff1154232885..92576a3e84ef 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -184,20 +184,14 @@ struct iwl_rx_packet { * @CMD_SYNC: The caller will be stalled until the fw responds to the command * @CMD_ASYNC: Return right away and don't want for the response * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the - * response. The caller needs to call iwl_free_resp when done. - * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the - * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be - * copied. The pointer passed to the response handler is in the transport - * ownership and don't need to be freed by the op_mode. This also means - * that the pointer is invalidated after the op_mode's handler returns. + * response. * @CMD_ON_DEMAND: This command is sent by the test mode pipe. */ enum CMD_MODE { CMD_SYNC = 0, CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), - CMD_WANT_HCMD = BIT(2), - CMD_ON_DEMAND = BIT(3), + CMD_ON_DEMAND = BIT(2), }; #define DEF_CMD_PAYLOAD_SIZE 320 @@ -466,8 +460,6 @@ struct iwl_trans { size_t dev_cmd_headroom; char dev_cmd_pool_name[50]; - struct dentry *dbgfs_dir; - /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char trans_specific[0] __aligned(sizeof(void *)); diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c b/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c index 89bfb43f4946..f4c3500b68c6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -282,14 +282,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!trans_pcie->drv) goto out_free_trans; - /* register transport layer debugfs here */ - if (iwl_trans_dbgfs_register(iwl_trans, iwl_trans->dbgfs_dir)) - goto out_free_drv; - return 0; -out_free_drv: - iwl_drv_stop(trans_pcie->drv); out_free_trans: iwl_trans_pcie_free(iwl_trans); pci_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h index 71c79943e633..d9694c58208c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -184,7 +184,6 @@ struct iwl_queue { struct iwl_pcie_tx_queue_entry { struct iwl_device_cmd *cmd; - struct iwl_device_cmd *copy_cmd; struct sk_buff *skb; struct iwl_cmd_meta meta; }; @@ -351,7 +350,7 @@ int iwl_queue_space(const struct iwl_queue *q); /***************************************************** * Error handling ******************************************************/ -int iwl_dump_fh(struct iwl_trans *trans, char **buf); +int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display); void iwl_dump_csr(struct iwl_trans *trans); /***************************************************** diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c index 498372008810..39a6ca1f009c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -421,23 +421,13 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, index = SEQ_TO_INDEX(sequence); cmd_index = get_cmd_index(&txq->q, index); - if (reclaim) { - struct iwl_pcie_tx_queue_entry *ent; - ent = &txq->entries[cmd_index]; - cmd = ent->copy_cmd; - WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); - } else { + if (reclaim) + cmd = txq->entries[cmd_index].cmd; + else cmd = NULL; - } err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); - if (reclaim) { - /* The original command isn't needed any more */ - kfree(txq->entries[cmd_index].copy_cmd); - txq->entries[cmd_index].copy_cmd = NULL; - } - /* * After here, we should always check rxcb._page_stolen, * if it is true then one of the handlers took the page. @@ -565,7 +555,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) } iwl_dump_csr(trans); - iwl_dump_fh(trans, NULL); + iwl_dump_fh(trans, NULL, false); iwl_op_mode_nic_error(trans->op_mode); } diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c index 848851177e7e..939c2f78df58 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -492,11 +492,10 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) iwl_tx_queue_unmap(trans, txq_id); /* De-alloc array of command/tx buffers */ + if (txq_id == trans_pcie->cmd_queue) - for (i = 0; i < txq->q.n_window; i++) { + for (i = 0; i < txq->q.n_window; i++) kfree(txq->entries[i].cmd); - kfree(txq->entries[i].copy_cmd); - } /* De-alloc circular buffer of TFDs */ if (txq->q.n_bd) { @@ -897,7 +896,6 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) static int iwl_prepare_card_hw(struct iwl_trans *trans) { int ret; - int t = 0; IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); @@ -910,15 +908,17 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans) iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); - do { - ret = iwl_set_hw_ready(trans); - if (ret >= 0) - return 0; + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, + ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, + CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); - usleep_range(200, 1000); - t += 200; - } while (t < 150000); + if (ret < 0) + return ret; + /* HW should be ready by now, check again. */ + ret = iwl_set_hw_ready(trans); + if (ret >= 0) + return 0; return ret; } @@ -1649,9 +1649,13 @@ static const char *get_fh_string(int cmd) #undef IWL_CMD } -int iwl_dump_fh(struct iwl_trans *trans, char **buf) +int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) { int i; +#ifdef CONFIG_IWLWIFI_DEBUG + int pos = 0; + size_t bufsz = 0; +#endif static const u32 fh_tbl[] = { FH_RSCSR_CHNL0_STTS_WPTR_REG, FH_RSCSR_CHNL0_RBDCB_BASE_REG, @@ -1663,35 +1667,29 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf) FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_ERROR_REG }; - -#ifdef CONFIG_IWLWIFI_DEBUGFS - if (buf) { - int pos = 0; - size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; - +#ifdef CONFIG_IWLWIFI_DEBUG + if (display) { + bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; *buf = kmalloc(bufsz, GFP_KERNEL); if (!*buf) return -ENOMEM; - pos += scnprintf(*buf + pos, bufsz - pos, "FH register values:\n"); - - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { pos += scnprintf(*buf + pos, bufsz - pos, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), iwl_read_direct32(trans, fh_tbl[i])); - + } return pos; } #endif - IWL_ERR(trans, "FH register values:\n"); - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { IWL_ERR(trans, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), iwl_read_direct32(trans, fh_tbl[i])); - + } return 0; } @@ -1771,7 +1769,7 @@ void iwl_dump_csr(struct iwl_trans *trans) #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ if (!debugfs_create_file(#name, mode, parent, trans, \ &iwl_dbgfs_##name##_ops)) \ - goto err; \ + return -ENOMEM; \ } while (0) /* file operation */ @@ -1984,11 +1982,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_trans *trans = file->private_data; - char *buf = NULL; + char *buf; int pos = 0; ssize_t ret = -EFAULT; - ret = pos = iwl_dump_fh(trans, &buf); + ret = pos = iwl_dump_fh(trans, &buf, true); if (buf) { ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); @@ -2035,10 +2033,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR); return 0; - -err: - IWL_ERR(trans, "failed to create the trans debugfs entry\n"); - return -ENOMEM; } #else static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c index 392d2bc5e357..6baf8deef519 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -521,7 +521,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) u16 copy_size, cmd_size; bool had_nocopy = false; int i; - u32 cmd_pos; + u8 *cmd_dest; #ifdef CONFIG_IWLWIFI_DEVICE_TRACING const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {}; int trace_lens[IWL_MAX_CMD_TFDS + 1] = {}; @@ -584,31 +584,15 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) INDEX_TO_SEQ(q->write_ptr)); /* and copy the data that needs to be copied */ - cmd_pos = offsetof(struct iwl_device_cmd, payload); + + cmd_dest = out_cmd->payload; for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) break; - memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); - cmd_pos += cmd->len[i]; - } - - WARN_ON_ONCE(txq->entries[idx].copy_cmd); - - /* - * since out_cmd will be the source address of the FH, it will write - * the retry count there. So when the user needs to receivce the HCMD - * that corresponds to the response in the response handler, it needs - * to set CMD_WANT_HCMD. - */ - if (cmd->flags & CMD_WANT_HCMD) { - txq->entries[idx].copy_cmd = - kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); - if (unlikely(!txq->entries[idx].copy_cmd)) { - idx = -ENOMEM; - goto out; - } + memcpy(cmd_dest, cmd->data[i], cmd->len[i]); + cmd_dest += cmd->len[i]; } IWL_DEBUG_HC(trans, diff --git a/trunk/drivers/net/wireless/libertas_tf/main.c b/trunk/drivers/net/wireless/libertas_tf/main.c index 7001856241e6..a03457292c88 100644 --- a/trunk/drivers/net/wireless/libertas_tf/main.c +++ b/trunk/drivers/net/wireless/libertas_tf/main.c @@ -227,9 +227,7 @@ static void lbtf_free_adapter(struct lbtf_private *priv) lbtf_deb_leave(LBTF_DEB_MAIN); } -static void lbtf_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct lbtf_private *priv = hw->priv; diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index 72b0456e41bf..00838395778c 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -709,9 +709,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, return ack; } -static void mac80211_hwsim_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { bool ack; struct ieee80211_tx_info *txi; @@ -1729,7 +1727,6 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = { #endif BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO) }, - { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, }; static const struct ieee80211_iface_combination hwsim_if_comb = { @@ -1816,8 +1813,7 @@ static int __init init_mac80211_hwsim(void) BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_MESH_POINT) | - BIT(NL80211_IFTYPE_P2P_DEVICE); + BIT(NL80211_IFTYPE_MESH_POINT); hw->flags = IEEE80211_HW_MFP_CAPABLE | IEEE80211_HW_SIGNAL_DBM | diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index 5099e5375cb3..224e03ade145 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -1830,14 +1830,12 @@ static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid) } static void -mwl8k_txq_xmit(struct ieee80211_hw *hw, - int index, - struct ieee80211_sta *sta, - struct sk_buff *skb) +mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) { struct mwl8k_priv *priv = hw->priv; struct ieee80211_tx_info *tx_info; struct mwl8k_vif *mwl8k_vif; + struct ieee80211_sta *sta; struct ieee80211_hdr *wh; struct mwl8k_tx_queue *txq; struct mwl8k_tx_desc *tx; @@ -1869,6 +1867,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, wh = &((struct mwl8k_dma_data *)skb->data)->wh; tx_info = IEEE80211_SKB_CB(skb); + sta = tx_info->control.sta; mwl8k_vif = MWL8K_VIF(tx_info->control.vif); if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { @@ -2020,8 +2019,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, tx->pkt_phys_addr = cpu_to_le32(dma); tx->pkt_len = cpu_to_le16(skb->len); tx->rate_info = 0; - if (!priv->ap_fw && sta != NULL) - tx->peer_id = MWL8K_STA(sta)->peer_id; + if (!priv->ap_fw && tx_info->control.sta != NULL) + tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id; else tx->peer_id = 0; @@ -4365,9 +4364,7 @@ static void mwl8k_rx_poll(unsigned long data) /* * Core driver operations. */ -static void mwl8k_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct mwl8k_priv *priv = hw->priv; int index = skb_get_queue_mapping(skb); @@ -4379,7 +4376,7 @@ static void mwl8k_tx(struct ieee80211_hw *hw, return; } - mwl8k_txq_xmit(hw, index, control->sta, skb); + mwl8k_txq_xmit(hw, index, skb); } static int mwl8k_start(struct ieee80211_hw *hw) diff --git a/trunk/drivers/net/wireless/p54/lmac.h b/trunk/drivers/net/wireless/p54/lmac.h index de1d46bf97df..3d8d622bec55 100644 --- a/trunk/drivers/net/wireless/p54/lmac.h +++ b/trunk/drivers/net/wireless/p54/lmac.h @@ -526,9 +526,7 @@ int p54_init_leds(struct p54_common *priv); void p54_unregister_leds(struct p54_common *priv); /* xmit functions */ -void p54_tx_80211(struct ieee80211_hw *dev, - struct ieee80211_tx_control *control, - struct sk_buff *skb); +void p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb); int p54_tx_cancel(struct p54_common *priv, __le32 req_id); void p54_tx(struct p54_common *priv, struct sk_buff *skb); diff --git a/trunk/drivers/net/wireless/p54/main.c b/trunk/drivers/net/wireless/p54/main.c index 5e91ad06dd5d..7cffea795ad2 100644 --- a/trunk/drivers/net/wireless/p54/main.c +++ b/trunk/drivers/net/wireless/p54/main.c @@ -158,7 +158,7 @@ static int p54_beacon_update(struct p54_common *priv, * to cancel the old beacon template by hand, instead the firmware * will release the previous one through the feedback mechanism. */ - p54_tx_80211(priv->hw, NULL, beacon); + p54_tx_80211(priv->hw, beacon); priv->tsf_high32 = 0; priv->tsf_low32 = 0; diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c index 5861e13a6fd8..f38786e02623 100644 --- a/trunk/drivers/net/wireless/p54/txrx.c +++ b/trunk/drivers/net/wireless/p54/txrx.c @@ -676,9 +676,8 @@ int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb) EXPORT_SYMBOL_GPL(p54_rx); static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - u8 *queue, u32 *extra_len, u16 *flags, u16 *aid, + struct ieee80211_tx_info *info, u8 *queue, + u32 *extra_len, u16 *flags, u16 *aid, bool *burst_possible) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -747,8 +746,8 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb, } } - if (sta) - *aid = sta->aid; + if (info->control.sta) + *aid = info->control.sta->aid; break; } } @@ -768,9 +767,7 @@ static u8 p54_convert_algo(u32 cipher) } } -void p54_tx_80211(struct ieee80211_hw *dev, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +void p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) { struct p54_common *priv = dev->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -787,7 +784,7 @@ void p54_tx_80211(struct ieee80211_hw *dev, u8 nrates = 0, nremaining = 8; bool burst_allowed = false; - p54_tx_80211_header(priv, skb, info, control->sta, &queue, &extra_len, + p54_tx_80211_header(priv, skb, info, &queue, &extra_len, &hdr_flags, &aid, &burst_allowed); if (p54_tx_qos_accounting_alloc(priv, skb, queue)) { diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00.h b/trunk/drivers/net/wireless/rt2x00/rt2x00.h index f991e8bedc70..8afb546c2b2d 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00.h @@ -1287,9 +1287,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp); /* * mac80211 handlers. */ -void rt2x00mac_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb); +void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); int rt2x00mac_start(struct ieee80211_hw *hw); void rt2x00mac_stop(struct ieee80211_hw *hw); int rt2x00mac_add_interface(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index a59048ffa092..a6b88bd4a1a5 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -194,7 +194,7 @@ static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac, */ skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); while (skb) { - rt2x00mac_tx(rt2x00dev->hw, NULL, skb); + rt2x00mac_tx(rt2x00dev->hw, skb); skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); } } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c index c3d0f2f87b69..4ff26c2159bf 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -99,9 +99,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, return retval; } -void rt2x00mac_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rt2x00_dev *rt2x00dev = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c index e488b944a034..f7e74a0a7759 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -315,7 +315,6 @@ static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev, static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct txentry_desc *txdesc, - struct ieee80211_sta *sta, const struct rt2x00_rate *hwrate) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -323,11 +322,11 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct rt2x00_sta *sta_priv = NULL; - if (sta) { + if (tx_info->control.sta) { txdesc->u.ht.mpdu_density = - sta->ht_cap.ampdu_density; + tx_info->control.sta->ht_cap.ampdu_density; - sta_priv = sta_to_rt2x00_sta(sta); + sta_priv = sta_to_rt2x00_sta(tx_info->control.sta); txdesc->u.ht.wcid = sta_priv->wcid; } @@ -342,8 +341,8 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, * MIMO PS should be set to 1 for STA's using dynamic SM PS * when using more then one tx stream (>MCS7). */ - if (sta && txdesc->u.ht.mcs > 7 && - ((sta->ht_cap.cap & + if (tx_info->control.sta && txdesc->u.ht.mcs > 7 && + ((tx_info->control.sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT) == WLAN_HT_CAP_SM_PS_DYNAMIC) @@ -410,8 +409,7 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, static void rt2x00queue_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, - struct txentry_desc *txdesc, - struct ieee80211_sta *sta) + struct txentry_desc *txdesc) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -505,7 +503,7 @@ static void rt2x00queue_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) rt2x00queue_create_tx_descriptor_ht(rt2x00dev, skb, txdesc, - sta, hwrate); + hwrate); else rt2x00queue_create_tx_descriptor_plcp(rt2x00dev, skb, txdesc, hwrate); @@ -597,7 +595,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * after that we are free to use the skb->cb array * for our information. */ - rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc, NULL); + rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc); /* * All information is retrieved from the skb->cb array, @@ -742,7 +740,7 @@ int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev, * after that we are free to use the skb->cb array * for our information. */ - rt2x00queue_create_tx_descriptor(rt2x00dev, intf->beacon->skb, &txdesc, NULL); + rt2x00queue_create_tx_descriptor(rt2x00dev, intf->beacon->skb, &txdesc); /* * Fill in skb descriptor diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c index 021d83e1b1d3..aceaf689f737 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -244,9 +244,7 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static void rtl8180_tx(struct ieee80211_hw *dev, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -712,7 +710,7 @@ static void rtl8180_beacon_work(struct work_struct *work) /* TODO: use actual beacon queue */ skb_set_queue_mapping(skb, 0); - rtl8180_tx(dev, NULL, skb); + rtl8180_tx(dev, skb); resched: /* diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c index 7811b6315973..533024095c43 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -228,9 +228,7 @@ static void rtl8187_tx_cb(struct urb *urb) } } -static void rtl8187_tx(struct ieee80211_hw *dev, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct rtl8187_priv *priv = dev->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1078,7 +1076,7 @@ static void rtl8187_beacon_work(struct work_struct *work) /* TODO: use actual beacon queue */ skb_set_queue_mapping(skb, 0); - rtl8187_tx(dev, NULL, skb); + rtl8187_tx(dev, skb); resched: /* diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index 59381fe8ed06..942e56b77b60 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -1341,8 +1341,9 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); info->control.rates[0].idx = 0; + info->control.sta = sta; info->band = hw->conf.channel->band; - rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc); + rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); } err_free: return 0; diff --git a/trunk/drivers/net/wireless/rtlwifi/core.c b/trunk/drivers/net/wireless/rtlwifi/core.c index a7c0e52869ba..a18ad2a98938 100644 --- a/trunk/drivers/net/wireless/rtlwifi/core.c +++ b/trunk/drivers/net/wireless/rtlwifi/core.c @@ -124,9 +124,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) mutex_unlock(&rtlpriv->locks.conf_mutex); } -static void rtl_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void rtl_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -140,8 +138,8 @@ static void rtl_op_tx(struct ieee80211_hw *hw, if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status)) goto err_free; - if (!rtlpriv->intf_ops->waitq_insert(hw, control->sta, skb)) - rtlpriv->intf_ops->adapter_tx(hw, control->sta, skb, &tcb_desc); + if (!rtlpriv->intf_ops->waitq_insert(hw, skb)) + rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); return; diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index aad9d44c0a51..80f75d3ba84a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -504,7 +504,7 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) _rtl_update_earlymode_info(hw, skb, &tcb_desc, tid); - rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, &tcb_desc); + rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc); } } } @@ -929,7 +929,7 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) info = IEEE80211_SKB_CB(pskb); pdesc = &ring->desc[0]; rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc, - info, NULL, pskb, BEACON_QUEUE, &tcb_desc); + info, pskb, BEACON_QUEUE, &tcb_desc); __skb_queue_tail(&ring->queue, pskb); @@ -1305,10 +1305,11 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) } static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, struct sk_buff *skb) { struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = info->control.sta; struct rtl_sta_info *sta_entry = NULL; u8 tid = rtl_get_tid(skb); @@ -1336,14 +1337,13 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, return true; } -static int rtl_pci_tx(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct sk_buff *skb, - struct rtl_tcb_desc *ptcb_desc) +static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, + struct rtl_tcb_desc *ptcb_desc) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_sta_info *sta_entry = NULL; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = info->control.sta; struct rtl8192_tx_ring *ring; struct rtl_tx_desc *pdesc; u8 idx; @@ -1418,7 +1418,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, - info, sta, skb, hw_queue, ptcb_desc); + info, skb, hw_queue, ptcb_desc); __skb_queue_tail(&ring->queue, skb); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 390d6d4fcaa0..52166640f167 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -596,9 +596,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, + struct ieee80211_tx_info *info, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *tcb_desc) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -606,6 +604,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool defaultadapter = true; + struct ieee80211_sta *sta; u8 *pdesc = pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index a7cdd514cb2e..c4adb9777365 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -713,7 +713,6 @@ struct rx_desc_92c { void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc, struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 27863d773790..2e6eb356a93e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -496,9 +496,7 @@ static void _rtl_tx_desc_checksum(u8 *txdesc) void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, + struct ieee80211_tx_info *info, struct sk_buff *skb, u8 queue_index, struct rtl_tcb_desc *tcb_desc) { @@ -506,6 +504,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); bool defaultadapter = true; + struct ieee80211_sta *sta = info->control.sta = info->control.sta; u8 *qc = ieee80211_get_qos_ctl(hdr); u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; u16 seq_number; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h index 725c53accc58..332b06e78b00 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h @@ -420,9 +420,7 @@ struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *, struct sk_buff_head *); void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, + struct ieee80211_tx_info *info, struct sk_buff *skb, u8 queue_index, struct rtl_tcb_desc *tcb_desc); void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 4686f340b9d6..f80690d82c11 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -551,9 +551,7 @@ static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, + struct ieee80211_tx_info *info, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -561,6 +559,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct ieee80211_sta *sta = info->control.sta; u8 *pdesc = pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.h index c1b5dfb79d53..057a52431b00 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.h @@ -730,7 +730,6 @@ struct rx_desc_92d { void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc, struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 28c53fb12aeb..36d1cb3aef8a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -591,15 +591,14 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, + struct ieee80211_tx_info *info, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct ieee80211_sta *sta = info->control.sta; u8 *pdesc = pdesc_tx; u16 seq_number; __le16 fc = hdr->frame_control; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.h index 64dd66f287c1..011e7b0695f2 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.h @@ -31,7 +31,6 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc, struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg, diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c index 914046903cfd..aa970fc18a21 100644 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ b/trunk/drivers/net/wireless/rtlwifi/usb.c @@ -848,10 +848,8 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, _rtl_submit_tx_urb(hw, _urb); } -static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct sk_buff *skb, - u16 hw_queue) +static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, + u16 hw_queue) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -893,7 +891,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, seq_number += 1; seq_number <<= 4; } - rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, sta, skb, + rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb, hw_queue, &tcb_desc); if (!ieee80211_has_morefrags(hdr->frame_control)) { if (qc) @@ -903,9 +901,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); } -static int rtl_usb_tx(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct sk_buff *skb, +static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb, struct rtl_tcb_desc *dummy) { struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); @@ -917,7 +913,7 @@ static int rtl_usb_tx(struct ieee80211_hw *hw, if (unlikely(is_hal_stop(rtlhal))) goto err_free; hw_queue = rtlusb->usb_mq_to_hwq(fc, skb_get_queue_mapping(skb)); - _rtl_usb_tx_preprocess(hw, sta, skb, hw_queue); + _rtl_usb_tx_preprocess(hw, skb, hw_queue); _rtl_usb_transmit(hw, skb, hw_queue); return NETDEV_TX_OK; @@ -927,7 +923,6 @@ static int rtl_usb_tx(struct ieee80211_hw *hw, } static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, struct sk_buff *skb) { return false; diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h index 40153e7bf702..cdaa21f29710 100644 --- a/trunk/drivers/net/wireless/rtlwifi/wifi.h +++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h @@ -122,7 +122,7 @@ enum rt_eeprom_type { EEPROM_BOOT_EFUSE, }; -enum ttl_status { +enum rtl_status { RTL_STATUS_INTERFACE_START = 0, }; @@ -1418,7 +1418,6 @@ struct rtl_hal_ops { void (*fill_tx_desc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, u8 *pdesc_tx, struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, struct sk_buff *skb, u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 *pDesc, @@ -1476,15 +1475,11 @@ struct rtl_intf_ops { int (*adapter_start) (struct ieee80211_hw *hw); void (*adapter_stop) (struct ieee80211_hw *hw); - int (*adapter_tx) (struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct sk_buff *skb, - struct rtl_tcb_desc *ptcb_desc); + int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb, + struct rtl_tcb_desc *ptcb_desc); void (*flush)(struct ieee80211_hw *hw, bool drop); int (*reset_trx_ring) (struct ieee80211_hw *hw); - bool (*waitq_insert) (struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct sk_buff *skb); + bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); /*pci */ void (*disable_aspm) (struct ieee80211_hw *hw); diff --git a/trunk/drivers/net/wireless/ti/wl1251/main.c b/trunk/drivers/net/wireless/ti/wl1251/main.c index 441cbccbd381..3118c425bcf1 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/main.c +++ b/trunk/drivers/net/wireless/ti/wl1251/main.c @@ -354,9 +354,7 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, return ret; } -static void wl1251_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1251 *wl = hw->priv; unsigned long flags; diff --git a/trunk/drivers/net/wireless/ti/wlcore/main.c b/trunk/drivers/net/wireless/ti/wlcore/main.c index ff830cf50c70..72548609f711 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/main.c +++ b/trunk/drivers/net/wireless/ti/wlcore/main.c @@ -1181,9 +1181,7 @@ int wl1271_plt_stop(struct wl1271 *wl) return ret; } -static void wl1271_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1271 *wl = hw->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1199,7 +1197,7 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, mapping = skb_get_queue_mapping(skb); q = wl1271_tx_get_queue(mapping); - hlid = wl12xx_tx_get_hlid(wl, wlvif, skb, control->sta); + hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); spin_lock_irqsave(&wl->wl_lock, flags); diff --git a/trunk/drivers/net/wireless/ti/wlcore/tx.c b/trunk/drivers/net/wireless/ti/wlcore/tx.c index 1a2f31c289c5..f0081f746482 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/tx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/tx.c @@ -130,13 +130,16 @@ bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb) } EXPORT_SYMBOL(wl12xx_is_dummy_packet); -static u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct sk_buff *skb, struct ieee80211_sta *sta) +u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct sk_buff *skb) { - if (sta) { + struct ieee80211_tx_info *control = IEEE80211_SKB_CB(skb); + + if (control->control.sta) { struct wl1271_station *wl_sta; - wl_sta = (struct wl1271_station *)sta->drv_priv; + wl_sta = (struct wl1271_station *) + control->control.sta->drv_priv; return wl_sta->hlid; } else { struct ieee80211_hdr *hdr; @@ -153,7 +156,7 @@ static u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, } u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct sk_buff *skb, struct ieee80211_sta *sta) + struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -161,7 +164,7 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, return wl->system_hlid; if (wlvif->bss_type == BSS_TYPE_AP_BSS) - return wl12xx_tx_get_hlid_ap(wl, wlvif, skb, sta); + return wl12xx_tx_get_hlid_ap(wl, wlvif, skb); if ((test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) || test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags)) && @@ -341,12 +344,13 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, /* caller must hold wl->mutex */ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct sk_buff *skb, u32 buf_offset, u8 hlid) + struct sk_buff *skb, u32 buf_offset) { struct ieee80211_tx_info *info; u32 extra = 0; int ret = 0; u32 total_len; + u8 hlid; bool is_dummy; bool is_gem = false; @@ -355,13 +359,9 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, return -EINVAL; } - if (hlid == WL12XX_INVALID_LINK_ID) { - wl1271_error("invalid hlid. dropping skb 0x%p", skb); - return -EINVAL; - } - info = IEEE80211_SKB_CB(skb); + /* TODO: handle dummy packets on multi-vifs */ is_dummy = wl12xx_is_dummy_packet(wl, skb); if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && @@ -386,6 +386,11 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, is_gem = (cipher == WL1271_CIPHER_SUITE_GEM); } + hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); + if (hlid == WL12XX_INVALID_LINK_ID) { + wl1271_error("invalid hlid. dropping skb 0x%p", skb); + return -EINVAL; + } ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid, is_gem); @@ -512,8 +517,7 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl, } static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl, - struct wl12xx_vif *wlvif, - u8 *hlid) + struct wl12xx_vif *wlvif) { struct sk_buff *skb = NULL; int i, h, start_hlid; @@ -540,11 +544,10 @@ static struct sk_buff *wl12xx_vif_skb_dequeue(struct wl1271 *wl, if (!skb) wlvif->last_tx_hlid = 0; - *hlid = wlvif->last_tx_hlid; return skb; } -static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid) +static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) { unsigned long flags; struct wl12xx_vif *wlvif = wl->last_wlvif; @@ -553,7 +556,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid) /* continue from last wlvif (round robin) */ if (wlvif) { wl12xx_for_each_wlvif_continue(wl, wlvif) { - skb = wl12xx_vif_skb_dequeue(wl, wlvif, hlid); + skb = wl12xx_vif_skb_dequeue(wl, wlvif); if (skb) { wl->last_wlvif = wlvif; break; @@ -562,15 +565,13 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid) } /* dequeue from the system HLID before the restarting wlvif list */ - if (!skb) { + if (!skb) skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); - *hlid = wl->system_hlid; - } /* do a new pass over the wlvif list */ if (!skb) { wl12xx_for_each_wlvif(wl, wlvif) { - skb = wl12xx_vif_skb_dequeue(wl, wlvif, hlid); + skb = wl12xx_vif_skb_dequeue(wl, wlvif); if (skb) { wl->last_wlvif = wlvif; break; @@ -590,7 +591,6 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid) int q; skb = wl->dummy_packet; - *hlid = wl->system_hlid; q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); spin_lock_irqsave(&wl->wl_lock, flags); WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); @@ -602,7 +602,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl, u8 *hlid) } static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct sk_buff *skb, u8 hlid) + struct sk_buff *skb) { unsigned long flags; int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); @@ -610,6 +610,7 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (wl12xx_is_dummy_packet(wl, skb)) { set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags); } else { + u8 hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); skb_queue_head(&wl->links[hlid].tx_queue[q], skb); /* make sure we dequeue the same packet next time */ @@ -685,30 +686,26 @@ int wlcore_tx_work_locked(struct wl1271 *wl) unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; int ret = 0; int bus_ret = 0; - u8 hlid; if (unlikely(wl->state == WL1271_STATE_OFF)) return 0; - while ((skb = wl1271_skb_dequeue(wl, &hlid))) { + while ((skb = wl1271_skb_dequeue(wl))) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); bool has_data = false; wlvif = NULL; if (!wl12xx_is_dummy_packet(wl, skb) && info->control.vif) wlvif = wl12xx_vif_to_data(info->control.vif); - else - hlid = wl->system_hlid; has_data = wlvif && wl1271_tx_is_data_present(skb); - ret = wl1271_prepare_tx_frame(wl, wlvif, skb, buf_offset, - hlid); + ret = wl1271_prepare_tx_frame(wl, wlvif, skb, buf_offset); if (ret == -EAGAIN) { /* * Aggregation buffer is full. * Flush buffer and try again. */ - wl1271_skb_queue_head(wl, wlvif, skb, hlid); + wl1271_skb_queue_head(wl, wlvif, skb); buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); @@ -725,7 +722,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl) * Firmware buffer is full. * Queue back last skb, and stop aggregating. */ - wl1271_skb_queue_head(wl, wlvif, skb, hlid); + wl1271_skb_queue_head(wl, wlvif, skb); /* No work left, avoid scheduling redundant tx work */ set_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); goto out_ack; @@ -735,7 +732,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl) * fw still expects dummy packet, * so re-enqueue it */ - wl1271_skb_queue_head(wl, wlvif, skb, hlid); + wl1271_skb_queue_head(wl, wlvif, skb); else ieee80211_free_txskb(wl->hw, skb); goto out_ack; diff --git a/trunk/drivers/net/wireless/ti/wlcore/tx.h b/trunk/drivers/net/wireless/ti/wlcore/tx.h index 349520d8b724..1e939b016155 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/tx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/tx.h @@ -243,8 +243,10 @@ u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band); u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, enum ieee80211_band rate_band); u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set); +u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, + struct sk_buff *skb); u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct sk_buff *skb, struct ieee80211_sta *sta); + struct sk_buff *skb); void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); void wl1271_handle_tx_low_watermark(struct wl1271 *wl); bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c index 459880104758..c9e2660e1263 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c @@ -937,9 +937,7 @@ static int fill_ctrlset(struct zd_mac *mac, * control block of the skbuff will be initialized. If necessary the incoming * mac80211 queues will be stopped. */ -static void zd_op_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct zd_mac *mac = zd_hw_mac(hw); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1178,7 +1176,7 @@ static void zd_beacon_done(struct zd_mac *mac) skb = ieee80211_get_buffered_bc(mac->hw, mac->vif); if (!skb) break; - zd_op_tx(mac->hw, NULL, skb); + zd_op_tx(mac->hw, skb); } /* diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index c934fe8583f5..39afd37e62b3 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -57,7 +57,8 @@ static const struct ethtool_ops xennet_ethtool_ops; struct netfront_cb { - int pull_to; + struct page *page; + unsigned offset; }; #define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb)) @@ -866,9 +867,15 @@ static int handle_incoming_queue(struct net_device *dev, struct sk_buff *skb; while ((skb = __skb_dequeue(rxq)) != NULL) { - int pull_to = NETFRONT_SKB_CB(skb)->pull_to; + struct page *page = NETFRONT_SKB_CB(skb)->page; + void *vaddr = page_address(page); + unsigned offset = NETFRONT_SKB_CB(skb)->offset; + + memcpy(skb->data, vaddr + offset, + skb_headlen(skb)); - __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); + if (page != skb_frag_page(&skb_shinfo(skb)->frags[0])) + __free_page(page); /* Ethernet work: Delayed to here as it peeks the header. */ skb->protocol = eth_type_trans(skb, dev); @@ -906,6 +913,7 @@ static int xennet_poll(struct napi_struct *napi, int budget) struct sk_buff_head errq; struct sk_buff_head tmpq; unsigned long flags; + unsigned int len; int err; spin_lock(&np->rx_lock); @@ -947,13 +955,24 @@ static int xennet_poll(struct napi_struct *napi, int budget) } } - NETFRONT_SKB_CB(skb)->pull_to = rx->status; - if (NETFRONT_SKB_CB(skb)->pull_to > RX_COPY_THRESHOLD) - NETFRONT_SKB_CB(skb)->pull_to = RX_COPY_THRESHOLD; + NETFRONT_SKB_CB(skb)->page = + skb_frag_page(&skb_shinfo(skb)->frags[0]); + NETFRONT_SKB_CB(skb)->offset = rx->offset; + + len = rx->status; + if (len > RX_COPY_THRESHOLD) + len = RX_COPY_THRESHOLD; + skb_put(skb, len); - skb_shinfo(skb)->frags[0].page_offset = rx->offset; - skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status); - skb->data_len = rx->status; + if (rx->status > len) { + skb_shinfo(skb)->frags[0].page_offset = + rx->offset + len; + skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status - len); + skb->data_len = rx->status - len; + } else { + __skb_fill_page_desc(skb, 0, NULL, 0, 0); + skb_shinfo(skb)->nr_frags = 0; + } i = xennet_fill_frags(np, skb, &tmpq); @@ -980,7 +999,7 @@ static int xennet_poll(struct napi_struct *napi, int budget) * receive throughout using the standard receive * buffer size was cut by 25%(!!!). */ - skb->truesize += skb->data_len - RX_COPY_THRESHOLD; + skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); skb->len += skb->data_len; if (rx->flags & XEN_NETRXF_csum_blank) diff --git a/trunk/drivers/pwm/Kconfig b/trunk/drivers/pwm/Kconfig index 90c5c7357a50..8fc3808d7a3e 100644 --- a/trunk/drivers/pwm/Kconfig +++ b/trunk/drivers/pwm/Kconfig @@ -1,31 +1,12 @@ menuconfig PWM - bool "Pulse-Width Modulation (PWM) Support" + bool "PWM Support" depends on !MACH_JZ4740 && !PUV3_PWM help - Generic Pulse-Width Modulation (PWM) support. - - In Pulse-Width Modulation, a variation of the width of pulses - in a rectangular pulse signal is used as a means to alter the - average power of the signal. Applications include efficient - power delivery and voltage regulation. In computer systems, - PWMs are commonly used to control fans or the brightness of - display backlights. - - This framework provides a generic interface to PWM devices - within the Linux kernel. On the driver side it provides an API - to register and unregister a PWM chip, an abstraction of a PWM - controller, that supports one or more PWM devices. Client - drivers can request PWM devices and use the generic framework - to configure as well as enable and disable them. - - This generic framework replaces the legacy PWM framework which - allows only a single driver implementing the required API. Not - all legacy implementations have been ported to the framework - yet. The framework provides an API that is backward compatible - with the legacy framework so that existing client drivers - continue to work as expected. - - If unsure, say no. + This enables PWM support through the generic PWM framework. + You only need to enable this, if you also want to enable + one or more of the PWM drivers below. + + If unsure, say N. if PWM diff --git a/trunk/drivers/pwm/core.c b/trunk/drivers/pwm/core.c index c6e05078d3ad..ecb76909e946 100644 --- a/trunk/drivers/pwm/core.c +++ b/trunk/drivers/pwm/core.c @@ -129,8 +129,8 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label) return 0; } -static struct pwm_device * -of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) +static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc, + const struct of_phandle_args *args) { struct pwm_device *pwm; @@ -149,7 +149,7 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) return pwm; } -static void of_pwmchip_add(struct pwm_chip *chip) +void of_pwmchip_add(struct pwm_chip *chip) { if (!chip->dev || !chip->dev->of_node) return; @@ -162,7 +162,7 @@ static void of_pwmchip_add(struct pwm_chip *chip) of_node_get(chip->dev->of_node); } -static void of_pwmchip_remove(struct pwm_chip *chip) +void of_pwmchip_remove(struct pwm_chip *chip) { if (chip->dev && chip->dev->of_node) of_node_put(chip->dev->of_node); @@ -527,7 +527,7 @@ void __init pwm_add_table(struct pwm_lookup *table, size_t num) struct pwm_device *pwm_get(struct device *dev, const char *con_id) { struct pwm_device *pwm = ERR_PTR(-EPROBE_DEFER); - const char *dev_id = dev ? dev_name(dev) : NULL; + const char *dev_id = dev ? dev_name(dev): NULL; struct pwm_chip *chip = NULL; unsigned int index = 0; unsigned int best = 0; @@ -609,7 +609,7 @@ void pwm_put(struct pwm_device *pwm) mutex_lock(&pwm_lock); if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) { - pr_warn("PWM device already freed\n"); + pr_warning("PWM device already freed\n"); goto out; } diff --git a/trunk/drivers/pwm/pwm-samsung.c b/trunk/drivers/pwm/pwm-samsung.c index e5187c0ade9f..d10386528c9c 100644 --- a/trunk/drivers/pwm/pwm-samsung.c +++ b/trunk/drivers/pwm/pwm-samsung.c @@ -225,7 +225,6 @@ static int s3c_pwm_probe(struct platform_device *pdev) /* calculate base of control bits in TCON */ s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4; - s3c->chip.dev = &pdev->dev; s3c->chip.ops = &s3c_pwm_ops; s3c->chip.base = -1; s3c->chip.npwm = 1; diff --git a/trunk/drivers/pwm/pwm-tegra.c b/trunk/drivers/pwm/pwm-tegra.c index 057465e0553c..02ce18d5e49a 100644 --- a/trunk/drivers/pwm/pwm-tegra.c +++ b/trunk/drivers/pwm/pwm-tegra.c @@ -187,8 +187,10 @@ static int tegra_pwm_probe(struct platform_device *pdev) } pwm->mmio_base = devm_request_and_ioremap(&pdev->dev, r); - if (!pwm->mmio_base) + if (!pwm->mmio_base) { + dev_err(&pdev->dev, "failed to ioremap() region\n"); return -EADDRNOTAVAIL; + } platform_set_drvdata(pdev, pwm); diff --git a/trunk/drivers/pwm/pwm-tiecap.c b/trunk/drivers/pwm/pwm-tiecap.c index 0b66d0f25922..3c2ad284ee3e 100644 --- a/trunk/drivers/pwm/pwm-tiecap.c +++ b/trunk/drivers/pwm/pwm-tiecap.c @@ -192,8 +192,10 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev) } pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); - if (!pc->mmio_base) + if (!pc->mmio_base) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); return -EADDRNOTAVAIL; + } ret = pwmchip_add(&pc->chip); if (ret < 0) { diff --git a/trunk/drivers/pwm/pwm-tiehrpwm.c b/trunk/drivers/pwm/pwm-tiehrpwm.c index c3756d1be194..010d232cb0c8 100644 --- a/trunk/drivers/pwm/pwm-tiehrpwm.c +++ b/trunk/drivers/pwm/pwm-tiehrpwm.c @@ -371,8 +371,10 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev) } pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); - if (!pc->mmio_base) + if (!pc->mmio_base) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); return -EADDRNOTAVAIL; + } ret = pwmchip_add(&pc->chip); if (ret < 0) { diff --git a/trunk/drivers/pwm/pwm-vt8500.c b/trunk/drivers/pwm/pwm-vt8500.c index ad14389b7144..548021439f0c 100644 --- a/trunk/drivers/pwm/pwm-vt8500.c +++ b/trunk/drivers/pwm/pwm-vt8500.c @@ -41,7 +41,7 @@ static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask) cpu_relax(); if (unlikely(!loops)) - pr_warn("Waiting for status bits 0x%x to clear timed out\n", + pr_warning("Waiting for status bits 0x%x to clear timed out\n", bitmask); } diff --git a/trunk/drivers/staging/winbond/wbusb.c b/trunk/drivers/staging/winbond/wbusb.c index 48aa1361903e..0ca857ac473e 100644 --- a/trunk/drivers/staging/winbond/wbusb.c +++ b/trunk/drivers/staging/winbond/wbusb.c @@ -119,9 +119,7 @@ static void wbsoft_configure_filter(struct ieee80211_hw *dev, *total_flags = new_flags; } -static void wbsoft_tx(struct ieee80211_hw *dev, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static void wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct wbsoft_priv *priv = dev->priv; diff --git a/trunk/drivers/target/target_core_pscsi.c b/trunk/drivers/target/target_core_pscsi.c index 5552fa7426bc..6e32ff6f2fa0 100644 --- a/trunk/drivers/target/target_core_pscsi.c +++ b/trunk/drivers/target/target_core_pscsi.c @@ -673,15 +673,8 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) struct scsi_device *sd = pdv->pdv_sd; int result; struct pscsi_plugin_task *pt = cmd->priv; - unsigned char *cdb; - /* - * Special case for REPORT_LUNs handling where pscsi_plugin_task has - * not been allocated because TCM is handling the emulation directly. - */ - if (!pt) - return 0; + unsigned char *cdb = &pt->pscsi_cdb[0]; - cdb = &pt->pscsi_cdb[0]; result = pt->pscsi_result; /* * Hack to make sure that Write-Protect modepage is set if R/O mode is diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 4de3186dc44e..0eaae23d12b5 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -1165,6 +1165,8 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) " 0x%02x\n", cmd->se_tfo->get_fabric_name(), cmd->data_length, size, cmd->t_task_cdb[0]); + cmd->cmd_spdtl = size; + if (cmd->data_direction == DMA_TO_DEVICE) { pr_err("Rejecting underflow/overflow" " WRITE data\n"); @@ -2292,9 +2294,9 @@ transport_generic_get_mem(struct se_cmd *cmd) return 0; out: - while (i > 0) { - i--; + while (i >= 0) { __free_page(sg_page(&cmd->t_data_sg[i])); + i--; } kfree(cmd->t_data_sg); cmd->t_data_sg = NULL; @@ -2321,12 +2323,9 @@ int transport_generic_new_cmd(struct se_cmd *cmd) if (ret < 0) goto out_fail; } - /* - * If this command doesn't have any payload and we don't have to call - * into the fabric for data transfers, go ahead and complete it right - * away. - */ - if (!cmd->data_length) { + + /* Workaround for handling zero-length control CDBs */ + if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->data_length) { spin_lock_irq(&cmd->t_state_lock); cmd->t_state = TRANSPORT_COMPLETE; cmd->transport_state |= CMD_T_ACTIVE; diff --git a/trunk/drivers/target/tcm_fc/tcm_fc.h b/trunk/drivers/target/tcm_fc/tcm_fc.h index eea69358ced3..c5eb3c33c3db 100644 --- a/trunk/drivers/target/tcm_fc/tcm_fc.h +++ b/trunk/drivers/target/tcm_fc/tcm_fc.h @@ -131,7 +131,6 @@ extern struct list_head ft_lport_list; extern struct mutex ft_lport_lock; extern struct fc4_prov ft_prov; extern struct target_fabric_configfs *ft_configfs; -extern unsigned int ft_debug_logging; /* * Fabric methods. diff --git a/trunk/drivers/target/tcm_fc/tfc_cmd.c b/trunk/drivers/target/tcm_fc/tfc_cmd.c index 823e6922249d..b9cb5006177e 100644 --- a/trunk/drivers/target/tcm_fc/tfc_cmd.c +++ b/trunk/drivers/target/tcm_fc/tfc_cmd.c @@ -48,7 +48,7 @@ /* * Dump cmd state for debugging. */ -static void _ft_dump_cmd(struct ft_cmd *cmd, const char *caller) +void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) { struct fc_exch *ep; struct fc_seq *sp; @@ -80,12 +80,6 @@ static void _ft_dump_cmd(struct ft_cmd *cmd, const char *caller) } } -void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) -{ - if (unlikely(ft_debug_logging)) - _ft_dump_cmd(cmd, caller); -} - static void ft_free_cmd(struct ft_cmd *cmd) { struct fc_frame *fp; diff --git a/trunk/drivers/target/tcm_fc/tfc_sess.c b/trunk/drivers/target/tcm_fc/tfc_sess.c index 3c9e5b57caab..87901fa74dd7 100644 --- a/trunk/drivers/target/tcm_fc/tfc_sess.c +++ b/trunk/drivers/target/tcm_fc/tfc_sess.c @@ -456,9 +456,7 @@ static void ft_prlo(struct fc_rport_priv *rdata) struct ft_tport *tport; mutex_lock(&ft_lport_lock); - tport = rcu_dereference_protected(rdata->local_port->prov[FC_TYPE_FCP], - lockdep_is_held(&ft_lport_lock)); - + tport = rcu_dereference(rdata->local_port->prov[FC_TYPE_FCP]); if (!tport) { mutex_unlock(&ft_lport_lock); return; diff --git a/trunk/drivers/vfio/vfio.c b/trunk/drivers/vfio/vfio.c index 17830c9c7cc6..9591e2b509d7 100644 --- a/trunk/drivers/vfio/vfio.c +++ b/trunk/drivers/vfio/vfio.c @@ -264,7 +264,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) return group; } -/* called with vfio.group_lock held */ static void vfio_group_release(struct kref *kref) { struct vfio_group *group = container_of(kref, struct vfio_group, kref); @@ -288,7 +287,13 @@ static void vfio_group_release(struct kref *kref) static void vfio_group_put(struct vfio_group *group) { - kref_put_mutex(&group->kref, vfio_group_release, &vfio.group_lock); + mutex_lock(&vfio.group_lock); + /* + * Release needs to unlock to unregister the notifier, so only + * unlock if not released. + */ + if (!kref_put(&group->kref, vfio_group_release)) + mutex_unlock(&vfio.group_lock); } /* Assume group_lock or group reference is held */ @@ -396,6 +401,7 @@ static void vfio_device_release(struct kref *kref) struct vfio_device, kref); struct vfio_group *group = device->group; + mutex_lock(&group->device_lock); list_del(&device->group_next); mutex_unlock(&group->device_lock); @@ -410,9 +416,8 @@ static void vfio_device_release(struct kref *kref) /* Device reference always implies a group reference */ static void vfio_device_put(struct vfio_device *device) { - struct vfio_group *group = device->group; - kref_put_mutex(&device->kref, vfio_device_release, &group->device_lock); - vfio_group_put(group); + kref_put(&device->kref, vfio_device_release); + vfio_group_put(device->group); } static void vfio_device_get(struct vfio_device *device) @@ -1111,10 +1116,10 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) */ filep->f_mode |= (FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); + fd_install(ret, filep); + vfio_device_get(device); atomic_inc(&group->container_users); - - fd_install(ret, filep); break; } mutex_unlock(&group->device_lock); diff --git a/trunk/drivers/vhost/tcm_vhost.c b/trunk/drivers/vhost/tcm_vhost.c index ed8e2e6c8df2..fb366540ed54 100644 --- a/trunk/drivers/vhost/tcm_vhost.c +++ b/trunk/drivers/vhost/tcm_vhost.c @@ -53,14 +53,9 @@ #include "vhost.h" #include "tcm_vhost.h" -enum { - VHOST_SCSI_VQ_CTL = 0, - VHOST_SCSI_VQ_EVT = 1, - VHOST_SCSI_VQ_IO = 2, -}; - struct vhost_scsi { - struct tcm_vhost_tpg *vs_tpg; /* Protected by vhost_scsi->dev.mutex */ + atomic_t vhost_ref_cnt; + struct tcm_vhost_tpg *vs_tpg; struct vhost_dev dev; struct vhost_virtqueue vqs[3]; @@ -136,7 +131,8 @@ static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg) return 1; } -static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg, +static u32 tcm_vhost_get_pr_transport_id( + struct se_portal_group *se_tpg, struct se_node_acl *se_nacl, struct t10_pr_registration *pr_reg, int *format_code, @@ -166,7 +162,8 @@ static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg, format_code, buf); } -static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg, +static u32 tcm_vhost_get_pr_transport_id_len( + struct se_portal_group *se_tpg, struct se_node_acl *se_nacl, struct t10_pr_registration *pr_reg, int *format_code) @@ -195,7 +192,8 @@ static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg, format_code); } -static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg, +static char *tcm_vhost_parse_pr_out_transport_id( + struct se_portal_group *se_tpg, const char *buf, u32 *out_tid_len, char **port_nexus_ptr) @@ -238,7 +236,8 @@ static struct se_node_acl *tcm_vhost_alloc_fabric_acl( return &nacl->se_node_acl; } -static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg, +static void tcm_vhost_release_fabric_acl( + struct se_portal_group *se_tpg, struct se_node_acl *se_nacl) { struct tcm_vhost_nacl *nacl = container_of(se_nacl, @@ -298,16 +297,7 @@ static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd) return 0; } -static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd) -{ - struct vhost_scsi *vs = tv_cmd->tvc_vhost; - - spin_lock_bh(&vs->vs_completion_lock); - list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list); - spin_unlock_bh(&vs->vs_completion_lock); - - vhost_work_queue(&vs->dev, &vs->vs_completion_work); -} +static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *); static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd) { @@ -391,7 +381,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) vs_completion_work); struct tcm_vhost_cmd *tv_cmd; - while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs))) { + while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs)) != NULL) { struct virtio_scsi_cmd_resp v_rsp; struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; int ret; @@ -418,6 +408,19 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) vhost_signal(&vs->dev, &vs->vqs[2]); } +static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd) +{ + struct vhost_scsi *vs = tv_cmd->tvc_vhost; + + pr_debug("%s tv_cmd %p\n", __func__, tv_cmd); + + spin_lock_bh(&vs->vs_completion_lock); + list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list); + spin_unlock_bh(&vs->vs_completion_lock); + + vhost_work_queue(&vs->dev, &vs->vs_completion_work); +} + static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( struct tcm_vhost_tpg *tv_tpg, struct virtio_scsi_cmd_req *v_req, @@ -530,8 +533,8 @@ static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd, sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC); if (!sg) return -ENOMEM; - pr_debug("%s sg %p sgl_count %u is_err %d\n", __func__, - sg, sgl_count, !sg); + pr_debug("%s sg %p sgl_count %u is_err %ld\n", __func__, + sg, sgl_count, IS_ERR(sg)); sg_init_table(sg, sgl_count); tv_cmd->tvc_sgl = sg; @@ -784,12 +787,12 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs) static void vhost_scsi_ctl_handle_kick(struct vhost_work *work) { - pr_debug("%s: The handling func for control queue.\n", __func__); + pr_err("%s: The handling func for control queue.\n", __func__); } static void vhost_scsi_evt_handle_kick(struct vhost_work *work) { - pr_debug("%s: The handling func for event queue.\n", __func__); + pr_err("%s: The handling func for event queue.\n", __func__); } static void vhost_scsi_handle_kick(struct vhost_work *work) @@ -822,6 +825,11 @@ static int vhost_scsi_set_endpoint( return -EFAULT; } } + + if (vs->vs_tpg) { + mutex_unlock(&vs->dev.mutex); + return -EEXIST; + } mutex_unlock(&vs->dev.mutex); mutex_lock(&tcm_vhost_mutex); @@ -831,7 +839,7 @@ static int vhost_scsi_set_endpoint( mutex_unlock(&tv_tpg->tv_tpg_mutex); continue; } - if (tv_tpg->tv_tpg_vhost_count != 0) { + if (atomic_read(&tv_tpg->tv_tpg_vhost_count)) { mutex_unlock(&tv_tpg->tv_tpg_mutex); continue; } @@ -839,20 +847,14 @@ static int vhost_scsi_set_endpoint( if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) && (tv_tpg->tport_tpgt == t->vhost_tpgt)) { - tv_tpg->tv_tpg_vhost_count++; + atomic_inc(&tv_tpg->tv_tpg_vhost_count); + smp_mb__after_atomic_inc(); mutex_unlock(&tv_tpg->tv_tpg_mutex); mutex_unlock(&tcm_vhost_mutex); mutex_lock(&vs->dev.mutex); - if (vs->vs_tpg) { - mutex_unlock(&vs->dev.mutex); - mutex_lock(&tv_tpg->tv_tpg_mutex); - tv_tpg->tv_tpg_vhost_count--; - mutex_unlock(&tv_tpg->tv_tpg_mutex); - return -EEXIST; - } - vs->vs_tpg = tv_tpg; + atomic_inc(&vs->vhost_ref_cnt); smp_mb__after_atomic_inc(); mutex_unlock(&vs->dev.mutex); return 0; @@ -869,42 +871,38 @@ static int vhost_scsi_clear_endpoint( { struct tcm_vhost_tport *tv_tport; struct tcm_vhost_tpg *tv_tpg; - int index, ret; + int index; mutex_lock(&vs->dev.mutex); /* Verify that ring has been setup correctly. */ for (index = 0; index < vs->dev.nvqs; ++index) { if (!vhost_vq_access_ok(&vs->vqs[index])) { - ret = -EFAULT; - goto err; + mutex_unlock(&vs->dev.mutex); + return -EFAULT; } } if (!vs->vs_tpg) { - ret = -ENODEV; - goto err; + mutex_unlock(&vs->dev.mutex); + return -ENODEV; } tv_tpg = vs->vs_tpg; tv_tport = tv_tpg->tport; if (strcmp(tv_tport->tport_name, t->vhost_wwpn) || (tv_tpg->tport_tpgt != t->vhost_tpgt)) { + mutex_unlock(&vs->dev.mutex); pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu" " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n", tv_tport->tport_name, tv_tpg->tport_tpgt, t->vhost_wwpn, t->vhost_tpgt); - ret = -EINVAL; - goto err; + return -EINVAL; } - tv_tpg->tv_tpg_vhost_count--; + atomic_dec(&tv_tpg->tv_tpg_vhost_count); vs->vs_tpg = NULL; mutex_unlock(&vs->dev.mutex); return 0; - -err: - mutex_unlock(&vs->dev.mutex); - return ret; } static int vhost_scsi_open(struct inode *inode, struct file *f) @@ -920,9 +918,9 @@ static int vhost_scsi_open(struct inode *inode, struct file *f) INIT_LIST_HEAD(&s->vs_completion_list); spin_lock_init(&s->vs_completion_lock); - s->vqs[VHOST_SCSI_VQ_CTL].handle_kick = vhost_scsi_ctl_handle_kick; - s->vqs[VHOST_SCSI_VQ_EVT].handle_kick = vhost_scsi_evt_handle_kick; - s->vqs[VHOST_SCSI_VQ_IO].handle_kick = vhost_scsi_handle_kick; + s->vqs[0].handle_kick = vhost_scsi_ctl_handle_kick; + s->vqs[1].handle_kick = vhost_scsi_evt_handle_kick; + s->vqs[2].handle_kick = vhost_scsi_handle_kick; r = vhost_dev_init(&s->dev, s->vqs, 3); if (r < 0) { kfree(s); @@ -951,18 +949,6 @@ static int vhost_scsi_release(struct inode *inode, struct file *f) return 0; } -static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index) -{ - vhost_poll_flush(&vs->dev.vqs[index].poll); -} - -static void vhost_scsi_flush(struct vhost_scsi *vs) -{ - vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_CTL); - vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_EVT); - vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_IO); -} - static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) { if (features & ~VHOST_FEATURES) @@ -975,8 +961,7 @@ static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) return -EFAULT; } vs->dev.acked_features = features; - smp_wmb(); - vhost_scsi_flush(vs); + /* TODO possibly smp_wmb() and flush vqs */ mutex_unlock(&vs->dev.mutex); return 0; } @@ -989,25 +974,26 @@ static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, void __user *argp = (void __user *)arg; u64 __user *featurep = argp; u64 features; - int r, abi_version = VHOST_SCSI_ABI_VERSION; + int r; switch (ioctl) { case VHOST_SCSI_SET_ENDPOINT: if (copy_from_user(&backend, argp, sizeof backend)) return -EFAULT; - if (backend.reserved != 0) - return -EOPNOTSUPP; return vhost_scsi_set_endpoint(vs, &backend); case VHOST_SCSI_CLEAR_ENDPOINT: if (copy_from_user(&backend, argp, sizeof backend)) return -EFAULT; - if (backend.reserved != 0) - return -EOPNOTSUPP; return vhost_scsi_clear_endpoint(vs, &backend); case VHOST_SCSI_GET_ABI_VERSION: - if (copy_to_user(argp, &abi_version, sizeof abi_version)) + if (copy_from_user(&backend, argp, sizeof backend)) + return -EFAULT; + + backend.abi_version = VHOST_SCSI_ABI_VERSION; + + if (copy_to_user(argp, &backend, sizeof backend)) return -EFAULT; return 0; case VHOST_GET_FEATURES: @@ -1027,21 +1013,11 @@ static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, } } -#ifdef CONFIG_COMPAT -static long vhost_scsi_compat_ioctl(struct file *f, unsigned int ioctl, - unsigned long arg) -{ - return vhost_scsi_ioctl(f, ioctl, (unsigned long)compat_ptr(arg)); -} -#endif - static const struct file_operations vhost_scsi_fops = { .owner = THIS_MODULE, .release = vhost_scsi_release, .unlocked_ioctl = vhost_scsi_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = vhost_scsi_compat_ioctl, -#endif + /* TODO compat ioctl? */ .open = vhost_scsi_open, .llseek = noop_llseek, }; @@ -1078,28 +1054,28 @@ static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport) return "Unknown"; } -static int tcm_vhost_port_link(struct se_portal_group *se_tpg, +static int tcm_vhost_port_link( + struct se_portal_group *se_tpg, struct se_lun *lun) { struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, struct tcm_vhost_tpg, se_tpg); - mutex_lock(&tv_tpg->tv_tpg_mutex); - tv_tpg->tv_tpg_port_count++; - mutex_unlock(&tv_tpg->tv_tpg_mutex); + atomic_inc(&tv_tpg->tv_tpg_port_count); + smp_mb__after_atomic_inc(); return 0; } -static void tcm_vhost_port_unlink(struct se_portal_group *se_tpg, +static void tcm_vhost_port_unlink( + struct se_portal_group *se_tpg, struct se_lun *se_lun) { struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, struct tcm_vhost_tpg, se_tpg); - mutex_lock(&tv_tpg->tv_tpg_mutex); - tv_tpg->tv_tpg_port_count--; - mutex_unlock(&tv_tpg->tv_tpg_mutex); + atomic_dec(&tv_tpg->tv_tpg_port_count); + smp_mb__after_atomic_dec(); } static struct se_node_acl *tcm_vhost_make_nodeacl( @@ -1146,7 +1122,8 @@ static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl) kfree(nacl); } -static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, +static int tcm_vhost_make_nexus( + struct tcm_vhost_tpg *tv_tpg, const char *name) { struct se_portal_group *se_tpg; @@ -1191,7 +1168,7 @@ static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, return -ENOMEM; } /* - * Now register the TCM vhost virtual I_T Nexus as active with the + * Now register the TCM vHost virtual I_T Nexus as active with the * call to __transport_register_session() */ __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, @@ -1202,7 +1179,8 @@ static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, return 0; } -static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg) +static int tcm_vhost_drop_nexus( + struct tcm_vhost_tpg *tpg) { struct se_session *se_sess; struct tcm_vhost_nexus *tv_nexus; @@ -1220,27 +1198,27 @@ static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg) return -ENODEV; } - if (tpg->tv_tpg_port_count != 0) { + if (atomic_read(&tpg->tv_tpg_port_count)) { mutex_unlock(&tpg->tv_tpg_mutex); - pr_err("Unable to remove TCM_vhost I_T Nexus with" + pr_err("Unable to remove TCM_vHost I_T Nexus with" " active TPG port count: %d\n", - tpg->tv_tpg_port_count); - return -EBUSY; + atomic_read(&tpg->tv_tpg_port_count)); + return -EPERM; } - if (tpg->tv_tpg_vhost_count != 0) { + if (atomic_read(&tpg->tv_tpg_vhost_count)) { mutex_unlock(&tpg->tv_tpg_mutex); - pr_err("Unable to remove TCM_vhost I_T Nexus with" + pr_err("Unable to remove TCM_vHost I_T Nexus with" " active TPG vhost count: %d\n", - tpg->tv_tpg_vhost_count); - return -EBUSY; + atomic_read(&tpg->tv_tpg_vhost_count)); + return -EPERM; } - pr_debug("TCM_vhost_ConfigFS: Removing I_T Nexus to emulated" + pr_debug("TCM_vHost_ConfigFS: Removing I_T Nexus to emulated" " %s Initiator Port: %s\n", tcm_vhost_dump_proto_id(tpg->tport), tv_nexus->tvn_se_sess->se_node_acl->initiatorname); /* - * Release the SCSI I_T Nexus to the emulated vhost Target Port + * Release the SCSI I_T Nexus to the emulated vHost Target Port */ transport_deregister_session(tv_nexus->tvn_se_sess); tpg->tpg_nexus = NULL; @@ -1250,7 +1228,8 @@ static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg) return 0; } -static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg, +static ssize_t tcm_vhost_tpg_show_nexus( + struct se_portal_group *se_tpg, char *page) { struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, @@ -1271,7 +1250,8 @@ static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg, return ret; } -static ssize_t tcm_vhost_tpg_store_nexus(struct se_portal_group *se_tpg, +static ssize_t tcm_vhost_tpg_store_nexus( + struct se_portal_group *se_tpg, const char *page, size_t count) { @@ -1356,7 +1336,8 @@ static struct configfs_attribute *tcm_vhost_tpg_attrs[] = { NULL, }; -static struct se_portal_group *tcm_vhost_make_tpg(struct se_wwn *wwn, +static struct se_portal_group *tcm_vhost_make_tpg( + struct se_wwn *wwn, struct config_group *group, const char *name) { @@ -1404,7 +1385,7 @@ static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg) list_del(&tpg->tv_tpg_list); mutex_unlock(&tcm_vhost_mutex); /* - * Release the virtual I_T Nexus for this vhost TPG + * Release the virtual I_T Nexus for this vHost TPG */ tcm_vhost_drop_nexus(tpg); /* @@ -1414,7 +1395,8 @@ static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg) kfree(tpg); } -static struct se_wwn *tcm_vhost_make_tport(struct target_fabric_configfs *tf, +static struct se_wwn *tcm_vhost_make_tport( + struct target_fabric_configfs *tf, struct config_group *group, const char *name) { @@ -1610,10 +1592,7 @@ static void tcm_vhost_deregister_configfs(void) static int __init tcm_vhost_init(void) { int ret = -ENOMEM; - /* - * Use our own dedicated workqueue for submitting I/O into - * target core to avoid contention within system_wq. - */ + tcm_vhost_workqueue = alloc_workqueue("tcm_vhost", 0, 0); if (!tcm_vhost_workqueue) goto out; diff --git a/trunk/drivers/vhost/tcm_vhost.h b/trunk/drivers/vhost/tcm_vhost.h index d9e93557d669..c983ed21e413 100644 --- a/trunk/drivers/vhost/tcm_vhost.h +++ b/trunk/drivers/vhost/tcm_vhost.h @@ -47,9 +47,9 @@ struct tcm_vhost_tpg { /* Vhost port target portal group tag for TCM */ u16 tport_tpgt; /* Used to track number of TPG Port/Lun Links wrt to explict I_T Nexus shutdown */ - int tv_tpg_port_count; - /* Used for vhost_scsi device reference to tpg_nexus, protected by tv_tpg_mutex */ - int tv_tpg_vhost_count; + atomic_t tv_tpg_port_count; + /* Used for vhost_scsi device reference to tpg_nexus */ + atomic_t tv_tpg_vhost_count; /* list for tcm_vhost_list */ struct list_head tv_tpg_list; /* Used to protect access for tpg_nexus */ @@ -91,13 +91,11 @@ struct tcm_vhost_tport { struct vhost_scsi_target { int abi_version; - char vhost_wwpn[TRANSPORT_IQN_LEN]; + unsigned char vhost_wwpn[TRANSPORT_IQN_LEN]; unsigned short vhost_tpgt; - unsigned short reserved; }; /* VHOST_SCSI specific defines */ #define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) -/* Changing this breaks userspace. */ -#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int) +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct vhost_scsi_target) diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 88e92041d8f0..f8a79fca4a22 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -374,9 +374,6 @@ static void fb_flashcursor(struct work_struct *work) int mode; int ret; - /* FIXME: we should sort out the unbind locking instead */ - /* instead we just fail to flash the cursor if we can't get - * the lock instead of blocking fbcon deinit */ ret = console_trylock(); if (ret == 0) return; diff --git a/trunk/fs/ceph/debugfs.c b/trunk/fs/ceph/debugfs.c index 6d59006bfa27..fb962efdacee 100644 --- a/trunk/fs/ceph/debugfs.c +++ b/trunk/fs/ceph/debugfs.c @@ -201,7 +201,6 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) int err = -ENOMEM; dout("ceph_fs_debugfs_init\n"); - BUG_ON(!fsc->client->debugfs_dir); fsc->debugfs_congestion_kb = debugfs_create_file("writeback_congestion_kb", 0600, diff --git a/trunk/fs/ceph/inode.c b/trunk/fs/ceph/inode.c index 4b5762ef7c2b..9fff9f3b17e4 100644 --- a/trunk/fs/ceph/inode.c +++ b/trunk/fs/ceph/inode.c @@ -992,15 +992,11 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, if (rinfo->head->is_dentry) { struct inode *dir = req->r_locked_dir; - if (dir) { - err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, - session, req->r_request_started, -1, - &req->r_caps_reservation); - if (err < 0) - return err; - } else { - WARN_ON_ONCE(1); - } + err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, + session, req->r_request_started, -1, + &req->r_caps_reservation); + if (err < 0) + return err; } /* @@ -1008,7 +1004,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, * will have trouble splicing in the virtual snapdir later */ if (rinfo->head->is_dentry && !req->r_aborted && - req->r_locked_dir && (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name, fsc->mount_options->snapdir_name, req->r_dentry->d_name.len))) { diff --git a/trunk/fs/ceph/ioctl.c b/trunk/fs/ceph/ioctl.c index 1396ceb46797..8e3fb69fbe62 100644 --- a/trunk/fs/ceph/ioctl.c +++ b/trunk/fs/ceph/ioctl.c @@ -42,8 +42,7 @@ static long __validate_layout(struct ceph_mds_client *mdsc, /* validate striping parameters */ if ((l->object_size & ~PAGE_MASK) || (l->stripe_unit & ~PAGE_MASK) || - (l->stripe_unit != 0 && - ((unsigned)l->object_size % (unsigned)l->stripe_unit))) + ((unsigned)l->object_size % (unsigned)l->stripe_unit)) return -EINVAL; /* make sure it's a valid data pool */ diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index eedec84c1809..1c8b55670804 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1654,8 +1654,8 @@ SYSCALL_DEFINE1(epoll_create1, int, flags) error = PTR_ERR(file); goto out_free_fd; } - ep->file = file; fd_install(fd, file); + ep->file = file; return fd; out_free_fd: diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index a856e7f7b6e3..db76b866a097 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -352,7 +352,6 @@ int __inode_permission(struct inode *inode, int mask) /** * sb_permission - Check superblock-level permissions * @sb: Superblock of inode to check permission on - * @inode: Inode to check permission on * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) * * Separate out file-system wide checks from inode-specific permission checks. @@ -657,7 +656,6 @@ int sysctl_protected_hardlinks __read_mostly = 1; /** * may_follow_link - Check symlink following for unsafe situations * @link: The path of the symlink - * @nd: nameidata pathwalk data * * In the case of the sysctl_protected_symlinks sysctl being enabled, * CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is @@ -680,7 +678,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) /* Allowed if owner and follower match. */ inode = link->dentry->d_inode; - if (uid_eq(current_cred()->fsuid, inode->i_uid)) + if (current_cred()->fsuid == inode->i_uid) return 0; /* Allowed if parent directory not sticky and world-writable. */ @@ -689,7 +687,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) return 0; /* Allowed if parent directory and link owner match. */ - if (uid_eq(parent->i_uid, inode->i_uid)) + if (parent->i_uid == inode->i_uid) return 0; path_put_conditional(link, nd); @@ -759,7 +757,7 @@ static int may_linkat(struct path *link) /* Source inode owner (or CAP_FOWNER) can hardlink all they like, * otherwise, it must be a safe source. */ - if (uid_eq(cred->fsuid, inode->i_uid) || safe_hardlink_source(inode) || + if (cred->fsuid == inode->i_uid || safe_hardlink_source(inode) || capable(CAP_FOWNER)) return 0; diff --git a/trunk/fs/nfs/Makefile b/trunk/fs/nfs/Makefile index b7db60897f91..8bf3a3f6925a 100644 --- a/trunk/fs/nfs/Makefile +++ b/trunk/fs/nfs/Makefile @@ -12,19 +12,19 @@ nfs-$(CONFIG_ROOT_NFS) += nfsroot.o nfs-$(CONFIG_SYSCTL) += sysctl.o nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o -obj-$(CONFIG_NFS_V2) += nfsv2.o -nfsv2-y := nfs2super.o proc.o nfs2xdr.o +obj-$(CONFIG_NFS_V2) += nfs2.o +nfs2-y := nfs2super.o proc.o nfs2xdr.o -obj-$(CONFIG_NFS_V3) += nfsv3.o -nfsv3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o -nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o +obj-$(CONFIG_NFS_V3) += nfs3.o +nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o +nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o -obj-$(CONFIG_NFS_V4) += nfsv4.o -nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \ +obj-$(CONFIG_NFS_V4) += nfs4.o +nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \ delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \ nfs4namespace.o nfs4getroot.o nfs4client.o -nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o -nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o +nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o +nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index 99694442b93f..9fc0d9dfc91b 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -105,7 +105,7 @@ struct nfs_subversion *get_nfs_version(unsigned int version) if (IS_ERR(nfs)) { mutex_lock(&nfs_version_mutex); - request_module("nfsv%d", version); + request_module("nfs%d", version); nfs = find_nfs_version(version); mutex_unlock(&nfs_version_mutex); } diff --git a/trunk/fs/nfs/idmap.c b/trunk/fs/nfs/idmap.c index a850079467d8..b701358c39c3 100644 --- a/trunk/fs/nfs/idmap.c +++ b/trunk/fs/nfs/idmap.c @@ -61,12 +61,6 @@ struct idmap { struct mutex idmap_mutex; }; -struct idmap_legacy_upcalldata { - struct rpc_pipe_msg pipe_msg; - struct idmap_msg idmap_msg; - struct idmap *idmap; -}; - /** * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields * @fattr: fully initialised struct nfs_fattr @@ -330,7 +324,6 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, name, namelen, type, data, data_size, idmap); - idmap->idmap_key_cons = NULL; mutex_unlock(&idmap->idmap_mutex); } return ret; @@ -387,13 +380,11 @@ static const match_table_t nfs_idmap_tokens = { static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); static ssize_t idmap_pipe_downcall(struct file *, const char __user *, size_t); -static void idmap_release_pipe(struct inode *); static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); static const struct rpc_pipe_ops idmap_upcall_ops = { .upcall = rpc_pipe_generic_upcall, .downcall = idmap_pipe_downcall, - .release_pipe = idmap_release_pipe, .destroy_msg = idmap_pipe_destroy_msg, }; @@ -625,8 +616,7 @@ void nfs_idmap_quit(void) nfs_idmap_quit_keyring(); } -static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap, - struct idmap_msg *im, +static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im, struct rpc_pipe_msg *msg) { substring_t substr; @@ -669,7 +659,6 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, const char *op, void *aux) { - struct idmap_legacy_upcalldata *data; struct rpc_pipe_msg *msg; struct idmap_msg *im; struct idmap *idmap = (struct idmap *)aux; @@ -677,15 +666,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, int ret = -ENOMEM; /* msg and im are freed in idmap_pipe_destroy_msg */ - data = kmalloc(sizeof(*data), GFP_KERNEL); - if (!data) - goto out1; + msg = kmalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) + goto out0; - msg = &data->pipe_msg; - im = &data->idmap_msg; - data->idmap = idmap; + im = kmalloc(sizeof(*im), GFP_KERNEL); + if (!im) + goto out1; - ret = nfs_idmap_prepare_message(key->description, idmap, im, msg); + ret = nfs_idmap_prepare_message(key->description, im, msg); if (ret < 0) goto out2; @@ -694,15 +683,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, ret = rpc_queue_upcall(idmap->idmap_pipe, msg); if (ret < 0) - goto out3; + goto out2; return ret; -out3: - idmap->idmap_key_cons = NULL; out2: - kfree(data); + kfree(im); out1: + kfree(msg); +out0: complete_request_key(cons, ret); return ret; } @@ -760,8 +749,9 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) } if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { - ret = -ENOKEY; - goto out; + ret = mlen; + complete_request_key(cons, -ENOKEY); + goto out_incomplete; } namelen_in = strnlen(im.im_name, IDMAP_NAMESZ); @@ -778,32 +768,16 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) out: complete_request_key(cons, ret); +out_incomplete: return ret; } static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) { - struct idmap_legacy_upcalldata *data = container_of(msg, - struct idmap_legacy_upcalldata, - pipe_msg); - struct idmap *idmap = data->idmap; - struct key_construction *cons; - if (msg->errno) { - cons = ACCESS_ONCE(idmap->idmap_key_cons); - idmap->idmap_key_cons = NULL; - complete_request_key(cons, msg->errno); - } /* Free memory allocated in nfs_idmap_legacy_upcall() */ - kfree(data); -} - -static void -idmap_release_pipe(struct inode *inode) -{ - struct rpc_inode *rpci = RPC_I(inode); - struct idmap *idmap = (struct idmap *)rpci->private; - idmap->idmap_key_cons = NULL; + kfree(msg->data); + kfree(msg); } int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) diff --git a/trunk/fs/nfs/nfs3proc.c b/trunk/fs/nfs/nfs3proc.c index d6b3b5f2d779..0952c791df36 100644 --- a/trunk/fs/nfs/nfs3proc.c +++ b/trunk/fs/nfs/nfs3proc.c @@ -69,7 +69,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle, nfs_fattr_init(info->fattr); status = rpc_call_sync(client, &msg, 0); dprintk("%s: reply fsinfo: %d\n", __func__, status); - if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) { + if (!(info->fattr->valid & NFS_ATTR_FATTR)) { msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; msg.rpc_resp = info->fattr; status = rpc_call_sync(client, &msg, 0); diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index da0618aeeadb..3b950dd81e81 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -205,9 +205,6 @@ extern const struct dentry_operations nfs4_dentry_operations; int nfs_atomic_open(struct inode *, struct dentry *, struct file *, unsigned, umode_t, int *); -/* super.c */ -extern struct file_system_type nfs4_fs_type; - /* nfs4namespace.c */ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); diff --git a/trunk/fs/nfs/nfs4client.c b/trunk/fs/nfs/nfs4client.c index 24eb663f8ed5..cbcdfaf32505 100644 --- a/trunk/fs/nfs/nfs4client.c +++ b/trunk/fs/nfs/nfs4client.c @@ -74,7 +74,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) return clp; error: - nfs_free_client(clp); + kfree(clp); return ERR_PTR(err); } diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 635274140b18..a99a8d948721 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -3737,10 +3737,9 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) { struct nfs4_cached_acl *acl; - size_t buflen = sizeof(*acl) + acl_len; - if (pages && buflen <= PAGE_SIZE) { - acl = kmalloc(buflen, GFP_KERNEL); + if (pages && acl_len <= PAGE_SIZE) { + acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL); if (acl == NULL) goto out; acl->cached = 1; @@ -3820,7 +3819,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu if (ret) goto out_free; - acl_len = res.acl_len; + acl_len = res.acl_len - res.acl_data_offset; if (acl_len > args.acl_len) nfs4_write_cached_acl(inode, NULL, 0, acl_len); else @@ -6224,58 +6223,11 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) dprintk("<-- %s\n", __func__); } -static size_t max_response_pages(struct nfs_server *server) -{ - u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; - return nfs_page_array_len(0, max_resp_sz); -} - -static void nfs4_free_pages(struct page **pages, size_t size) -{ - int i; - - if (!pages) - return; - - for (i = 0; i < size; i++) { - if (!pages[i]) - break; - __free_page(pages[i]); - } - kfree(pages); -} - -static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags) -{ - struct page **pages; - int i; - - pages = kcalloc(size, sizeof(struct page *), gfp_flags); - if (!pages) { - dprintk("%s: can't alloc array of %zu pages\n", __func__, size); - return NULL; - } - - for (i = 0; i < size; i++) { - pages[i] = alloc_page(gfp_flags); - if (!pages[i]) { - dprintk("%s: failed to allocate page\n", __func__); - nfs4_free_pages(pages, size); - return NULL; - } - } - - return pages; -} - static void nfs4_layoutget_release(void *calldata) { struct nfs4_layoutget *lgp = calldata; - struct nfs_server *server = NFS_SERVER(lgp->args.inode); - size_t max_pages = max_response_pages(server); dprintk("--> %s\n", __func__); - nfs4_free_pages(lgp->args.layout.pages, max_pages); put_nfs_open_context(lgp->args.ctx); kfree(calldata); dprintk("<-- %s\n", __func__); @@ -6287,10 +6239,9 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = { .rpc_release = nfs4_layoutget_release, }; -void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) +int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) { struct nfs_server *server = NFS_SERVER(lgp->args.inode); - size_t max_pages = max_response_pages(server); struct rpc_task *task; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET], @@ -6308,19 +6259,12 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) dprintk("--> %s\n", __func__); - lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); - if (!lgp->args.layout.pages) { - nfs4_layoutget_release(lgp); - return; - } - lgp->args.layout.pglen = max_pages * PAGE_SIZE; - lgp->res.layoutp = &lgp->args.layout; lgp->res.seq_res.sr_slot = NULL; nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) - return; + return PTR_ERR(task); status = nfs4_wait_for_completion_rpc_task(task); if (status == 0) status = task->tk_status; @@ -6328,7 +6272,7 @@ void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) status = pnfs_layout_process(lgp); rpc_put_task(task); dprintk("<-- %s status=%d\n", __func__, status); - return; + return status; } static void @@ -6360,8 +6304,12 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) return; } spin_lock(&lo->plh_inode->i_lock); - if (task->tk_status == 0 && lrp->res.lrs_present) - pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); + if (task->tk_status == 0) { + if (lrp->res.lrs_present) { + pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); + } else + BUG_ON(!list_empty(&lo->plh_segs)); + } lo->plh_block_lgets--; spin_unlock(&lo->plh_inode->i_lock); dprintk("<-- %s\n", __func__); diff --git a/trunk/fs/nfs/nfs4super.c b/trunk/fs/nfs/nfs4super.c index bd61221ad2c5..12a31a9dbcdd 100644 --- a/trunk/fs/nfs/nfs4super.c +++ b/trunk/fs/nfs/nfs4super.c @@ -23,6 +23,14 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data); +static struct file_system_type nfs4_fs_type = { + .owner = THIS_MODULE, + .name = "nfs4", + .mount = nfs_fs_mount, + .kill_sb = nfs_kill_super, + .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, +}; + static struct file_system_type nfs4_remote_fs_type = { .owner = THIS_MODULE, .name = "nfs4", @@ -336,8 +344,14 @@ static int __init init_nfs_v4(void) if (err) goto out1; + err = register_filesystem(&nfs4_fs_type); + if (err < 0) + goto out2; + register_nfs_version(&nfs_v4); return 0; +out2: + nfs4_unregister_sysctl(); out1: nfs_idmap_quit(); out: @@ -347,6 +361,7 @@ static int __init init_nfs_v4(void) static void __exit exit_nfs_v4(void) { unregister_nfs_version(&nfs_v4); + unregister_filesystem(&nfs4_fs_type); nfs4_unregister_sysctl(); nfs_idmap_quit(); } diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index 1bfbd67c556d..ca13483edd60 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -5045,19 +5045,22 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_getaclres *res) { unsigned int savep; + __be32 *bm_p; uint32_t attrlen, bitmap[3] = {0}; int status; - unsigned int pg_offset; + size_t page_len = xdr->buf->page_len; res->acl_len = 0; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) goto out; - xdr_enter_page(xdr, xdr->buf->page_len); - - /* Calculate the offset of the page data */ - pg_offset = xdr->buf->head[0].iov_len; + bm_p = xdr->p; + res->acl_data_offset = be32_to_cpup(bm_p) + 2; + res->acl_data_offset <<= 2; + /* Check if the acl data starts beyond the allocated buffer */ + if (res->acl_data_offset > page_len) + return -ERANGE; if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) goto out; @@ -5071,20 +5074,23 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, /* The bitmap (xdr len + bitmaps) and the attr xdr len words * are stored with the acl data to handle the problem of * variable length bitmaps.*/ - res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; + xdr->p = bm_p; /* We ignore &savep and don't do consistency checks on * the attr length. Let userspace figure it out.... */ - res->acl_len = attrlen; - if (attrlen > (xdr->nwords << 2)) { + attrlen += res->acl_data_offset; + if (attrlen > page_len) { if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { /* getxattr interface called with a NULL buf */ + res->acl_len = attrlen; goto out; } - dprintk("NFS: acl reply: attrlen %u > page_len %u\n", - attrlen, xdr->nwords << 2); + dprintk("NFS: acl reply: attrlen %u > page_len %zu\n", + attrlen, page_len); return -EINVAL; } + xdr_read_pages(xdr, attrlen); + res->acl_len = attrlen; } else status = -EOPNOTSUPP; diff --git a/trunk/fs/nfs/objlayout/objio_osd.c b/trunk/fs/nfs/objlayout/objio_osd.c index ea6d111b03e9..f50d3e8d6f22 100644 --- a/trunk/fs/nfs/objlayout/objio_osd.c +++ b/trunk/fs/nfs/objlayout/objio_osd.c @@ -570,66 +570,17 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, return false; return pgio->pg_count + req->wb_bytes <= - (unsigned long)pgio->pg_layout_private; -} - -void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) -{ - pnfs_generic_pg_init_read(pgio, req); - if (unlikely(pgio->pg_lseg == NULL)) - return; /* Not pNFS */ - - pgio->pg_layout_private = (void *) - OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; -} - -static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout, - unsigned long *stripe_end) -{ - u32 stripe_off; - unsigned stripe_size; - - if (layout->raid_algorithm == PNFS_OSD_RAID_0) - return true; - - stripe_size = layout->stripe_unit * - (layout->group_width - layout->parity); - - div_u64_rem(offset, stripe_size, &stripe_off); - if (!stripe_off) - return true; - - *stripe_end = stripe_size - stripe_off; - return false; -} - -void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) -{ - unsigned long stripe_end = 0; - - pnfs_generic_pg_init_write(pgio, req); - if (unlikely(pgio->pg_lseg == NULL)) - return; /* Not pNFS */ - - if (req->wb_offset || - !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE, - &OBJIO_LSEG(pgio->pg_lseg)->layout, - &stripe_end)) { - pgio->pg_layout_private = (void *)stripe_end; - } else { - pgio->pg_layout_private = (void *) - OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; - } + OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; } static const struct nfs_pageio_ops objio_pg_read_ops = { - .pg_init = objio_init_read, + .pg_init = pnfs_generic_pg_init_read, .pg_test = objio_pg_test, .pg_doio = pnfs_generic_pg_readpages, }; static const struct nfs_pageio_ops objio_pg_write_ops = { - .pg_init = objio_init_write, + .pg_init = pnfs_generic_pg_init_write, .pg_test = objio_pg_test, .pg_doio = pnfs_generic_pg_writepages, }; diff --git a/trunk/fs/nfs/pagelist.c b/trunk/fs/nfs/pagelist.c index 311a79681e2b..1a6732ed04a4 100644 --- a/trunk/fs/nfs/pagelist.c +++ b/trunk/fs/nfs/pagelist.c @@ -49,7 +49,6 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, hdr->io_start = req_offset(hdr->req); hdr->good_bytes = desc->pg_count; hdr->dreq = desc->pg_dreq; - hdr->layout_private = desc->pg_layout_private; hdr->release = release; hdr->completion_ops = desc->pg_completion_ops; if (hdr->completion_ops->init_hdr) @@ -269,7 +268,6 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, desc->pg_error = 0; desc->pg_lseg = NULL; desc->pg_dreq = NULL; - desc->pg_layout_private = NULL; } EXPORT_SYMBOL_GPL(nfs_pageio_init); diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 2e00feacd4be..76875bfcf19c 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -583,6 +583,9 @@ send_layoutget(struct pnfs_layout_hdr *lo, struct nfs_server *server = NFS_SERVER(ino); struct nfs4_layoutget *lgp; struct pnfs_layout_segment *lseg = NULL; + struct page **pages = NULL; + int i; + u32 max_resp_sz, max_pages; dprintk("--> %s\n", __func__); @@ -591,6 +594,20 @@ send_layoutget(struct pnfs_layout_hdr *lo, if (lgp == NULL) return NULL; + /* allocate pages for xdr post processing */ + max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; + max_pages = nfs_page_array_len(0, max_resp_sz); + + pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); + if (!pages) + goto out_err_free; + + for (i = 0; i < max_pages; i++) { + pages[i] = alloc_page(gfp_flags); + if (!pages[i]) + goto out_err_free; + } + lgp->args.minlength = PAGE_CACHE_SIZE; if (lgp->args.minlength > range->length) lgp->args.minlength = range->length; @@ -599,19 +616,39 @@ send_layoutget(struct pnfs_layout_hdr *lo, lgp->args.type = server->pnfs_curr_ld->id; lgp->args.inode = ino; lgp->args.ctx = get_nfs_open_context(ctx); + lgp->args.layout.pages = pages; + lgp->args.layout.pglen = max_pages * PAGE_SIZE; lgp->lsegpp = &lseg; lgp->gfp_flags = gfp_flags; /* Synchronously retrieve layout information from server and * store in lseg. */ - nfs4_proc_layoutget(lgp, gfp_flags); + nfs4_proc_layoutget(lgp); if (!lseg) { /* remember that LAYOUTGET failed and suspend trying */ set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); } + /* free xdr pages */ + for (i = 0; i < max_pages; i++) + __free_page(pages[i]); + kfree(pages); + return lseg; + +out_err_free: + /* free any allocated xdr pages, lgp as it's not used */ + if (pages) { + for (i = 0; i < max_pages; i++) { + if (!pages[i]) + break; + __free_page(pages[i]); + } + kfree(pages); + } + kfree(lgp); + return NULL; } /* diff --git a/trunk/fs/nfs/pnfs.h b/trunk/fs/nfs/pnfs.h index 745aa1b39e7c..2c6c80503ba4 100644 --- a/trunk/fs/nfs/pnfs.h +++ b/trunk/fs/nfs/pnfs.h @@ -172,7 +172,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server, struct pnfs_devicelist *devlist); extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *dev); -extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags); +extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); /* pnfs.c */ diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 239aff7338eb..ac6a3c55dce4 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -319,34 +319,6 @@ EXPORT_SYMBOL_GPL(nfs_sops); static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); static int nfs4_validate_mount_data(void *options, struct nfs_parsed_mount_data *args, const char *dev_name); - -struct file_system_type nfs4_fs_type = { - .owner = THIS_MODULE, - .name = "nfs4", - .mount = nfs_fs_mount, - .kill_sb = nfs_kill_super, - .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, -}; -EXPORT_SYMBOL_GPL(nfs4_fs_type); - -static int __init register_nfs4_fs(void) -{ - return register_filesystem(&nfs4_fs_type); -} - -static void unregister_nfs4_fs(void) -{ - unregister_filesystem(&nfs4_fs_type); -} -#else -static int __init register_nfs4_fs(void) -{ - return 0; -} - -static void unregister_nfs4_fs(void) -{ -} #endif static struct shrinker acl_shrinker = { @@ -365,18 +337,12 @@ int __init register_nfs_fs(void) if (ret < 0) goto error_0; - ret = register_nfs4_fs(); - if (ret < 0) - goto error_1; - ret = nfs_register_sysctl(); if (ret < 0) - goto error_2; + goto error_1; register_shrinker(&acl_shrinker); return 0; -error_2: - unregister_nfs4_fs(); error_1: unregister_filesystem(&nfs_fs_type); error_0: @@ -390,7 +356,6 @@ void __exit unregister_nfs_fs(void) { unregister_shrinker(&acl_shrinker); nfs_unregister_sysctl(); - unregister_nfs4_fs(); unregister_filesystem(&nfs_fs_type); } @@ -2680,6 +2645,4 @@ MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 " module_param(send_implementation_id, ushort, 0644); MODULE_PARM_DESC(send_implementation_id, "Send implementation ID with NFSv4.1 exchange_id"); -MODULE_ALIAS("nfs4"); - #endif /* CONFIG_NFS_V4 */ diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index e3b55372726c..5829d0ce7cfb 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -1814,19 +1814,19 @@ int __init nfs_init_writepagecache(void) nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE, nfs_wdata_cachep); if (nfs_wdata_mempool == NULL) - goto out_destroy_write_cache; + return -ENOMEM; nfs_cdata_cachep = kmem_cache_create("nfs_commit_data", sizeof(struct nfs_commit_data), 0, SLAB_HWCACHE_ALIGN, NULL); if (nfs_cdata_cachep == NULL) - goto out_destroy_write_mempool; + return -ENOMEM; nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, nfs_wdata_cachep); if (nfs_commit_mempool == NULL) - goto out_destroy_commit_cache; + return -ENOMEM; /* * NFS congestion size, scale with available memory. @@ -1849,20 +1849,11 @@ int __init nfs_init_writepagecache(void) nfs_congestion_kb = 256*1024; return 0; - -out_destroy_commit_cache: - kmem_cache_destroy(nfs_cdata_cachep); -out_destroy_write_mempool: - mempool_destroy(nfs_wdata_mempool); -out_destroy_write_cache: - kmem_cache_destroy(nfs_wdata_cachep); - return -ENOMEM; } void nfs_destroy_writepagecache(void) { mempool_destroy(nfs_commit_mempool); - kmem_cache_destroy(nfs_cdata_cachep); mempool_destroy(nfs_wdata_mempool); kmem_cache_destroy(nfs_wdata_cachep); } diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index 99dffab4c4e4..14cf9de1dbe1 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -57,9 +56,6 @@ int seq_open(struct file *file, const struct seq_operations *op) memset(p, 0, sizeof(*p)); mutex_init(&p->lock); p->op = op; -#ifdef CONFIG_USER_NS - p->user_ns = file->f_cred->user_ns; -#endif /* * Wrappers around seq_open(e.g. swaps_open) need to be diff --git a/trunk/include/drm/drm_crtc.h b/trunk/include/drm/drm_crtc.h index ced362533e3c..a1a0386e0160 100644 --- a/trunk/include/drm/drm_crtc.h +++ b/trunk/include/drm/drm_crtc.h @@ -166,6 +166,8 @@ struct drm_display_mode { int crtc_vsync_start; int crtc_vsync_end; int crtc_vtotal; + int crtc_hadjusted; + int crtc_vadjusted; /* Driver private mode info */ int private_size; diff --git a/trunk/include/linux/bcma/bcma_driver_chipcommon.h b/trunk/include/linux/bcma/bcma_driver_chipcommon.h index 6ba45d2b99db..3fb8bbafe5e7 100644 --- a/trunk/include/linux/bcma/bcma_driver_chipcommon.h +++ b/trunk/include/linux/bcma/bcma_driver_chipcommon.h @@ -515,26 +515,6 @@ struct bcma_pflash { u32 window_size; }; -#ifdef CONFIG_BCMA_SFLASH -struct bcma_sflash { - bool present; - u32 window; - u32 blocksize; - u16 numblocks; - u32 size; -}; -#endif - -#ifdef CONFIG_BCMA_NFLASH -struct mtd_info; - -struct bcma_nflash { - bool present; - - struct mtd_info *mtd; -}; -#endif - struct bcma_serial_port { void *regs; unsigned long clockspeed; @@ -555,12 +535,6 @@ struct bcma_drv_cc { struct bcma_chipcommon_pmu pmu; #ifdef CONFIG_BCMA_DRIVER_MIPS struct bcma_pflash pflash; -#ifdef CONFIG_BCMA_SFLASH - struct bcma_sflash sflash; -#endif -#ifdef CONFIG_BCMA_NFLASH - struct bcma_nflash nflash; -#endif int nr_serial_ports; struct bcma_serial_port serial_ports[4]; diff --git a/trunk/include/linux/bcma/bcma_regs.h b/trunk/include/linux/bcma/bcma_regs.h index 6c9cb93ae3de..a393e82bf7bf 100644 --- a/trunk/include/linux/bcma/bcma_regs.h +++ b/trunk/include/linux/bcma/bcma_regs.h @@ -85,6 +85,4 @@ * (2 ZettaBytes), high 32 bits */ -#define BCMA_SFLASH 0x1c000000 - #endif /* LINUX_BCMA_REGS_H_ */ diff --git a/trunk/include/linux/if_vlan.h b/trunk/include/linux/if_vlan.h index e6ff12dd717b..a810987cb80e 100644 --- a/trunk/include/linux/if_vlan.h +++ b/trunk/include/linux/if_vlan.h @@ -74,6 +74,8 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) /* found in socket.c */ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); +struct vlan_info; + static inline int is_vlan_dev(struct net_device *dev) { return dev->priv_flags & IFF_802_1Q_VLAN; @@ -99,8 +101,6 @@ extern int vlan_vids_add_by_dev(struct net_device *dev, const struct net_device *by_dev); extern void vlan_vids_del_by_dev(struct net_device *dev, const struct net_device *by_dev); - -extern bool vlan_uses_dev(const struct net_device *dev); #else static inline struct net_device * __vlan_find_dev_deep(struct net_device *real_dev, u16 vlan_id) @@ -151,11 +151,6 @@ static inline void vlan_vids_del_by_dev(struct net_device *dev, const struct net_device *by_dev) { } - -static inline bool vlan_uses_dev(const struct net_device *dev) -{ - return false; -} #endif /** diff --git a/trunk/include/linux/inet_diag.h b/trunk/include/linux/inet_diag.h index e788c186ed3a..f1362b5447fc 100644 --- a/trunk/include/linux/inet_diag.h +++ b/trunk/include/linux/inet_diag.h @@ -159,7 +159,6 @@ struct inet_diag_handler { struct inet_connection_sock; int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, struct sk_buff *skb, struct inet_diag_req_v2 *req, - struct user_namespace *user_ns, u32 pid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh); void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb, diff --git a/trunk/include/linux/kref.h b/trunk/include/linux/kref.h index 65af6887872f..9c07dcebded7 100644 --- a/trunk/include/linux/kref.h +++ b/trunk/include/linux/kref.h @@ -18,7 +18,6 @@ #include #include #include -#include struct kref { atomic_t refcount; @@ -94,21 +93,4 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref) { return kref_sub(kref, 1, release); } - -static inline int kref_put_mutex(struct kref *kref, - void (*release)(struct kref *kref), - struct mutex *lock) -{ - WARN_ON(release == NULL); - if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { - mutex_lock(lock); - if (unlikely(!atomic_dec_and_test(&kref->refcount))) { - mutex_unlock(lock); - return 0; - } - release(kref); - return 1; - } - return 0; -} #endif /* _KREF_H_ */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index ccac82e61604..9ad7fa8c10e0 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -2227,7 +2227,6 @@ static inline void dev_hold(struct net_device *dev) * kind of lower layer not just hardware media. */ -extern void linkwatch_init_dev(struct net_device *dev); extern void linkwatch_fire_event(struct net_device *dev); extern void linkwatch_forget_dev(struct net_device *dev); diff --git a/trunk/include/linux/netlink.h b/trunk/include/linux/netlink.h index c9fdde2bc73f..f74dd133788f 100644 --- a/trunk/include/linux/netlink.h +++ b/trunk/include/linux/netlink.h @@ -165,7 +165,6 @@ struct netlink_skb_parms { struct ucred creds; /* Skb credentials */ __u32 pid; __u32 dst_group; - struct sock *ssk; }; #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) diff --git a/trunk/include/linux/nfs_page.h b/trunk/include/linux/nfs_page.h index 92ce5783b707..880805774f9f 100644 --- a/trunk/include/linux/nfs_page.h +++ b/trunk/include/linux/nfs_page.h @@ -69,7 +69,6 @@ struct nfs_pageio_descriptor { const struct nfs_pgio_completion_ops *pg_completion_ops; struct pnfs_layout_segment *pg_lseg; struct nfs_direct_req *pg_dreq; - void *pg_layout_private; }; #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index ac7c8ae254f2..00485e084394 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -1248,7 +1248,6 @@ struct nfs_pgio_header { void (*release) (struct nfs_pgio_header *hdr); const struct nfs_pgio_completion_ops *completion_ops; struct nfs_direct_req *dreq; - void *layout_private; spinlock_t lock; /* fields protected by lock */ int pnfs_error; diff --git a/trunk/include/linux/nl80211.h b/trunk/include/linux/nl80211.h index 458416279347..2f3878806403 100644 --- a/trunk/include/linux/nl80211.h +++ b/trunk/include/linux/nl80211.h @@ -565,14 +565,6 @@ * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ with * %NL80211_ATTR_WIPHY_CHANNEL_TYPE. * - * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by - * its %NL80211_ATTR_WDEV identifier. It must have been created with - * %NL80211_CMD_NEW_INTERFACE previously. After it has been started, the - * P2P Device can be used for P2P operations, e.g. remain-on-channel and - * public action frame TX. - * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by - * its %NL80211_ATTR_WDEV identifier. - * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -716,9 +708,6 @@ enum nl80211_commands { NL80211_CMD_CH_SWITCH_NOTIFY, - NL80211_CMD_START_P2P_DEVICE, - NL80211_CMD_STOP_P2P_DEVICE, - /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1586,10 +1575,6 @@ enum nl80211_attrs { * @NL80211_IFTYPE_MESH_POINT: mesh point * @NL80211_IFTYPE_P2P_CLIENT: P2P client * @NL80211_IFTYPE_P2P_GO: P2P group owner - * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev - * and therefore can't be created in the normal ways, use the - * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE - * commands to create and destroy one * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NUM_NL80211_IFTYPES: number of defined interface types * @@ -1608,7 +1593,6 @@ enum nl80211_iftype { NL80211_IFTYPE_MESH_POINT, NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_P2P_GO, - NL80211_IFTYPE_P2P_DEVICE, /* keep last */ NUM_NL80211_IFTYPES, @@ -3010,18 +2994,12 @@ enum nl80211_ap_sme_features { * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested * to work properly to suppport receiving regulatory hints from * cellular base stations. - * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active - * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel - * in the interface combinations, even when it's only used for scan - * and remain-on-channel. This could be due to, for example, the - * remain-on-channel implementation requiring a channel context. */ enum nl80211_feature_flags { - NL80211_FEATURE_SK_TX_STATUS = 1 << 0, - NL80211_FEATURE_HT_IBSS = 1 << 1, - NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, - NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, - NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, + NL80211_FEATURE_SK_TX_STATUS = 1 << 0, + NL80211_FEATURE_HT_IBSS = 1 << 1, + NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, + NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, }; /** diff --git a/trunk/include/linux/of_mdio.h b/trunk/include/linux/of_mdio.h index 6ef49b803efb..912c27a0f7ee 100644 --- a/trunk/include/linux/of_mdio.h +++ b/trunk/include/linux/of_mdio.h @@ -12,7 +12,6 @@ #include #include -#ifdef CONFIG_OF extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np); extern struct phy_device *of_phy_find_device(struct device_node *phy_np); extern struct phy_device *of_phy_connect(struct net_device *dev, @@ -25,36 +24,4 @@ extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np); -#else /* CONFIG_OF */ -int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) -{ - return -ENOSYS; -} - -struct phy_device *of_phy_find_device(struct device_node *phy_np) -{ - return NULL; -} - -struct phy_device *of_phy_connect(struct net_device *dev, - struct device_node *phy_np, - void (*hndlr)(struct net_device *), - u32 flags, phy_interface_t iface) -{ - return NULL; -} - -struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, - void (*hndlr)(struct net_device *), - phy_interface_t iface) -{ - return NULL; -} - -struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np) -{ - return NULL; -} -#endif /* CONFIG_OF */ - #endif /* __LINUX_OF_MDIO_H */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 6b4565c440c8..fc3526077348 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2149,7 +2149,7 @@ #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 #define PCI_DEVICE_ID_NX2_57800_VF 0x16a9 #define PCI_DEVICE_ID_NX2_5706S 0x16aa -#define PCI_DEVICE_ID_NX2_57840_MF 0x16a4 +#define PCI_DEVICE_ID_NX2_57840_MF 0x16ab #define PCI_DEVICE_ID_NX2_5708S 0x16ac #define PCI_DEVICE_ID_NX2_57840_VF 0x16ad #define PCI_DEVICE_ID_NX2_57810_MF 0x16ae diff --git a/trunk/include/linux/rfkill.h b/trunk/include/linux/rfkill.h index 0ec590bb3611..6fdf02737e9d 100644 --- a/trunk/include/linux/rfkill.h +++ b/trunk/include/linux/rfkill.h @@ -354,37 +354,6 @@ static inline bool rfkill_blocked(struct rfkill *rfkill) } #endif /* RFKILL || RFKILL_MODULE */ - -#ifdef CONFIG_RFKILL_LEDS -/** - * rfkill_get_led_trigger_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. - */ -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) -{ - 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/seq_file.h b/trunk/include/linux/seq_file.h index 68a04a343cad..83c44eefe698 100644 --- a/trunk/include/linux/seq_file.h +++ b/trunk/include/linux/seq_file.h @@ -13,7 +13,6 @@ struct file; struct path; struct inode; struct dentry; -struct user_namespace; struct seq_file { char *buf; @@ -26,9 +25,6 @@ struct seq_file { struct mutex lock; const struct seq_operations *op; int poll_event; -#ifdef CONFIG_USER_NS - struct user_namespace *user_ns; -#endif void *private; }; @@ -132,16 +128,6 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter, int seq_put_decimal_ll(struct seq_file *m, char delimiter, long long num); -static inline struct user_namespace *seq_user_ns(struct seq_file *seq) -{ -#ifdef CONFIG_USER_NS - return seq->user_ns; -#else - extern struct user_namespace init_user_ns; - return &init_user_ns; -#endif -} - #define SEQ_START_TOKEN ((void *)1) /* * Helpers for iteration over list_head-s in seq_files diff --git a/trunk/include/linux/snmp.h b/trunk/include/linux/snmp.h index fdfba235f9f1..ad6e3a6bf9fb 100644 --- a/trunk/include/linux/snmp.h +++ b/trunk/include/linux/snmp.h @@ -241,10 +241,6 @@ enum LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */ LINUX_MIB_TCPFASTOPENACTIVE, /* TCPFastOpenActive */ - LINUX_MIB_TCPFASTOPENPASSIVE, /* TCPFastOpenPassive*/ - LINUX_MIB_TCPFASTOPENPASSIVEFAIL, /* TCPFastOpenPassiveFail */ - LINUX_MIB_TCPFASTOPENLISTENOVERFLOW, /* TCPFastOpenListenOverflow */ - LINUX_MIB_TCPFASTOPENCOOKIEREQD, /* TCPFastOpenCookieReqd */ __LINUX_MIB_MAX }; diff --git a/trunk/include/linux/stmmac.h b/trunk/include/linux/stmmac.h index a1547ea3920d..b69bdb1e08b6 100644 --- a/trunk/include/linux/stmmac.h +++ b/trunk/include/linux/stmmac.h @@ -76,6 +76,7 @@ /* Platfrom data for platform device structure's platform_data field */ struct stmmac_mdio_bus_data { + int bus_id; int (*phy_reset)(void *priv); unsigned int phy_mask; int *irqs; diff --git a/trunk/include/linux/tcp.h b/trunk/include/linux/tcp.h index ae46df590629..eb125a4c30b3 100644 --- a/trunk/include/linux/tcp.h +++ b/trunk/include/linux/tcp.h @@ -110,7 +110,6 @@ enum { #define TCP_REPAIR_QUEUE 20 #define TCP_QUEUE_SEQ 21 #define TCP_REPAIR_OPTIONS 22 -#define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */ struct tcp_repair_opt { __u32 opt_code; @@ -247,7 +246,6 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb) /* TCP Fast Open */ #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ #define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ -#define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */ /* TCP Fast Open Cookie as stored in memory */ struct tcp_fastopen_cookie { @@ -314,14 +312,9 @@ struct tcp_request_sock { /* Only used by TCP MD5 Signature so far. */ const struct tcp_request_sock_ops *af_specific; #endif - struct sock *listener; /* needed for TFO */ u32 rcv_isn; u32 snt_isn; u32 snt_synack; /* synack sent time */ - u32 rcv_nxt; /* the ack # by SYNACK. For - * FastOpen it's the seq# - * after data-in-SYN. - */ }; static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req) @@ -512,18 +505,14 @@ struct tcp_sock { struct tcp_md5sig_info __rcu *md5sig_info; #endif +/* TCP fastopen related information */ + struct tcp_fastopen_request *fastopen_req; + /* When the cookie options are generated and exchanged, then this * object holds a reference to them (cookie_values->kref). Also * contains related tcp_cookie_transactions fields. */ struct tcp_cookie_values *cookie_values; - -/* TCP fastopen related information */ - struct tcp_fastopen_request *fastopen_req; - /* fastopen_rsk points to request_sock that resulted in this big - * socket. Used to retransmit SYNACKs etc. - */ - struct request_sock *fastopen_rsk; }; enum tsq_flags { @@ -563,34 +552,6 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) return (struct tcp_timewait_sock *)sk; } -static inline bool tcp_passive_fastopen(const struct sock *sk) -{ - return (sk->sk_state == TCP_SYN_RECV && - tcp_sk(sk)->fastopen_rsk != NULL); -} - -static inline bool fastopen_cookie_present(struct tcp_fastopen_cookie *foc) -{ - return foc->len != -1; -} - -static inline int fastopen_init_queue(struct sock *sk, int backlog) -{ - struct request_sock_queue *queue = - &inet_csk(sk)->icsk_accept_queue; - - if (queue->fastopenq == NULL) { - queue->fastopenq = kzalloc( - sizeof(struct fastopen_queue), - sk->sk_allocation); - if (queue->fastopenq == NULL) - return -ENOMEM; - spin_lock_init(&queue->fastopenq->lock); - } - queue->fastopenq->max_qlen = backlog; - return 0; -} - #endif /* __KERNEL__ */ #endif /* _LINUX_TCP_H */ diff --git a/trunk/include/net/ax25.h b/trunk/include/net/ax25.h index 53539acbd81a..5d2352154cf6 100644 --- a/trunk/include/net/ax25.h +++ b/trunk/include/net/ax25.h @@ -157,7 +157,7 @@ enum { typedef struct ax25_uid_assoc { struct hlist_node uid_node; atomic_t refcount; - kuid_t uid; + uid_t uid; ax25_address call; } ax25_uid_assoc; @@ -434,7 +434,7 @@ extern unsigned long ax25_display_timer(struct timer_list *); /* ax25_uid.c */ extern int ax25_uid_policy; -extern ax25_uid_assoc *ax25_findbyuid(kuid_t); +extern ax25_uid_assoc *ax25_findbyuid(uid_t); extern int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *); extern const struct file_operations ax25_uid_fops; extern void ax25_uid_free(void); diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index ba2e6160fad1..3d254e10ff30 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -1439,8 +1439,7 @@ struct cfg80211_gtk_rekey_data { * @add_virtual_intf: create a new virtual interface with the given name, * must set the struct wireless_dev's iftype. Beware: You must create * the new netdev in the wiphy's network namespace! Returns the struct - * wireless_dev, or an ERR_PTR. For P2P device wdevs, the driver must - * also set the address member in the wdev. + * wireless_dev, or an ERR_PTR. * * @del_virtual_intf: remove the virtual interface * @@ -1619,9 +1618,6 @@ struct cfg80211_gtk_rekey_data { * @get_channel: Get the current operating channel for the virtual interface. * For monitor interfaces, it should return %NULL unless there's a single * current monitoring channel. - * - * @start_p2p_device: Start the given P2P device. - * @stop_p2p_device: Stop the given P2P device. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -1838,11 +1834,6 @@ struct cfg80211_ops { (*get_channel)(struct wiphy *wiphy, struct wireless_dev *wdev, enum nl80211_channel_type *type); - - int (*start_p2p_device)(struct wiphy *wiphy, - struct wireless_dev *wdev); - void (*stop_p2p_device)(struct wiphy *wiphy, - struct wireless_dev *wdev); }; /* @@ -2406,8 +2397,6 @@ struct cfg80211_cached_keys; * @cleanup_work: work struct used for cleanup that can't be done directly * @beacon_interval: beacon interval used on this device for transmitting * beacons, 0 when not valid - * @address: The address for this device, valid only if @netdev is %NULL - * @p2p_started: true if this is a P2P Device that has been started */ struct wireless_dev { struct wiphy *wiphy; @@ -2426,9 +2415,7 @@ struct wireless_dev { struct work_struct cleanup_work; - bool use_4addr, p2p_started; - - u8 address[ETH_ALEN] __aligned(sizeof(u16)); + bool use_4addr; /* currently used for IBSS and SME - might be rearranged later */ u8 ssid[IEEE80211_MAX_SSID_LEN]; @@ -2476,13 +2463,6 @@ struct wireless_dev { #endif }; -static inline u8 *wdev_address(struct wireless_dev *wdev) -{ - if (wdev->netdev) - return wdev->netdev->dev_addr; - return wdev->address; -} - /** * wdev_priv - return wiphy priv from wireless_dev * @@ -3550,22 +3530,6 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, */ u32 cfg80211_calculate_bitrate(struct rate_info *rate); -/** - * cfg80211_unregister_wdev - remove the given wdev - * @wdev: struct wireless_dev to remove - * - * Call this function only for wdevs that have no netdev assigned, - * e.g. P2P Devices. It removes the device from the list so that - * it can no longer be used. It is necessary to call this function - * even when cfg80211 requests the removal of the interface by - * calling the del_virtual_intf() callback. The function must also - * be called when the driver wishes to unregister the wdev, e.g. - * when the device is unbound from the driver. - * - * Requires the RTNL to be held. - */ -void cfg80211_unregister_wdev(struct wireless_dev *wdev); - /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/trunk/include/net/ieee80211_radiotap.h b/trunk/include/net/ieee80211_radiotap.h index 7f0df133d119..71392545d0a1 100644 --- a/trunk/include/net/ieee80211_radiotap.h +++ b/trunk/include/net/ieee80211_radiotap.h @@ -183,9 +183,6 @@ struct ieee80211_radiotap_header { * Contains a bitmap of known fields/flags, the flags, and * the MCS index. * - * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless - * - * Contains the AMPDU information for the subframe. */ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_TSFT = 0, @@ -208,7 +205,6 @@ enum ieee80211_radiotap_type { IEEE80211_RADIOTAP_DATA_RETRIES = 17, IEEE80211_RADIOTAP_MCS = 19, - IEEE80211_RADIOTAP_AMPDU_STATUS = 20, /* valid in every it_present bitmap, even vendor namespaces */ IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, @@ -274,13 +270,6 @@ enum ieee80211_radiotap_type { #define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 -/* For IEEE80211_RADIOTAP_AMPDU_STATUS */ -#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 -#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 -#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 -#define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 -#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 -#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 /* helpers */ static inline int ieee80211_get_radiotap_len(unsigned char *data) diff --git a/trunk/include/net/inet_frag.h b/trunk/include/net/inet_frag.h index 2431cf83aeca..5098ee7b7e0e 100644 --- a/trunk/include/net/inet_frag.h +++ b/trunk/include/net/inet_frag.h @@ -29,6 +29,8 @@ struct inet_frag_queue { #define INET_FRAG_COMPLETE 4 #define INET_FRAG_FIRST_IN 2 #define INET_FRAG_LAST_IN 1 + + u16 max_size; }; #define INETFRAGS_HASHSZ 64 diff --git a/trunk/include/net/ip.h b/trunk/include/net/ip.h index 5a5d84d3d2c6..0707fb9551aa 100644 --- a/trunk/include/net/ip.h +++ b/trunk/include/net/ip.h @@ -42,6 +42,8 @@ struct inet_skb_parm { #define IPSKB_XFRM_TRANSFORMED 4 #define IPSKB_FRAG_COMPLETE 8 #define IPSKB_REROUTED 16 + + u16 frag_max_size; }; static inline unsigned int ip_hdrlen(const struct sk_buff *skb) diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index 9bed5d483405..6d01fb00ff2b 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -223,10 +223,7 @@ struct ip6_flowlabel { struct ipv6_txoptions *opt; unsigned long linger; u8 share; - union { - struct pid *pid; - kuid_t uid; - } owner; + u32 owner; unsigned long lastuse; unsigned long expires; struct net *fl_net; diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 71f8262fc1df..bb86aa6f98dd 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -171,7 +171,6 @@ struct ieee80211_low_level_stats { * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode) * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode) - * @BSS_CHANGED_PS: PS changed for this BSS (STA mode) */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -191,7 +190,6 @@ enum ieee80211_bss_change { BSS_CHANGED_IDLE = 1<<14, BSS_CHANGED_SSID = 1<<15, BSS_CHANGED_AP_PROBE_RESP = 1<<16, - BSS_CHANGED_PS = 1<<17, /* when adding here, make sure to change ieee80211_reconfig */ }; @@ -268,8 +266,6 @@ enum ieee80211_rssi_event { * @idle: This interface is idle. There's also a global idle flag in the * hardware config which may be more appropriate depending on what * your driver/device needs to do. - * @ps: power-save mode (STA only). This flag is NOT affected by - * offchannel/dynamic_ps operations. * @ssid: The SSID of the current vif. Only valid in AP-mode. * @ssid_len: Length of SSID given in @ssid. * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. @@ -300,7 +296,6 @@ struct ieee80211_bss_conf { bool arp_filter_enabled; bool qos; bool idle; - bool ps; u8 ssid[IEEE80211_MAX_SSID_LEN]; size_t ssid_len; bool hidden_ssid; @@ -527,6 +522,9 @@ struct ieee80211_tx_rate { * (2) driver internal use (if applicable) * (3) TX status information - driver tells mac80211 what happened * + * The TX control's sta pointer is only valid during the ->tx call, + * it may be NULL. + * * @flags: transmit info flags, defined above * @band: the band to transmit on (use for checking for races) * @hw_queue: HW queue to put the frame on, skb_get_queue_mapping() gives the AC @@ -557,7 +555,6 @@ struct ieee80211_tx_info { struct ieee80211_tx_rate rates[ IEEE80211_TX_MAX_RATES]; s8 rts_cts_rate_idx; - /* 3 bytes free */ }; /* only needed before rate control */ unsigned long jiffies; @@ -565,7 +562,7 @@ struct ieee80211_tx_info { /* NB: vif can be NULL for injected frames */ struct ieee80211_vif *vif; struct ieee80211_key_conf *hw_key; - /* 8 bytes free */ + struct ieee80211_sta *sta; } control; struct { struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; @@ -676,41 +673,21 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_HT_GF: This frame was received in a HT-greenfield transmission, if * the driver fills this value it should add %IEEE80211_RADIOTAP_MCS_HAVE_FMT * to hw.radiotap_mcs_details to advertise that fact - * @RX_FLAG_AMPDU_DETAILS: A-MPDU details are known, in particular the reference - * number (@ampdu_reference) must be populated and be a distinct number for - * each A-MPDU - * @RX_FLAG_AMPDU_REPORT_ZEROLEN: driver reports 0-length subframes - * @RX_FLAG_AMPDU_IS_ZEROLEN: This is a zero-length subframe, for - * monitoring purposes only - * @RX_FLAG_AMPDU_LAST_KNOWN: last subframe is known, should be set on all - * subframes of a single A-MPDU - * @RX_FLAG_AMPDU_IS_LAST: this subframe is the last subframe of the A-MPDU - * @RX_FLAG_AMPDU_DELIM_CRC_ERROR: A delimiter CRC error has been detected - * on this subframe - * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC - * is stored in the @ampdu_delimiter_crc field) */ enum mac80211_rx_flags { - RX_FLAG_MMIC_ERROR = BIT(0), - RX_FLAG_DECRYPTED = BIT(1), - RX_FLAG_MMIC_STRIPPED = BIT(3), - RX_FLAG_IV_STRIPPED = BIT(4), - RX_FLAG_FAILED_FCS_CRC = BIT(5), - RX_FLAG_FAILED_PLCP_CRC = BIT(6), - RX_FLAG_MACTIME_MPDU = BIT(7), - RX_FLAG_SHORTPRE = BIT(8), - RX_FLAG_HT = BIT(9), - RX_FLAG_40MHZ = BIT(10), - RX_FLAG_SHORT_GI = BIT(11), - RX_FLAG_NO_SIGNAL_VAL = BIT(12), - RX_FLAG_HT_GF = BIT(13), - RX_FLAG_AMPDU_DETAILS = BIT(14), - RX_FLAG_AMPDU_REPORT_ZEROLEN = BIT(15), - RX_FLAG_AMPDU_IS_ZEROLEN = BIT(16), - RX_FLAG_AMPDU_LAST_KNOWN = BIT(17), - RX_FLAG_AMPDU_IS_LAST = BIT(18), - RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19), - RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20), + RX_FLAG_MMIC_ERROR = 1<<0, + RX_FLAG_DECRYPTED = 1<<1, + RX_FLAG_MMIC_STRIPPED = 1<<3, + RX_FLAG_IV_STRIPPED = 1<<4, + RX_FLAG_FAILED_FCS_CRC = 1<<5, + RX_FLAG_FAILED_PLCP_CRC = 1<<6, + RX_FLAG_MACTIME_MPDU = 1<<7, + RX_FLAG_SHORTPRE = 1<<8, + RX_FLAG_HT = 1<<9, + RX_FLAG_40MHZ = 1<<10, + RX_FLAG_SHORT_GI = 1<<11, + RX_FLAG_NO_SIGNAL_VAL = 1<<12, + RX_FLAG_HT_GF = 1<<13, }; /** @@ -734,22 +711,17 @@ enum mac80211_rx_flags { * HT rates are use (RX_FLAG_HT) * @flag: %RX_FLAG_* * @rx_flags: internal RX flags for mac80211 - * @ampdu_reference: A-MPDU reference number, must be a different value for - * each A-MPDU but the same for each subframe within one A-MPDU - * @ampdu_delimiter_crc: A-MPDU delimiter CRC */ struct ieee80211_rx_status { u64 mactime; u32 device_timestamp; - u32 ampdu_reference; - u32 flag; + u16 flag; u16 freq; u8 rate_idx; u8 rx_flags; u8 band; u8 antenna; s8 signal; - u8 ampdu_delimiter_crc; }; /** @@ -1101,16 +1073,6 @@ enum sta_notify_cmd { STA_NOTIFY_SLEEP, STA_NOTIFY_AWAKE, }; -/** - * struct ieee80211_tx_control - TX control data - * - * @sta: station table entry, this sta pointer may be NULL and - * it is not allowed to copy the pointer, due to RCU. - */ -struct ieee80211_tx_control { - struct ieee80211_sta *sta; -}; - /** * enum ieee80211_hw_flags - hardware flags * @@ -1241,10 +1203,6 @@ struct ieee80211_tx_control { * queue mapping in order to use different queues (not just one per AC) * for different virtual interfaces. See the doc section on HW queue * control for more details. - * - * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any - * P2P Interface. This will be honoured even if more than one interface - * is supported. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, @@ -1272,7 +1230,6 @@ enum ieee80211_hw_flags { IEEE80211_HW_AP_LINK_PS = 1<<22, IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, IEEE80211_HW_SCAN_WHILE_IDLE = 1<<24, - IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25, }; /** @@ -1927,14 +1884,10 @@ enum ieee80211_frame_release_type { * @IEEE80211_RC_BW_CHANGED: The bandwidth that can be used to transmit * to this station changed. * @IEEE80211_RC_SMPS_CHANGED: The SMPS state of the station changed. - * @IEEE80211_RC_SUPP_RATES_CHANGED: The supported rate set of this peer - * changed (in IBSS mode) due to discovering more information about - * the peer. */ enum ieee80211_rate_control_changed { IEEE80211_RC_BW_CHANGED = BIT(0), IEEE80211_RC_SMPS_CHANGED = BIT(1), - IEEE80211_RC_SUPP_RATES_CHANGED = BIT(2), }; /** @@ -2311,9 +2264,7 @@ enum ieee80211_rate_control_changed { * The callback is optional and can (should!) sleep. */ struct ieee80211_ops { - void (*tx)(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb); + void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); int (*start)(struct ieee80211_hw *hw); void (*stop)(struct ieee80211_hw *hw); #ifdef CONFIG_PM diff --git a/trunk/include/net/netfilter/nf_conntrack_ecache.h b/trunk/include/net/netfilter/nf_conntrack_ecache.h index 4a045cda9c60..e1ce1048fe5f 100644 --- a/trunk/include/net/netfilter/nf_conntrack_ecache.h +++ b/trunk/include/net/netfilter/nf_conntrack_ecache.h @@ -18,7 +18,6 @@ struct nf_conntrack_ecache { u16 ctmask; /* bitmask of ct events to be delivered */ u16 expmask; /* bitmask of expect events to be delivered */ u32 pid; /* netlink pid of destroyer */ - struct timer_list timeout; }; static inline struct nf_conntrack_ecache * diff --git a/trunk/include/net/netns/ipv4.h b/trunk/include/net/netns/ipv4.h index 3516dc0cc615..1474dd65c66f 100644 --- a/trunk/include/net/netns/ipv4.h +++ b/trunk/include/net/netns/ipv4.h @@ -5,7 +5,6 @@ #ifndef __NETNS_IPV4_H__ #define __NETNS_IPV4_H__ -#include #include struct tcpm_hash_bucket; @@ -63,7 +62,7 @@ struct netns_ipv4 { int sysctl_icmp_ratemask; int sysctl_icmp_errors_use_inbound_ifaddr; - kgid_t sysctl_ping_group_range[2]; + unsigned int sysctl_ping_group_range[2]; long sysctl_tcp_mem[3]; atomic_t rt_genid; diff --git a/trunk/include/net/netns/packet.h b/trunk/include/net/netns/packet.h index 17ec2b95c062..4780b080a436 100644 --- a/trunk/include/net/netns/packet.h +++ b/trunk/include/net/netns/packet.h @@ -5,7 +5,7 @@ #define __NETNS_PACKET_H__ #include -#include +#include struct netns_packet { struct mutex sklist_lock; diff --git a/trunk/include/net/request_sock.h b/trunk/include/net/request_sock.h index b01d8dd9ee7c..4c0766e201e3 100644 --- a/trunk/include/net/request_sock.h +++ b/trunk/include/net/request_sock.h @@ -106,34 +106,6 @@ struct listen_sock { struct request_sock *syn_table[0]; }; -/* - * For a TCP Fast Open listener - - * lock - protects the access to all the reqsk, which is co-owned by - * the listener and the child socket. - * qlen - pending TFO requests (still in TCP_SYN_RECV). - * max_qlen - max TFO reqs allowed before TFO is disabled. - * - * XXX (TFO) - ideally these fields can be made as part of "listen_sock" - * structure above. But there is some implementation difficulty due to - * listen_sock being part of request_sock_queue hence will be freed when - * a listener is stopped. But TFO related fields may continue to be - * accessed even after a listener is closed, until its sk_refcnt drops - * to 0 implying no more outstanding TFO reqs. One solution is to keep - * listen_opt around until sk_refcnt drops to 0. But there is some other - * complexity that needs to be resolved. E.g., a listener can be disabled - * temporarily through shutdown()->tcp_disconnect(), and re-enabled later. - */ -struct fastopen_queue { - struct request_sock *rskq_rst_head; /* Keep track of past TFO */ - struct request_sock *rskq_rst_tail; /* requests that caused RST. - * This is part of the defense - * against spoofing attack. - */ - spinlock_t lock; - int qlen; /* # of pending (TCP_SYN_RECV) reqs */ - int max_qlen; /* != 0 iff TFO is currently enabled */ -}; - /** struct request_sock_queue - queue of request_socks * * @rskq_accept_head - FIFO head of established children @@ -157,12 +129,6 @@ struct request_sock_queue { u8 rskq_defer_accept; /* 3 bytes hole, try to pack */ struct listen_sock *listen_opt; - struct fastopen_queue *fastopenq; /* This is non-NULL iff TFO has been - * enabled on this listener. Check - * max_qlen != 0 in fastopen_queue - * to determine if TFO is enabled - * right at this moment. - */ }; extern int reqsk_queue_alloc(struct request_sock_queue *queue, @@ -170,8 +136,6 @@ extern int reqsk_queue_alloc(struct request_sock_queue *queue, extern void __reqsk_queue_destroy(struct request_sock_queue *queue); extern void reqsk_queue_destroy(struct request_sock_queue *queue); -extern void reqsk_fastopen_remove(struct sock *sk, - struct request_sock *req, bool reset); static inline struct request_sock * reqsk_queue_yank_acceptq(struct request_sock_queue *queue) @@ -226,6 +190,19 @@ static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue return req; } +static inline struct sock *reqsk_queue_get_child(struct request_sock_queue *queue, + struct sock *parent) +{ + struct request_sock *req = reqsk_queue_remove(queue); + struct sock *child = req->sk; + + WARN_ON(child == NULL); + + sk_acceptq_removed(parent); + __reqsk_free(req); + return child; +} + static inline int reqsk_queue_removed(struct request_sock_queue *queue, struct request_sock *req) { diff --git a/trunk/include/net/sch_generic.h b/trunk/include/net/sch_generic.h index 4616f468d599..d9611e032418 100644 --- a/trunk/include/net/sch_generic.h +++ b/trunk/include/net/sch_generic.h @@ -188,8 +188,7 @@ struct tcf_proto_ops { unsigned long (*get)(struct tcf_proto*, u32 handle); void (*put)(struct tcf_proto*, unsigned long); - int (*change)(struct sk_buff *, - struct tcf_proto*, unsigned long, + int (*change)(struct tcf_proto*, unsigned long, u32 handle, struct nlattr **, unsigned long *); int (*delete)(struct tcf_proto*, unsigned long); diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 84bdaeca1314..72132aef53fc 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -606,15 +606,6 @@ static inline void sk_add_bind_node(struct sock *sk, #define sk_for_each_bound(__sk, node, list) \ hlist_for_each_entry(__sk, node, list, sk_bind_node) -static inline struct user_namespace *sk_user_ns(struct sock *sk) -{ - /* Careful only use this in a context where these parameters - * can not change and must all be valid, such as recvmsg from - * userspace. - */ - return sk->sk_socket->file->f_cred->user_ns; -} - /* Sock flags */ enum sock_flags { SOCK_DEAD, @@ -1679,7 +1670,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) write_unlock_bh(&sk->sk_callback_lock); } -extern kuid_t sock_i_uid(struct sock *sk); +extern int sock_i_uid(struct sock *sk); extern unsigned long sock_i_ino(struct sock *sk); static inline struct dst_entry * diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index a8cb00c0c6d9..1f000ffe7075 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -98,21 +98,11 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); * 15 is ~13-30min depending on RTO. */ -#define TCP_SYN_RETRIES 6 /* This is how many retries are done - * when active opening a connection. - * RFC1122 says the minimum retry MUST - * be at least 180secs. Nevertheless - * this value is corresponding to - * 63secs of retransmission with the - * current initial RTO. - */ +#define TCP_SYN_RETRIES 5 /* number of times to retry active opening a + * connection: ~180sec is RFC minimum */ -#define TCP_SYNACK_RETRIES 5 /* This is how may retries are done - * when passive opening a connection. - * This is corresponding to 31secs of - * retransmission with the current - * initial RTO. - */ +#define TCP_SYNACK_RETRIES 5 /* number of times to retry passive opening a + * connection: ~180sec is RFC minimum */ #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */ @@ -224,24 +214,8 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); /* Bit Flags for sysctl_tcp_fastopen */ #define TFO_CLIENT_ENABLE 1 -#define TFO_SERVER_ENABLE 2 #define TFO_CLIENT_NO_COOKIE 4 /* Data in SYN w/o cookie option */ -/* Process SYN data but skip cookie validation */ -#define TFO_SERVER_COOKIE_NOT_CHKED 0x100 -/* Accept SYN data w/o any cookie option */ -#define TFO_SERVER_COOKIE_NOT_REQD 0x200 - -/* Force enable TFO on all listeners, i.e., not requiring the - * TCP_FASTOPEN socket option. SOCKOPT1/2 determine how to set max_qlen. - */ -#define TFO_SERVER_WO_SOCKOPT1 0x400 -#define TFO_SERVER_WO_SOCKOPT2 0x800 -/* Always create TFO child sockets on a TFO listener even when - * cookie/data not present. (For testing purpose!) - */ -#define TFO_SERVER_ALWAYS 0x1000 - extern struct inet_timewait_death_row tcp_death_row; /* sysctl variables for tcp */ @@ -424,8 +398,7 @@ extern enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock * const struct tcphdr *th); extern struct sock * tcp_check_req(struct sock *sk,struct sk_buff *skb, struct request_sock *req, - struct request_sock **prev, - bool fastopen); + struct request_sock **prev); extern int tcp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb); extern bool tcp_use_frto(struct sock *sk); @@ -438,6 +411,12 @@ extern void tcp_metrics_init(void); extern bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst, bool paws_check); extern bool tcp_remember_stamp(struct sock *sk); extern bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw); +extern void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, + struct tcp_fastopen_cookie *cookie, + int *syn_loss, unsigned long *last_syn_loss); +extern void tcp_fastopen_cache_set(struct sock *sk, u16 mss, + struct tcp_fastopen_cookie *cookie, + bool syn_lost); extern void tcp_fetch_timewait_stamp(struct sock *sk, struct dst_entry *dst); extern void tcp_disable_fack(struct tcp_sock *tp); extern void tcp_close(struct sock *sk, long timeout); @@ -479,8 +458,7 @@ extern int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, extern int tcp_connect(struct sock *sk); extern struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct request_values *rvp, - struct tcp_fastopen_cookie *foc); + struct request_values *rvp); extern int tcp_disconnect(struct sock *sk, int flags); void tcp_connect_init(struct sock *sk); @@ -549,7 +527,6 @@ extern void tcp_send_delayed_ack(struct sock *sk); extern void tcp_cwnd_application_limited(struct sock *sk); extern void tcp_resume_early_retransmit(struct sock *sk); extern void tcp_rearm_rto(struct sock *sk); -extern void tcp_reset(struct sock *sk); /* tcp_timer.c */ extern void tcp_init_xmit_timers(struct sock *); @@ -599,7 +576,6 @@ extern int tcp_mtu_to_mss(struct sock *sk, int pmtu); extern int tcp_mss_to_mtu(struct sock *sk, int mss); extern void tcp_mtup_init(struct sock *sk); extern void tcp_valid_rtt_meas(struct sock *sk, u32 seq_rtt); -extern void tcp_init_buffer_space(struct sock *sk); static inline void tcp_bound_rto(const struct sock *sk) { @@ -913,21 +889,15 @@ static inline bool tcp_in_initial_slowstart(const struct tcp_sock *tp) return tp->snd_ssthresh >= TCP_INFINITE_SSTHRESH; } -static inline bool tcp_in_cwnd_reduction(const struct sock *sk) -{ - return (TCPF_CA_CWR | TCPF_CA_Recovery) & - (1 << inet_csk(sk)->icsk_ca_state); -} - /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. - * The exception is cwnd reduction phase, when cwnd is decreasing towards + * The exception is rate halving phase, when cwnd is decreasing towards * ssthresh. */ static inline __u32 tcp_current_ssthresh(const struct sock *sk) { const struct tcp_sock *tp = tcp_sk(sk); - if (tcp_in_cwnd_reduction(sk)) + if ((1 << inet_csk(sk)->icsk_ca_state) & (TCPF_CA_CWR | TCPF_CA_Recovery)) return tp->snd_ssthresh; else return max(tp->snd_ssthresh, @@ -1124,7 +1094,6 @@ static inline void tcp_openreq_init(struct request_sock *req, req->rcv_wnd = 0; /* So that tcp_send_synack() knows! */ req->cookie_ts = 0; tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq; - tcp_rsk(req)->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; req->mss = rx_opt->mss_clamp; req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0; ireq->tstamp_ok = rx_opt->tstamp_ok; @@ -1329,33 +1298,14 @@ extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, const struct sk_buff extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp, const struct tcp_md5sig_key *key); -/* From tcp_fastopen.c */ -extern void tcp_fastopen_cache_get(struct sock *sk, u16 *mss, - struct tcp_fastopen_cookie *cookie, - int *syn_loss, unsigned long *last_syn_loss); -extern void tcp_fastopen_cache_set(struct sock *sk, u16 mss, - struct tcp_fastopen_cookie *cookie, - bool syn_lost); struct tcp_fastopen_request { /* Fast Open cookie. Size 0 means a cookie request */ struct tcp_fastopen_cookie cookie; struct msghdr *data; /* data in MSG_FASTOPEN */ u16 copied; /* queued in tcp_connect() */ }; -void tcp_free_fastopen_req(struct tcp_sock *tp); - -extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx; -int tcp_fastopen_reset_cipher(void *key, unsigned int len); -void tcp_fastopen_cookie_gen(__be32 addr, struct tcp_fastopen_cookie *foc); -#define TCP_FASTOPEN_KEY_LENGTH 16 - -/* Fastopen key context */ -struct tcp_fastopen_context { - struct crypto_cipher __rcu *tfm; - __u8 key[TCP_FASTOPEN_KEY_LENGTH]; - struct rcu_head rcu; -}; +void tcp_free_fastopen_req(struct tcp_sock *tp); /* write queue abstraction */ static inline void tcp_write_queue_purge(struct sock *sk) @@ -1560,8 +1510,7 @@ struct tcp_iter_state { sa_family_t family; enum tcp_seq_states state; struct sock *syn_wait_sk; - int bucket, offset, sbucket, num; - kuid_t uid; + int bucket, offset, sbucket, num, uid; loff_t last_pos; }; diff --git a/trunk/include/target/target_core_base.h b/trunk/include/target/target_core_base.h index 015cea01ae39..128ce46fa48a 100644 --- a/trunk/include/target/target_core_base.h +++ b/trunk/include/target/target_core_base.h @@ -503,6 +503,8 @@ struct se_cmd { u32 se_ordered_id; /* Total size in bytes associated with command */ u32 data_length; + /* SCSI Presented Data Transfer Length */ + u32 cmd_spdtl; u32 residual_count; u32 orig_fe_lun; /* Persistent Reservation key */ diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index b445d6f49bcf..af6c7f8ba019 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -942,12 +942,28 @@ config UIDGID_CONVERTED depends on PROC_EVENTS = n # Networking + depends on NET = n depends on NET_9P = n + depends on IPX = n + depends on PHONET = n + depends on NET_CLS_FLOW = n + depends on NETFILTER_XT_MATCH_OWNER = n + depends on NETFILTER_XT_MATCH_RECENT = n + depends on NETFILTER_XT_TARGET_LOG = n + depends on NETFILTER_NETLINK_LOG = n + depends on INET = n + depends on IPV6 = n + depends on IP_SCTP = n depends on AF_RXRPC = n + depends on LLC2 = n depends on NET_KEY = n + depends on INET_DIAG = n depends on DNS_RESOLVER = n + depends on AX25 = n + depends on ATALK = n # Filesystems + depends on USB_DEVICEFS = n depends on USB_GADGETFS = n depends on USB_FUNCTIONFS = n depends on DEVTMPFS = n @@ -1003,6 +1019,9 @@ config UIDGID_CONVERTED depends on !UML || HOSTFS = n # The rare drivers that won't build + depends on AIRO = n + depends on AIRO_CS = n + depends on TUN = n depends on INFINIBAND_QIB = n depends on BLK_DEV_LOOP = n depends on ANDROID_BINDER_IPC = n diff --git a/trunk/ipc/mqueue.c b/trunk/ipc/mqueue.c index 9a08acc9e649..f8e54f5b9080 100644 --- a/trunk/ipc/mqueue.c +++ b/trunk/ipc/mqueue.c @@ -726,6 +726,7 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, struct mq_attr *attr) { const struct cred *cred = current_cred(); + struct file *result; int ret; if (attr) { @@ -747,11 +748,21 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, } mode &= ~current_umask(); - ret = vfs_create(dir, path->dentry, mode, true); - path->dentry->d_fsdata = NULL; + ret = mnt_want_write(path->mnt); if (ret) return ERR_PTR(ret); - return dentry_open(path, oflag, cred); + ret = vfs_create(dir, path->dentry, mode, true); + path->dentry->d_fsdata = NULL; + if (!ret) + result = dentry_open(path, oflag, cred); + else + result = ERR_PTR(ret); + /* + * dentry_open() took a persistent mnt_want_write(), + * so we can now drop this one. + */ + mnt_drop_write(path->mnt); + return result; } /* Opens existing queue */ @@ -777,9 +788,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, struct mq_attr attr; int fd, error; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; - struct vfsmount *mnt = ipc_ns->mq_mnt; - struct dentry *root = mnt->mnt_root; - int ro; + struct dentry *root = ipc_ns->mq_mnt->mnt_root; if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) return -EFAULT; @@ -793,7 +802,6 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, if (fd < 0) goto out_putname; - ro = mnt_want_write(mnt); /* we'll drop it in any case */ error = 0; mutex_lock(&root->d_inode->i_mutex); path.dentry = lookup_one_len(name, root, strlen(name)); @@ -801,7 +809,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, error = PTR_ERR(path.dentry); goto out_putfd; } - path.mnt = mntget(mnt); + path.mnt = mntget(ipc_ns->mq_mnt); if (oflag & O_CREAT) { if (path.dentry->d_inode) { /* entry already exists */ @@ -812,10 +820,6 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, } filp = do_open(&path, oflag); } else { - if (ro) { - error = ro; - goto out; - } filp = do_create(ipc_ns, root->d_inode, &path, oflag, mode, u_attr ? &attr : NULL); @@ -841,7 +845,6 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, fd = error; } mutex_unlock(&root->d_inode->i_mutex); - mnt_drop_write(mnt); out_putname: putname(name); return fd; @@ -854,38 +857,40 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) struct dentry *dentry; struct inode *inode = NULL; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; - struct vfsmount *mnt = ipc_ns->mq_mnt; name = getname(u_name); if (IS_ERR(name)) return PTR_ERR(name); - err = mnt_want_write(mnt); - if (err) - goto out_name; - mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT); - dentry = lookup_one_len(name, mnt->mnt_root, strlen(name)); + mutex_lock_nested(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex, + I_MUTEX_PARENT); + dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name)); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); goto out_unlock; } - inode = dentry->d_inode; - if (!inode) { + if (!dentry->d_inode) { err = -ENOENT; - } else { - ihold(inode); - err = vfs_unlink(dentry->d_parent->d_inode, dentry); + goto out_err; } + + inode = dentry->d_inode; + if (inode) + ihold(inode); + err = mnt_want_write(ipc_ns->mq_mnt); + if (err) + goto out_err; + err = vfs_unlink(dentry->d_parent->d_inode, dentry); + mnt_drop_write(ipc_ns->mq_mnt); +out_err: dput(dentry); out_unlock: - mutex_unlock(&mnt->mnt_root->d_inode->i_mutex); + mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); + putname(name); if (inode) iput(inode); - mnt_drop_write(mnt); -out_name: - putname(name); return err; } diff --git a/trunk/kernel/pid.c b/trunk/kernel/pid.c index aebd4f5aaf41..e86b291ad834 100644 --- a/trunk/kernel/pid.c +++ b/trunk/kernel/pid.c @@ -479,7 +479,6 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) } return nr; } -EXPORT_SYMBOL_GPL(pid_nr_ns); pid_t pid_vnr(struct pid *pid) { diff --git a/trunk/kernel/pid_namespace.c b/trunk/kernel/pid_namespace.c index baa528d7dfbd..b3c7fd554250 100644 --- a/trunk/kernel/pid_namespace.c +++ b/trunk/kernel/pid_namespace.c @@ -16,7 +16,6 @@ #include #include #include -#include #define BITS_PER_PAGE (PAGE_SIZE*8) @@ -145,7 +144,6 @@ void free_pid_ns(struct kref *kref) if (parent != NULL) put_pid_ns(parent); } -EXPORT_SYMBOL_GPL(free_pid_ns); void zap_pid_ns_processes(struct pid_namespace *pid_ns) { diff --git a/trunk/lib/nlattr.c b/trunk/lib/nlattr.c index 18eca7809b08..4226dfeb5178 100644 --- a/trunk/lib/nlattr.c +++ b/trunk/lib/nlattr.c @@ -22,10 +22,6 @@ static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = { [NLA_U64] = sizeof(u64), [NLA_MSECS] = sizeof(u64), [NLA_NESTED] = NLA_HDRLEN, - [NLA_S8] = sizeof(s8), - [NLA_S16] = sizeof(s16), - [NLA_S32] = sizeof(s32), - [NLA_S64] = sizeof(s64), }; static int validate_nla(const struct nlattr *nla, int maxtype, diff --git a/trunk/net/8021q/vlan_core.c b/trunk/net/8021q/vlan_core.c index b258da88f675..8ca533c95de0 100644 --- a/trunk/net/8021q/vlan_core.c +++ b/trunk/net/8021q/vlan_core.c @@ -368,9 +368,3 @@ void vlan_vids_del_by_dev(struct net_device *dev, vlan_vid_del(dev, vid_info->vid); } EXPORT_SYMBOL(vlan_vids_del_by_dev); - -bool vlan_uses_dev(const struct net_device *dev) -{ - return rtnl_dereference(dev->vlan_info) ? true : false; -} -EXPORT_SYMBOL(vlan_uses_dev); diff --git a/trunk/net/appletalk/atalk_proc.c b/trunk/net/appletalk/atalk_proc.c index c30f3a0717fb..b5b1a221c242 100644 --- a/trunk/net/appletalk/atalk_proc.c +++ b/trunk/net/appletalk/atalk_proc.c @@ -183,8 +183,7 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v) ntohs(at->dest_net), at->dest_node, at->dest_port, sk_wmem_alloc_get(s), sk_rmem_alloc_get(s), - s->sk_state, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(s))); + s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); out: return 0; } diff --git a/trunk/net/atm/resources.c b/trunk/net/atm/resources.c index 0447d5d0b639..23f45ce6f351 100644 --- a/trunk/net/atm/resources.c +++ b/trunk/net/atm/resources.c @@ -432,7 +432,7 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat) size = dev->ops->ioctl(dev, cmd, buf); } if (size < 0) { - error = (size == -ENOIOCTLCMD ? -ENOTTY : size); + error = (size == -ENOIOCTLCMD ? -EINVAL : size); goto done; } } diff --git a/trunk/net/ax25/ax25_uid.c b/trunk/net/ax25/ax25_uid.c index 957999e43ff7..e3c579ba6325 100644 --- a/trunk/net/ax25/ax25_uid.c +++ b/trunk/net/ax25/ax25_uid.c @@ -51,14 +51,14 @@ int ax25_uid_policy; EXPORT_SYMBOL(ax25_uid_policy); -ax25_uid_assoc *ax25_findbyuid(kuid_t uid) +ax25_uid_assoc *ax25_findbyuid(uid_t uid) { ax25_uid_assoc *ax25_uid, *res = NULL; struct hlist_node *node; read_lock(&ax25_uid_lock); ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { - if (uid_eq(ax25_uid->uid, uid)) { + if (ax25_uid->uid == uid) { ax25_uid_hold(ax25_uid); res = ax25_uid; break; @@ -84,7 +84,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) read_lock(&ax25_uid_lock); ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) { - res = from_kuid_munged(current_user_ns(), ax25_uid->uid); + res = ax25_uid->uid; break; } } @@ -93,14 +93,9 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) return res; case SIOCAX25ADDUID: - { - kuid_t sax25_kuid; if (!capable(CAP_NET_ADMIN)) return -EPERM; - sax25_kuid = make_kuid(current_user_ns(), sax->sax25_uid); - if (!uid_valid(sax25_kuid)) - return -EINVAL; - user = ax25_findbyuid(sax25_kuid); + user = ax25_findbyuid(sax->sax25_uid); if (user) { ax25_uid_put(user); return -EEXIST; @@ -111,7 +106,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) return -ENOMEM; atomic_set(&ax25_uid->refcount, 1); - ax25_uid->uid = sax25_kuid; + ax25_uid->uid = sax->sax25_uid; ax25_uid->call = sax->sax25_call; write_lock(&ax25_uid_lock); @@ -119,7 +114,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) write_unlock(&ax25_uid_lock); return 0; - } + case SIOCAX25DELUID: if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -177,9 +172,7 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v) struct ax25_uid_assoc *pt; pt = hlist_entry(v, struct ax25_uid_assoc, uid_node); - seq_printf(seq, "%6d %s\n", - from_kuid_munged(seq_user_ns(seq), pt->uid), - ax2asc(buf, &pt->call)); + seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(buf, &pt->call)); } return 0; } diff --git a/trunk/net/batman-adv/bat_iv_ogm.c b/trunk/net/batman-adv/bat_iv_ogm.c index df79300dcb7b..e877af8bdd1e 100644 --- a/trunk/net/batman-adv/bat_iv_ogm.c +++ b/trunk/net/batman-adv/bat_iv_ogm.c @@ -166,15 +166,13 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, int16_t buff_pos; struct batadv_ogm_packet *batadv_ogm_packet; struct sk_buff *skb; - uint8_t *packet_pos; if (hard_iface->if_status != BATADV_IF_ACTIVE) return; packet_num = 0; buff_pos = 0; - packet_pos = forw_packet->skb->data; - batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; + batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data; /* adjust all flags and log packets */ while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, @@ -183,17 +181,15 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, /* we might have aggregated direct link packets with an * ordinary base packet */ - if (forw_packet->direct_link_flags & BIT(packet_num) && - forw_packet->if_incoming == hard_iface) + if ((forw_packet->direct_link_flags & (1 << packet_num)) && + (forw_packet->if_incoming == hard_iface)) batadv_ogm_packet->flags |= BATADV_DIRECTLINK; else batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK; - if (packet_num > 0 || !forw_packet->own) - fwd_str = "Forwarding"; - else - fwd_str = "Sending own"; - + fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? + "Sending own" : + "Forwarding")); batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n", fwd_str, (packet_num > 0 ? "aggregated " : ""), @@ -208,8 +204,8 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, buff_pos += BATADV_OGM_HLEN; buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes); packet_num++; - packet_pos = forw_packet->skb->data + buff_pos; - batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; + batadv_ogm_packet = (struct batadv_ogm_packet *) + (forw_packet->skb->data + buff_pos); } /* create clone because function is called more than once */ @@ -231,10 +227,9 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet) struct batadv_hard_iface *primary_if = NULL; struct batadv_ogm_packet *batadv_ogm_packet; unsigned char directlink; - uint8_t *packet_pos; - packet_pos = forw_packet->skb->data; - batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; + batadv_ogm_packet = (struct batadv_ogm_packet *) + (forw_packet->skb->data); directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0); if (!forw_packet->if_incoming) { @@ -459,7 +454,6 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr, int packet_len, bool direct_link) { unsigned char *skb_buff; - unsigned long new_direct_link_flag; skb_buff = skb_put(forw_packet_aggr->skb, packet_len); memcpy(skb_buff, packet_buff, packet_len); @@ -467,10 +461,9 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr, forw_packet_aggr->num_packets++; /* save packet direct link flag status */ - if (direct_link) { - new_direct_link_flag = BIT(forw_packet_aggr->num_packets); - forw_packet_aggr->direct_link_flags |= new_direct_link_flag; - } + if (direct_link) + forw_packet_aggr->direct_link_flags |= + (1 << forw_packet_aggr->num_packets); } static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv, @@ -593,8 +586,6 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) struct batadv_ogm_packet *batadv_ogm_packet; struct batadv_hard_iface *primary_if; int vis_server, tt_num_changes = 0; - uint32_t seqno; - uint8_t bandwidth; vis_server = atomic_read(&bat_priv->vis_mode); primary_if = batadv_primary_if_get_selected(bat_priv); @@ -608,12 +599,12 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff; /* change sequence number to network order */ - seqno = (uint32_t)atomic_read(&hard_iface->seqno); - batadv_ogm_packet->seqno = htonl(seqno); + batadv_ogm_packet->seqno = + htonl((uint32_t)atomic_read(&hard_iface->seqno)); atomic_inc(&hard_iface->seqno); - batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn); - batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc); + batadv_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn); + batadv_ogm_packet->tt_crc = htons(bat_priv->tt_crc); if (tt_num_changes >= 0) batadv_ogm_packet->tt_num_changes = tt_num_changes; @@ -622,13 +613,12 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) else batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER; - if (hard_iface == primary_if && - atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) { - bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth); - batadv_ogm_packet->gw_flags = bandwidth; - } else { + if ((hard_iface == primary_if) && + (atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER)) + batadv_ogm_packet->gw_flags = + (uint8_t)atomic_read(&bat_priv->gw_bandwidth); + else batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS; - } batadv_slide_own_bcast_window(hard_iface); batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, @@ -652,9 +642,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, struct batadv_neigh_node *router = NULL; struct batadv_orig_node *orig_node_tmp; struct hlist_node *node; - uint8_t sum_orig, sum_neigh; + uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; uint8_t *neigh_addr; - uint8_t tq_avg; batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "update_originator(): Searching and updating originator entry of received packet\n"); @@ -678,8 +667,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, spin_lock_bh(&tmp_neigh_node->lq_update_lock); batadv_ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0); - tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); - tmp_neigh_node->tq_avg = tq_avg; + tmp_neigh_node->tq_avg = + batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); spin_unlock_bh(&tmp_neigh_node->lq_update_lock); } @@ -738,15 +727,17 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, if (router && (neigh_node->tq_avg == router->tq_avg)) { orig_node_tmp = router->orig_node; spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); - sum_orig = orig_node_tmp->bcast_own_sum[if_incoming->if_num]; + bcast_own_sum_orig = + orig_node_tmp->bcast_own_sum[if_incoming->if_num]; spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); orig_node_tmp = neigh_node->orig_node; spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); - sum_neigh = orig_node_tmp->bcast_own_sum[if_incoming->if_num]; + bcast_own_sum_neigh = + orig_node_tmp->bcast_own_sum[if_incoming->if_num]; spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); - if (sum_orig >= sum_neigh) + if (bcast_own_sum_orig >= bcast_own_sum_neigh) goto update_tt; } @@ -844,10 +835,8 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, spin_unlock_bh(&orig_node->ogm_cnt_lock); /* pay attention to not get a value bigger than 100 % */ - if (orig_eq_count > neigh_rq_count) - total_count = neigh_rq_count; - else - total_count = orig_eq_count; + total_count = (orig_eq_count > neigh_rq_count ? + neigh_rq_count : orig_eq_count); /* if we have too few packets (too less data) we set tq_own to zero * if we receive too few packets it is not considered bidirectional @@ -921,7 +910,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, int set_mark, ret = -1; uint32_t seqno = ntohl(batadv_ogm_packet->seqno); uint8_t *neigh_addr; - uint8_t packet_count; orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); if (!orig_node) @@ -956,9 +944,9 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, tmp_neigh_node->real_bits, seq_diff, set_mark); - packet_count = bitmap_weight(tmp_neigh_node->real_bits, - BATADV_TQ_LOCAL_WINDOW_SIZE); - tmp_neigh_node->real_packet_count = packet_count; + tmp_neigh_node->real_packet_count = + bitmap_weight(tmp_neigh_node->real_bits, + BATADV_TQ_LOCAL_WINDOW_SIZE); } rcu_read_unlock(); @@ -1175,12 +1163,9 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, /* if sender is a direct neighbor the sender mac equals * originator mac */ - if (is_single_hop_neigh) - orig_neigh_node = orig_node; - else - orig_neigh_node = batadv_get_orig_node(bat_priv, - ethhdr->h_source); - + orig_neigh_node = (is_single_hop_neigh ? + orig_node : + batadv_get_orig_node(bat_priv, ethhdr->h_source)); if (!orig_neigh_node) goto out; @@ -1266,7 +1251,6 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, int buff_pos = 0, packet_len; unsigned char *tt_buff, *packet_buff; bool ret; - uint8_t *packet_pos; ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN); if (!ret) @@ -1297,8 +1281,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, buff_pos += BATADV_OGM_HLEN; buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes); - packet_pos = packet_buff + buff_pos; - batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos; + batadv_ogm_packet = (struct batadv_ogm_packet *) + (packet_buff + buff_pos); } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len, batadv_ogm_packet->tt_num_changes)); diff --git a/trunk/net/batman-adv/bridge_loop_avoidance.c b/trunk/net/batman-adv/bridge_loop_avoidance.c index 0a9084ad19a6..6705d35b17ce 100644 --- a/trunk/net/batman-adv/bridge_loop_avoidance.c +++ b/trunk/net/batman-adv/bridge_loop_avoidance.c @@ -133,7 +133,7 @@ static void batadv_claim_free_ref(struct batadv_claim *claim) static struct batadv_claim *batadv_claim_hash_find(struct batadv_priv *bat_priv, struct batadv_claim *data) { - struct batadv_hashtable *hash = bat_priv->bla.claim_hash; + struct batadv_hashtable *hash = bat_priv->claim_hash; struct hlist_head *head; struct hlist_node *node; struct batadv_claim *claim; @@ -174,7 +174,7 @@ static struct batadv_backbone_gw * batadv_backbone_hash_find(struct batadv_priv *bat_priv, uint8_t *addr, short vid) { - struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; + struct batadv_hashtable *hash = bat_priv->backbone_hash; struct hlist_head *head; struct hlist_node *node; struct batadv_backbone_gw search_entry, *backbone_gw; @@ -218,7 +218,7 @@ batadv_bla_del_backbone_claims(struct batadv_backbone_gw *backbone_gw) int i; spinlock_t *list_lock; /* protects write access to the hash lists */ - hash = backbone_gw->bat_priv->bla.claim_hash; + hash = backbone_gw->bat_priv->claim_hash; if (!hash) return; @@ -265,7 +265,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, if (!primary_if) return; - memcpy(&local_claim_dest, &bat_priv->bla.claim_dest, + memcpy(&local_claim_dest, &bat_priv->claim_dest, sizeof(local_claim_dest)); local_claim_dest.type = claimtype; @@ -281,7 +281,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, NULL, /* Ethernet SRC/HW SRC: originator mac */ primary_if->net_dev->dev_addr, - /* HW DST: FF:43:05:XX:YY:YY + /* HW DST: FF:43:05:XX:00:00 * with XX = claim type * and YY:YY = group id */ @@ -295,7 +295,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, /* now we pretend that the client would have sent this ... */ switch (claimtype) { - case BATADV_CLAIM_TYPE_CLAIM: + case BATADV_CLAIM_TYPE_ADD: /* normal claim frame * set Ethernet SRC to the clients mac */ @@ -303,7 +303,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid); break; - case BATADV_CLAIM_TYPE_UNCLAIM: + case BATADV_CLAIM_TYPE_DEL: /* unclaim frame * set HW SRC to the clients mac */ @@ -323,8 +323,7 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, break; case BATADV_CLAIM_TYPE_REQUEST: /* request frame - * set HW SRC and header destination to the receiving backbone - * gws mac + * set HW SRC to the special mac containg the crc */ memcpy(hw_src, mac, ETH_ALEN); memcpy(ethhdr->h_dest, mac, ETH_ALEN); @@ -340,9 +339,8 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, uint8_t *mac, skb_reset_mac_header(skb); skb->protocol = eth_type_trans(skb, soft_iface); - batadv_inc_counter(bat_priv, BATADV_CNT_RX); - batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, - skb->len + ETH_HLEN); + bat_priv->stats.rx_packets++; + bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; soft_iface->last_rx = jiffies; netif_rx(skb); @@ -391,7 +389,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig, /* one for the hash, one for returning */ atomic_set(&entry->refcount, 2); - hash_added = batadv_hash_add(bat_priv->bla.backbone_hash, + hash_added = batadv_hash_add(bat_priv->backbone_hash, batadv_compare_backbone_gw, batadv_choose_backbone_gw, entry, &entry->hash_entry); @@ -458,7 +456,7 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv, if (!backbone_gw) return; - hash = bat_priv->bla.claim_hash; + hash = bat_priv->claim_hash; for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -469,7 +467,7 @@ static void batadv_bla_answer_request(struct batadv_priv *bat_priv, continue; batadv_bla_send_claim(bat_priv, claim->addr, claim->vid, - BATADV_CLAIM_TYPE_CLAIM); + BATADV_CLAIM_TYPE_ADD); } rcu_read_unlock(); } @@ -499,7 +497,7 @@ static void batadv_bla_send_request(struct batadv_backbone_gw *backbone_gw) /* no local broadcasts should be sent or received, for now. */ if (!atomic_read(&backbone_gw->request_sent)) { - atomic_inc(&backbone_gw->bat_priv->bla.num_requests); + atomic_inc(&backbone_gw->bat_priv->bla_num_requests); atomic_set(&backbone_gw->request_sent, 1); } } @@ -559,7 +557,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n", mac, vid); - hash_added = batadv_hash_add(bat_priv->bla.claim_hash, + hash_added = batadv_hash_add(bat_priv->claim_hash, batadv_compare_claim, batadv_choose_claim, claim, &claim->hash_entry); @@ -579,7 +577,8 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv, "bla_add_claim(): changing ownership for %pM, vid %d\n", mac, vid); - claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN); + claim->backbone_gw->crc ^= + crc16(0, claim->addr, ETH_ALEN); batadv_backbone_gw_free_ref(claim->backbone_gw); } @@ -611,7 +610,7 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv, batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, vid); - batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim, + batadv_hash_remove(bat_priv->claim_hash, batadv_compare_claim, batadv_choose_claim, claim); batadv_claim_free_ref(claim); /* reference from the hash is gone */ @@ -658,7 +657,7 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv, * we can allow traffic again. */ if (atomic_read(&backbone_gw->request_sent)) { - atomic_dec(&backbone_gw->bat_priv->bla.num_requests); + atomic_dec(&backbone_gw->bat_priv->bla_num_requests); atomic_set(&backbone_gw->request_sent, 0); } } @@ -703,7 +702,7 @@ static int batadv_handle_unclaim(struct batadv_priv *bat_priv, if (primary_if && batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) batadv_bla_send_claim(bat_priv, claim_addr, vid, - BATADV_CLAIM_TYPE_UNCLAIM); + BATADV_CLAIM_TYPE_DEL); backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid); @@ -739,7 +738,7 @@ static int batadv_handle_claim(struct batadv_priv *bat_priv, batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw); if (batadv_compare_eth(backbone_addr, primary_if->net_dev->dev_addr)) batadv_bla_send_claim(bat_priv, claim_addr, vid, - BATADV_CLAIM_TYPE_CLAIM); + BATADV_CLAIM_TYPE_ADD); /* TODO: we could call something like tt_local_del() here. */ @@ -773,7 +772,7 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, struct batadv_bla_claim_dst *bla_dst, *bla_dst_own; bla_dst = (struct batadv_bla_claim_dst *)hw_dst; - bla_dst_own = &bat_priv->bla.claim_dest; + bla_dst_own = &bat_priv->claim_dest; /* check if it is a claim packet in general */ if (memcmp(bla_dst->magic, bla_dst_own->magic, @@ -784,12 +783,12 @@ static int batadv_check_claim_group(struct batadv_priv *bat_priv, * otherwise assume it is in the hw_src */ switch (bla_dst->type) { - case BATADV_CLAIM_TYPE_CLAIM: + case BATADV_CLAIM_TYPE_ADD: backbone_addr = hw_src; break; case BATADV_CLAIM_TYPE_REQUEST: case BATADV_CLAIM_TYPE_ANNOUNCE: - case BATADV_CLAIM_TYPE_UNCLAIM: + case BATADV_CLAIM_TYPE_DEL: backbone_addr = ethhdr->h_source; break; default: @@ -905,12 +904,12 @@ static int batadv_bla_process_claim(struct batadv_priv *bat_priv, /* check for the different types of claim frames ... */ switch (bla_dst->type) { - case BATADV_CLAIM_TYPE_CLAIM: + case BATADV_CLAIM_TYPE_ADD: if (batadv_handle_claim(bat_priv, primary_if, hw_src, ethhdr->h_source, vid)) return 1; break; - case BATADV_CLAIM_TYPE_UNCLAIM: + case BATADV_CLAIM_TYPE_DEL: if (batadv_handle_unclaim(bat_priv, primary_if, ethhdr->h_source, hw_src, vid)) return 1; @@ -946,7 +945,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now) spinlock_t *list_lock; /* protects write access to the hash lists */ int i; - hash = bat_priv->bla.backbone_hash; + hash = bat_priv->backbone_hash; if (!hash) return; @@ -970,7 +969,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now) purge_now: /* don't wait for the pending request anymore */ if (atomic_read(&backbone_gw->request_sent)) - atomic_dec(&bat_priv->bla.num_requests); + atomic_dec(&bat_priv->bla_num_requests); batadv_bla_del_backbone_claims(backbone_gw); @@ -1000,7 +999,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv, struct batadv_hashtable *hash; int i; - hash = bat_priv->bla.claim_hash; + hash = bat_priv->claim_hash; if (!hash) return; @@ -1047,12 +1046,11 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, struct hlist_node *node; struct hlist_head *head; struct batadv_hashtable *hash; - __be16 group; int i; /* reset bridge loop avoidance group id */ - group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); - bat_priv->bla.claim_dest.group = group; + bat_priv->claim_dest.group = + htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); if (!oldif) { batadv_bla_purge_claims(bat_priv, NULL, 1); @@ -1060,7 +1058,7 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, return; } - hash = bat_priv->bla.backbone_hash; + hash = bat_priv->backbone_hash; if (!hash) return; @@ -1090,8 +1088,8 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, /* (re)start the timer */ static void batadv_bla_start_timer(struct batadv_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->bla.work, batadv_bla_periodic_work); - queue_delayed_work(batadv_event_workqueue, &bat_priv->bla.work, + INIT_DELAYED_WORK(&bat_priv->bla_work, batadv_bla_periodic_work); + queue_delayed_work(batadv_event_workqueue, &bat_priv->bla_work, msecs_to_jiffies(BATADV_BLA_PERIOD_LENGTH)); } @@ -1101,9 +1099,9 @@ static void batadv_bla_start_timer(struct batadv_priv *bat_priv) */ static void batadv_bla_periodic_work(struct work_struct *work) { - struct delayed_work *delayed_work; + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); struct batadv_priv *bat_priv; - struct batadv_priv_bla *priv_bla; struct hlist_node *node; struct hlist_head *head; struct batadv_backbone_gw *backbone_gw; @@ -1111,9 +1109,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) struct batadv_hard_iface *primary_if; int i; - delayed_work = container_of(work, struct delayed_work, work); - priv_bla = container_of(delayed_work, struct batadv_priv_bla, work); - bat_priv = container_of(priv_bla, struct batadv_priv, bla); + bat_priv = container_of(delayed_work, struct batadv_priv, bla_work); primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; @@ -1124,7 +1120,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) if (!atomic_read(&bat_priv->bridge_loop_avoidance)) goto out; - hash = bat_priv->bla.backbone_hash; + hash = bat_priv->backbone_hash; if (!hash) goto out; @@ -1164,41 +1160,40 @@ int batadv_bla_init(struct batadv_priv *bat_priv) int i; uint8_t claim_dest[ETH_ALEN] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00}; struct batadv_hard_iface *primary_if; - uint16_t crc; - unsigned long entrytime; batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n"); /* setting claim destination address */ - memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3); - bat_priv->bla.claim_dest.type = 0; + memcpy(&bat_priv->claim_dest.magic, claim_dest, 3); + bat_priv->claim_dest.type = 0; primary_if = batadv_primary_if_get_selected(bat_priv); if (primary_if) { - crc = crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN); - bat_priv->bla.claim_dest.group = htons(crc); + bat_priv->claim_dest.group = + htons(crc16(0, primary_if->net_dev->dev_addr, + ETH_ALEN)); batadv_hardif_free_ref(primary_if); } else { - bat_priv->bla.claim_dest.group = 0; /* will be set later */ + bat_priv->claim_dest.group = 0; /* will be set later */ } /* initialize the duplicate list */ - entrytime = jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT); for (i = 0; i < BATADV_DUPLIST_SIZE; i++) - bat_priv->bla.bcast_duplist[i].entrytime = entrytime; - bat_priv->bla.bcast_duplist_curr = 0; + bat_priv->bcast_duplist[i].entrytime = + jiffies - msecs_to_jiffies(BATADV_DUPLIST_TIMEOUT); + bat_priv->bcast_duplist_curr = 0; - if (bat_priv->bla.claim_hash) + if (bat_priv->claim_hash) return 0; - bat_priv->bla.claim_hash = batadv_hash_new(128); - bat_priv->bla.backbone_hash = batadv_hash_new(32); + bat_priv->claim_hash = batadv_hash_new(128); + bat_priv->backbone_hash = batadv_hash_new(32); - if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash) + if (!bat_priv->claim_hash || !bat_priv->backbone_hash) return -ENOMEM; - batadv_hash_set_lock_class(bat_priv->bla.claim_hash, + batadv_hash_set_lock_class(bat_priv->claim_hash, &batadv_claim_hash_lock_class_key); - batadv_hash_set_lock_class(bat_priv->bla.backbone_hash, + batadv_hash_set_lock_class(bat_priv->backbone_hash, &batadv_backbone_hash_lock_class_key); batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hashes initialized\n"); @@ -1239,9 +1234,8 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, crc = crc16(0, content, length); for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { - curr = (bat_priv->bla.bcast_duplist_curr + i); - curr %= BATADV_DUPLIST_SIZE; - entry = &bat_priv->bla.bcast_duplist[curr]; + curr = (bat_priv->bcast_duplist_curr + i) % BATADV_DUPLIST_SIZE; + entry = &bat_priv->bcast_duplist[curr]; /* we can stop searching if the entry is too old ; * later entries will be even older @@ -1262,13 +1256,13 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, return 1; } /* not found, add a new entry (overwrite the oldest entry) */ - curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); + curr = (bat_priv->bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); curr %= BATADV_DUPLIST_SIZE; - entry = &bat_priv->bla.bcast_duplist[curr]; + entry = &bat_priv->bcast_duplist[curr]; entry->crc = crc; entry->entrytime = jiffies; memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); - bat_priv->bla.bcast_duplist_curr = curr; + bat_priv->bcast_duplist_curr = curr; /* allow it, its the first occurence. */ return 0; @@ -1285,7 +1279,7 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, */ int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) { - struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; + struct batadv_hashtable *hash = bat_priv->backbone_hash; struct hlist_head *head; struct hlist_node *node; struct batadv_backbone_gw *backbone_gw; @@ -1345,7 +1339,8 @@ int batadv_bla_is_backbone_gw(struct sk_buff *skb, if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr))) return 0; - vhdr = (struct vlan_ethhdr *)(skb->data + hdr_size); + vhdr = (struct vlan_ethhdr *)(((uint8_t *)skb->data) + + hdr_size); vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; } @@ -1364,18 +1359,18 @@ void batadv_bla_free(struct batadv_priv *bat_priv) { struct batadv_hard_iface *primary_if; - cancel_delayed_work_sync(&bat_priv->bla.work); + cancel_delayed_work_sync(&bat_priv->bla_work); primary_if = batadv_primary_if_get_selected(bat_priv); - if (bat_priv->bla.claim_hash) { + if (bat_priv->claim_hash) { batadv_bla_purge_claims(bat_priv, primary_if, 1); - batadv_hash_destroy(bat_priv->bla.claim_hash); - bat_priv->bla.claim_hash = NULL; + batadv_hash_destroy(bat_priv->claim_hash); + bat_priv->claim_hash = NULL; } - if (bat_priv->bla.backbone_hash) { + if (bat_priv->backbone_hash) { batadv_bla_purge_backbone_gw(bat_priv, 1); - batadv_hash_destroy(bat_priv->bla.backbone_hash); - bat_priv->bla.backbone_hash = NULL; + batadv_hash_destroy(bat_priv->backbone_hash); + bat_priv->backbone_hash = NULL; } if (primary_if) batadv_hardif_free_ref(primary_if); @@ -1414,7 +1409,7 @@ int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid, goto allow; - if (unlikely(atomic_read(&bat_priv->bla.num_requests))) + if (unlikely(atomic_read(&bat_priv->bla_num_requests))) /* don't allow broadcasts while requests are in flight */ if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) goto handled; @@ -1513,7 +1508,7 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid) ethhdr = (struct ethhdr *)skb_mac_header(skb); - if (unlikely(atomic_read(&bat_priv->bla.num_requests))) + if (unlikely(atomic_read(&bat_priv->bla_num_requests))) /* don't allow broadcasts while requests are in flight */ if (is_multicast_ether_addr(ethhdr->h_dest)) goto handled; @@ -1569,7 +1564,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->bla.claim_hash; + struct batadv_hashtable *hash = bat_priv->claim_hash; struct batadv_claim *claim; struct batadv_hard_iface *primary_if; struct hlist_node *node; @@ -1598,7 +1593,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, "Claims announced for the mesh %s (orig %pM, group id %04x)\n", net_dev->name, primary_addr, - ntohs(bat_priv->bla.claim_dest.group)); + ntohs(bat_priv->claim_dest.group)); seq_printf(seq, " %-17s %-5s %-17s [o] (%-4s)\n", "Client", "VID", "Originator", "CRC"); for (i = 0; i < hash->size; i++) { @@ -1621,68 +1616,3 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset) batadv_hardif_free_ref(primary_if); return ret; } - -int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset) -{ - struct net_device *net_dev = (struct net_device *)seq->private; - struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->bla.backbone_hash; - struct batadv_backbone_gw *backbone_gw; - struct batadv_hard_iface *primary_if; - struct hlist_node *node; - struct hlist_head *head; - int secs, msecs; - uint32_t i; - bool is_own; - int ret = 0; - uint8_t *primary_addr; - - primary_if = batadv_primary_if_get_selected(bat_priv); - if (!primary_if) { - ret = seq_printf(seq, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); - goto out; - } - - if (primary_if->if_status != BATADV_IF_ACTIVE) { - ret = seq_printf(seq, - "BATMAN mesh %s disabled - primary interface not active\n", - net_dev->name); - goto out; - } - - primary_addr = primary_if->net_dev->dev_addr; - seq_printf(seq, - "Backbones announced for the mesh %s (orig %pM, group id %04x)\n", - net_dev->name, primary_addr, - ntohs(bat_priv->bla.claim_dest.group)); - seq_printf(seq, " %-17s %-5s %-9s (%-4s)\n", - "Originator", "VID", "last seen", "CRC"); - for (i = 0; i < hash->size; i++) { - head = &hash->table[i]; - - rcu_read_lock(); - hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) { - msecs = jiffies_to_msecs(jiffies - - backbone_gw->lasttime); - secs = msecs / 1000; - msecs = msecs % 1000; - - is_own = batadv_compare_eth(backbone_gw->orig, - primary_addr); - if (is_own) - continue; - - seq_printf(seq, - " * %pM on % 5d % 4i.%03is (%04x)\n", - backbone_gw->orig, backbone_gw->vid, - secs, msecs, backbone_gw->crc); - } - rcu_read_unlock(); - } -out: - if (primary_if) - batadv_hardif_free_ref(primary_if); - return ret; -} diff --git a/trunk/net/batman-adv/bridge_loop_avoidance.h b/trunk/net/batman-adv/bridge_loop_avoidance.h index 789cb73bde67..563cfbf94a7f 100644 --- a/trunk/net/batman-adv/bridge_loop_avoidance.h +++ b/trunk/net/batman-adv/bridge_loop_avoidance.h @@ -27,8 +27,6 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid); int batadv_bla_is_backbone_gw(struct sk_buff *skb, struct batadv_orig_node *orig_node, int hdr_size); int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); -int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, - void *offset); int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig); int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, struct batadv_bcast_packet *bcast_packet, @@ -43,7 +41,8 @@ void batadv_bla_free(struct batadv_priv *bat_priv); #else /* ifdef CONFIG_BATMAN_ADV_BLA */ static inline int batadv_bla_rx(struct batadv_priv *bat_priv, - struct sk_buff *skb, short vid, bool is_bcast) + struct sk_buff *skb, short vid, + bool is_bcast) { return 0; } @@ -67,12 +66,6 @@ static inline int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, return 0; } -static inline int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, - void *offset) -{ - return 0; -} - static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig) { diff --git a/trunk/net/batman-adv/debugfs.c b/trunk/net/batman-adv/debugfs.c index 391d4fb2026f..34fbb1667bcd 100644 --- a/trunk/net/batman-adv/debugfs.c +++ b/trunk/net/batman-adv/debugfs.c @@ -267,15 +267,6 @@ static int batadv_bla_claim_table_open(struct inode *inode, struct file *file) return single_open(file, batadv_bla_claim_table_seq_print_text, net_dev); } - -static int batadv_bla_backbone_table_open(struct inode *inode, - struct file *file) -{ - struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, batadv_bla_backbone_table_seq_print_text, - net_dev); -} - #endif static int batadv_transtable_local_open(struct inode *inode, struct file *file) @@ -314,8 +305,6 @@ static BATADV_DEBUGINFO(transtable_global, S_IRUGO, batadv_transtable_global_open); #ifdef CONFIG_BATMAN_ADV_BLA static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open); -static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO, - batadv_bla_backbone_table_open); #endif static BATADV_DEBUGINFO(transtable_local, S_IRUGO, batadv_transtable_local_open); @@ -327,7 +316,6 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = { &batadv_debuginfo_transtable_global, #ifdef CONFIG_BATMAN_ADV_BLA &batadv_debuginfo_bla_claim_table, - &batadv_debuginfo_bla_backbone_table, #endif &batadv_debuginfo_transtable_local, &batadv_debuginfo_vis_data, diff --git a/trunk/net/batman-adv/gateway_client.c b/trunk/net/batman-adv/gateway_client.c index 15d67abc10a4..fc866f2e4528 100644 --- a/trunk/net/batman-adv/gateway_client.c +++ b/trunk/net/batman-adv/gateway_client.c @@ -48,7 +48,7 @@ batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv) struct batadv_gw_node *gw_node; rcu_read_lock(); - gw_node = rcu_dereference(bat_priv->gw.curr_gw); + gw_node = rcu_dereference(bat_priv->curr_gw); if (!gw_node) goto out; @@ -91,23 +91,23 @@ static void batadv_gw_select(struct batadv_priv *bat_priv, { struct batadv_gw_node *curr_gw_node; - spin_lock_bh(&bat_priv->gw.list_lock); + spin_lock_bh(&bat_priv->gw_list_lock); if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount)) new_gw_node = NULL; - curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1); - rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node); + curr_gw_node = rcu_dereference_protected(bat_priv->curr_gw, 1); + rcu_assign_pointer(bat_priv->curr_gw, new_gw_node); if (curr_gw_node) batadv_gw_node_free_ref(curr_gw_node); - spin_unlock_bh(&bat_priv->gw.list_lock); + spin_unlock_bh(&bat_priv->gw_list_lock); } void batadv_gw_deselect(struct batadv_priv *bat_priv) { - atomic_set(&bat_priv->gw.reselect, 1); + atomic_set(&bat_priv->gw_reselect, 1); } static struct batadv_gw_node * @@ -117,17 +117,12 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) struct hlist_node *node; struct batadv_gw_node *gw_node, *curr_gw = NULL; uint32_t max_gw_factor = 0, tmp_gw_factor = 0; - uint32_t gw_divisor; uint8_t max_tq = 0; int down, up; - uint8_t tq_avg; struct batadv_orig_node *orig_node; - gw_divisor = BATADV_TQ_LOCAL_WINDOW_SIZE * BATADV_TQ_LOCAL_WINDOW_SIZE; - gw_divisor *= 64; - rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) { + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { if (gw_node->deleted) continue; @@ -139,19 +134,19 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) if (!atomic_inc_not_zero(&gw_node->refcount)) goto next; - tq_avg = router->tq_avg; - switch (atomic_read(&bat_priv->gw_sel_class)) { case 1: /* fast connection */ batadv_gw_bandwidth_to_kbit(orig_node->gw_flags, &down, &up); - tmp_gw_factor = tq_avg * tq_avg * down * 100 * 100; - tmp_gw_factor /= gw_divisor; + tmp_gw_factor = (router->tq_avg * router->tq_avg * + down * 100 * 100) / + (BATADV_TQ_LOCAL_WINDOW_SIZE * + BATADV_TQ_LOCAL_WINDOW_SIZE * 64); if ((tmp_gw_factor > max_gw_factor) || ((tmp_gw_factor == max_gw_factor) && - (tq_avg > max_tq))) { + (router->tq_avg > max_tq))) { if (curr_gw) batadv_gw_node_free_ref(curr_gw); curr_gw = gw_node; @@ -166,7 +161,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) * soon as a better gateway appears which has * $routing_class more tq points) */ - if (tq_avg > max_tq) { + if (router->tq_avg > max_tq) { if (curr_gw) batadv_gw_node_free_ref(curr_gw); curr_gw = gw_node; @@ -175,8 +170,8 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) break; } - if (tq_avg > max_tq) - max_tq = tq_avg; + if (router->tq_avg > max_tq) + max_tq = router->tq_avg; if (tmp_gw_factor > max_gw_factor) max_gw_factor = tmp_gw_factor; @@ -207,7 +202,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv) curr_gw = batadv_gw_get_selected_gw_node(bat_priv); - if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw) + if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw) goto out; next_gw = batadv_gw_get_best_gw_node(bat_priv); @@ -326,9 +321,9 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, gw_node->orig_node = orig_node; atomic_set(&gw_node->refcount, 1); - spin_lock_bh(&bat_priv->gw.list_lock); - hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list); - spin_unlock_bh(&bat_priv->gw.list_lock); + spin_lock_bh(&bat_priv->gw_list_lock); + hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); + spin_unlock_bh(&bat_priv->gw_list_lock); batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up); batadv_dbg(BATADV_DBG_BATMAN, bat_priv, @@ -355,7 +350,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv, curr_gw = batadv_gw_get_selected_gw_node(bat_priv); rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) { + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { if (gw_node->orig_node != orig_node) continue; @@ -409,10 +404,10 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv) curr_gw = batadv_gw_get_selected_gw_node(bat_priv); - spin_lock_bh(&bat_priv->gw.list_lock); + spin_lock_bh(&bat_priv->gw_list_lock); hlist_for_each_entry_safe(gw_node, node, node_tmp, - &bat_priv->gw.list, list) { + &bat_priv->gw_list, list) { if (((!gw_node->deleted) || (time_before(jiffies, gw_node->deleted + timeout))) && atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) @@ -425,7 +420,7 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv) batadv_gw_node_free_ref(gw_node); } - spin_unlock_bh(&bat_priv->gw.list_lock); + spin_unlock_bh(&bat_priv->gw_list_lock); /* gw_deselect() needs to acquire the gw_list_lock */ if (do_deselect) @@ -501,7 +496,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset) primary_if->net_dev->dev_addr, net_dev->name); rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) { + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { if (gw_node->deleted) continue; diff --git a/trunk/net/batman-adv/hard-interface.c b/trunk/net/batman-adv/hard-interface.c index d112fd6750b0..282bf6e9353e 100644 --- a/trunk/net/batman-adv/hard-interface.c +++ b/trunk/net/batman-adv/hard-interface.c @@ -103,14 +103,13 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv, { struct batadv_vis_packet *vis_packet; struct batadv_hard_iface *primary_if; - struct sk_buff *skb; primary_if = batadv_primary_if_get_selected(bat_priv); if (!primary_if) goto out; - skb = bat_priv->vis.my_info->skb_packet; - vis_packet = (struct batadv_vis_packet *)skb->data; + vis_packet = (struct batadv_vis_packet *) + bat_priv->my_vis_info->skb_packet->data; memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN); memcpy(vis_packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN); @@ -314,13 +313,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, hard_iface->if_num = bat_priv->num_ifaces; bat_priv->num_ifaces++; hard_iface->if_status = BATADV_IF_INACTIVE; - ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); - if (ret < 0) { - bat_priv->bat_algo_ops->bat_iface_disable(hard_iface); - bat_priv->num_ifaces--; - hard_iface->if_status = BATADV_IF_NOT_IN_USE; - goto err_dev; - } + batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces); hard_iface->batman_adv_ptype.type = ethertype; hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv; diff --git a/trunk/net/batman-adv/main.c b/trunk/net/batman-adv/main.c index b4aa470bc4a6..13c88b25ab31 100644 --- a/trunk/net/batman-adv/main.c +++ b/trunk/net/batman-adv/main.c @@ -58,6 +58,9 @@ static int __init batadv_init(void) batadv_iv_init(); + /* the name should not be longer than 10 chars - see + * http://lwn.net/Articles/23634/ + */ batadv_event_workqueue = create_singlethread_workqueue("bat_events"); if (!batadv_event_workqueue) @@ -94,20 +97,20 @@ int batadv_mesh_init(struct net_device *soft_iface) spin_lock_init(&bat_priv->forw_bat_list_lock); spin_lock_init(&bat_priv->forw_bcast_list_lock); - spin_lock_init(&bat_priv->tt.changes_list_lock); - spin_lock_init(&bat_priv->tt.req_list_lock); - spin_lock_init(&bat_priv->tt.roam_list_lock); - spin_lock_init(&bat_priv->tt.last_changeset_lock); - spin_lock_init(&bat_priv->gw.list_lock); - spin_lock_init(&bat_priv->vis.hash_lock); - spin_lock_init(&bat_priv->vis.list_lock); + spin_lock_init(&bat_priv->tt_changes_list_lock); + spin_lock_init(&bat_priv->tt_req_list_lock); + spin_lock_init(&bat_priv->tt_roam_list_lock); + spin_lock_init(&bat_priv->tt_buff_lock); + spin_lock_init(&bat_priv->gw_list_lock); + spin_lock_init(&bat_priv->vis_hash_lock); + spin_lock_init(&bat_priv->vis_list_lock); INIT_HLIST_HEAD(&bat_priv->forw_bat_list); INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); - INIT_HLIST_HEAD(&bat_priv->gw.list); - INIT_LIST_HEAD(&bat_priv->tt.changes_list); - INIT_LIST_HEAD(&bat_priv->tt.req_list); - INIT_LIST_HEAD(&bat_priv->tt.roam_list); + INIT_HLIST_HEAD(&bat_priv->gw_list); + INIT_LIST_HEAD(&bat_priv->tt_changes_list); + INIT_LIST_HEAD(&bat_priv->tt_req_list); + INIT_LIST_HEAD(&bat_priv->tt_roam_list); ret = batadv_originator_init(bat_priv); if (ret < 0) @@ -128,7 +131,7 @@ int batadv_mesh_init(struct net_device *soft_iface) if (ret < 0) goto err; - atomic_set(&bat_priv->gw.reselect, 0); + atomic_set(&bat_priv->gw_reselect, 0); atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); return 0; diff --git a/trunk/net/batman-adv/main.h b/trunk/net/batman-adv/main.h index d57b746219de..5d8fa0757947 100644 --- a/trunk/net/batman-adv/main.h +++ b/trunk/net/batman-adv/main.h @@ -26,7 +26,7 @@ #define BATADV_DRIVER_DEVICE "batman-adv" #ifndef BATADV_SOURCE_VERSION -#define BATADV_SOURCE_VERSION "2012.4.0" +#define BATADV_SOURCE_VERSION "2012.3.0" #endif /* B.A.T.M.A.N. parameters */ @@ -41,14 +41,13 @@ * -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE */ #define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */ -#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */ -#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */ -#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */ +#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */ +#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */ /* sliding packet range of received originator messages in sequence numbers * (should be a multiple of our word size) */ #define BATADV_TQ_LOCAL_WINDOW_SIZE 64 -/* milliseconds we have to keep pending tt_req */ +/* miliseconds we have to keep pending tt_req */ #define BATADV_TT_REQUEST_TIMEOUT 3000 #define BATADV_TQ_GLOBAL_WINDOW_SIZE 5 @@ -60,7 +59,7 @@ #define BATADV_TT_OGM_APPEND_MAX 3 /* Time in which a client can roam at most ROAMING_MAX_COUNT times in - * milliseconds + * miliseconds */ #define BATADV_ROAMING_MAX_TIME 20000 #define BATADV_ROAMING_MAX_COUNT 5 @@ -124,6 +123,15 @@ enum batadv_uev_type { /* Append 'batman-adv: ' before kernel messages */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +/* all messages related to routing / flooding / broadcasting / etc */ +enum batadv_dbg_level { + BATADV_DBG_BATMAN = 1 << 0, + BATADV_DBG_ROUTES = 1 << 1, /* route added / changed / deleted */ + BATADV_DBG_TT = 1 << 2, /* translation table operations */ + BATADV_DBG_BLA = 1 << 3, /* bridge loop avoidance */ + BATADV_DBG_ALL = 15, +}; + /* Kernel headers */ #include /* mutex */ @@ -165,15 +173,6 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops); int batadv_algo_select(struct batadv_priv *bat_priv, char *name); int batadv_algo_seq_print_text(struct seq_file *seq, void *offset); -/* all messages related to routing / flooding / broadcasting / etc */ -enum batadv_dbg_level { - BATADV_DBG_BATMAN = BIT(0), - BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */ - BATADV_DBG_TT = BIT(2), /* translation table operations */ - BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */ - BATADV_DBG_ALL = 15, -}; - #ifdef CONFIG_BATMAN_ADV_DEBUG int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) __printf(2, 3); diff --git a/trunk/net/batman-adv/packet.h b/trunk/net/batman-adv/packet.h index 2d23a14c220e..8d3e55a96adc 100644 --- a/trunk/net/batman-adv/packet.h +++ b/trunk/net/batman-adv/packet.h @@ -37,10 +37,10 @@ enum batadv_packettype { #define BATADV_COMPAT_VERSION 14 enum batadv_iv_flags { - BATADV_NOT_BEST_NEXT_HOP = BIT(3), - BATADV_PRIMARIES_FIRST_HOP = BIT(4), - BATADV_VIS_SERVER = BIT(5), - BATADV_DIRECTLINK = BIT(6), + BATADV_NOT_BEST_NEXT_HOP = 1 << 3, + BATADV_PRIMARIES_FIRST_HOP = 1 << 4, + BATADV_VIS_SERVER = 1 << 5, + BATADV_DIRECTLINK = 1 << 6, }; /* ICMP message types */ @@ -60,8 +60,8 @@ enum batadv_vis_packettype { /* fragmentation defines */ enum batadv_unicast_frag_flags { - BATADV_UNI_FRAG_HEAD = BIT(0), - BATADV_UNI_FRAG_LARGETAIL = BIT(1), + BATADV_UNI_FRAG_HEAD = 1 << 0, + BATADV_UNI_FRAG_LARGETAIL = 1 << 1, }; /* TT_QUERY subtypes */ @@ -74,27 +74,26 @@ enum batadv_tt_query_packettype { /* TT_QUERY flags */ enum batadv_tt_query_flags { - BATADV_TT_FULL_TABLE = BIT(2), + BATADV_TT_FULL_TABLE = 1 << 2, }; /* BATADV_TT_CLIENT flags. - * Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to - * BIT(15) are used for local computation only + * Flags from 1 to 1 << 7 are sent on the wire, while flags from 1 << 8 to + * 1 << 15 are used for local computation only */ enum batadv_tt_client_flags { - BATADV_TT_CLIENT_DEL = BIT(0), - BATADV_TT_CLIENT_ROAM = BIT(1), - BATADV_TT_CLIENT_WIFI = BIT(2), - BATADV_TT_CLIENT_TEMP = BIT(3), - BATADV_TT_CLIENT_NOPURGE = BIT(8), - BATADV_TT_CLIENT_NEW = BIT(9), - BATADV_TT_CLIENT_PENDING = BIT(10), + BATADV_TT_CLIENT_DEL = 1 << 0, + BATADV_TT_CLIENT_ROAM = 1 << 1, + BATADV_TT_CLIENT_WIFI = 1 << 2, + BATADV_TT_CLIENT_NOPURGE = 1 << 8, + BATADV_TT_CLIENT_NEW = 1 << 9, + BATADV_TT_CLIENT_PENDING = 1 << 10, }; /* claim frame types for the bridge loop avoidance */ enum batadv_bla_claimframe { - BATADV_CLAIM_TYPE_CLAIM = 0x00, - BATADV_CLAIM_TYPE_UNCLAIM = 0x01, + BATADV_CLAIM_TYPE_ADD = 0x00, + BATADV_CLAIM_TYPE_DEL = 0x01, BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, BATADV_CLAIM_TYPE_REQUEST = 0x03, }; diff --git a/trunk/net/batman-adv/routing.c b/trunk/net/batman-adv/routing.c index 939fc01371df..bc2b88bbea1f 100644 --- a/trunk/net/batman-adv/routing.c +++ b/trunk/net/batman-adv/routing.c @@ -579,45 +579,32 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, return router; } -static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) +int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { + struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); + struct batadv_tt_query_packet *tt_query; + uint16_t tt_size; struct ethhdr *ethhdr; + char tt_flag; + size_t packet_size; /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, hdr_size))) - return -1; + if (unlikely(!pskb_may_pull(skb, + sizeof(struct batadv_tt_query_packet)))) + goto out; + + /* I could need to modify it */ + if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0) + goto out; ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with unicast indication but broadcast recipient */ if (is_broadcast_ether_addr(ethhdr->h_dest)) - return -1; + goto out; /* packet with broadcast sender address */ if (is_broadcast_ether_addr(ethhdr->h_source)) - return -1; - - /* not for me */ - if (!batadv_is_my_mac(ethhdr->h_dest)) - return -1; - - return 0; -} - -int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) -{ - struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); - struct batadv_tt_query_packet *tt_query; - uint16_t tt_size; - int hdr_size = sizeof(*tt_query); - char tt_flag; - size_t packet_size; - - if (batadv_check_unicast_packet(skb, hdr_size) < 0) - return NET_RX_DROP; - - /* I could need to modify it */ - if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0) goto out; tt_query = (struct batadv_tt_query_packet *)skb->data; @@ -734,7 +721,7 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if) * been incremented yet. This flag will make me check all the incoming * packets for the correct destination. */ - bat_priv->tt.poss_change = true; + bat_priv->tt_poss_change = true; batadv_orig_node_free_ref(orig_node); out: @@ -832,6 +819,31 @@ batadv_find_router(struct batadv_priv *bat_priv, return NULL; } +static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) +{ + struct ethhdr *ethhdr; + + /* drop packet if it has not necessary minimum size */ + if (unlikely(!pskb_may_pull(skb, hdr_size))) + return -1; + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + /* packet with unicast indication but broadcast recipient */ + if (is_broadcast_ether_addr(ethhdr->h_dest)) + return -1; + + /* packet with broadcast sender address */ + if (is_broadcast_ether_addr(ethhdr->h_source)) + return -1; + + /* not for me */ + if (!batadv_is_my_mac(ethhdr->h_dest)) + return -1; + + return 0; +} + static int batadv_route_unicast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { @@ -935,8 +947,8 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, unicast_packet = (struct batadv_unicast_packet *)skb->data; if (batadv_is_my_mac(unicast_packet->dest)) { - tt_poss_change = bat_priv->tt.poss_change; - curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); + tt_poss_change = bat_priv->tt_poss_change; + curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); } else { orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->dest); @@ -981,7 +993,8 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, } else { memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); - curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); + curr_ttvn = (uint8_t) + atomic_read(&orig_node->last_ttvn); batadv_orig_node_free_ref(orig_node); } @@ -1012,9 +1025,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, /* packet for me */ if (batadv_is_my_mac(unicast_packet->dest)) { - batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, - NULL); - + batadv_interface_rx(recv_if->soft_iface, skb, recv_if, + hdr_size); return NET_RX_SUCCESS; } @@ -1051,7 +1063,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, return NET_RX_SUCCESS; batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, - sizeof(struct batadv_unicast_packet), NULL); + sizeof(struct batadv_unicast_packet)); return NET_RX_SUCCESS; } @@ -1138,8 +1150,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, goto out; /* broadcast for me */ - batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, - orig_node); + batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); ret = NET_RX_SUCCESS; goto out; diff --git a/trunk/net/batman-adv/send.c b/trunk/net/batman-adv/send.c index 570a8bce0364..3b4b2daa3b3e 100644 --- a/trunk/net/batman-adv/send.c +++ b/trunk/net/batman-adv/send.c @@ -190,13 +190,13 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, static void batadv_send_outstanding_bcast_packet(struct work_struct *work) { struct batadv_hard_iface *hard_iface; - struct delayed_work *delayed_work; + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); struct batadv_forw_packet *forw_packet; struct sk_buff *skb1; struct net_device *soft_iface; struct batadv_priv *bat_priv; - delayed_work = container_of(work, struct delayed_work, work); forw_packet = container_of(delayed_work, struct batadv_forw_packet, delayed_work); soft_iface = forw_packet->if_incoming->soft_iface; @@ -239,11 +239,11 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work) { - struct delayed_work *delayed_work; + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); struct batadv_forw_packet *forw_packet; struct batadv_priv *bat_priv; - delayed_work = container_of(work, struct delayed_work, work); forw_packet = container_of(delayed_work, struct batadv_forw_packet, delayed_work); bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); diff --git a/trunk/net/batman-adv/soft-interface.c b/trunk/net/batman-adv/soft-interface.c index 7b683e0bd668..109ea2aae96c 100644 --- a/trunk/net/batman-adv/soft-interface.c +++ b/trunk/net/batman-adv/soft-interface.c @@ -93,14 +93,7 @@ static int batadv_interface_release(struct net_device *dev) static struct net_device_stats *batadv_interface_stats(struct net_device *dev) { struct batadv_priv *bat_priv = netdev_priv(dev); - struct net_device_stats *stats = &bat_priv->stats; - - stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); - stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); - stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); - stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); - stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); - return stats; + return &bat_priv->stats; } static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) @@ -149,7 +142,6 @@ static int batadv_interface_tx(struct sk_buff *skb, int data_len = skb->len, ret; short vid __maybe_unused = -1; bool do_bcast = false; - uint32_t seqno; if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) goto dropped; @@ -231,8 +223,8 @@ static int batadv_interface_tx(struct sk_buff *skb, primary_if->net_dev->dev_addr, ETH_ALEN); /* set broadcast sequence number */ - seqno = atomic_inc_return(&bat_priv->bcast_seqno); - bcast_packet->seqno = htonl(seqno); + bcast_packet->seqno = + htonl(atomic_inc_return(&bat_priv->bcast_seqno)); batadv_add_bcast_packet_to_list(bat_priv, skb, 1); @@ -254,14 +246,14 @@ static int batadv_interface_tx(struct sk_buff *skb, goto dropped_freed; } - batadv_inc_counter(bat_priv, BATADV_CNT_TX); - batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); + bat_priv->stats.tx_packets++; + bat_priv->stats.tx_bytes += data_len; goto end; dropped: kfree_skb(skb); dropped_freed: - batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); + bat_priv->stats.tx_dropped++; end: if (primary_if) batadv_hardif_free_ref(primary_if); @@ -270,7 +262,7 @@ static int batadv_interface_tx(struct sk_buff *skb, void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, struct batadv_hard_iface *recv_if, - int hdr_size, struct batadv_orig_node *orig_node) + int hdr_size) { struct batadv_priv *bat_priv = netdev_priv(soft_iface); struct ethhdr *ethhdr; @@ -316,16 +308,11 @@ void batadv_interface_rx(struct net_device *soft_iface, /* skb->ip_summed = CHECKSUM_UNNECESSARY; */ - batadv_inc_counter(bat_priv, BATADV_CNT_RX); - batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, - skb->len + ETH_HLEN); + bat_priv->stats.rx_packets++; + bat_priv->stats.rx_bytes += skb->len + ETH_HLEN; soft_iface->last_rx = jiffies; - if (orig_node) - batadv_tt_add_temporary_global_entry(bat_priv, orig_node, - ethhdr->h_source); - if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped; @@ -392,22 +379,15 @@ struct net_device *batadv_softif_create(const char *name) if (!soft_iface) goto out; - bat_priv = netdev_priv(soft_iface); - - /* batadv_interface_stats() needs to be available as soon as - * register_netdevice() has been called - */ - bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); - if (!bat_priv->bat_counters) - goto free_soft_iface; - ret = register_netdevice(soft_iface); if (ret < 0) { pr_err("Unable to register the batman interface '%s': %i\n", name, ret); - goto free_bat_counters; + goto free_soft_iface; } + bat_priv = netdev_priv(soft_iface); + atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->bonding, 0); atomic_set(&bat_priv->bridge_loop_avoidance, 0); @@ -425,26 +405,29 @@ struct net_device *batadv_softif_create(const char *name) atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); atomic_set(&bat_priv->bcast_seqno, 1); - atomic_set(&bat_priv->tt.vn, 0); - atomic_set(&bat_priv->tt.local_changes, 0); - atomic_set(&bat_priv->tt.ogm_append_cnt, 0); -#ifdef CONFIG_BATMAN_ADV_BLA - atomic_set(&bat_priv->bla.num_requests, 0); -#endif - bat_priv->tt.last_changeset = NULL; - bat_priv->tt.last_changeset_len = 0; - bat_priv->tt.poss_change = false; + atomic_set(&bat_priv->ttvn, 0); + atomic_set(&bat_priv->tt_local_changes, 0); + atomic_set(&bat_priv->tt_ogm_append_cnt, 0); + atomic_set(&bat_priv->bla_num_requests, 0); + + bat_priv->tt_buff = NULL; + bat_priv->tt_buff_len = 0; + bat_priv->tt_poss_change = false; bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; + bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); + if (!bat_priv->bat_counters) + goto unreg_soft_iface; + ret = batadv_algo_select(bat_priv, batadv_routing_algo); if (ret < 0) - goto unreg_soft_iface; + goto free_bat_counters; ret = batadv_sysfs_add_meshif(soft_iface); if (ret < 0) - goto unreg_soft_iface; + goto free_bat_counters; ret = batadv_debugfs_add_meshif(soft_iface); if (ret < 0) @@ -460,13 +443,12 @@ struct net_device *batadv_softif_create(const char *name) batadv_debugfs_del_meshif(soft_iface); unreg_sysfs: batadv_sysfs_del_meshif(soft_iface); -unreg_soft_iface: +free_bat_counters: free_percpu(bat_priv->bat_counters); +unreg_soft_iface: unregister_netdevice(soft_iface); return NULL; -free_bat_counters: - free_percpu(bat_priv->bat_counters); free_soft_iface: free_netdev(soft_iface); out: @@ -536,11 +518,6 @@ static u32 batadv_get_link(struct net_device *dev) static const struct { const char name[ETH_GSTRING_LEN]; } batadv_counters_strings[] = { - { "tx" }, - { "tx_bytes" }, - { "tx_dropped" }, - { "rx" }, - { "rx_bytes" }, { "forward" }, { "forward_bytes" }, { "mgmt_tx" }, diff --git a/trunk/net/batman-adv/soft-interface.h b/trunk/net/batman-adv/soft-interface.h index 07a08fed28b9..852c683b06a1 100644 --- a/trunk/net/batman-adv/soft-interface.h +++ b/trunk/net/batman-adv/soft-interface.h @@ -21,9 +21,8 @@ #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ int batadv_skb_head_push(struct sk_buff *skb, unsigned int len); -void batadv_interface_rx(struct net_device *soft_iface, - struct sk_buff *skb, struct batadv_hard_iface *recv_if, - int hdr_size, struct batadv_orig_node *orig_node); +void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb, + struct batadv_hard_iface *recv_if, int hdr_size); struct net_device *batadv_softif_create(const char *name); void batadv_softif_destroy(struct net_device *soft_iface); int batadv_softif_is_valid(const struct net_device *net_dev); diff --git a/trunk/net/batman-adv/translation-table.c b/trunk/net/batman-adv/translation-table.c index 112edd371b2f..99dd8f75b3ff 100644 --- a/trunk/net/batman-adv/translation-table.c +++ b/trunk/net/batman-adv/translation-table.c @@ -34,10 +34,6 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, static void batadv_tt_purge(struct work_struct *work); static void batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry); -static void batadv_tt_global_del(struct batadv_priv *bat_priv, - struct batadv_orig_node *orig_node, - const unsigned char *addr, - const char *message, bool roaming); /* returns 1 if they are the same mac addr */ static int batadv_compare_tt(const struct hlist_node *node, const void *data2) @@ -50,8 +46,8 @@ static int batadv_compare_tt(const struct hlist_node *node, const void *data2) static void batadv_tt_start_timer(struct batadv_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge); - queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work, + INIT_DELAYED_WORK(&bat_priv->tt_work, batadv_tt_purge); + queue_delayed_work(batadv_event_workqueue, &bat_priv->tt_work, msecs_to_jiffies(5000)); } @@ -92,7 +88,7 @@ batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data) struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_local_entry *tt_local_entry = NULL; - tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data); + tt_common_entry = batadv_tt_hash_find(bat_priv->tt_local_hash, data); if (tt_common_entry) tt_local_entry = container_of(tt_common_entry, struct batadv_tt_local_entry, @@ -106,7 +102,7 @@ batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data) struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_global_entry *tt_global_entry = NULL; - tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data); + tt_common_entry = batadv_tt_hash_find(bat_priv->tt_global_hash, data); if (tt_common_entry) tt_global_entry = container_of(tt_common_entry, struct batadv_tt_global_entry, @@ -156,8 +152,6 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu) static void batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) { - if (!atomic_dec_and_test(&orig_entry->refcount)) - return; /* to avoid race conditions, immediately decrease the tt counter */ atomic_dec(&orig_entry->orig_node->tt_size); call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); @@ -181,8 +175,8 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, del_op_requested = flags & BATADV_TT_CLIENT_DEL; /* check for ADD+DEL or DEL+ADD events */ - spin_lock_bh(&bat_priv->tt.changes_list_lock); - list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, + spin_lock_bh(&bat_priv->tt_changes_list_lock); + list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, list) { if (!batadv_compare_eth(entry->change.addr, addr)) continue; @@ -209,15 +203,15 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, } /* track the change in the OGMinterval list */ - list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list); + list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list); unlock: - spin_unlock_bh(&bat_priv->tt.changes_list_lock); + spin_unlock_bh(&bat_priv->tt_changes_list_lock); if (event_removed) - atomic_dec(&bat_priv->tt.local_changes); + atomic_dec(&bat_priv->tt_local_changes); else - atomic_inc(&bat_priv->tt.local_changes); + atomic_inc(&bat_priv->tt_local_changes); } int batadv_tt_len(int changes_num) @@ -227,12 +221,12 @@ int batadv_tt_len(int changes_num) static int batadv_tt_local_init(struct batadv_priv *bat_priv) { - if (bat_priv->tt.local_hash) + if (bat_priv->tt_local_hash) return 0; - bat_priv->tt.local_hash = batadv_hash_new(1024); + bat_priv->tt_local_hash = batadv_hash_new(1024); - if (!bat_priv->tt.local_hash) + if (!bat_priv->tt_local_hash) return -ENOMEM; return 0; @@ -264,7 +258,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, batadv_dbg(BATADV_DBG_TT, bat_priv, "Creating new local tt entry: %pM (ttvn: %d)\n", addr, - (uint8_t)atomic_read(&bat_priv->tt.vn)); + (uint8_t)atomic_read(&bat_priv->ttvn)); memcpy(tt_local_entry->common.addr, addr, ETH_ALEN); tt_local_entry->common.flags = BATADV_NO_FLAGS; @@ -272,7 +266,6 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI; atomic_set(&tt_local_entry->common.refcount, 2); tt_local_entry->last_seen = jiffies; - tt_local_entry->common.added_at = tt_local_entry->last_seen; /* the batman interface mac address should never be purged */ if (batadv_compare_eth(addr, soft_iface->dev_addr)) @@ -284,7 +277,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, */ tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW; - hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt, + hash_added = batadv_hash_add(bat_priv->tt_local_hash, batadv_compare_tt, batadv_choose_orig, &tt_local_entry->common, &tt_local_entry->common.hash_entry); @@ -355,7 +348,7 @@ static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv, primary_if = batadv_primary_if_get_selected(bat_priv); req_len = min_packet_len; - req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes)); + req_len += batadv_tt_len(atomic_read(&bat_priv->tt_local_changes)); /* if we have too many changes for one packet don't send any * and wait for the tt table request which will be fragmented @@ -388,10 +381,10 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv, if (new_len > 0) tot_changes = new_len / batadv_tt_len(1); - spin_lock_bh(&bat_priv->tt.changes_list_lock); - atomic_set(&bat_priv->tt.local_changes, 0); + spin_lock_bh(&bat_priv->tt_changes_list_lock); + atomic_set(&bat_priv->tt_local_changes, 0); - list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, + list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, list) { if (count < tot_changes) { memcpy(tt_buff + batadv_tt_len(count), @@ -401,25 +394,25 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv, list_del(&entry->list); kfree(entry); } - spin_unlock_bh(&bat_priv->tt.changes_list_lock); + spin_unlock_bh(&bat_priv->tt_changes_list_lock); /* Keep the buffer for possible tt_request */ - spin_lock_bh(&bat_priv->tt.last_changeset_lock); - kfree(bat_priv->tt.last_changeset); - bat_priv->tt.last_changeset_len = 0; - bat_priv->tt.last_changeset = NULL; + spin_lock_bh(&bat_priv->tt_buff_lock); + kfree(bat_priv->tt_buff); + bat_priv->tt_buff_len = 0; + bat_priv->tt_buff = NULL; /* check whether this new OGM has no changes due to size problems */ if (new_len > 0) { /* if kmalloc() fails we will reply with the full table * instead of providing the diff */ - bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC); - if (bat_priv->tt.last_changeset) { - memcpy(bat_priv->tt.last_changeset, tt_buff, new_len); - bat_priv->tt.last_changeset_len = new_len; + bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC); + if (bat_priv->tt_buff) { + memcpy(bat_priv->tt_buff, tt_buff, new_len); + bat_priv->tt_buff_len = new_len; } } - spin_unlock_bh(&bat_priv->tt.last_changeset_lock); + spin_unlock_bh(&bat_priv->tt_buff_lock); return count; } @@ -428,7 +421,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->tt.local_hash; + struct batadv_hashtable *hash = bat_priv->tt_local_hash; struct batadv_tt_common_entry *tt_common_entry; struct batadv_hard_iface *primary_if; struct hlist_node *node; @@ -453,7 +446,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", - net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn)); + net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn)); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -551,7 +544,7 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv, static void batadv_tt_local_purge(struct batadv_priv *bat_priv) { - struct batadv_hashtable *hash = bat_priv->tt.local_hash; + struct batadv_hashtable *hash = bat_priv->tt_local_hash; struct hlist_head *head; spinlock_t *list_lock; /* protects write access to the hash lists */ uint32_t i; @@ -577,10 +570,10 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) struct hlist_head *head; uint32_t i; - if (!bat_priv->tt.local_hash) + if (!bat_priv->tt_local_hash) return; - hash = bat_priv->tt.local_hash; + hash = bat_priv->tt_local_hash; for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -600,17 +593,17 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv) batadv_hash_destroy(hash); - bat_priv->tt.local_hash = NULL; + bat_priv->tt_local_hash = NULL; } static int batadv_tt_global_init(struct batadv_priv *bat_priv) { - if (bat_priv->tt.global_hash) + if (bat_priv->tt_global_hash) return 0; - bat_priv->tt.global_hash = batadv_hash_new(1024); + bat_priv->tt_global_hash = batadv_hash_new(1024); - if (!bat_priv->tt.global_hash) + if (!bat_priv->tt_global_hash) return -ENOMEM; return 0; @@ -620,99 +613,62 @@ static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv) { struct batadv_tt_change_node *entry, *safe; - spin_lock_bh(&bat_priv->tt.changes_list_lock); + spin_lock_bh(&bat_priv->tt_changes_list_lock); - list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, + list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, list) { list_del(&entry->list); kfree(entry); } - atomic_set(&bat_priv->tt.local_changes, 0); - spin_unlock_bh(&bat_priv->tt.changes_list_lock); + atomic_set(&bat_priv->tt_local_changes, 0); + spin_unlock_bh(&bat_priv->tt_changes_list_lock); } -/* retrieves the orig_tt_list_entry belonging to orig_node from the - * batadv_tt_global_entry list - * - * returns it with an increased refcounter, NULL if not found +/* find out if an orig_node is already in the list of a tt_global_entry. + * returns 1 if found, 0 otherwise */ -static struct batadv_tt_orig_list_entry * -batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, - const struct batadv_orig_node *orig_node) +static bool +batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, + const struct batadv_orig_node *orig_node) { - struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL; + struct batadv_tt_orig_list_entry *tmp_orig_entry; const struct hlist_head *head; struct hlist_node *node; + bool found = false; rcu_read_lock(); head = &entry->orig_list; hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) { - if (tmp_orig_entry->orig_node != orig_node) - continue; - if (!atomic_inc_not_zero(&tmp_orig_entry->refcount)) - continue; - - orig_entry = tmp_orig_entry; - break; + if (tmp_orig_entry->orig_node == orig_node) { + found = true; + break; + } } rcu_read_unlock(); - - return orig_entry; -} - -/* find out if an orig_node is already in the list of a tt_global_entry. - * returns true if found, false otherwise - */ -static bool -batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, - const struct batadv_orig_node *orig_node) -{ - struct batadv_tt_orig_list_entry *orig_entry; - bool found = false; - - orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node); - if (orig_entry) { - found = true; - batadv_tt_orig_list_entry_free_ref(orig_entry); - } - return found; } static void -batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, +batadv_tt_global_add_orig_entry(struct batadv_tt_global_entry *tt_global_entry, struct batadv_orig_node *orig_node, int ttvn) { struct batadv_tt_orig_list_entry *orig_entry; - orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node); - if (orig_entry) { - /* refresh the ttvn: the current value could be a bogus one that - * was added during a "temporary client detection" - */ - orig_entry->ttvn = ttvn; - goto out; - } - orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC); if (!orig_entry) - goto out; + return; INIT_HLIST_NODE(&orig_entry->list); atomic_inc(&orig_node->refcount); atomic_inc(&orig_node->tt_size); orig_entry->orig_node = orig_node; orig_entry->ttvn = ttvn; - atomic_set(&orig_entry->refcount, 2); - spin_lock_bh(&tt_global->list_lock); + spin_lock_bh(&tt_global_entry->list_lock); hlist_add_head_rcu(&orig_entry->list, - &tt_global->orig_list); - spin_unlock_bh(&tt_global->list_lock); -out: - if (orig_entry) - batadv_tt_orig_list_entry_free_ref(orig_entry); + &tt_global_entry->orig_list); + spin_unlock_bh(&tt_global_entry->list_lock); } /* caller must hold orig_node refcount */ @@ -739,12 +695,11 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, common->flags = flags; tt_global_entry->roam_at = 0; atomic_set(&common->refcount, 2); - common->added_at = jiffies; INIT_HLIST_HEAD(&tt_global_entry->orig_list); spin_lock_init(&tt_global_entry->list_lock); - hash_added = batadv_hash_add(bat_priv->tt.global_hash, + hash_added = batadv_hash_add(bat_priv->tt_global_hash, batadv_compare_tt, batadv_choose_orig, common, &common->hash_entry); @@ -754,20 +709,11 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, batadv_tt_global_entry_free_ref(tt_global_entry); goto out_remove; } - } else { - /* If there is already a global entry, we can use this one for - * our processing. - * But if we are trying to add a temporary client we can exit - * directly because the temporary information should never - * override any already known client state (whatever it is) - */ - if (flags & BATADV_TT_CLIENT_TEMP) - goto out; - /* if the client was temporary added before receiving the first - * OGM announcing it, we have to clear the TEMP flag - */ - tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; + batadv_tt_global_add_orig_entry(tt_global_entry, orig_node, + ttvn); + } else { + /* there is already a global entry, use this one. */ /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only * one originator left in the list and we previously received a @@ -781,9 +727,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; tt_global_entry->roam_at = 0; } + + if (!batadv_tt_global_entry_has_orig(tt_global_entry, + orig_node)) + batadv_tt_global_add_orig_entry(tt_global_entry, + orig_node, ttvn); } - /* add the new orig_entry (if needed) or update it */ - batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); batadv_dbg(BATADV_DBG_TT, bat_priv, "Creating new global tt entry: %pM (via %pM)\n", @@ -822,12 +771,11 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, hlist_for_each_entry_rcu(orig_entry, node, head, list) { flags = tt_common_entry->flags; last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); - seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c%c]\n", + seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c]\n", tt_global_entry->common.addr, orig_entry->ttvn, orig_entry->orig_node->orig, last_ttvn, (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), - (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'), - (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.')); + (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.')); } } @@ -835,7 +783,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->tt.global_hash; + struct batadv_hashtable *hash = bat_priv->tt_global_hash; struct batadv_tt_common_entry *tt_common_entry; struct batadv_tt_global_entry *tt_global; struct batadv_hard_iface *primary_if; @@ -936,7 +884,7 @@ batadv_tt_global_del_struct(struct batadv_priv *bat_priv, "Deleting global tt entry %pM: %s\n", tt_global_entry->common.addr, message); - batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt, + batadv_hash_remove(bat_priv->tt_global_hash, batadv_compare_tt, batadv_choose_orig, tt_global_entry->common.addr); batadv_tt_global_entry_free_ref(tt_global_entry); @@ -1047,7 +995,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, struct batadv_tt_global_entry *tt_global; struct batadv_tt_common_entry *tt_common_entry; uint32_t i; - struct batadv_hashtable *hash = bat_priv->tt.global_hash; + struct batadv_hashtable *hash = bat_priv->tt_global_hash; struct hlist_node *node, *safe; struct hlist_head *head; spinlock_t *list_lock; /* protects write access to the hash lists */ @@ -1082,63 +1030,49 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, orig_node->tt_initialised = false; } -static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global, - char **msg) +static void batadv_tt_global_roam_purge_list(struct batadv_priv *bat_priv, + struct hlist_head *head) { - bool purge = false; - unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT; - unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT; + struct batadv_tt_common_entry *tt_common_entry; + struct batadv_tt_global_entry *tt_global_entry; + struct hlist_node *node, *node_tmp; - if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) && - batadv_has_timed_out(tt_global->roam_at, roam_timeout)) { - purge = true; - *msg = "Roaming timeout\n"; - } + hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head, + hash_entry) { + tt_global_entry = container_of(tt_common_entry, + struct batadv_tt_global_entry, + common); + if (!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM)) + continue; + if (!batadv_has_timed_out(tt_global_entry->roam_at, + BATADV_TT_CLIENT_ROAM_TIMEOUT)) + continue; - if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) && - batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) { - purge = true; - *msg = "Temporary client timeout\n"; - } + batadv_dbg(BATADV_DBG_TT, bat_priv, + "Deleting global tt entry (%pM): Roaming timeout\n", + tt_global_entry->common.addr); - return purge; + hlist_del_rcu(node); + batadv_tt_global_entry_free_ref(tt_global_entry); + } } -static void batadv_tt_global_purge(struct batadv_priv *bat_priv) +static void batadv_tt_global_roam_purge(struct batadv_priv *bat_priv) { - struct batadv_hashtable *hash = bat_priv->tt.global_hash; + struct batadv_hashtable *hash = bat_priv->tt_global_hash; struct hlist_head *head; - struct hlist_node *node, *node_tmp; spinlock_t *list_lock; /* protects write access to the hash lists */ uint32_t i; - char *msg = NULL; - struct batadv_tt_common_entry *tt_common; - struct batadv_tt_global_entry *tt_global; for (i = 0; i < hash->size; i++) { head = &hash->table[i]; list_lock = &hash->list_locks[i]; spin_lock_bh(list_lock); - hlist_for_each_entry_safe(tt_common, node, node_tmp, head, - hash_entry) { - tt_global = container_of(tt_common, - struct batadv_tt_global_entry, - common); - - if (!batadv_tt_global_to_purge(tt_global, &msg)) - continue; - - batadv_dbg(BATADV_DBG_TT, bat_priv, - "Deleting global tt entry (%pM): %s\n", - tt_global->common.addr, msg); - - hlist_del_rcu(node); - - batadv_tt_global_entry_free_ref(tt_global); - } + batadv_tt_global_roam_purge_list(bat_priv, head); spin_unlock_bh(list_lock); } + } static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) @@ -1151,10 +1085,10 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) struct hlist_head *head; uint32_t i; - if (!bat_priv->tt.global_hash) + if (!bat_priv->tt_global_hash) return; - hash = bat_priv->tt.global_hash; + hash = bat_priv->tt_global_hash; for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -1174,7 +1108,7 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) batadv_hash_destroy(hash); - bat_priv->tt.global_hash = NULL; + bat_priv->tt_global_hash = NULL; } static bool @@ -1253,7 +1187,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, struct batadv_orig_node *orig_node) { uint16_t total = 0, total_one; - struct batadv_hashtable *hash = bat_priv->tt.global_hash; + struct batadv_hashtable *hash = bat_priv->tt_global_hash; struct batadv_tt_common_entry *tt_common; struct batadv_tt_global_entry *tt_global; struct hlist_node *node; @@ -1276,12 +1210,6 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, */ if (tt_common->flags & BATADV_TT_CLIENT_ROAM) continue; - /* Temporary clients have not been announced yet, so - * they have to be skipped while computing the global - * crc - */ - if (tt_common->flags & BATADV_TT_CLIENT_TEMP) - continue; /* find out if this global entry is announced by this * originator @@ -1306,7 +1234,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv, static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv) { uint16_t total = 0, total_one; - struct batadv_hashtable *hash = bat_priv->tt.local_hash; + struct batadv_hashtable *hash = bat_priv->tt_local_hash; struct batadv_tt_common_entry *tt_common; struct hlist_node *node; struct hlist_head *head; @@ -1339,14 +1267,14 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv) { struct batadv_tt_req_node *node, *safe; - spin_lock_bh(&bat_priv->tt.req_list_lock); + spin_lock_bh(&bat_priv->tt_req_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { + list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { list_del(&node->list); kfree(node); } - spin_unlock_bh(&bat_priv->tt.req_list_lock); + spin_unlock_bh(&bat_priv->tt_req_list_lock); } static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, @@ -1376,15 +1304,15 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv) { struct batadv_tt_req_node *node, *safe; - spin_lock_bh(&bat_priv->tt.req_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { + spin_lock_bh(&bat_priv->tt_req_list_lock); + list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { if (batadv_has_timed_out(node->issued_at, BATADV_TT_REQUEST_TIMEOUT)) { list_del(&node->list); kfree(node); } } - spin_unlock_bh(&bat_priv->tt.req_list_lock); + spin_unlock_bh(&bat_priv->tt_req_list_lock); } /* returns the pointer to the new tt_req_node struct if no request @@ -1396,8 +1324,8 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv, { struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL; - spin_lock_bh(&bat_priv->tt.req_list_lock); - list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) { + spin_lock_bh(&bat_priv->tt_req_list_lock); + list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) { if (batadv_compare_eth(tt_req_node_tmp, orig_node) && !batadv_has_timed_out(tt_req_node_tmp->issued_at, BATADV_TT_REQUEST_TIMEOUT)) @@ -1411,9 +1339,9 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv, memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN); tt_req_node->issued_at = jiffies; - list_add(&tt_req_node->list, &bat_priv->tt.req_list); + list_add(&tt_req_node->list, &bat_priv->tt_req_list); unlock: - spin_unlock_bh(&bat_priv->tt.req_list_lock); + spin_unlock_bh(&bat_priv->tt_req_list_lock); return tt_req_node; } @@ -1435,8 +1363,7 @@ static int batadv_tt_global_valid(const void *entry_ptr, const struct batadv_tt_global_entry *tt_global_entry; const struct batadv_orig_node *orig_node = data_ptr; - if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM || - tt_common_entry->flags & BATADV_TT_CLIENT_TEMP) + if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM) return 0; tt_global_entry = container_of(tt_common_entry, @@ -1580,9 +1507,9 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv, if (ret) kfree_skb(skb); if (ret && tt_req_node) { - spin_lock_bh(&bat_priv->tt.req_list_lock); + spin_lock_bh(&bat_priv->tt_req_list_lock); list_del(&tt_req_node->list); - spin_unlock_bh(&bat_priv->tt.req_list_lock); + spin_unlock_bh(&bat_priv->tt_req_list_lock); kfree(tt_req_node); } return ret; @@ -1603,7 +1530,6 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, uint16_t tt_len, tt_tot; struct sk_buff *skb = NULL; struct batadv_tt_query_packet *tt_response; - uint8_t *packet_pos; size_t len; batadv_dbg(BATADV_DBG_TT, bat_priv, @@ -1657,8 +1583,8 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, goto unlock; skb_reserve(skb, ETH_HLEN); - packet_pos = skb_put(skb, len); - tt_response = (struct batadv_tt_query_packet *)packet_pos; + tt_response = (struct batadv_tt_query_packet *)skb_put(skb, + len); tt_response->ttvn = req_ttvn; tt_response->tt_data = htons(tt_tot); @@ -1674,7 +1600,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); skb = batadv_tt_response_fill_table(tt_len, ttvn, - bat_priv->tt.global_hash, + bat_priv->tt_global_hash, primary_if, batadv_tt_global_valid, req_dst_orig_node); @@ -1737,7 +1663,6 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, uint16_t tt_len, tt_tot; struct sk_buff *skb = NULL; struct batadv_tt_query_packet *tt_response; - uint8_t *packet_pos; size_t len; batadv_dbg(BATADV_DBG_TT, bat_priv, @@ -1746,7 +1671,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); - my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); + my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); req_ttvn = tt_request->ttvn; orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); @@ -1765,7 +1690,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, * is too big send the whole local translation table */ if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || - !bat_priv->tt.last_changeset) + !bat_priv->tt_buff) full_table = true; else full_table = false; @@ -1774,8 +1699,8 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, * I'll send only one packet with as much TT entries as I can */ if (!full_table) { - spin_lock_bh(&bat_priv->tt.last_changeset_lock); - tt_len = bat_priv->tt.last_changeset_len; + spin_lock_bh(&bat_priv->tt_buff_lock); + tt_len = bat_priv->tt_buff_len; tt_tot = tt_len / sizeof(struct batadv_tt_change); len = sizeof(*tt_response) + tt_len; @@ -1784,22 +1709,22 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, goto unlock; skb_reserve(skb, ETH_HLEN); - packet_pos = skb_put(skb, len); - tt_response = (struct batadv_tt_query_packet *)packet_pos; + tt_response = (struct batadv_tt_query_packet *)skb_put(skb, + len); tt_response->ttvn = req_ttvn; tt_response->tt_data = htons(tt_tot); tt_buff = skb->data + sizeof(*tt_response); - memcpy(tt_buff, bat_priv->tt.last_changeset, - bat_priv->tt.last_changeset_len); - spin_unlock_bh(&bat_priv->tt.last_changeset_lock); + memcpy(tt_buff, bat_priv->tt_buff, + bat_priv->tt_buff_len); + spin_unlock_bh(&bat_priv->tt_buff_lock); } else { - tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num); + tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt); tt_len *= sizeof(struct batadv_tt_change); - ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); + ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); skb = batadv_tt_response_fill_table(tt_len, ttvn, - bat_priv->tt.local_hash, + bat_priv->tt_local_hash, primary_if, batadv_tt_local_valid_entry, NULL); @@ -1831,7 +1756,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, goto out; unlock: - spin_unlock_bh(&bat_priv->tt.last_changeset_lock); + spin_unlock_bh(&bat_priv->tt_buff_lock); out: if (orig_node) batadv_orig_node_free_ref(orig_node); @@ -1984,14 +1909,14 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv, } /* Delete the tt_req_node from pending tt_requests list */ - spin_lock_bh(&bat_priv->tt.req_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) { + spin_lock_bh(&bat_priv->tt_req_list_lock); + list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { if (!batadv_compare_eth(node->addr, tt_response->src)) continue; list_del(&node->list); kfree(node); } - spin_unlock_bh(&bat_priv->tt.req_list_lock); + spin_unlock_bh(&bat_priv->tt_req_list_lock); /* Recalculate the CRC for this orig_node and store it */ orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); @@ -2025,22 +1950,22 @@ static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv) { struct batadv_tt_roam_node *node, *safe; - spin_lock_bh(&bat_priv->tt.roam_list_lock); + spin_lock_bh(&bat_priv->tt_roam_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { + list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { list_del(&node->list); kfree(node); } - spin_unlock_bh(&bat_priv->tt.roam_list_lock); + spin_unlock_bh(&bat_priv->tt_roam_list_lock); } static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) { struct batadv_tt_roam_node *node, *safe; - spin_lock_bh(&bat_priv->tt.roam_list_lock); - list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) { + spin_lock_bh(&bat_priv->tt_roam_list_lock); + list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { if (!batadv_has_timed_out(node->first_time, BATADV_ROAMING_MAX_TIME)) continue; @@ -2048,7 +1973,7 @@ static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) list_del(&node->list); kfree(node); } - spin_unlock_bh(&bat_priv->tt.roam_list_lock); + spin_unlock_bh(&bat_priv->tt_roam_list_lock); } /* This function checks whether the client already reached the @@ -2063,11 +1988,11 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, struct batadv_tt_roam_node *tt_roam_node; bool ret = false; - spin_lock_bh(&bat_priv->tt.roam_list_lock); + spin_lock_bh(&bat_priv->tt_roam_list_lock); /* The new tt_req will be issued only if I'm not waiting for a * reply from the same orig_node yet */ - list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) { + list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) { if (!batadv_compare_eth(tt_roam_node->addr, client)) continue; @@ -2092,12 +2017,12 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, BATADV_ROAMING_MAX_COUNT - 1); memcpy(tt_roam_node->addr, client, ETH_ALEN); - list_add(&tt_roam_node->list, &bat_priv->tt.roam_list); + list_add(&tt_roam_node->list, &bat_priv->tt_roam_list); ret = true; } unlock: - spin_unlock_bh(&bat_priv->tt.roam_list_lock); + spin_unlock_bh(&bat_priv->tt_roam_list_lock); return ret; } @@ -2161,15 +2086,13 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, static void batadv_tt_purge(struct work_struct *work) { struct delayed_work *delayed_work; - struct batadv_priv_tt *priv_tt; struct batadv_priv *bat_priv; delayed_work = container_of(work, struct delayed_work, work); - priv_tt = container_of(delayed_work, struct batadv_priv_tt, work); - bat_priv = container_of(priv_tt, struct batadv_priv, tt); + bat_priv = container_of(delayed_work, struct batadv_priv, tt_work); batadv_tt_local_purge(bat_priv); - batadv_tt_global_purge(bat_priv); + batadv_tt_global_roam_purge(bat_priv); batadv_tt_req_purge(bat_priv); batadv_tt_roam_purge(bat_priv); @@ -2178,7 +2101,7 @@ static void batadv_tt_purge(struct work_struct *work) void batadv_tt_free(struct batadv_priv *bat_priv) { - cancel_delayed_work_sync(&bat_priv->tt.work); + cancel_delayed_work_sync(&bat_priv->tt_work); batadv_tt_local_table_free(bat_priv); batadv_tt_global_table_free(bat_priv); @@ -2186,7 +2109,7 @@ void batadv_tt_free(struct batadv_priv *bat_priv) batadv_tt_changes_list_free(bat_priv); batadv_tt_roam_list_free(bat_priv); - kfree(bat_priv->tt.last_changeset); + kfree(bat_priv->tt_buff); } /* This function will enable or disable the specified flags for all the entries @@ -2230,7 +2153,7 @@ static uint16_t batadv_tt_set_flags(struct batadv_hashtable *hash, /* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) { - struct batadv_hashtable *hash = bat_priv->tt.local_hash; + struct batadv_hashtable *hash = bat_priv->tt_local_hash; struct batadv_tt_common_entry *tt_common; struct batadv_tt_local_entry *tt_local; struct hlist_node *node, *node_tmp; @@ -2255,7 +2178,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) "Deleting local tt entry (%pM): pending\n", tt_common->addr); - atomic_dec(&bat_priv->tt.local_entry_num); + atomic_dec(&bat_priv->num_local_tt); hlist_del_rcu(node); tt_local = container_of(tt_common, struct batadv_tt_local_entry, @@ -2273,26 +2196,26 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv, { uint16_t changed_num = 0; - if (atomic_read(&bat_priv->tt.local_changes) < 1) + if (atomic_read(&bat_priv->tt_local_changes) < 1) return -ENOENT; - changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash, + changed_num = batadv_tt_set_flags(bat_priv->tt_local_hash, BATADV_TT_CLIENT_NEW, false); /* all reset entries have to be counted as local entries */ - atomic_add(changed_num, &bat_priv->tt.local_entry_num); + atomic_add(changed_num, &bat_priv->num_local_tt); batadv_tt_local_purge_pending_clients(bat_priv); - bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv); + bat_priv->tt_crc = batadv_tt_local_crc(bat_priv); /* Increment the TTVN only once per OGM interval */ - atomic_inc(&bat_priv->tt.vn); + atomic_inc(&bat_priv->ttvn); batadv_dbg(BATADV_DBG_TT, bat_priv, "Local changes committed, updating to ttvn %u\n", - (uint8_t)atomic_read(&bat_priv->tt.vn)); - bat_priv->tt.poss_change = false; + (uint8_t)atomic_read(&bat_priv->ttvn)); + bat_priv->tt_poss_change = false; /* reset the sending counter */ - atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); + atomic_set(&bat_priv->tt_ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); return batadv_tt_changes_fill_buff(bat_priv, packet_buff, packet_buff_len, packet_min_len); @@ -2312,7 +2235,7 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv, /* if the changes have been sent often enough */ if ((tt_num_changes < 0) && - (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) { + (!batadv_atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, packet_min_len, packet_min_len); tt_num_changes = 0; @@ -2443,22 +2366,3 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, out: return ret; } - -bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, - struct batadv_orig_node *orig_node, - const unsigned char *addr) -{ - bool ret = false; - - if (!batadv_tt_global_add(bat_priv, orig_node, addr, - BATADV_TT_CLIENT_TEMP, - atomic_read(&orig_node->last_ttvn))) - goto out; - - batadv_dbg(BATADV_DBG_TT, bat_priv, - "Added temporary global client (addr: %pM orig: %pM)\n", - addr, orig_node->orig); - ret = true; -out: - return ret; -} diff --git a/trunk/net/batman-adv/translation-table.h b/trunk/net/batman-adv/translation-table.h index 811fffd4760c..ffa87355096b 100644 --- a/trunk/net/batman-adv/translation-table.h +++ b/trunk/net/batman-adv/translation-table.h @@ -59,8 +59,6 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv, int packet_min_len); bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv, uint8_t *addr); -bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, - struct batadv_orig_node *orig_node, - const unsigned char *addr); + #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ diff --git a/trunk/net/batman-adv/types.h b/trunk/net/batman-adv/types.h index 2ed82caacdca..12635fd2c3d3 100644 --- a/trunk/net/batman-adv/types.h +++ b/trunk/net/batman-adv/types.h @@ -145,11 +145,6 @@ struct batadv_bcast_duplist_entry { #endif enum batadv_counters { - BATADV_CNT_TX, - BATADV_CNT_TX_BYTES, - BATADV_CNT_TX_DROPPED, - BATADV_CNT_RX, - BATADV_CNT_RX_BYTES, BATADV_CNT_FORWARD, BATADV_CNT_FORWARD_BYTES, BATADV_CNT_MGMT_TX, @@ -165,67 +160,6 @@ enum batadv_counters { BATADV_CNT_NUM, }; -/** - * struct batadv_priv_tt - per mesh interface translation table data - * @vn: translation table version number - * @local_changes: changes registered in an originator interval - * @poss_change: Detect an ongoing roaming phase. If true, then this node - * received a roaming_adv and has to inspect every packet directed to it to - * check whether it still is the true destination or not. This flag will be - * reset to false as soon as the this node's ttvn is increased - * @changes_list: tracks tt local changes within an originator interval - * @req_list: list of pending tt_requests - * @local_crc: Checksum of the local table, recomputed before sending a new OGM - */ -struct batadv_priv_tt { - atomic_t vn; - atomic_t ogm_append_cnt; - atomic_t local_changes; - bool poss_change; - struct list_head changes_list; - struct batadv_hashtable *local_hash; - struct batadv_hashtable *global_hash; - struct list_head req_list; - struct list_head roam_list; - spinlock_t changes_list_lock; /* protects changes */ - spinlock_t req_list_lock; /* protects req_list */ - spinlock_t roam_list_lock; /* protects roam_list */ - atomic_t local_entry_num; - uint16_t local_crc; - unsigned char *last_changeset; - int16_t last_changeset_len; - spinlock_t last_changeset_lock; /* protects last_changeset */ - struct delayed_work work; -}; - -#ifdef CONFIG_BATMAN_ADV_BLA -struct batadv_priv_bla { - atomic_t num_requests; /* number of bla requests in flight */ - struct batadv_hashtable *claim_hash; - struct batadv_hashtable *backbone_hash; - struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; - int bcast_duplist_curr; - struct batadv_bla_claim_dst claim_dest; - struct delayed_work work; -}; -#endif - -struct batadv_priv_gw { - struct hlist_head list; - spinlock_t list_lock; /* protects gw_list and curr_gw */ - struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ - atomic_t reselect; -}; - -struct batadv_priv_vis { - struct list_head send_list; - struct batadv_hashtable *hash; - spinlock_t hash_lock; /* protects hash */ - spinlock_t list_lock; /* protects info::recv_list */ - struct delayed_work work; - struct batadv_vis_info *my_info; -}; - struct batadv_priv { atomic_t mesh_state; struct net_device_stats stats; @@ -245,24 +179,64 @@ struct batadv_priv { atomic_t bcast_seqno; atomic_t bcast_queue_left; atomic_t batman_queue_left; + atomic_t ttvn; /* translation table version number */ + atomic_t tt_ogm_append_cnt; + atomic_t tt_local_changes; /* changes registered in a OGM interval */ + atomic_t bla_num_requests; /* number of bla requests in flight */ + /* The tt_poss_change flag is used to detect an ongoing roaming phase. + * If true, then I received a Roaming_adv and I have to inspect every + * packet directed to me to check whether I am still the true + * destination or not. This flag will be reset to false as soon as I + * increase my TTVN + */ + bool tt_poss_change; char num_ifaces; struct batadv_debug_log *debug_log; struct kobject *mesh_obj; struct dentry *debug_dir; struct hlist_head forw_bat_list; struct hlist_head forw_bcast_list; + struct hlist_head gw_list; + struct list_head tt_changes_list; /* tracks changes in a OGM int */ + struct list_head vis_send_list; struct batadv_hashtable *orig_hash; + struct batadv_hashtable *tt_local_hash; + struct batadv_hashtable *tt_global_hash; +#ifdef CONFIG_BATMAN_ADV_BLA + struct batadv_hashtable *claim_hash; + struct batadv_hashtable *backbone_hash; +#endif + struct list_head tt_req_list; /* list of pending tt_requests */ + struct list_head tt_roam_list; + struct batadv_hashtable *vis_hash; +#ifdef CONFIG_BATMAN_ADV_BLA + struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; + int bcast_duplist_curr; + struct batadv_bla_claim_dst claim_dest; +#endif spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ spinlock_t forw_bcast_list_lock; /* protects */ + spinlock_t tt_changes_list_lock; /* protects tt_changes */ + spinlock_t tt_req_list_lock; /* protects tt_req_list */ + spinlock_t tt_roam_list_lock; /* protects tt_roam_list */ + spinlock_t gw_list_lock; /* protects gw_list and curr_gw */ + spinlock_t vis_hash_lock; /* protects vis_hash */ + spinlock_t vis_list_lock; /* protects vis_info::recv_list */ + atomic_t num_local_tt; + /* Checksum of the local table, recomputed before sending a new OGM */ + uint16_t tt_crc; + unsigned char *tt_buff; + int16_t tt_buff_len; + spinlock_t tt_buff_lock; /* protects tt_buff */ + struct delayed_work tt_work; struct delayed_work orig_work; + struct delayed_work vis_work; + struct delayed_work bla_work; + struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */ + atomic_t gw_reselect; struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */ + struct batadv_vis_info *my_vis_info; struct batadv_algo_ops *bat_algo_ops; -#ifdef CONFIG_BATMAN_ADV_BLA - struct batadv_priv_bla bla; -#endif - struct batadv_priv_gw gw; - struct batadv_priv_tt tt; - struct batadv_priv_vis vis; }; struct batadv_socket_client { @@ -284,7 +258,6 @@ struct batadv_tt_common_entry { uint8_t addr[ETH_ALEN]; struct hlist_node hash_entry; uint16_t flags; - unsigned long added_at; atomic_t refcount; struct rcu_head rcu; }; @@ -304,7 +277,6 @@ struct batadv_tt_global_entry { struct batadv_tt_orig_list_entry { struct batadv_orig_node *orig_node; uint8_t ttvn; - atomic_t refcount; struct rcu_head rcu; struct hlist_node list; }; diff --git a/trunk/net/batman-adv/unicast.c b/trunk/net/batman-adv/unicast.c index f39723281ca1..00164645b3f7 100644 --- a/trunk/net/batman-adv/unicast.c +++ b/trunk/net/batman-adv/unicast.c @@ -39,7 +39,6 @@ batadv_frag_merge_packet(struct list_head *head, struct batadv_unicast_packet *unicast_packet; int hdr_len = sizeof(*unicast_packet); int uni_diff = sizeof(*up) - hdr_len; - uint8_t *packet_pos; up = (struct batadv_unicast_frag_packet *)skb->data; /* set skb to the first part and tmp_skb to the second part */ @@ -66,8 +65,8 @@ batadv_frag_merge_packet(struct list_head *head, kfree_skb(tmp_skb); memmove(skb->data + uni_diff, skb->data, hdr_len); - packet_pos = skb_pull(skb, uni_diff); - unicast_packet = (struct batadv_unicast_packet *)packet_pos; + unicast_packet = (struct batadv_unicast_packet *)skb_pull(skb, + uni_diff); unicast_packet->header.packet_type = BATADV_UNICAST; return skb; @@ -122,7 +121,6 @@ batadv_frag_search_packet(struct list_head *head, { struct batadv_frag_packet_list_entry *tfp; struct batadv_unicast_frag_packet *tmp_up = NULL; - int is_head_tmp, is_head; uint16_t search_seqno; if (up->flags & BATADV_UNI_FRAG_HEAD) @@ -130,8 +128,6 @@ batadv_frag_search_packet(struct list_head *head, else search_seqno = ntohs(up->seqno)-1; - is_head = !!(up->flags & BATADV_UNI_FRAG_HEAD); - list_for_each_entry(tfp, head, list) { if (!tfp->skb) @@ -143,8 +139,9 @@ batadv_frag_search_packet(struct list_head *head, tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data; if (tfp->seqno == search_seqno) { - is_head_tmp = !!(tmp_up->flags & BATADV_UNI_FRAG_HEAD); - if (is_head_tmp != is_head) + + if ((tmp_up->flags & BATADV_UNI_FRAG_HEAD) != + (up->flags & BATADV_UNI_FRAG_HEAD)) return tfp; else goto mov_tail; @@ -337,7 +334,8 @@ int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv) /* copy the destination for faster routing */ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); /* set the destination tt version number */ - unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn); + unicast_packet->ttvn = + (uint8_t)atomic_read(&orig_node->last_ttvn); /* inform the destination node that we are still missing a correct route * for this client. The destination will receive this packet and will diff --git a/trunk/net/batman-adv/vis.c b/trunk/net/batman-adv/vis.c index 5abd1454fb07..2a2ea0681469 100644 --- a/trunk/net/batman-adv/vis.c +++ b/trunk/net/batman-adv/vis.c @@ -41,13 +41,13 @@ static void batadv_free_info(struct kref *ref) bat_priv = info->bat_priv; list_del_init(&info->send_list); - spin_lock_bh(&bat_priv->vis.list_lock); + spin_lock_bh(&bat_priv->vis_list_lock); list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { list_del(&entry->list); kfree(entry); } - spin_unlock_bh(&bat_priv->vis.list_lock); + spin_unlock_bh(&bat_priv->vis_list_lock); kfree_skb(info->skb_packet); kfree(info); } @@ -94,7 +94,7 @@ static uint32_t batadv_vis_info_choose(const void *data, uint32_t size) static struct batadv_vis_info * batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data) { - struct batadv_hashtable *hash = bat_priv->vis.hash; + struct batadv_hashtable *hash = bat_priv->vis_hash; struct hlist_head *head; struct hlist_node *node; struct batadv_vis_info *vis_info, *vis_info_tmp = NULL; @@ -252,7 +252,7 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) struct hlist_head *head; struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->vis.hash; + struct batadv_hashtable *hash = bat_priv->vis_hash; uint32_t i; int ret = 0; int vis_server = atomic_read(&bat_priv->vis_mode); @@ -264,12 +264,12 @@ int batadv_vis_seq_print_text(struct seq_file *seq, void *offset) if (vis_server == BATADV_VIS_TYPE_CLIENT_UPDATE) goto out; - spin_lock_bh(&bat_priv->vis.hash_lock); + spin_lock_bh(&bat_priv->vis_hash_lock); for (i = 0; i < hash->size; i++) { head = &hash->table[i]; batadv_vis_seq_print_text_bucket(seq, head); } - spin_unlock_bh(&bat_priv->vis.hash_lock); + spin_unlock_bh(&bat_priv->vis_hash_lock); out: if (primary_if) @@ -285,7 +285,7 @@ static void batadv_send_list_add(struct batadv_priv *bat_priv, { if (list_empty(&info->send_list)) { kref_get(&info->refcount); - list_add_tail(&info->send_list, &bat_priv->vis.send_list); + list_add_tail(&info->send_list, &bat_priv->vis_send_list); } } @@ -311,9 +311,9 @@ static void batadv_recv_list_add(struct batadv_priv *bat_priv, return; memcpy(entry->mac, mac, ETH_ALEN); - spin_lock_bh(&bat_priv->vis.list_lock); + spin_lock_bh(&bat_priv->vis_list_lock); list_add_tail(&entry->list, recv_list); - spin_unlock_bh(&bat_priv->vis.list_lock); + spin_unlock_bh(&bat_priv->vis_list_lock); } /* returns 1 if this mac is in the recv_list */ @@ -323,14 +323,14 @@ static int batadv_recv_list_is_in(struct batadv_priv *bat_priv, { const struct batadv_recvlist_node *entry; - spin_lock_bh(&bat_priv->vis.list_lock); + spin_lock_bh(&bat_priv->vis_list_lock); list_for_each_entry(entry, recv_list, list) { if (batadv_compare_eth(entry->mac, mac)) { - spin_unlock_bh(&bat_priv->vis.list_lock); + spin_unlock_bh(&bat_priv->vis_list_lock); return 1; } } - spin_unlock_bh(&bat_priv->vis.list_lock); + spin_unlock_bh(&bat_priv->vis_list_lock); return 0; } @@ -354,7 +354,7 @@ batadv_add_packet(struct batadv_priv *bat_priv, *is_new = 0; /* sanity check */ - if (!bat_priv->vis.hash) + if (!bat_priv->vis_hash) return NULL; /* see if the packet is already in vis_hash */ @@ -385,7 +385,7 @@ batadv_add_packet(struct batadv_priv *bat_priv, } } /* remove old entry */ - batadv_hash_remove(bat_priv->vis.hash, batadv_vis_info_cmp, + batadv_hash_remove(bat_priv->vis_hash, batadv_vis_info_cmp, batadv_vis_info_choose, old_info); batadv_send_list_del(old_info); kref_put(&old_info->refcount, batadv_free_info); @@ -426,7 +426,7 @@ batadv_add_packet(struct batadv_priv *bat_priv, batadv_recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); /* try to add it */ - hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp, + hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, batadv_vis_info_choose, info, &info->hash_entry); if (hash_added != 0) { @@ -449,7 +449,7 @@ void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv, make_broadcast = (vis_server == BATADV_VIS_TYPE_SERVER_SYNC); - spin_lock_bh(&bat_priv->vis.hash_lock); + spin_lock_bh(&bat_priv->vis_hash_lock); info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, &is_new, make_broadcast); if (!info) @@ -461,7 +461,7 @@ void batadv_receive_server_sync_packet(struct batadv_priv *bat_priv, if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && is_new) batadv_send_list_add(bat_priv, info); end: - spin_unlock_bh(&bat_priv->vis.hash_lock); + spin_unlock_bh(&bat_priv->vis_hash_lock); } /* handle an incoming client update packet and schedule forward if needed. */ @@ -484,7 +484,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, batadv_is_my_mac(vis_packet->target_orig)) are_target = 1; - spin_lock_bh(&bat_priv->vis.hash_lock); + spin_lock_bh(&bat_priv->vis_hash_lock); info = batadv_add_packet(bat_priv, vis_packet, vis_info_len, &is_new, are_target); @@ -505,7 +505,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, } end: - spin_unlock_bh(&bat_priv->vis.hash_lock); + spin_unlock_bh(&bat_priv->vis_hash_lock); } /* Walk the originators and find the VIS server with the best tq. Set the packet @@ -574,11 +574,10 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) struct hlist_head *head; struct batadv_orig_node *orig_node; struct batadv_neigh_node *router; - struct batadv_vis_info *info = bat_priv->vis.my_info; + struct batadv_vis_info *info = bat_priv->my_vis_info; struct batadv_vis_packet *packet; struct batadv_vis_info_entry *entry; struct batadv_tt_common_entry *tt_common_entry; - uint8_t *packet_pos; int best_tq = -1; uint32_t i; @@ -619,8 +618,8 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) goto next; /* fill one entry into buffer. */ - packet_pos = skb_put(info->skb_packet, sizeof(*entry)); - entry = (struct batadv_vis_info_entry *)packet_pos; + entry = (struct batadv_vis_info_entry *) + skb_put(info->skb_packet, sizeof(*entry)); memcpy(entry->src, router->if_incoming->net_dev->dev_addr, ETH_ALEN); @@ -637,7 +636,7 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) rcu_read_unlock(); } - hash = bat_priv->tt.local_hash; + hash = bat_priv->tt_local_hash; for (i = 0; i < hash->size; i++) { head = &hash->table[i]; @@ -645,8 +644,9 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) rcu_read_lock(); hlist_for_each_entry_rcu(tt_common_entry, node, head, hash_entry) { - packet_pos = skb_put(info->skb_packet, sizeof(*entry)); - entry = (struct batadv_vis_info_entry *)packet_pos; + entry = (struct batadv_vis_info_entry *) + skb_put(info->skb_packet, + sizeof(*entry)); memset(entry->src, 0, ETH_ALEN); memcpy(entry->dest, tt_common_entry->addr, ETH_ALEN); entry->quality = 0; /* 0 means TT */ @@ -671,7 +671,7 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) static void batadv_purge_vis_packets(struct batadv_priv *bat_priv) { uint32_t i; - struct batadv_hashtable *hash = bat_priv->vis.hash; + struct batadv_hashtable *hash = bat_priv->vis_hash; struct hlist_node *node, *node_tmp; struct hlist_head *head; struct batadv_vis_info *info; @@ -682,7 +682,7 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv) hlist_for_each_entry_safe(info, node, node_tmp, head, hash_entry) { /* never purge own data. */ - if (info == bat_priv->vis.my_info) + if (info == bat_priv->my_vis_info) continue; if (batadv_has_timed_out(info->first_seen, @@ -814,36 +814,34 @@ static void batadv_send_vis_packet(struct batadv_priv *bat_priv, /* called from timer; send (and maybe generate) vis packet. */ static void batadv_send_vis_packets(struct work_struct *work) { - struct delayed_work *delayed_work; + struct delayed_work *delayed_work = + container_of(work, struct delayed_work, work); struct batadv_priv *bat_priv; - struct batadv_priv_vis *priv_vis; struct batadv_vis_info *info; - delayed_work = container_of(work, struct delayed_work, work); - priv_vis = container_of(delayed_work, struct batadv_priv_vis, work); - bat_priv = container_of(priv_vis, struct batadv_priv, vis); - spin_lock_bh(&bat_priv->vis.hash_lock); + bat_priv = container_of(delayed_work, struct batadv_priv, vis_work); + spin_lock_bh(&bat_priv->vis_hash_lock); batadv_purge_vis_packets(bat_priv); if (batadv_generate_vis_packet(bat_priv) == 0) { /* schedule if generation was successful */ - batadv_send_list_add(bat_priv, bat_priv->vis.my_info); + batadv_send_list_add(bat_priv, bat_priv->my_vis_info); } - while (!list_empty(&bat_priv->vis.send_list)) { - info = list_first_entry(&bat_priv->vis.send_list, + while (!list_empty(&bat_priv->vis_send_list)) { + info = list_first_entry(&bat_priv->vis_send_list, typeof(*info), send_list); kref_get(&info->refcount); - spin_unlock_bh(&bat_priv->vis.hash_lock); + spin_unlock_bh(&bat_priv->vis_hash_lock); batadv_send_vis_packet(bat_priv, info); - spin_lock_bh(&bat_priv->vis.hash_lock); + spin_lock_bh(&bat_priv->vis_hash_lock); batadv_send_list_del(info); kref_put(&info->refcount, batadv_free_info); } - spin_unlock_bh(&bat_priv->vis.hash_lock); + spin_unlock_bh(&bat_priv->vis_hash_lock); batadv_start_vis_timer(bat_priv); } @@ -858,37 +856,37 @@ int batadv_vis_init(struct batadv_priv *bat_priv) unsigned long first_seen; struct sk_buff *tmp_skb; - if (bat_priv->vis.hash) + if (bat_priv->vis_hash) return 0; - spin_lock_bh(&bat_priv->vis.hash_lock); + spin_lock_bh(&bat_priv->vis_hash_lock); - bat_priv->vis.hash = batadv_hash_new(256); - if (!bat_priv->vis.hash) { + bat_priv->vis_hash = batadv_hash_new(256); + if (!bat_priv->vis_hash) { pr_err("Can't initialize vis_hash\n"); goto err; } - bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); - if (!bat_priv->vis.my_info) + bat_priv->my_vis_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); + if (!bat_priv->my_vis_info) goto err; len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN; - bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len); - if (!bat_priv->vis.my_info->skb_packet) + bat_priv->my_vis_info->skb_packet = dev_alloc_skb(len); + if (!bat_priv->my_vis_info->skb_packet) goto free_info; - skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN); - tmp_skb = bat_priv->vis.my_info->skb_packet; + skb_reserve(bat_priv->my_vis_info->skb_packet, ETH_HLEN); + tmp_skb = bat_priv->my_vis_info->skb_packet; packet = (struct batadv_vis_packet *)skb_put(tmp_skb, sizeof(*packet)); /* prefill the vis info */ first_seen = jiffies - msecs_to_jiffies(BATADV_VIS_INTERVAL); - bat_priv->vis.my_info->first_seen = first_seen; - INIT_LIST_HEAD(&bat_priv->vis.my_info->recv_list); - INIT_LIST_HEAD(&bat_priv->vis.my_info->send_list); - kref_init(&bat_priv->vis.my_info->refcount); - bat_priv->vis.my_info->bat_priv = bat_priv; + bat_priv->my_vis_info->first_seen = first_seen; + INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list); + INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); + kref_init(&bat_priv->my_vis_info->refcount); + bat_priv->my_vis_info->bat_priv = bat_priv; packet->header.version = BATADV_COMPAT_VERSION; packet->header.packet_type = BATADV_VIS; packet->header.ttl = BATADV_TTL; @@ -896,28 +894,28 @@ int batadv_vis_init(struct batadv_priv *bat_priv) packet->reserved = 0; packet->entries = 0; - INIT_LIST_HEAD(&bat_priv->vis.send_list); + INIT_LIST_HEAD(&bat_priv->vis_send_list); - hash_added = batadv_hash_add(bat_priv->vis.hash, batadv_vis_info_cmp, + hash_added = batadv_hash_add(bat_priv->vis_hash, batadv_vis_info_cmp, batadv_vis_info_choose, - bat_priv->vis.my_info, - &bat_priv->vis.my_info->hash_entry); + bat_priv->my_vis_info, + &bat_priv->my_vis_info->hash_entry); if (hash_added != 0) { pr_err("Can't add own vis packet into hash\n"); /* not in hash, need to remove it manually. */ - kref_put(&bat_priv->vis.my_info->refcount, batadv_free_info); + kref_put(&bat_priv->my_vis_info->refcount, batadv_free_info); goto err; } - spin_unlock_bh(&bat_priv->vis.hash_lock); + spin_unlock_bh(&bat_priv->vis_hash_lock); batadv_start_vis_timer(bat_priv); return 0; free_info: - kfree(bat_priv->vis.my_info); - bat_priv->vis.my_info = NULL; + kfree(bat_priv->my_vis_info); + bat_priv->my_vis_info = NULL; err: - spin_unlock_bh(&bat_priv->vis.hash_lock); + spin_unlock_bh(&bat_priv->vis_hash_lock); batadv_vis_quit(bat_priv); return -ENOMEM; } @@ -935,23 +933,23 @@ static void batadv_free_info_ref(struct hlist_node *node, void *arg) /* shutdown vis-server */ void batadv_vis_quit(struct batadv_priv *bat_priv) { - if (!bat_priv->vis.hash) + if (!bat_priv->vis_hash) return; - cancel_delayed_work_sync(&bat_priv->vis.work); + cancel_delayed_work_sync(&bat_priv->vis_work); - spin_lock_bh(&bat_priv->vis.hash_lock); + spin_lock_bh(&bat_priv->vis_hash_lock); /* properly remove, kill timers ... */ - batadv_hash_delete(bat_priv->vis.hash, batadv_free_info_ref, NULL); - bat_priv->vis.hash = NULL; - bat_priv->vis.my_info = NULL; - spin_unlock_bh(&bat_priv->vis.hash_lock); + batadv_hash_delete(bat_priv->vis_hash, batadv_free_info_ref, NULL); + bat_priv->vis_hash = NULL; + bat_priv->my_vis_info = NULL; + spin_unlock_bh(&bat_priv->vis_hash_lock); } /* schedule packets for (re)transmission */ static void batadv_start_vis_timer(struct batadv_priv *bat_priv) { - INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets); - queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work, + INIT_DELAYED_WORK(&bat_priv->vis_work, batadv_send_vis_packets); + queue_delayed_work(batadv_event_workqueue, &bat_priv->vis_work, msecs_to_jiffies(BATADV_VIS_INTERVAL)); } diff --git a/trunk/net/batman-adv/vis.h b/trunk/net/batman-adv/vis.h index 873282fa86da..84e716ed8963 100644 --- a/trunk/net/batman-adv/vis.h +++ b/trunk/net/batman-adv/vis.h @@ -20,7 +20,7 @@ #ifndef _NET_BATMAN_ADV_VIS_H_ #define _NET_BATMAN_ADV_VIS_H_ -/* timeout of vis packets in milliseconds */ +/* timeout of vis packets in miliseconds */ #define BATADV_VIS_TIMEOUT 200000 int batadv_vis_seq_print_text(struct seq_file *seq, void *offset); diff --git a/trunk/net/ceph/ceph_common.c b/trunk/net/ceph/ceph_common.c index a8020293f342..69e38db28e5f 100644 --- a/trunk/net/ceph/ceph_common.c +++ b/trunk/net/ceph/ceph_common.c @@ -84,6 +84,7 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid) return -1; } } else { + pr_info("client%lld fsid %pU\n", ceph_client_id(client), fsid); memcpy(&client->fsid, fsid, sizeof(*fsid)); } return 0; diff --git a/trunk/net/ceph/debugfs.c b/trunk/net/ceph/debugfs.c index 38b5dc1823d4..54b531a01121 100644 --- a/trunk/net/ceph/debugfs.c +++ b/trunk/net/ceph/debugfs.c @@ -189,9 +189,6 @@ int ceph_debugfs_client_init(struct ceph_client *client) snprintf(name, sizeof(name), "%pU.client%lld", &client->fsid, client->monc.auth->global_id); - dout("ceph_debugfs_client_init %p %s\n", client, name); - - BUG_ON(client->debugfs_dir); client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir); if (!client->debugfs_dir) goto out; @@ -237,7 +234,6 @@ int ceph_debugfs_client_init(struct ceph_client *client) void ceph_debugfs_client_cleanup(struct ceph_client *client) { - dout("ceph_debugfs_client_cleanup %p\n", client); debugfs_remove(client->debugfs_osdmap); debugfs_remove(client->debugfs_monmap); debugfs_remove(client->osdc.debugfs_file); diff --git a/trunk/net/ceph/messenger.c b/trunk/net/ceph/messenger.c index 24c5eea8c45b..b9796750034a 100644 --- a/trunk/net/ceph/messenger.c +++ b/trunk/net/ceph/messenger.c @@ -915,6 +915,7 @@ static int prepare_write_connect(struct ceph_connection *con) con->out_connect.authorizer_len = auth ? cpu_to_le32(auth->authorizer_buf_len) : 0; + con_out_kvec_reset(con); con_out_kvec_add(con, sizeof (con->out_connect), &con->out_connect); if (auth && auth->authorizer_buf_len) @@ -1556,7 +1557,6 @@ static int process_connect(struct ceph_connection *con) return -1; } con->auth_retry = 1; - con_out_kvec_reset(con); ret = prepare_write_connect(con); if (ret < 0) return ret; @@ -1577,7 +1577,6 @@ static int process_connect(struct ceph_connection *con) ENTITY_NAME(con->peer_name), ceph_pr_addr(&con->peer_addr.in_addr)); reset_connection(con); - con_out_kvec_reset(con); ret = prepare_write_connect(con); if (ret < 0) return ret; @@ -1602,7 +1601,6 @@ static int process_connect(struct ceph_connection *con) le32_to_cpu(con->out_connect.connect_seq), le32_to_cpu(con->in_reply.connect_seq)); con->connect_seq = le32_to_cpu(con->in_reply.connect_seq); - con_out_kvec_reset(con); ret = prepare_write_connect(con); if (ret < 0) return ret; @@ -1619,7 +1617,6 @@ static int process_connect(struct ceph_connection *con) le32_to_cpu(con->in_reply.global_seq)); get_global_seq(con->msgr, le32_to_cpu(con->in_reply.global_seq)); - con_out_kvec_reset(con); ret = prepare_write_connect(con); if (ret < 0) return ret; @@ -2138,11 +2135,7 @@ static int try_read(struct ceph_connection *con) BUG_ON(con->state != CON_STATE_CONNECTING); con->state = CON_STATE_NEGOTIATING; - /* - * Received banner is good, exchange connection info. - * Do not reset out_kvec, as sending our banner raced - * with receiving peer banner after connect completed. - */ + /* Banner is good, exchange connection info */ ret = prepare_write_connect(con); if (ret < 0) goto out; diff --git a/trunk/net/ceph/mon_client.c b/trunk/net/ceph/mon_client.c index 900ea0f043fc..105d533b55f3 100644 --- a/trunk/net/ceph/mon_client.c +++ b/trunk/net/ceph/mon_client.c @@ -310,17 +310,6 @@ int ceph_monc_open_session(struct ceph_mon_client *monc) } EXPORT_SYMBOL(ceph_monc_open_session); -/* - * We require the fsid and global_id in order to initialize our - * debugfs dir. - */ -static bool have_debugfs_info(struct ceph_mon_client *monc) -{ - dout("have_debugfs_info fsid %d globalid %lld\n", - (int)monc->client->have_fsid, monc->auth->global_id); - return monc->client->have_fsid && monc->auth->global_id > 0; -} - /* * The monitor responds with mount ack indicate mount success. The * included client ticket allows the client to talk to MDSs and OSDs. @@ -331,12 +320,9 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, struct ceph_client *client = monc->client; struct ceph_monmap *monmap = NULL, *old = monc->monmap; void *p, *end; - int had_debugfs_info, init_debugfs = 0; mutex_lock(&monc->mutex); - had_debugfs_info = have_debugfs_info(monc); - dout("handle_monmap\n"); p = msg->front.iov_base; end = p + msg->front.iov_len; @@ -358,22 +344,12 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, if (!client->have_fsid) { client->have_fsid = true; - if (!had_debugfs_info && have_debugfs_info(monc)) { - pr_info("client%lld fsid %pU\n", - ceph_client_id(monc->client), - &monc->client->fsid); - init_debugfs = 1; - } mutex_unlock(&monc->mutex); - - if (init_debugfs) { - /* - * do debugfs initialization without mutex to avoid - * creating a locking dependency - */ - ceph_debugfs_client_init(monc->client); - } - + /* + * do debugfs initialization without mutex to avoid + * creating a locking dependency + */ + ceph_debugfs_client_init(client); goto out_unlocked; } out: @@ -889,10 +865,8 @@ static void handle_auth_reply(struct ceph_mon_client *monc, { int ret; int was_auth = 0; - int had_debugfs_info, init_debugfs = 0; mutex_lock(&monc->mutex); - had_debugfs_info = have_debugfs_info(monc); if (monc->auth->ops) was_auth = monc->auth->ops->is_authenticated(monc->auth); monc->pending_auth = 0; @@ -915,22 +889,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc, __send_subscribe(monc); __resend_generic_request(monc); } - - if (!had_debugfs_info && have_debugfs_info(monc)) { - pr_info("client%lld fsid %pU\n", - ceph_client_id(monc->client), - &monc->client->fsid); - init_debugfs = 1; - } mutex_unlock(&monc->mutex); - - if (init_debugfs) { - /* - * do debugfs initialization without mutex to avoid - * creating a locking dependency - */ - ceph_debugfs_client_init(monc->client); - } } static int __validate_auth(struct ceph_mon_client *monc) diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index b1e6d6385516..0640d2a859c6 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1466,7 +1466,8 @@ EXPORT_SYMBOL(unregister_netdevice_notifier); int call_netdevice_notifiers(unsigned long val, struct net_device *dev) { - ASSERT_RTNL(); + if (val != NETDEV_UNREGISTER_FINAL) + ASSERT_RTNL(); return raw_notifier_call_chain(&netdev_chain, val, dev); } EXPORT_SYMBOL(call_netdevice_notifiers); @@ -2184,7 +2185,9 @@ EXPORT_SYMBOL(netif_skb_features); /* * Returns true if either: * 1. skb has frag_list and the device doesn't support FRAGLIST, or - * 2. skb is fragmented and the device does not support SG. + * 2. skb is fragmented and the device does not support SG, or if + * at least one of fragments is in highmem and device does not + * support DMA from it. */ static inline int skb_needs_linearize(struct sk_buff *skb, int features) @@ -4518,8 +4521,8 @@ static void dev_change_rx_flags(struct net_device *dev, int flags) static int __dev_set_promiscuity(struct net_device *dev, int inc) { unsigned int old_flags = dev->flags; - kuid_t uid; - kgid_t gid; + uid_t uid; + gid_t gid; ASSERT_RTNL(); @@ -4551,8 +4554,7 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc) dev->name, (dev->flags & IFF_PROMISC), (old_flags & IFF_PROMISC), audit_get_loginuid(current), - from_kuid(&init_user_ns, uid), - from_kgid(&init_user_ns, gid), + uid, gid, audit_get_sessionid(current)); } @@ -5647,8 +5649,6 @@ int register_netdevice(struct net_device *dev) set_bit(__LINK_STATE_PRESENT, &dev->state); - linkwatch_init_dev(dev); - dev_init_scheduler(dev); dev_hold(dev); list_netdevice(dev); @@ -5782,11 +5782,7 @@ static void netdev_wait_allrefs(struct net_device *dev) /* Rebroadcast unregister notification */ call_netdevice_notifiers(NETDEV_UNREGISTER, dev); - - __rtnl_unlock(); rcu_barrier(); - rtnl_lock(); - call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev); if (test_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) { @@ -5859,9 +5855,7 @@ void netdev_run_todo(void) = list_first_entry(&list, struct net_device, todo_list); list_del(&dev->todo_list); - rtnl_lock(); call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev); - __rtnl_unlock(); if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) { pr_err("network todo '%s' but state %d\n", @@ -6257,8 +6251,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char the device is just moving and can keep their slaves up. */ call_netdevice_notifiers(NETDEV_UNREGISTER, dev); - rcu_barrier(); - call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev); rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); /* diff --git a/trunk/net/core/fib_rules.c b/trunk/net/core/fib_rules.c index ab7db83236c9..585093755c23 100644 --- a/trunk/net/core/fib_rules.c +++ b/trunk/net/core/fib_rules.c @@ -711,15 +711,16 @@ static int fib_rules_event(struct notifier_block *this, unsigned long event, struct net *net = dev_net(dev); struct fib_rules_ops *ops; - ASSERT_RTNL(); switch (event) { case NETDEV_REGISTER: + ASSERT_RTNL(); list_for_each_entry(ops, &net->rules_ops, list) attach_rules(&ops->rules_list, dev); break; case NETDEV_UNREGISTER: + ASSERT_RTNL(); list_for_each_entry(ops, &net->rules_ops, list) detach_rules(&ops->rules_list, dev); break; diff --git a/trunk/net/core/link_watch.c b/trunk/net/core/link_watch.c index a01922219a23..c3519c6d1b16 100644 --- a/trunk/net/core/link_watch.c +++ b/trunk/net/core/link_watch.c @@ -76,14 +76,6 @@ static void rfc2863_policy(struct net_device *dev) } -void linkwatch_init_dev(struct net_device *dev) -{ - /* Handle pre-registration link state changes */ - if (!netif_carrier_ok(dev) || netif_dormant(dev)) - rfc2863_policy(dev); -} - - static bool linkwatch_urgent_event(struct net_device *dev) { if (!netif_running(dev)) diff --git a/trunk/net/core/netpoll.c b/trunk/net/core/netpoll.c index dd67818025d1..346b1eb83a1f 100644 --- a/trunk/net/core/netpoll.c +++ b/trunk/net/core/netpoll.c @@ -168,16 +168,24 @@ static void poll_napi(struct net_device *dev) struct napi_struct *napi; int budget = 16; + WARN_ON_ONCE(!irqs_disabled()); + list_for_each_entry(napi, &dev->napi_list, dev_list) { + local_irq_enable(); if (napi->poll_owner != smp_processor_id() && spin_trylock(&napi->poll_lock)) { + rcu_read_lock_bh(); budget = poll_one_napi(rcu_dereference_bh(dev->npinfo), napi, budget); + rcu_read_unlock_bh(); spin_unlock(&napi->poll_lock); - if (!budget) + if (!budget) { + local_irq_disable(); break; + } } + local_irq_disable(); } } @@ -380,7 +388,6 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) struct udphdr *udph; struct iphdr *iph; struct ethhdr *eth; - static atomic_t ip_ident; udp_len = len + sizeof(*udph); ip_len = udp_len + sizeof(*iph); @@ -416,7 +423,7 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) put_unaligned(0x45, (unsigned char *)iph); iph->tos = 0; put_unaligned(htons(ip_len), &(iph->tot_len)); - iph->id = htons(atomic_inc_return(&ip_ident)); + iph->id = 0; iph->frag_off = 0; iph->ttl = 64; iph->protocol = IPPROTO_UDP; diff --git a/trunk/net/core/request_sock.c b/trunk/net/core/request_sock.c index c31d9e8668c3..9b570a6a33c5 100644 --- a/trunk/net/core/request_sock.c +++ b/trunk/net/core/request_sock.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -131,97 +130,3 @@ void reqsk_queue_destroy(struct request_sock_queue *queue) kfree(lopt); } -/* - * This function is called to set a Fast Open socket's "fastopen_rsk" field - * to NULL when a TFO socket no longer needs to access the request_sock. - * This happens only after 3WHS has been either completed or aborted (e.g., - * RST is received). - * - * Before TFO, a child socket is created only after 3WHS is completed, - * hence it never needs to access the request_sock. things get a lot more - * complex with TFO. A child socket, accepted or not, has to access its - * request_sock for 3WHS processing, e.g., to retransmit SYN-ACK pkts, - * until 3WHS is either completed or aborted. Afterwards the req will stay - * until either the child socket is accepted, or in the rare case when the - * listener is closed before the child is accepted. - * - * In short, a request socket is only freed after BOTH 3WHS has completed - * (or aborted) and the child socket has been accepted (or listener closed). - * When a child socket is accepted, its corresponding req->sk is set to - * NULL since it's no longer needed. More importantly, "req->sk == NULL" - * will be used by the code below to determine if a child socket has been - * accepted or not, and the check is protected by the fastopenq->lock - * described below. - * - * Note that fastopen_rsk is only accessed from the child socket's context - * with its socket lock held. But a request_sock (req) can be accessed by - * both its child socket through fastopen_rsk, and a listener socket through - * icsk_accept_queue.rskq_accept_head. To protect the access a simple spin - * lock per listener "icsk->icsk_accept_queue.fastopenq->lock" is created. - * only in the rare case when both the listener and the child locks are held, - * e.g., in inet_csk_listen_stop() do we not need to acquire the lock. - * The lock also protects other fields such as fastopenq->qlen, which is - * decremented by this function when fastopen_rsk is no longer needed. - * - * Note that another solution was to simply use the existing socket lock - * from the listener. But first socket lock is difficult to use. It is not - * a simple spin lock - one must consider sock_owned_by_user() and arrange - * to use sk_add_backlog() stuff. But what really makes it infeasible is the - * locking hierarchy violation. E.g., inet_csk_listen_stop() may try to - * acquire a child's lock while holding listener's socket lock. A corner - * case might also exist in tcp_v4_hnd_req() that will trigger this locking - * order. - * - * When a TFO req is created, it needs to sock_hold its listener to prevent - * the latter data structure from going away. - * - * This function also sets "treq->listener" to NULL and unreference listener - * socket. treq->listener is used by the listener so it is protected by the - * fastopenq->lock in this function. - */ -void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, - bool reset) -{ - struct sock *lsk = tcp_rsk(req)->listener; - struct fastopen_queue *fastopenq = - inet_csk(lsk)->icsk_accept_queue.fastopenq; - - BUG_ON(!spin_is_locked(&sk->sk_lock.slock) && !sock_owned_by_user(sk)); - - tcp_sk(sk)->fastopen_rsk = NULL; - spin_lock_bh(&fastopenq->lock); - fastopenq->qlen--; - tcp_rsk(req)->listener = NULL; - if (req->sk) /* the child socket hasn't been accepted yet */ - goto out; - - if (!reset || lsk->sk_state != TCP_LISTEN) { - /* If the listener has been closed don't bother with the - * special RST handling below. - */ - spin_unlock_bh(&fastopenq->lock); - sock_put(lsk); - reqsk_free(req); - return; - } - /* Wait for 60secs before removing a req that has triggered RST. - * This is a simple defense against TFO spoofing attack - by - * counting the req against fastopen.max_qlen, and disabling - * TFO when the qlen exceeds max_qlen. - * - * For more details see CoNext'11 "TCP Fast Open" paper. - */ - req->expires = jiffies + 60*HZ; - if (fastopenq->rskq_rst_head == NULL) - fastopenq->rskq_rst_head = req; - else - fastopenq->rskq_rst_tail->dl_next = req; - - req->dl_next = NULL; - fastopenq->rskq_rst_tail = req; - fastopenq->qlen++; -out: - spin_unlock_bh(&fastopenq->lock); - sock_put(lsk); - return; -} diff --git a/trunk/net/core/scm.c b/trunk/net/core/scm.c index 6ab491d6c26f..040cebeed45b 100644 --- a/trunk/net/core/scm.c +++ b/trunk/net/core/scm.c @@ -45,17 +45,12 @@ static __inline__ int scm_check_creds(struct ucred *creds) { const struct cred *cred = current_cred(); - kuid_t uid = make_kuid(cred->user_ns, creds->uid); - kgid_t gid = make_kgid(cred->user_ns, creds->gid); - - if (!uid_valid(uid) || !gid_valid(gid)) - return -EINVAL; if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && - ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || - uid_eq(uid, cred->suid)) || capable(CAP_SETUID)) && - ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || - gid_eq(gid, cred->sgid)) || capable(CAP_SETGID))) { + ((creds->uid == cred->uid || creds->uid == cred->euid || + creds->uid == cred->suid) || capable(CAP_SETUID)) && + ((creds->gid == cred->gid || creds->gid == cred->egid || + creds->gid == cred->sgid) || capable(CAP_SETGID))) { return 0; } return -EPERM; @@ -154,9 +149,6 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) goto error; break; case SCM_CREDENTIALS: - { - kuid_t uid; - kgid_t gid; if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) goto error; memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred)); @@ -174,29 +166,22 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) p->pid = pid; } - err = -EINVAL; - uid = make_kuid(current_user_ns(), p->creds.uid); - gid = make_kgid(current_user_ns(), p->creds.gid); - if (!uid_valid(uid) || !gid_valid(gid)) - goto error; - if (!p->cred || - !uid_eq(p->cred->euid, uid) || - !gid_eq(p->cred->egid, gid)) { + (p->cred->euid != p->creds.uid) || + (p->cred->egid != p->creds.gid)) { struct cred *cred; err = -ENOMEM; cred = prepare_creds(); if (!cred) goto error; - cred->uid = cred->euid = uid; - cred->gid = cred->egid = gid; + cred->uid = cred->euid = p->creds.uid; + cred->gid = cred->egid = p->creds.gid; if (p->cred) put_cred(p->cred); p->cred = cred; } break; - } default: goto error; } diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index d765156eab65..8f67ced8d6a8 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -868,8 +868,8 @@ void cred_to_ucred(struct pid *pid, const struct cred *cred, if (cred) { struct user_namespace *current_ns = current_user_ns(); - ucred->uid = from_kuid_munged(current_ns, cred->euid); - ucred->gid = from_kgid_munged(current_ns, cred->egid); + ucred->uid = from_kuid(current_ns, cred->euid); + ucred->gid = from_kgid(current_ns, cred->egid); } } EXPORT_SYMBOL_GPL(cred_to_ucred); @@ -1230,7 +1230,7 @@ void sock_update_classid(struct sock *sk) rcu_read_lock(); /* doing current task, which cannot vanish. */ classid = task_cls_classid(current); rcu_read_unlock(); - if (classid != sk->sk_classid) + if (classid && classid != sk->sk_classid) sk->sk_classid = classid; } EXPORT_SYMBOL(sock_update_classid); @@ -1527,12 +1527,12 @@ void sock_edemux(struct sk_buff *skb) } EXPORT_SYMBOL(sock_edemux); -kuid_t sock_i_uid(struct sock *sk) +int sock_i_uid(struct sock *sk) { - kuid_t uid; + int uid; read_lock_bh(&sk->sk_callback_lock); - uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : GLOBAL_ROOT_UID; + uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; read_unlock_bh(&sk->sk_callback_lock); return uid; } diff --git a/trunk/net/decnet/af_decnet.c b/trunk/net/decnet/af_decnet.c index 307c322d53bb..2ba1a2814c24 100644 --- a/trunk/net/decnet/af_decnet.c +++ b/trunk/net/decnet/af_decnet.c @@ -1313,10 +1313,10 @@ static int dn_shutdown(struct socket *sock, int how) if (scp->state == DN_O) goto out; - if (how != SHUT_RDWR) + if (how != SHUTDOWN_MASK) goto out; - sk->sk_shutdown = SHUTDOWN_MASK; + sk->sk_shutdown = how; dn_destroy_sock(sk); err = 0; diff --git a/trunk/net/ieee802154/6lowpan.c b/trunk/net/ieee802154/6lowpan.c index d5291113584f..6a095225148e 100644 --- a/trunk/net/ieee802154/6lowpan.c +++ b/trunk/net/ieee802154/6lowpan.c @@ -1063,6 +1063,12 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev) return (err < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK); } +static void lowpan_dev_free(struct net_device *dev) +{ + dev_put(lowpan_dev_info(dev)->real_dev); + free_netdev(dev); +} + static struct wpan_phy *lowpan_get_phy(const struct net_device *dev) { struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; @@ -1112,7 +1118,7 @@ static void lowpan_setup(struct net_device *dev) dev->netdev_ops = &lowpan_netdev_ops; dev->header_ops = &lowpan_header_ops; dev->ml_priv = &lowpan_mlme; - dev->destructor = free_netdev; + dev->destructor = lowpan_dev_free; } static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[]) @@ -1127,8 +1133,6 @@ static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[]) static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { - struct sk_buff *local_skb; - if (!netif_running(dev)) goto drop; @@ -1140,12 +1144,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ - local_skb = skb_clone(skb, GFP_ATOMIC); - if (!local_skb) - goto drop; - lowpan_process_data(local_skb); - - kfree_skb(skb); + lowpan_process_data(skb); break; default: break; @@ -1238,34 +1237,6 @@ static inline void __init lowpan_netlink_fini(void) rtnl_link_unregister(&lowpan_link_ops); } -static int lowpan_device_event(struct notifier_block *unused, - unsigned long event, - void *ptr) -{ - struct net_device *dev = ptr; - LIST_HEAD(del_list); - struct lowpan_dev_record *entry, *tmp; - - if (dev->type != ARPHRD_IEEE802154) - goto out; - - if (event == NETDEV_UNREGISTER) { - list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { - if (lowpan_dev_info(entry->ldev)->real_dev == dev) - lowpan_dellink(entry->ldev, &del_list); - } - - unregister_netdevice_many(&del_list); - }; - -out: - return NOTIFY_DONE; -} - -static struct notifier_block lowpan_dev_notifier = { - .notifier_call = lowpan_device_event, -}; - static struct packet_type lowpan_packet_type = { .type = __constant_htons(ETH_P_IEEE802154), .func = lowpan_rcv, @@ -1280,12 +1251,6 @@ static int __init lowpan_init_module(void) goto out; dev_add_pack(&lowpan_packet_type); - - err = register_netdevice_notifier(&lowpan_dev_notifier); - if (err < 0) { - dev_remove_pack(&lowpan_packet_type); - lowpan_netlink_fini(); - } out: return err; } @@ -1298,8 +1263,6 @@ static void __exit lowpan_cleanup_module(void) dev_remove_pack(&lowpan_packet_type); - unregister_netdevice_notifier(&lowpan_dev_notifier); - /* Now 6lowpan packet_type is removed, so no new fragments are * expected on RX, therefore that's the time to clean incomplete * fragments. diff --git a/trunk/net/ipv4/af_inet.c b/trunk/net/ipv4/af_inet.c index 4f70ef0b946d..6681ccf5c3ee 100644 --- a/trunk/net/ipv4/af_inet.c +++ b/trunk/net/ipv4/af_inet.c @@ -149,11 +149,6 @@ void inet_sock_destruct(struct sock *sk) pr_err("Attempt to release alive inet socket %p\n", sk); return; } - if (sk->sk_type == SOCK_STREAM) { - struct fastopen_queue *fastopenq = - inet_csk(sk)->icsk_accept_queue.fastopenq; - kfree(fastopenq); - } WARN_ON(atomic_read(&sk->sk_rmem_alloc)); WARN_ON(atomic_read(&sk->sk_wmem_alloc)); @@ -217,26 +212,6 @@ int inet_listen(struct socket *sock, int backlog) * we can only allow the backlog to be adjusted. */ if (old_state != TCP_LISTEN) { - /* Check special setups for testing purpose to enable TFO w/o - * requiring TCP_FASTOPEN sockopt. - * Note that only TCP sockets (SOCK_STREAM) will reach here. - * Also fastopenq may already been allocated because this - * socket was in TCP_LISTEN state previously but was - * shutdown() (rather than close()). - */ - if ((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) != 0 && - inet_csk(sk)->icsk_accept_queue.fastopenq == NULL) { - if ((sysctl_tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) != 0) - err = fastopen_init_queue(sk, backlog); - else if ((sysctl_tcp_fastopen & - TFO_SERVER_WO_SOCKOPT2) != 0) - err = fastopen_init_queue(sk, - ((uint)sysctl_tcp_fastopen) >> 16); - else - err = 0; - if (err) - goto out; - } err = inet_csk_listen_start(sk, backlog); if (err) goto out; @@ -726,8 +701,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags) sock_rps_record_flow(sk2); WARN_ON(!((1 << sk2->sk_state) & - (TCPF_ESTABLISHED | TCPF_SYN_RECV | - TCPF_CLOSE_WAIT | TCPF_CLOSE))); + (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); sock_graft(sk2, newsock); diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index adf273f8ad2e..6a5e6e4b142c 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -1147,8 +1147,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = ptr; - struct in_device *in_dev = __in_dev_get_rtnl(dev); + struct in_device *in_dev; + if (event == NETDEV_UNREGISTER_FINAL) + goto out; + + in_dev = __in_dev_get_rtnl(dev); ASSERT_RTNL(); if (!in_dev) { diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index acdee325d972..fd7d9ae64f16 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -1050,6 +1050,9 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo return NOTIFY_DONE; } + if (event == NETDEV_UNREGISTER_FINAL) + return NOTIFY_DONE; + in_dev = __in_dev_get_rtnl(dev); switch (event) { @@ -1061,14 +1064,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo fib_sync_up(dev); #endif atomic_inc(&net->ipv4.dev_addr_genid); - rt_cache_flush(net, -1); + rt_cache_flush(dev_net(dev), -1); break; case NETDEV_DOWN: fib_disable_ip(dev, 0, 0); break; case NETDEV_CHANGEMTU: case NETDEV_CHANGE: - rt_cache_flush(net, 0); + rt_cache_flush(dev_net(dev), 0); break; } return NOTIFY_DONE; diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 8464b79c493f..7f75f21d7b83 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -283,9 +283,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) struct sock *inet_csk_accept(struct sock *sk, int flags, int *err) { struct inet_connection_sock *icsk = inet_csk(sk); - struct request_sock_queue *queue = &icsk->icsk_accept_queue; struct sock *newsk; - struct request_sock *req; int error; lock_sock(sk); @@ -298,7 +296,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err) goto out_err; /* Find already established connection */ - if (reqsk_queue_empty(queue)) { + if (reqsk_queue_empty(&icsk->icsk_accept_queue)) { long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); /* If this is a non blocking socket don't sleep */ @@ -310,32 +308,14 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err) if (error) goto out_err; } - req = reqsk_queue_remove(queue); - newsk = req->sk; - - sk_acceptq_removed(sk); - if (sk->sk_type == SOCK_STREAM && queue->fastopenq != NULL) { - spin_lock_bh(&queue->fastopenq->lock); - if (tcp_rsk(req)->listener) { - /* We are still waiting for the final ACK from 3WHS - * so can't free req now. Instead, we set req->sk to - * NULL to signify that the child socket is taken - * so reqsk_fastopen_remove() will free the req - * when 3WHS finishes (or is aborted). - */ - req->sk = NULL; - req = NULL; - } - spin_unlock_bh(&queue->fastopenq->lock); - } + + newsk = reqsk_queue_get_child(&icsk->icsk_accept_queue, sk); + WARN_ON(newsk->sk_state == TCP_SYN_RECV); out: release_sock(sk); - if (req) - __reqsk_free(req); return newsk; out_err: newsk = NULL; - req = NULL; *err = error; goto out; } @@ -740,14 +720,13 @@ EXPORT_SYMBOL_GPL(inet_csk_listen_start); void inet_csk_listen_stop(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); - struct request_sock_queue *queue = &icsk->icsk_accept_queue; struct request_sock *acc_req; struct request_sock *req; inet_csk_delete_keepalive_timer(sk); /* make all the listen_opt local to us */ - acc_req = reqsk_queue_yank_acceptq(queue); + acc_req = reqsk_queue_yank_acceptq(&icsk->icsk_accept_queue); /* Following specs, it would be better either to send FIN * (and enter FIN-WAIT-1, it is normal close) @@ -757,7 +736,7 @@ void inet_csk_listen_stop(struct sock *sk) * To be honest, we are not able to make either * of the variants now. --ANK */ - reqsk_queue_destroy(queue); + reqsk_queue_destroy(&icsk->icsk_accept_queue); while ((req = acc_req) != NULL) { struct sock *child = req->sk; @@ -775,19 +754,6 @@ void inet_csk_listen_stop(struct sock *sk) percpu_counter_inc(sk->sk_prot->orphan_count); - if (sk->sk_type == SOCK_STREAM && tcp_rsk(req)->listener) { - BUG_ON(tcp_sk(child)->fastopen_rsk != req); - BUG_ON(sk != tcp_rsk(req)->listener); - - /* Paranoid, to prevent race condition if - * an inbound pkt destined for child is - * blocked by sock lock in tcp_v4_rcv(). - * Also to satisfy an assertion in - * tcp_v4_destroy_sock(). - */ - tcp_sk(child)->fastopen_rsk = NULL; - sock_put(sk); - } inet_csk_destroy_sock(child); bh_unlock_sock(child); @@ -797,17 +763,6 @@ void inet_csk_listen_stop(struct sock *sk) sk_acceptq_removed(sk); __reqsk_free(req); } - if (queue->fastopenq != NULL) { - /* Free all the reqs queued in rskq_rst_head. */ - spin_lock_bh(&queue->fastopenq->lock); - acc_req = queue->fastopenq->rskq_rst_head; - queue->fastopenq->rskq_rst_head = NULL; - spin_unlock_bh(&queue->fastopenq->lock); - while ((req = acc_req) != NULL) { - acc_req = req->dl_next; - __reqsk_free(req); - } - } WARN_ON(sk->sk_ack_backlog); } EXPORT_SYMBOL_GPL(inet_csk_listen_stop); diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 8bc005b1435f..570e61f9611f 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -69,7 +69,6 @@ static inline void inet_diag_unlock_handler( int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, struct sk_buff *skb, struct inet_diag_req_v2 *req, - struct user_namespace *user_ns, u32 pid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) { @@ -125,7 +124,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, } #endif - r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk)); + r->idiag_uid = sock_i_uid(sk); r->idiag_inode = sock_i_ino(sk); if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { @@ -200,12 +199,11 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill); static int inet_csk_diag_fill(struct sock *sk, struct sk_buff *skb, struct inet_diag_req_v2 *req, - struct user_namespace *user_ns, u32 pid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) { return inet_sk_diag_fill(sk, inet_csk(sk), - skb, req, user_ns, pid, seq, nlmsg_flags, unlh); + skb, req, pid, seq, nlmsg_flags, unlh); } static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, @@ -258,16 +256,14 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, } static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, - struct inet_diag_req_v2 *r, - struct user_namespace *user_ns, - u32 pid, u32 seq, u16 nlmsg_flags, + struct inet_diag_req_v2 *r, u32 pid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh) { if (sk->sk_state == TCP_TIME_WAIT) return inet_twsk_diag_fill((struct inet_timewait_sock *)sk, skb, r, pid, seq, nlmsg_flags, unlh); - return inet_csk_diag_fill(sk, skb, r, user_ns, pid, seq, nlmsg_flags, unlh); + return inet_csk_diag_fill(sk, skb, r, pid, seq, nlmsg_flags, unlh); } int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, @@ -315,7 +311,6 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s } err = sk_diag_fill(sk, rep, req, - sk_user_ns(NETLINK_CB(in_skb).ssk), NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, 0, nlh); if (err < 0) { @@ -556,7 +551,6 @@ static int inet_csk_diag_dump(struct sock *sk, return 0; return inet_csk_diag_fill(sk, skb, r, - sk_user_ns(NETLINK_CB(cb->skb).ssk), NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); } @@ -597,9 +591,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, } static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, - struct request_sock *req, - struct user_namespace *user_ns, - u32 pid, u32 seq, + struct request_sock *req, u32 pid, u32 seq, const struct nlmsghdr *unlh) { const struct inet_request_sock *ireq = inet_rsk(req); @@ -633,7 +625,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, r->idiag_expires = jiffies_to_msecs(tmo); r->idiag_rqueue = 0; r->idiag_wqueue = 0; - r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk)); + r->idiag_uid = sock_i_uid(sk); r->idiag_inode = 0; #if IS_ENABLED(CONFIG_IPV6) if (r->idiag_family == AF_INET6) { @@ -710,7 +702,6 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, } err = inet_diag_fill_req(skb, sk, req, - sk_user_ns(NETLINK_CB(cb->skb).ssk), NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, cb->nlh); if (err < 0) { diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 8d07c973409c..fa6a12c51066 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -523,6 +523,10 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) if (offset == 0) qp->q.last_in |= INET_FRAG_FIRST_IN; + if (ip_hdr(skb)->frag_off & htons(IP_DF) && + skb->len + ihl > qp->q.max_size) + qp->q.max_size = skb->len + ihl; + if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && qp->q.meat == qp->q.len) return ip_frag_reasm(qp, prev, dev); @@ -646,9 +650,11 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, head->next = NULL; head->dev = dev; head->tstamp = qp->q.stamp; + IPCB(head)->frag_max_size = qp->q.max_size; iph = ip_hdr(head); - iph->frag_off = 0; + /* max_size != 0 implies at least one fragment had IP_DF set */ + iph->frag_off = qp->q.max_size ? htons(IP_DF) : 0; iph->tot_len = htons(len); iph->tos |= ecn; IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS); diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index c196d749daf2..a5beab1dc958 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -467,7 +467,9 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) iph = ip_hdr(skb); - if (unlikely((iph->frag_off & htons(IP_DF)) && !skb->local_df)) { + if (unlikely(((iph->frag_off & htons(IP_DF)) && !skb->local_df) || + (IPCB(skb)->frag_max_size && + IPCB(skb)->frag_max_size > dst_mtu(&rt->dst)))) { IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(ip_skb_dst_mtu(skb))); diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index 8aa7a4cf9139..3a57570c8ee5 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -124,8 +124,6 @@ static DEFINE_SPINLOCK(mfc_unres_lock); static struct kmem_cache *mrt_cachep __read_mostly; static struct mr_table *ipmr_new_table(struct net *net, u32 id); -static void ipmr_free_table(struct mr_table *mrt); - static int ip_mr_forward(struct net *net, struct mr_table *mrt, struct sk_buff *skb, struct mfc_cache *cache, int local); @@ -133,7 +131,6 @@ static int ipmr_cache_report(struct mr_table *mrt, struct sk_buff *pkt, vifi_t vifi, int assert); static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm); -static void mroute_clean_tables(struct mr_table *mrt); static void ipmr_expire_process(unsigned long arg); #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES @@ -274,7 +271,7 @@ static void __net_exit ipmr_rules_exit(struct net *net) list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { list_del(&mrt->list); - ipmr_free_table(mrt); + kfree(mrt); } fib_rules_unregister(net->ipv4.mr_rules_ops); } @@ -302,7 +299,7 @@ static int __net_init ipmr_rules_init(struct net *net) static void __net_exit ipmr_rules_exit(struct net *net) { - ipmr_free_table(net->ipv4.mrt); + kfree(net->ipv4.mrt); } #endif @@ -339,13 +336,6 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id) return mrt; } -static void ipmr_free_table(struct mr_table *mrt) -{ - del_timer_sync(&mrt->ipmr_expire_timer); - mroute_clean_tables(mrt); - kfree(mrt); -} - /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v) diff --git a/trunk/net/ipv4/netfilter/nf_nat_sip.c b/trunk/net/ipv4/netfilter/nf_nat_sip.c index 9c87cde28ff8..4ad9cf173992 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_sip.c +++ b/trunk/net/ipv4/netfilter/nf_nat_sip.c @@ -502,10 +502,7 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff, ret = nf_ct_expect_related(rtcp_exp); if (ret == 0) break; - else if (ret == -EBUSY) { - nf_ct_unexpect_related(rtp_exp); - continue; - } else if (ret < 0) { + else if (ret != -EBUSY) { nf_ct_unexpect_related(rtp_exp); port = 0; break; diff --git a/trunk/net/ipv4/ping.c b/trunk/net/ipv4/ping.c index 8f3d05424a3e..6232d476f37e 100644 --- a/trunk/net/ipv4/ping.c +++ b/trunk/net/ipv4/ping.c @@ -185,10 +185,10 @@ static struct sock *ping_v4_lookup(struct net *net, __be32 saddr, __be32 daddr, return sk; } -static void inet_get_ping_group_range_net(struct net *net, kgid_t *low, - kgid_t *high) +static void inet_get_ping_group_range_net(struct net *net, gid_t *low, + gid_t *high) { - kgid_t *data = net->ipv4.sysctl_ping_group_range; + gid_t *data = net->ipv4.sysctl_ping_group_range; unsigned int seq; do { @@ -203,13 +203,19 @@ static void inet_get_ping_group_range_net(struct net *net, kgid_t *low, static int ping_init_sock(struct sock *sk) { struct net *net = sock_net(sk); - kgid_t group = current_egid(); + gid_t group = current_egid(); + gid_t range[2]; struct group_info *group_info = get_current_groups(); int i, j, count = group_info->ngroups; kgid_t low, high; - inet_get_ping_group_range_net(net, &low, &high); - if (gid_lte(low, group) && gid_lte(group, high)) + inet_get_ping_group_range_net(net, range, range+1); + low = make_kgid(&init_user_ns, range[0]); + high = make_kgid(&init_user_ns, range[1]); + if (!gid_valid(low) || !gid_valid(high) || gid_lt(high, low)) + return -EACCES; + + if (range[0] <= group && group <= range[1]) return 0; for (i = 0; i < group_info->nblocks; i++) { @@ -839,9 +845,7 @@ static void ping_format_sock(struct sock *sp, struct seq_file *f, bucket, src, srcp, dest, destp, sp->sk_state, sk_wmem_alloc_get(sp), sk_rmem_alloc_get(sp), - 0, 0L, 0, - from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)), - 0, sock_i_ino(sp), + 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops), len); } diff --git a/trunk/net/ipv4/proc.c b/trunk/net/ipv4/proc.c index 8de53e1ddd54..957acd12250b 100644 --- a/trunk/net/ipv4/proc.c +++ b/trunk/net/ipv4/proc.c @@ -263,10 +263,6 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK), SNMP_MIB_ITEM("TCPSYNChallenge", LINUX_MIB_TCPSYNCHALLENGE), SNMP_MIB_ITEM("TCPFastOpenActive", LINUX_MIB_TCPFASTOPENACTIVE), - SNMP_MIB_ITEM("TCPFastOpenPassive", LINUX_MIB_TCPFASTOPENPASSIVE), - SNMP_MIB_ITEM("TCPFastOpenPassiveFail", LINUX_MIB_TCPFASTOPENPASSIVEFAIL), - SNMP_MIB_ITEM("TCPFastOpenListenOverflow", LINUX_MIB_TCPFASTOPENLISTENOVERFLOW), - SNMP_MIB_ITEM("TCPFastOpenCookieReqd", LINUX_MIB_TCPFASTOPENCOOKIEREQD), SNMP_MIB_SENTINEL }; diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index f2425785d40a..ff0f071969ea 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -992,9 +992,7 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) i, src, srcp, dest, destp, sp->sk_state, sk_wmem_alloc_get(sp), sk_rmem_alloc_get(sp), - 0, 0L, 0, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), - 0, sock_i_ino(sp), + 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); } diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index dc9549b5eb1c..50f6d3adb474 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -934,14 +934,12 @@ static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) if (mtu < ip_rt_min_pmtu) mtu = ip_rt_min_pmtu; - rcu_read_lock(); if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) { struct fib_nh *nh = &FIB_RES_NH(res); update_or_create_fnhe(nh, fl4->daddr, 0, mtu, jiffies + ip_rt_mtu_expires); } - rcu_read_unlock(); return mtu; } @@ -958,7 +956,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, dst->obsolete = DST_OBSOLETE_KILL; } else { rt->rt_pmtu = mtu; - rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires); + dst_set_expires(&rt->dst, ip_rt_mtu_expires); } } @@ -1134,7 +1132,10 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) const struct rtable *rt = (const struct rtable *) dst; unsigned int mtu = rt->rt_pmtu; - if (!mtu || time_after_eq(jiffies, rt->dst.expires)) + if (mtu && time_after_eq(jiffies, rt->dst.expires)) + mtu = 0; + + if (!mtu) mtu = dst_metric_raw(dst, RTAX_MTU); if (mtu && rt_is_output_route(rt)) @@ -1262,7 +1263,7 @@ static void ipv4_dst_destroy(struct dst_entry *dst) { struct rtable *rt = (struct rtable *) dst; - if (!list_empty(&rt->rt_uncached)) { + if (dst->flags & DST_NOCACHE) { spin_lock_bh(&rt_uncached_lock); list_del(&rt->rt_uncached); spin_unlock_bh(&rt_uncached_lock); diff --git a/trunk/net/ipv4/syncookies.c b/trunk/net/ipv4/syncookies.c index ba48e799b031..650e1528e1e6 100644 --- a/trunk/net/ipv4/syncookies.c +++ b/trunk/net/ipv4/syncookies.c @@ -319,7 +319,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ireq->tstamp_ok = tcp_opt.saw_tstamp; req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; treq->snt_synack = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsecr : 0; - treq->listener = NULL; /* We throwed the options of the initial SYN away, so we hope * the ACK carries the same options again (see RFC1122 4.2.3.8) diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index 9205e492dc9d..1b5ce96707a3 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -76,9 +76,9 @@ static int ipv4_local_port_range(ctl_table *table, int write, } -static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high) +static void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high) { - kgid_t *data = table->data; + gid_t *data = table->data; unsigned int seq; do { seq = read_seqbegin(&sysctl_local_ports.lock); @@ -89,12 +89,12 @@ static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low } /* Update system visible IP port range */ -static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t high) +static void set_ping_group_range(struct ctl_table *table, gid_t range[2]) { - kgid_t *data = table->data; + gid_t *data = table->data; write_seqlock(&sysctl_local_ports.lock); - data[0] = low; - data[1] = high; + data[0] = range[0]; + data[1] = range[1]; write_sequnlock(&sysctl_local_ports.lock); } @@ -103,33 +103,21 @@ static int ipv4_ping_group_range(ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - struct user_namespace *user_ns = current_user_ns(); int ret; - gid_t urange[2]; - kgid_t low, high; + gid_t range[2]; ctl_table tmp = { - .data = &urange, - .maxlen = sizeof(urange), + .data = &range, + .maxlen = sizeof(range), .mode = table->mode, .extra1 = &ip_ping_group_range_min, .extra2 = &ip_ping_group_range_max, }; - inet_get_ping_group_range_table(table, &low, &high); - urange[0] = from_kgid_munged(user_ns, low); - urange[1] = from_kgid_munged(user_ns, high); + inet_get_ping_group_range_table(table, range, range + 1); ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); - if (write && ret == 0) { - low = make_kgid(user_ns, urange[0]); - high = make_kgid(user_ns, urange[1]); - if (!gid_valid(low) || !gid_valid(high) || - (urange[1] < urange[0]) || gid_lt(high, low)) { - low = make_kgid(&init_user_ns, 1); - high = make_kgid(&init_user_ns, 0); - } - set_ping_group_range(table, low, high); - } + if (write && ret == 0) + set_ping_group_range(table, range); return ret; } @@ -232,45 +220,6 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write, return 0; } -int proc_tcp_fastopen_key(ctl_table *ctl, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) -{ - ctl_table tbl = { .maxlen = (TCP_FASTOPEN_KEY_LENGTH * 2 + 10) }; - struct tcp_fastopen_context *ctxt; - int ret; - u32 user_key[4]; /* 16 bytes, matching TCP_FASTOPEN_KEY_LENGTH */ - - tbl.data = kmalloc(tbl.maxlen, GFP_KERNEL); - if (!tbl.data) - return -ENOMEM; - - rcu_read_lock(); - ctxt = rcu_dereference(tcp_fastopen_ctx); - if (ctxt) - memcpy(user_key, ctxt->key, TCP_FASTOPEN_KEY_LENGTH); - rcu_read_unlock(); - - snprintf(tbl.data, tbl.maxlen, "%08x-%08x-%08x-%08x", - user_key[0], user_key[1], user_key[2], user_key[3]); - ret = proc_dostring(&tbl, write, buffer, lenp, ppos); - - if (write && ret == 0) { - if (sscanf(tbl.data, "%x-%x-%x-%x", user_key, user_key + 1, - user_key + 2, user_key + 3) != 4) { - ret = -EINVAL; - goto bad_key; - } - tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH); - } - -bad_key: - pr_debug("proc FO key set 0x%x-%x-%x-%x <- 0x%s: %u\n", - user_key[0], user_key[1], user_key[2], user_key[3], - (char *)tbl.data, ret); - kfree(tbl.data); - return ret; -} - static struct ctl_table ipv4_table[] = { { .procname = "tcp_timestamps", @@ -424,12 +373,6 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, - { - .procname = "tcp_fastopen_key", - .mode = 0600, - .maxlen = ((TCP_FASTOPEN_KEY_LENGTH * 2) + 10), - .proc_handler = proc_tcp_fastopen_key, - }, { .procname = "tcp_tw_recycle", .data = &tcp_death_row.sysctl_tw_recycle, @@ -843,7 +786,7 @@ static struct ctl_table ipv4_net_table[] = { { .procname = "ping_group_range", .data = &init_net.ipv4.sysctl_ping_group_range, - .maxlen = sizeof(gid_t)*2, + .maxlen = sizeof(init_net.ipv4.sysctl_ping_group_range), .mode = 0644, .proc_handler = ipv4_ping_group_range, }, @@ -887,8 +830,8 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) * Sane defaults - nobody may create ping sockets. * Boot scripts should set this to distro-specific group. */ - net->ipv4.sysctl_ping_group_range[0] = make_kgid(&init_user_ns, 1); - net->ipv4.sysctl_ping_group_range[1] = make_kgid(&init_user_ns, 0); + net->ipv4.sysctl_ping_group_range[0] = 1; + net->ipv4.sysctl_ping_group_range[1] = 0; tcp_init_mem(net); diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index df83d744e380..2109ff4a1daf 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -486,9 +486,8 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) if (sk->sk_shutdown & RCV_SHUTDOWN) mask |= POLLIN | POLLRDNORM | POLLRDHUP; - /* Connected or passive Fast Open socket? */ - if (sk->sk_state != TCP_SYN_SENT && - (sk->sk_state != TCP_SYN_RECV || tp->fastopen_rsk != NULL)) { + /* Connected? */ + if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) { int target = sock_rcvlowat(sk, 0, INT_MAX); if (tp->urg_seq == tp->copied_seq && @@ -841,15 +840,10 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse ssize_t copied; long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); - /* Wait for a connection to finish. One exception is TCP Fast Open - * (passive side) where data is allowed to be sent before a connection - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && - !tcp_passive_fastopen(sk)) { + /* Wait for a connection to finish. */ + if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) if ((err = sk_stream_wait_connect(sk, &timeo)) != 0) goto out_err; - } clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); @@ -1048,15 +1042,10 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); - /* Wait for a connection to finish. One exception is TCP Fast Open - * (passive side) where data is allowed to be sent before a connection - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && - !tcp_passive_fastopen(sk)) { + /* Wait for a connection to finish. */ + if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) if ((err = sk_stream_wait_connect(sk, &timeo)) != 0) goto do_error; - } if (unlikely(tp->repair)) { if (tp->repair_queue == TCP_RECV_QUEUE) { @@ -2155,10 +2144,6 @@ void tcp_close(struct sock *sk, long timeout) * they look as CLOSING or LAST_ACK for Linux) * Probably, I missed some more holelets. * --ANK - * XXX (TFO) - To start off we don't support SYN+ACK+FIN - * in a single packet! (May consider it later but will - * probably need API support or TCP_CORK SYN-ACK until - * data is written and socket is closed.) */ tcp_send_fin(sk); } @@ -2230,16 +2215,8 @@ void tcp_close(struct sock *sk, long timeout) } } - if (sk->sk_state == TCP_CLOSE) { - struct request_sock *req = tcp_sk(sk)->fastopen_rsk; - /* We could get here with a non-NULL req if the socket is - * aborted (e.g., closed with unread data) before 3WHS - * finishes. - */ - if (req != NULL) - reqsk_fastopen_remove(sk, req, false); + if (sk->sk_state == TCP_CLOSE) inet_csk_destroy_sock(sk); - } /* Otherwise, socket is reprieved until protocol close. */ out: @@ -2711,14 +2688,6 @@ static int do_tcp_setsockopt(struct sock *sk, int level, else icsk->icsk_user_timeout = msecs_to_jiffies(val); break; - - case TCP_FASTOPEN: - if (val >= 0 && ((1 << sk->sk_state) & (TCPF_CLOSE | - TCPF_LISTEN))) - err = fastopen_init_queue(sk, val); - else - err = -EINVAL; - break; default: err = -ENOPROTOOPT; break; @@ -3532,15 +3501,11 @@ EXPORT_SYMBOL(tcp_cookie_generator); void tcp_done(struct sock *sk) { - struct request_sock *req = tcp_sk(sk)->fastopen_rsk; - if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_ATTEMPTFAILS); tcp_set_state(sk, TCP_CLOSE); tcp_clear_xmit_timers(sk); - if (req != NULL) - reqsk_fastopen_remove(sk, req, false); sk->sk_shutdown = SHUTDOWN_MASK; diff --git a/trunk/net/ipv4/tcp_fastopen.c b/trunk/net/ipv4/tcp_fastopen.c index 8f7ef0ad80e5..a7f729c409d7 100644 --- a/trunk/net/ipv4/tcp_fastopen.c +++ b/trunk/net/ipv4/tcp_fastopen.c @@ -1,91 +1,10 @@ -#include #include #include -#include -#include -#include -#include -#include -#include -int sysctl_tcp_fastopen __read_mostly; - -struct tcp_fastopen_context __rcu *tcp_fastopen_ctx; - -static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock); - -static void tcp_fastopen_ctx_free(struct rcu_head *head) -{ - struct tcp_fastopen_context *ctx = - container_of(head, struct tcp_fastopen_context, rcu); - crypto_free_cipher(ctx->tfm); - kfree(ctx); -} - -int tcp_fastopen_reset_cipher(void *key, unsigned int len) -{ - int err; - struct tcp_fastopen_context *ctx, *octx; - - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - ctx->tfm = crypto_alloc_cipher("aes", 0, 0); - - if (IS_ERR(ctx->tfm)) { - err = PTR_ERR(ctx->tfm); -error: kfree(ctx); - pr_err("TCP: TFO aes cipher alloc error: %d\n", err); - return err; - } - err = crypto_cipher_setkey(ctx->tfm, key, len); - if (err) { - pr_err("TCP: TFO cipher key error: %d\n", err); - crypto_free_cipher(ctx->tfm); - goto error; - } - memcpy(ctx->key, key, len); - - spin_lock(&tcp_fastopen_ctx_lock); - - octx = rcu_dereference_protected(tcp_fastopen_ctx, - lockdep_is_held(&tcp_fastopen_ctx_lock)); - rcu_assign_pointer(tcp_fastopen_ctx, ctx); - spin_unlock(&tcp_fastopen_ctx_lock); - - if (octx) - call_rcu(&octx->rcu, tcp_fastopen_ctx_free); - return err; -} - -/* Computes the fastopen cookie for the peer. - * The peer address is a 128 bits long (pad with zeros for IPv4). - * - * The caller must check foc->len to determine if a valid cookie - * has been generated successfully. -*/ -void tcp_fastopen_cookie_gen(__be32 addr, struct tcp_fastopen_cookie *foc) -{ - __be32 peer_addr[4] = { addr, 0, 0, 0 }; - struct tcp_fastopen_context *ctx; - - rcu_read_lock(); - ctx = rcu_dereference(tcp_fastopen_ctx); - if (ctx) { - crypto_cipher_encrypt_one(ctx->tfm, - foc->val, - (__u8 *)peer_addr); - foc->len = TCP_FASTOPEN_COOKIE_SIZE; - } - rcu_read_unlock(); -} +int sysctl_tcp_fastopen; static int __init tcp_fastopen_init(void) { - __u8 key[TCP_FASTOPEN_KEY_LENGTH]; - - get_random_bytes(key, sizeof(key)); - tcp_fastopen_reset_cipher(key, sizeof(key)); return 0; } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index e2bec815ff23..bcfccc5cb8d0 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -378,7 +378,7 @@ static void tcp_fixup_rcvbuf(struct sock *sk) /* 4. Try to fixup all. It is made immediately after connection enters * established state. */ -void tcp_init_buffer_space(struct sock *sk) +static void tcp_init_buffer_space(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); int maxwin; @@ -743,6 +743,29 @@ __u32 tcp_init_cwnd(const struct tcp_sock *tp, const struct dst_entry *dst) return min_t(__u32, cwnd, tp->snd_cwnd_clamp); } +/* Set slow start threshold and cwnd not falling to slow start */ +void tcp_enter_cwr(struct sock *sk, const int set_ssthresh) +{ + struct tcp_sock *tp = tcp_sk(sk); + const struct inet_connection_sock *icsk = inet_csk(sk); + + tp->prior_ssthresh = 0; + tp->bytes_acked = 0; + if (icsk->icsk_ca_state < TCP_CA_CWR) { + tp->undo_marker = 0; + if (set_ssthresh) + tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk); + tp->snd_cwnd = min(tp->snd_cwnd, + tcp_packets_in_flight(tp) + 1U); + tp->snd_cwnd_cnt = 0; + tp->high_seq = tp->snd_nxt; + tp->snd_cwnd_stamp = tcp_time_stamp; + TCP_ECN_queue_cwr(tp); + + tcp_set_ca_state(sk, TCP_CA_CWR); + } +} + /* * Packet counting of FACK is based on in-order assumptions, therefore TCP * disables it when reordering is detected @@ -2470,6 +2493,35 @@ static inline void tcp_moderate_cwnd(struct tcp_sock *tp) tp->snd_cwnd_stamp = tcp_time_stamp; } +/* Lower bound on congestion window is slow start threshold + * unless congestion avoidance choice decides to overide it. + */ +static inline u32 tcp_cwnd_min(const struct sock *sk) +{ + const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; + + return ca_ops->min_cwnd ? ca_ops->min_cwnd(sk) : tcp_sk(sk)->snd_ssthresh; +} + +/* Decrease cwnd each second ack. */ +static void tcp_cwnd_down(struct sock *sk, int flag) +{ + struct tcp_sock *tp = tcp_sk(sk); + int decr = tp->snd_cwnd_cnt + 1; + + if ((flag & (FLAG_ANY_PROGRESS | FLAG_DSACKING_ACK)) || + (tcp_is_reno(tp) && !(flag & FLAG_NOT_DUP))) { + tp->snd_cwnd_cnt = decr & 1; + decr >>= 1; + + if (decr && tp->snd_cwnd > tcp_cwnd_min(sk)) + tp->snd_cwnd -= decr; + + tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp) + 1); + tp->snd_cwnd_stamp = tcp_time_stamp; + } +} + /* Nothing was retransmitted or returned timestamp is less * than timestamp of the first retransmission. */ @@ -2671,80 +2723,24 @@ static bool tcp_try_undo_loss(struct sock *sk) return false; } -/* The cwnd reduction in CWR and Recovery use the PRR algorithm - * https://datatracker.ietf.org/doc/draft-ietf-tcpm-proportional-rate-reduction/ - * It computes the number of packets to send (sndcnt) based on packets newly - * delivered: - * 1) If the packets in flight is larger than ssthresh, PRR spreads the - * cwnd reductions across a full RTT. - * 2) If packets in flight is lower than ssthresh (such as due to excess - * losses and/or application stalls), do not perform any further cwnd - * reductions, but instead slow start up to ssthresh. - */ -static void tcp_init_cwnd_reduction(struct sock *sk, const bool set_ssthresh) -{ - struct tcp_sock *tp = tcp_sk(sk); - - tp->high_seq = tp->snd_nxt; - tp->bytes_acked = 0; - tp->snd_cwnd_cnt = 0; - tp->prior_cwnd = tp->snd_cwnd; - tp->prr_delivered = 0; - tp->prr_out = 0; - if (set_ssthresh) - tp->snd_ssthresh = inet_csk(sk)->icsk_ca_ops->ssthresh(sk); - TCP_ECN_queue_cwr(tp); -} - -static void tcp_cwnd_reduction(struct sock *sk, int newly_acked_sacked, - int fast_rexmit) -{ - struct tcp_sock *tp = tcp_sk(sk); - int sndcnt = 0; - int delta = tp->snd_ssthresh - tcp_packets_in_flight(tp); - - tp->prr_delivered += newly_acked_sacked; - if (tcp_packets_in_flight(tp) > tp->snd_ssthresh) { - u64 dividend = (u64)tp->snd_ssthresh * tp->prr_delivered + - tp->prior_cwnd - 1; - sndcnt = div_u64(dividend, tp->prior_cwnd) - tp->prr_out; - } else { - sndcnt = min_t(int, delta, - max_t(int, tp->prr_delivered - tp->prr_out, - newly_acked_sacked) + 1); - } - - sndcnt = max(sndcnt, (fast_rexmit ? 1 : 0)); - tp->snd_cwnd = tcp_packets_in_flight(tp) + sndcnt; -} - -static inline void tcp_end_cwnd_reduction(struct sock *sk) +static inline void tcp_complete_cwr(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - /* Reset cwnd to ssthresh in CWR or Recovery (unless it's undone) */ - if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR || - (tp->undo_marker && tp->snd_ssthresh < TCP_INFINITE_SSTHRESH)) { - tp->snd_cwnd = tp->snd_ssthresh; - tp->snd_cwnd_stamp = tcp_time_stamp; + /* Do not moderate cwnd if it's already undone in cwr or recovery. */ + if (tp->undo_marker) { + if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) { + tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); + tp->snd_cwnd_stamp = tcp_time_stamp; + } else if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH) { + /* PRR algorithm. */ + tp->snd_cwnd = tp->snd_ssthresh; + tp->snd_cwnd_stamp = tcp_time_stamp; + } } tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR); } -/* Enter CWR state. Disable cwnd undo since congestion is proven with ECN */ -void tcp_enter_cwr(struct sock *sk, const int set_ssthresh) -{ - struct tcp_sock *tp = tcp_sk(sk); - - tp->prior_ssthresh = 0; - tp->bytes_acked = 0; - if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { - tp->undo_marker = 0; - tcp_init_cwnd_reduction(sk, set_ssthresh); - tcp_set_ca_state(sk, TCP_CA_CWR); - } -} - static void tcp_try_keep_open(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); @@ -2759,7 +2755,7 @@ static void tcp_try_keep_open(struct sock *sk) } } -static void tcp_try_to_open(struct sock *sk, int flag, int newly_acked_sacked) +static void tcp_try_to_open(struct sock *sk, int flag) { struct tcp_sock *tp = tcp_sk(sk); @@ -2776,7 +2772,7 @@ static void tcp_try_to_open(struct sock *sk, int flag, int newly_acked_sacked) if (inet_csk(sk)->icsk_ca_state != TCP_CA_Open) tcp_moderate_cwnd(tp); } else { - tcp_cwnd_reduction(sk, newly_acked_sacked, 0); + tcp_cwnd_down(sk, flag); } } @@ -2858,6 +2854,38 @@ void tcp_simple_retransmit(struct sock *sk) } EXPORT_SYMBOL(tcp_simple_retransmit); +/* This function implements the PRR algorithm, specifcally the PRR-SSRB + * (proportional rate reduction with slow start reduction bound) as described in + * http://www.ietf.org/id/draft-mathis-tcpm-proportional-rate-reduction-01.txt. + * It computes the number of packets to send (sndcnt) based on packets newly + * delivered: + * 1) If the packets in flight is larger than ssthresh, PRR spreads the + * cwnd reductions across a full RTT. + * 2) If packets in flight is lower than ssthresh (such as due to excess + * losses and/or application stalls), do not perform any further cwnd + * reductions, but instead slow start up to ssthresh. + */ +static void tcp_update_cwnd_in_recovery(struct sock *sk, int newly_acked_sacked, + int fast_rexmit, int flag) +{ + struct tcp_sock *tp = tcp_sk(sk); + int sndcnt = 0; + int delta = tp->snd_ssthresh - tcp_packets_in_flight(tp); + + if (tcp_packets_in_flight(tp) > tp->snd_ssthresh) { + u64 dividend = (u64)tp->snd_ssthresh * tp->prr_delivered + + tp->prior_cwnd - 1; + sndcnt = div_u64(dividend, tp->prior_cwnd) - tp->prr_out; + } else { + sndcnt = min_t(int, delta, + max_t(int, tp->prr_delivered - tp->prr_out, + newly_acked_sacked) + 1); + } + + sndcnt = max(sndcnt, (fast_rexmit ? 1 : 0)); + tp->snd_cwnd = tcp_packets_in_flight(tp) + sndcnt; +} + static void tcp_enter_recovery(struct sock *sk, bool ece_ack) { struct tcp_sock *tp = tcp_sk(sk); @@ -2870,6 +2898,7 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack) NET_INC_STATS_BH(sock_net(sk), mib_idx); + tp->high_seq = tp->snd_nxt; tp->prior_ssthresh = 0; tp->undo_marker = tp->snd_una; tp->undo_retrans = tp->retrans_out; @@ -2877,8 +2906,15 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack) if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { if (!ece_ack) tp->prior_ssthresh = tcp_current_ssthresh(sk); - tcp_init_cwnd_reduction(sk, true); + tp->snd_ssthresh = inet_csk(sk)->icsk_ca_ops->ssthresh(sk); + TCP_ECN_queue_cwr(tp); } + + tp->bytes_acked = 0; + tp->snd_cwnd_cnt = 0; + tp->prior_cwnd = tp->snd_cwnd; + tp->prr_delivered = 0; + tp->prr_out = 0; tcp_set_ca_state(sk, TCP_CA_Recovery); } @@ -2894,14 +2930,13 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack) * tcp_xmit_retransmit_queue(). */ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, - int prior_sacked, bool is_dupack, + int newly_acked_sacked, bool is_dupack, int flag) { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && (tcp_fackets_out(tp) > tp->reordering)); - int newly_acked_sacked = 0; int fast_rexmit = 0; if (WARN_ON(!tp->packets_out && tp->sacked_out)) @@ -2938,7 +2973,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, /* CWR is to be held something *above* high_seq * is ACKed for CWR bit to reach receiver. */ if (tp->snd_una != tp->high_seq) { - tcp_end_cwnd_reduction(sk); + tcp_complete_cwr(sk); tcp_set_ca_state(sk, TCP_CA_Open); } break; @@ -2948,7 +2983,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, tcp_reset_reno_sack(tp); if (tcp_try_undo_recovery(sk)) return; - tcp_end_cwnd_reduction(sk); + tcp_complete_cwr(sk); break; } } @@ -2961,7 +2996,6 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, tcp_add_reno_sack(sk); } else do_lost = tcp_try_undo_partial(sk, pkts_acked); - newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; break; case TCP_CA_Loss: if (flag & FLAG_DATA_ACKED) @@ -2983,13 +3017,12 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, if (is_dupack) tcp_add_reno_sack(sk); } - newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; if (icsk->icsk_ca_state <= TCP_CA_Disorder) tcp_try_undo_dsack(sk); if (!tcp_time_to_recover(sk, flag)) { - tcp_try_to_open(sk, flag, newly_acked_sacked); + tcp_try_to_open(sk, flag); return; } @@ -3011,7 +3044,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, if (do_lost || (tcp_is_fack(tp) && tcp_head_timedout(sk))) tcp_update_scoreboard(sk, fast_rexmit); - tcp_cwnd_reduction(sk, newly_acked_sacked, fast_rexmit); + tp->prr_delivered += newly_acked_sacked; + tcp_update_cwnd_in_recovery(sk, newly_acked_sacked, fast_rexmit, flag); tcp_xmit_retransmit_queue(sk); } @@ -3090,12 +3124,6 @@ void tcp_rearm_rto(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - /* If the retrans timer is currently being used by Fast Open - * for SYN-ACK retrans purpose, stay put. - */ - if (tp->fastopen_rsk) - return; - if (!tp->packets_out) { inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); } else { @@ -3357,7 +3385,7 @@ static inline bool tcp_may_raise_cwnd(const struct sock *sk, const int flag) { const struct tcp_sock *tp = tcp_sk(sk); return (!(flag & FLAG_ECE) || tp->snd_cwnd < tp->snd_ssthresh) && - !tcp_in_cwnd_reduction(sk); + !((1 << inet_csk(sk)->icsk_ca_state) & (TCPF_CA_Recovery | TCPF_CA_CWR)); } /* Check that window update is acceptable. @@ -3425,9 +3453,9 @@ static void tcp_conservative_spur_to_response(struct tcp_sock *tp) } /* A conservative spurious RTO response algorithm: reduce cwnd using - * PRR and continue in congestion avoidance. + * rate halving and continue in congestion avoidance. */ -static void tcp_cwr_spur_to_response(struct sock *sk) +static void tcp_ratehalving_spur_to_response(struct sock *sk) { tcp_enter_cwr(sk, 0); } @@ -3435,7 +3463,7 @@ static void tcp_cwr_spur_to_response(struct sock *sk) static void tcp_undo_spur_to_response(struct sock *sk, int flag) { if (flag & FLAG_ECE) - tcp_cwr_spur_to_response(sk); + tcp_ratehalving_spur_to_response(sk); else tcp_undo_cwr(sk, true); } @@ -3542,7 +3570,7 @@ static bool tcp_process_frto(struct sock *sk, int flag) tcp_conservative_spur_to_response(tp); break; default: - tcp_cwr_spur_to_response(sk); + tcp_ratehalving_spur_to_response(sk); break; } tp->frto_counter = 0; @@ -3566,6 +3594,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) int prior_packets; int prior_sacked = tp->sacked_out; int pkts_acked = 0; + int newly_acked_sacked = 0; bool frto_cwnd = false; /* If the ack is older than previous acks @@ -3641,6 +3670,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); pkts_acked = prior_packets - tp->packets_out; + newly_acked_sacked = (prior_packets - prior_sacked) - + (tp->packets_out - tp->sacked_out); if (tp->frto_counter) frto_cwnd = tcp_process_frto(sk, flag); @@ -3654,7 +3685,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) tcp_may_raise_cwnd(sk, flag)) tcp_cong_avoid(sk, ack, prior_in_flight); is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); - tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, + tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, is_dupack, flag); } else { if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) @@ -3671,7 +3702,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) no_queue: /* If data was DSACKed, see if we can undo a cwnd reduction. */ if (flag & FLAG_DSACKING_ACK) - tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, + tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, is_dupack, flag); /* If this ack opens up a zero window, clear backoff. It was * being used to time the probes, and is probably far higher than @@ -3691,7 +3722,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) */ if (TCP_SKB_CB(skb)->sacked) { flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); - tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, + newly_acked_sacked = tp->sacked_out - prior_sacked; + tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked, is_dupack, flag); } @@ -4007,7 +4039,7 @@ static inline bool tcp_sequence(const struct tcp_sock *tp, u32 seq, u32 end_seq) } /* When we get a reset we do this. */ -void tcp_reset(struct sock *sk) +static void tcp_reset(struct sock *sk) { /* We want the right error as BSD sees it (and indeed as we do). */ switch (sk->sk_state) { @@ -5864,9 +5896,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, tcp_send_synack(sk); #if 0 /* Note, we could accept data and URG from this segment. - * There are no obstacles to make this (except that we must - * either change tcp_recvmsg() to prevent it from returning data - * before 3WHS completes per RFC793, or employ TCP Fast Open). + * There are no obstacles to make this. * * However, if we ignore data in ACKless segments sometimes, * we have no reasons to accept it sometimes. @@ -5906,7 +5936,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, { struct tcp_sock *tp = tcp_sk(sk); struct inet_connection_sock *icsk = inet_csk(sk); - struct request_sock *req; int queued = 0; tp->rx_opt.saw_tstamp = 0; @@ -5962,14 +5991,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, return 0; } - req = tp->fastopen_rsk; - if (req != NULL) { - BUG_ON(sk->sk_state != TCP_SYN_RECV && - sk->sk_state != TCP_FIN_WAIT1); - - if (tcp_check_req(sk, skb, req, NULL, true) == NULL) - goto discard; - } else if (!tcp_validate_incoming(sk, skb, th, 0)) + if (!tcp_validate_incoming(sk, skb, th, 0)) return 0; /* step 5: check the ACK field */ @@ -5979,22 +6001,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, switch (sk->sk_state) { case TCP_SYN_RECV: if (acceptable) { - /* Once we leave TCP_SYN_RECV, we no longer - * need req so release it. - */ - if (req) { - reqsk_fastopen_remove(sk, req, false); - } else { - /* Make sure socket is routed, for - * correct metrics. - */ - icsk->icsk_af_ops->rebuild_header(sk); - tcp_init_congestion_control(sk); - - tcp_mtup_init(sk); - tcp_init_buffer_space(sk); - tp->copied_seq = tp->rcv_nxt; - } + tp->copied_seq = tp->rcv_nxt; smp_mb(); tcp_set_state(sk, TCP_ESTABLISHED); sk->sk_state_change(sk); @@ -6016,27 +6023,23 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, if (tp->rx_opt.tstamp_ok) tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; - if (req) { - /* Re-arm the timer because data may - * have been sent out. This is similar - * to the regular data transmission case - * when new data has just been ack'ed. - * - * (TFO) - we could try to be more - * aggressive and retranmitting any data - * sooner based on when they were sent - * out. - */ - tcp_rearm_rto(sk); - } else - tcp_init_metrics(sk); + /* Make sure socket is routed, for + * correct metrics. + */ + icsk->icsk_af_ops->rebuild_header(sk); + + tcp_init_metrics(sk); + + tcp_init_congestion_control(sk); /* Prevent spurious tcp_cwnd_restart() on * first data packet. */ tp->lsndtime = tcp_time_stamp; + tcp_mtup_init(sk); tcp_initialize_rcv_mss(sk); + tcp_init_buffer_space(sk); tcp_fast_path_on(tp); } else { return 1; @@ -6044,16 +6047,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, break; case TCP_FIN_WAIT1: - /* If we enter the TCP_FIN_WAIT1 state and we are a - * Fast Open socket and this is the first acceptable - * ACK we have received, this would have acknowledged - * our SYNACK so stop the SYNACK timer. - */ - if (acceptable && req != NULL) { - /* We no longer need the request sock. */ - reqsk_fastopen_remove(sk, req, false); - tcp_rearm_rto(sk); - } if (tp->snd_una == tp->write_seq) { struct dst_entry *dst; diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index e64abed249cc..1e15c5be04e7 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -352,7 +352,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) const int code = icmp_hdr(icmp_skb)->code; struct sock *sk; struct sk_buff *skb; - struct request_sock *req; __u32 seq; __u32 remaining; int err; @@ -395,12 +394,9 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) icsk = inet_csk(sk); tp = tcp_sk(sk); - req = tp->fastopen_rsk; seq = ntohl(th->seq); if (sk->sk_state != TCP_LISTEN && - !between(seq, tp->snd_una, tp->snd_nxt) && - (req == NULL || seq != tcp_rsk(req)->snt_isn)) { - /* For a Fast Open socket, allow seq to be snt_isn. */ + !between(seq, tp->snd_una, tp->snd_nxt)) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); goto out; } @@ -439,8 +435,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) !icsk->icsk_backoff) break; - /* XXX (TFO) - revisit the following logic for TFO */ - if (sock_owned_by_user(sk)) break; @@ -472,14 +466,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) goto out; } - /* XXX (TFO) - if it's a TFO socket and has been accepted, rather - * than following the TCP_SYN_RECV case and closing the socket, - * we ignore the ICMP error and keep trying like a fully established - * socket. Is this the right thing to do? - */ - if (req && req->sk == NULL) - goto out; - switch (sk->sk_state) { struct request_sock *req, **prev; case TCP_LISTEN: @@ -512,8 +498,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) case TCP_SYN_SENT: case TCP_SYN_RECV: /* Cannot happen. - It can f.e. if SYNs crossed, - or Fast Open. + It can f.e. if SYNs crossed. */ if (!sock_owned_by_user(sk)) { sk->sk_err = err; @@ -824,12 +809,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. - */ - tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ? - tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, - tcp_rsk(req)->rcv_nxt, req->rcv_wnd, + tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1, + tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, 0, tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr, @@ -858,7 +839,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, if (!dst && (dst = inet_csk_route_req(sk, &fl4, req)) == NULL) return -1; - skb = tcp_make_synack(sk, dst, req, rvp, NULL); + skb = tcp_make_synack(sk, dst, req, rvp); if (skb) { __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr); @@ -1291,178 +1272,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { }; #endif -static bool tcp_fastopen_check(struct sock *sk, struct sk_buff *skb, - struct request_sock *req, - struct tcp_fastopen_cookie *foc, - struct tcp_fastopen_cookie *valid_foc) -{ - bool skip_cookie = false; - struct fastopen_queue *fastopenq; - - if (likely(!fastopen_cookie_present(foc))) { - /* See include/net/tcp.h for the meaning of these knobs */ - if ((sysctl_tcp_fastopen & TFO_SERVER_ALWAYS) || - ((sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_REQD) && - (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq + 1))) - skip_cookie = true; /* no cookie to validate */ - else - return false; - } - fastopenq = inet_csk(sk)->icsk_accept_queue.fastopenq; - /* A FO option is present; bump the counter. */ - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFASTOPENPASSIVE); - - /* Make sure the listener has enabled fastopen, and we don't - * exceed the max # of pending TFO requests allowed before trying - * to validating the cookie in order to avoid burning CPU cycles - * unnecessarily. - * - * XXX (TFO) - The implication of checking the max_qlen before - * processing a cookie request is that clients can't differentiate - * between qlen overflow causing Fast Open to be disabled - * temporarily vs a server not supporting Fast Open at all. - */ - if ((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) == 0 || - fastopenq == NULL || fastopenq->max_qlen == 0) - return false; - - if (fastopenq->qlen >= fastopenq->max_qlen) { - struct request_sock *req1; - spin_lock(&fastopenq->lock); - req1 = fastopenq->rskq_rst_head; - if ((req1 == NULL) || time_after(req1->expires, jiffies)) { - spin_unlock(&fastopenq->lock); - NET_INC_STATS_BH(sock_net(sk), - LINUX_MIB_TCPFASTOPENLISTENOVERFLOW); - /* Avoid bumping LINUX_MIB_TCPFASTOPENPASSIVEFAIL*/ - foc->len = -1; - return false; - } - fastopenq->rskq_rst_head = req1->dl_next; - fastopenq->qlen--; - spin_unlock(&fastopenq->lock); - reqsk_free(req1); - } - if (skip_cookie) { - tcp_rsk(req)->rcv_nxt = TCP_SKB_CB(skb)->end_seq; - return true; - } - if (foc->len == TCP_FASTOPEN_COOKIE_SIZE) { - if ((sysctl_tcp_fastopen & TFO_SERVER_COOKIE_NOT_CHKED) == 0) { - tcp_fastopen_cookie_gen(ip_hdr(skb)->saddr, valid_foc); - if ((valid_foc->len != TCP_FASTOPEN_COOKIE_SIZE) || - memcmp(&foc->val[0], &valid_foc->val[0], - TCP_FASTOPEN_COOKIE_SIZE) != 0) - return false; - valid_foc->len = -1; - } - /* Acknowledge the data received from the peer. */ - tcp_rsk(req)->rcv_nxt = TCP_SKB_CB(skb)->end_seq; - return true; - } else if (foc->len == 0) { /* Client requesting a cookie */ - tcp_fastopen_cookie_gen(ip_hdr(skb)->saddr, valid_foc); - NET_INC_STATS_BH(sock_net(sk), - LINUX_MIB_TCPFASTOPENCOOKIEREQD); - } else { - /* Client sent a cookie with wrong size. Treat it - * the same as invalid and return a valid one. - */ - tcp_fastopen_cookie_gen(ip_hdr(skb)->saddr, valid_foc); - } - return false; -} - -static int tcp_v4_conn_req_fastopen(struct sock *sk, - struct sk_buff *skb, - struct sk_buff *skb_synack, - struct request_sock *req, - struct request_values *rvp) -{ - struct tcp_sock *tp = tcp_sk(sk); - struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; - const struct inet_request_sock *ireq = inet_rsk(req); - struct sock *child; - - req->retrans = 0; - req->sk = NULL; - - child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL); - if (child == NULL) { - NET_INC_STATS_BH(sock_net(sk), - LINUX_MIB_TCPFASTOPENPASSIVEFAIL); - kfree_skb(skb_synack); - return -1; - } - ip_build_and_send_pkt(skb_synack, sk, ireq->loc_addr, - ireq->rmt_addr, ireq->opt); - /* XXX (TFO) - is it ok to ignore error and continue? */ - - spin_lock(&queue->fastopenq->lock); - queue->fastopenq->qlen++; - spin_unlock(&queue->fastopenq->lock); - - /* Initialize the child socket. Have to fix some values to take - * into account the child is a Fast Open socket and is created - * only out of the bits carried in the SYN packet. - */ - tp = tcp_sk(child); - - tp->fastopen_rsk = req; - /* Do a hold on the listner sk so that if the listener is being - * closed, the child that has been accepted can live on and still - * access listen_lock. - */ - sock_hold(sk); - tcp_rsk(req)->listener = sk; - - /* RFC1323: The window in SYN & SYN/ACK segments is never - * scaled. So correct it appropriately. - */ - tp->snd_wnd = ntohs(tcp_hdr(skb)->window); - - /* Activate the retrans timer so that SYNACK can be retransmitted. - * The request socket is not added to the SYN table of the parent - * because it's been added to the accept queue directly. - */ - inet_csk_reset_xmit_timer(child, ICSK_TIME_RETRANS, - TCP_TIMEOUT_INIT, TCP_RTO_MAX); - - /* Add the child socket directly into the accept queue */ - inet_csk_reqsk_queue_add(sk, req, child); - - /* Now finish processing the fastopen child socket. */ - inet_csk(child)->icsk_af_ops->rebuild_header(child); - tcp_init_congestion_control(child); - tcp_mtup_init(child); - tcp_init_buffer_space(child); - tcp_init_metrics(child); - - /* Queue the data carried in the SYN packet. We need to first - * bump skb's refcnt because the caller will attempt to free it. - * - * XXX (TFO) - we honor a zero-payload TFO request for now. - * (Any reason not to?) - */ - if (TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq + 1) { - /* Don't queue the skb if there is no payload in SYN. - * XXX (TFO) - How about SYN+FIN? - */ - tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; - } else { - skb = skb_get(skb); - skb_dst_drop(skb); - __skb_pull(skb, tcp_hdr(skb)->doff * 4); - skb_set_owner_r(skb, child); - __skb_queue_tail(&child->sk_receive_queue, skb); - tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; - } - sk->sk_data_ready(sk, 0); - bh_unlock_sock(child); - sock_put(child); - WARN_ON(req->sk == NULL); - return 0; -} - int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) { struct tcp_extend_values tmp_ext; @@ -1476,11 +1285,6 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) __be32 daddr = ip_hdr(skb)->daddr; __u32 isn = TCP_SKB_CB(skb)->when; bool want_cookie = false; - struct flowi4 fl4; - struct tcp_fastopen_cookie foc = { .len = -1 }; - struct tcp_fastopen_cookie valid_foc = { .len = -1 }; - struct sk_buff *skb_synack; - int do_fastopen; /* Never answer to SYNs send to broadcast or multicast */ if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) @@ -1515,8 +1319,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) tcp_clear_options(&tmp_opt); tmp_opt.mss_clamp = TCP_MSS_DEFAULT; tmp_opt.user_mss = tp->rx_opt.user_mss; - tcp_parse_options(skb, &tmp_opt, &hash_location, 0, - want_cookie ? NULL : &foc); + tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); if (tmp_opt.cookie_plus > 0 && tmp_opt.saw_tstamp && @@ -1574,6 +1377,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) isn = cookie_v4_init_sequence(sk, skb, &req->mss); req->cookie_ts = tmp_opt.tstamp_ok; } else if (!isn) { + struct flowi4 fl4; + /* VJ's idea. We save last timestamp seen * from the destination in peer table, when entering * state TIME-WAIT, and check against it before @@ -1614,52 +1419,14 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) tcp_rsk(req)->snt_isn = isn; tcp_rsk(req)->snt_synack = tcp_time_stamp; - if (dst == NULL) { - dst = inet_csk_route_req(sk, &fl4, req); - if (dst == NULL) - goto drop_and_free; - } - do_fastopen = tcp_fastopen_check(sk, skb, req, &foc, &valid_foc); - - /* We don't call tcp_v4_send_synack() directly because we need - * to make sure a child socket can be created successfully before - * sending back synack! - * - * XXX (TFO) - Ideally one would simply call tcp_v4_send_synack() - * (or better yet, call tcp_send_synack() in the child context - * directly, but will have to fix bunch of other code first) - * after syn_recv_sock() except one will need to first fix the - * latter to remove its dependency on the current implementation - * of tcp_v4_send_synack()->tcp_select_initial_window(). - */ - skb_synack = tcp_make_synack(sk, dst, req, - (struct request_values *)&tmp_ext, - fastopen_cookie_present(&valid_foc) ? &valid_foc : NULL); - - if (skb_synack) { - __tcp_v4_send_check(skb_synack, ireq->loc_addr, ireq->rmt_addr); - skb_set_queue_mapping(skb_synack, skb_get_queue_mapping(skb)); - } else - goto drop_and_free; - - if (likely(!do_fastopen)) { - int err; - err = ip_build_and_send_pkt(skb_synack, sk, ireq->loc_addr, - ireq->rmt_addr, ireq->opt); - err = net_xmit_eval(err); - if (err || want_cookie) - goto drop_and_free; - - tcp_rsk(req)->listener = NULL; - /* Add the request_sock to the SYN table */ - inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); - if (fastopen_cookie_present(&foc) && foc.len != 0) - NET_INC_STATS_BH(sock_net(sk), - LINUX_MIB_TCPFASTOPENPASSIVEFAIL); - } else if (tcp_v4_conn_req_fastopen(sk, skb, skb_synack, req, - (struct request_values *)&tmp_ext)) + if (tcp_v4_send_synack(sk, dst, req, + (struct request_values *)&tmp_ext, + skb_get_queue_mapping(skb), + want_cookie) || + want_cookie) goto drop_and_free; + inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); return 0; drop_and_release: @@ -1787,7 +1554,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) struct request_sock *req = inet_csk_search_req(sk, &prev, th->source, iph->saddr, iph->daddr); if (req) - return tcp_check_req(sk, skb, req, prev, false); + return tcp_check_req(sk, skb, req, prev); nsk = inet_lookup_established(sock_net(sk), &tcp_hashinfo, iph->saddr, th->source, iph->daddr, th->dest, inet_iif(skb)); @@ -2210,7 +1977,6 @@ void tcp_v4_destroy_sock(struct sock *sk) tcp_cookie_values_release); tp->cookie_values = NULL; } - BUG_ON(tp->fastopen_rsk != NULL); /* If socket is aborted during connect operation */ tcp_free_fastopen_req(tp); @@ -2627,7 +2393,7 @@ void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo) EXPORT_SYMBOL(tcp_proc_unregister); static void get_openreq4(const struct sock *sk, const struct request_sock *req, - struct seq_file *f, int i, kuid_t uid, int *len) + struct seq_file *f, int i, int uid, int *len) { const struct inet_request_sock *ireq = inet_rsk(req); long delta = req->expires - jiffies; @@ -2644,7 +2410,7 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req, 1, /* timers active (only the expire timer) */ jiffies_delta_to_clock_t(delta), req->retrans, - from_kuid_munged(seq_user_ns(f), uid), + uid, 0, /* non standard timer */ 0, /* open_requests have no inode */ atomic_read(&sk->sk_refcnt), @@ -2659,7 +2425,6 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) const struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); const struct inet_sock *inet = inet_sk(sk); - struct fastopen_queue *fastopenq = icsk->icsk_accept_queue.fastopenq; __be32 dest = inet->inet_daddr; __be32 src = inet->inet_rcv_saddr; __u16 destp = ntohs(inet->inet_dport); @@ -2696,7 +2461,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) timer_active, jiffies_delta_to_clock_t(timer_expires - jiffies), icsk->icsk_retransmits, - from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)), + sock_i_uid(sk), icsk->icsk_probes_out, sock_i_ino(sk), atomic_read(&sk->sk_refcnt), sk, @@ -2704,9 +2469,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) jiffies_to_clock_t(icsk->icsk_ack.ato), (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, tp->snd_cwnd, - sk->sk_state == TCP_LISTEN ? - (fastopenq ? fastopenq->max_qlen : 0) : - (tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh), + tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh, len); } diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c index e965319d610b..6ff7f10dce9d 100644 --- a/trunk/net/ipv4/tcp_minisocks.c +++ b/trunk/net/ipv4/tcp_minisocks.c @@ -507,7 +507,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len; newtp->rx_opt.mss_clamp = req->mss; TCP_ECN_openreq_child(newtp, req); - newtp->fastopen_rsk = NULL; TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); } @@ -516,18 +515,13 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, EXPORT_SYMBOL(tcp_create_openreq_child); /* - * Process an incoming packet for SYN_RECV sockets represented as a - * request_sock. Normally sk is the listener socket but for TFO it - * points to the child socket. - * - * XXX (TFO) - The current impl contains a special check for ack - * validation and inside tcp_v4_reqsk_send_ack(). Can we do better? + * Process an incoming packet for SYN_RECV sockets represented + * as a request_sock. */ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, struct request_sock *req, - struct request_sock **prev, - bool fastopen) + struct request_sock **prev) { struct tcp_options_received tmp_opt; const u8 *hash_location; @@ -536,8 +530,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); bool paws_reject = false; - BUG_ON(fastopen == (sk->sk_state == TCP_LISTEN)); - tmp_opt.saw_tstamp = 0; if (th->doff > (sizeof(struct tcphdr)>>2)) { tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL); @@ -573,9 +565,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, * * Enforce "SYN-ACK" according to figure 8, figure 6 * of RFC793, fixed by RFC1122. - * - * Note that even if there is new data in the SYN packet - * they will be thrown away too. */ req->rsk_ops->rtx_syn_ack(sk, req, NULL); return NULL; @@ -633,12 +622,9 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, * sent (the segment carries an unacceptable ACK) ... * a reset is sent." * - * Invalid ACK: reset will be sent by listening socket. - * Note that the ACK validity check for a Fast Open socket is done - * elsewhere and is checked directly against the child socket rather - * than req because user data may have been sent out. + * Invalid ACK: reset will be sent by listening socket */ - if ((flg & TCP_FLAG_ACK) && !fastopen && + if ((flg & TCP_FLAG_ACK) && (TCP_SKB_CB(skb)->ack_seq != tcp_rsk(req)->snt_isn + 1 + tcp_s_data_size(tcp_sk(sk)))) return sk; @@ -651,7 +637,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, /* RFC793: "first check sequence number". */ if (paws_reject || !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq, - tcp_rsk(req)->rcv_nxt, tcp_rsk(req)->rcv_nxt + req->rcv_wnd)) { + tcp_rsk(req)->rcv_isn + 1, tcp_rsk(req)->rcv_isn + 1 + req->rcv_wnd)) { /* Out of window: send ACK and drop. */ if (!(flg & TCP_FLAG_RST)) req->rsk_ops->send_ack(sk, skb, req); @@ -662,7 +648,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, /* In sequence, PAWS is OK. */ - if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) + if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_isn + 1)) req->ts_recent = tmp_opt.rcv_tsval; if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { @@ -681,19 +667,10 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, /* ACK sequence verified above, just make sure ACK is * set. If ACK not set, just silently drop the packet. - * - * XXX (TFO) - if we ever allow "data after SYN", the - * following check needs to be removed. */ if (!(flg & TCP_FLAG_ACK)) return NULL; - /* For Fast Open no more processing is needed (sk is the - * child socket). - */ - if (fastopen) - return sk; - /* While TCP_DEFER_ACCEPT is active, drop bare ACK. */ if (req->retrans < inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { @@ -729,21 +706,11 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, } embryonic_reset: - if (!(flg & TCP_FLAG_RST)) { - /* Received a bad SYN pkt - for TFO We try not to reset - * the local connection unless it's really necessary to - * avoid becoming vulnerable to outside attack aiming at - * resetting legit local connections. - */ + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); + if (!(flg & TCP_FLAG_RST)) req->rsk_ops->send_reset(sk, skb); - } else if (fastopen) { /* received a valid RST pkt */ - reqsk_fastopen_remove(sk, req, true); - tcp_reset(sk); - } - if (!fastopen) { - inet_csk_reqsk_queue_drop(sk, req, prev); - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS); - } + + inet_csk_reqsk_queue_drop(sk, req, prev); return NULL; } EXPORT_SYMBOL(tcp_check_req); @@ -752,12 +719,6 @@ EXPORT_SYMBOL(tcp_check_req); * Queue segment on the new socket if the new socket is active, * otherwise we just shortcircuit this and continue with * the new socket. - * - * For the vast majority of cases child->sk_state will be TCP_SYN_RECV - * when entering. But other states are possible due to a race condition - * where after __inet_lookup_established() fails but before the listener - * locked is obtained, other packets cause the same connection to - * be created. */ int tcp_child_process(struct sock *parent, struct sock *child, diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index cfe6ffe1c177..d04632673a9e 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -702,8 +702,7 @@ static unsigned int tcp_synack_options(struct sock *sk, unsigned int mss, struct sk_buff *skb, struct tcp_out_options *opts, struct tcp_md5sig_key **md5, - struct tcp_extend_values *xvp, - struct tcp_fastopen_cookie *foc) + struct tcp_extend_values *xvp) { struct inet_request_sock *ireq = inet_rsk(req); unsigned int remaining = MAX_TCP_OPTION_SPACE; @@ -748,15 +747,7 @@ static unsigned int tcp_synack_options(struct sock *sk, if (unlikely(!ireq->tstamp_ok)) remaining -= TCPOLEN_SACKPERM_ALIGNED; } - if (foc != NULL) { - u32 need = TCPOLEN_EXP_FASTOPEN_BASE + foc->len; - need = (need + 3) & ~3U; /* Align to 32 bits */ - if (remaining >= need) { - opts->options |= OPTION_FAST_OPEN_COOKIE; - opts->fastopen_cookie = foc; - remaining -= need; - } - } + /* Similar rationale to tcp_syn_options() applies here, too. * If the options fit, the same options should fit now! */ @@ -2037,10 +2028,10 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, if (push_one) break; } + if (inet_csk(sk)->icsk_ca_state == TCP_CA_Recovery) + tp->prr_out += sent_pkts; if (likely(sent_pkts)) { - if (tcp_in_cwnd_reduction(sk)) - tp->prr_out += sent_pkts; tcp_cwnd_validate(sk); return false; } @@ -2542,7 +2533,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk) } NET_INC_STATS_BH(sock_net(sk), mib_idx); - if (tcp_in_cwnd_reduction(sk)) + if (inet_csk(sk)->icsk_ca_state == TCP_CA_Recovery) tp->prr_out += tcp_skb_pcount(skb); if (skb == tcp_write_queue_head(sk)) @@ -2667,8 +2658,7 @@ int tcp_send_synack(struct sock *sk) */ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct request_values *rvp, - struct tcp_fastopen_cookie *foc) + struct request_values *rvp) { struct tcp_out_options opts; struct tcp_extend_values *xvp = tcp_xv(rvp); @@ -2728,7 +2718,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, #endif TCP_SKB_CB(skb)->when = tcp_time_stamp; tcp_header_size = tcp_synack_options(sk, req, mss, - skb, &opts, &md5, xvp, foc) + skb, &opts, &md5, xvp) + sizeof(*th); skb_push(skb, tcp_header_size); @@ -2782,8 +2772,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, } th->seq = htonl(TCP_SKB_CB(skb)->seq); - /* XXX data is queued and acked as is. No buffer/window check */ - th->ack_seq = htonl(tcp_rsk(req)->rcv_nxt); + th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ th->window = htons(min(req->rcv_wnd, 65535U)); diff --git a/trunk/net/ipv4/tcp_timer.c b/trunk/net/ipv4/tcp_timer.c index fc04711e80c8..b774a03bd1dc 100644 --- a/trunk/net/ipv4/tcp_timer.c +++ b/trunk/net/ipv4/tcp_timer.c @@ -304,35 +304,6 @@ static void tcp_probe_timer(struct sock *sk) } } -/* - * Timer for Fast Open socket to retransmit SYNACK. Note that the - * sk here is the child socket, not the parent (listener) socket. - */ -static void tcp_fastopen_synack_timer(struct sock *sk) -{ - struct inet_connection_sock *icsk = inet_csk(sk); - int max_retries = icsk->icsk_syn_retries ? : - sysctl_tcp_synack_retries + 1; /* add one more retry for fastopen */ - struct request_sock *req; - - req = tcp_sk(sk)->fastopen_rsk; - req->rsk_ops->syn_ack_timeout(sk, req); - - if (req->retrans >= max_retries) { - tcp_write_err(sk); - return; - } - /* XXX (TFO) - Unlike regular SYN-ACK retransmit, we ignore error - * returned from rtx_syn_ack() to make it more persistent like - * regular retransmit because if the child socket has been accepted - * it's not good to give up too easily. - */ - req->rsk_ops->rtx_syn_ack(sk, req, NULL); - req->retrans++; - inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, - TCP_TIMEOUT_INIT << req->retrans, TCP_RTO_MAX); -} - /* * The TCP retransmit timer. */ @@ -346,15 +317,7 @@ void tcp_retransmit_timer(struct sock *sk) tcp_resume_early_retransmit(sk); return; } - if (tp->fastopen_rsk) { - BUG_ON(sk->sk_state != TCP_SYN_RECV && - sk->sk_state != TCP_FIN_WAIT1); - tcp_fastopen_synack_timer(sk); - /* Before we receive ACK to our SYN-ACK don't retransmit - * anything else (e.g., data or FIN segments). - */ - return; - } + if (!tp->packets_out) goto out; diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index c4e64328d8ba..6f6d1aca3c3d 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -2110,9 +2110,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, bucket, src, srcp, dest, destp, sp->sk_state, sk_wmem_alloc_get(sp), sk_rmem_alloc_get(sp), - 0, 0L, 0, - from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)), - 0, sock_i_ino(sp), + 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops), len); } diff --git a/trunk/net/ipv4/udp_diag.c b/trunk/net/ipv4/udp_diag.c index d2f336ea82ca..16d0960062be 100644 --- a/trunk/net/ipv4/udp_diag.c +++ b/trunk/net/ipv4/udp_diag.c @@ -24,9 +24,7 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, if (!inet_diag_bc_sk(bc, sk)) return 0; - return inet_sk_diag_fill(sk, NULL, skb, req, - sk_user_ns(NETLINK_CB(cb->skb).ssk), - NETLINK_CB(cb->skb).pid, + return inet_sk_diag_fill(sk, NULL, skb, req, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); } @@ -71,7 +69,6 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, goto out; err = inet_sk_diag_fill(sk, NULL, rep, req, - sk_user_ns(NETLINK_CB(in_skb).ssk), NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, 0, nlh); if (err < 0) { diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 055627f6df22..e581009cb09e 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -127,8 +127,8 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev) #endif #ifdef CONFIG_IPV6_PRIVACY -static void __ipv6_regen_rndid(struct inet6_dev *idev); -static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); +static int __ipv6_regen_rndid(struct inet6_dev *idev); +static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); static void ipv6_regen_rndid(unsigned long data); #endif @@ -852,7 +852,16 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i } in6_ifa_hold(ifp); memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); - __ipv6_try_regen_rndid(idev, tmpaddr); + if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) { + spin_unlock_bh(&ifp->lock); + write_unlock(&idev->lock); + pr_warn("%s: regeneration of randomized interface id failed\n", + __func__); + in6_ifa_put(ifp); + in6_dev_put(idev); + ret = -1; + goto out; + } memcpy(&addr.s6_addr[8], idev->rndid, 8); age = (now - ifp->tstamp) / HZ; tmp_valid_lft = min_t(__u32, @@ -1591,7 +1600,7 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev) #ifdef CONFIG_IPV6_PRIVACY /* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */ -static void __ipv6_regen_rndid(struct inet6_dev *idev) +static int __ipv6_regen_rndid(struct inet6_dev *idev) { regen: get_random_bytes(idev->rndid, sizeof(idev->rndid)); @@ -1618,6 +1627,8 @@ static void __ipv6_regen_rndid(struct inet6_dev *idev) if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00) goto regen; } + + return 0; } static void ipv6_regen_rndid(unsigned long data) @@ -1631,7 +1642,8 @@ static void ipv6_regen_rndid(unsigned long data) if (idev->dead) goto out; - __ipv6_regen_rndid(idev); + if (__ipv6_regen_rndid(idev) < 0) + goto out; expires = jiffies + idev->cnf.temp_prefered_lft * HZ - @@ -1652,10 +1664,13 @@ static void ipv6_regen_rndid(unsigned long data) in6_dev_put(idev); } -static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) +static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) { + int ret = 0; + if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0) - __ipv6_regen_rndid(idev); + ret = __ipv6_regen_rndid(idev); + return ret; } #endif @@ -2551,10 +2566,14 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, void *data) { struct net_device *dev = (struct net_device *) data; - struct inet6_dev *idev = __in6_dev_get(dev); + struct inet6_dev *idev; int run_pending = 0; int err; + if (event == NETDEV_UNREGISTER_FINAL) + return NOTIFY_DONE; + + idev = __in6_dev_get(dev); switch (event) { case NETDEV_REGISTER: if (!idev && dev->mtu >= IPV6_MIN_MTU) { diff --git a/trunk/net/ipv6/ip6_flowlabel.c b/trunk/net/ipv6/ip6_flowlabel.c index 90bbefb57943..9772fbd8a3f5 100644 --- a/trunk/net/ipv6/ip6_flowlabel.c +++ b/trunk/net/ipv6/ip6_flowlabel.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -92,8 +91,6 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label) static void fl_free(struct ip6_flowlabel *fl) { if (fl) { - if (fl->share == IPV6_FL_S_PROCESS) - put_pid(fl->owner.pid); release_net(fl->fl_net); kfree(fl->opt); } @@ -397,10 +394,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, case IPV6_FL_S_ANY: break; case IPV6_FL_S_PROCESS: - fl->owner.pid = get_task_pid(current, PIDTYPE_PID); + fl->owner = current->pid; break; case IPV6_FL_S_USER: - fl->owner.uid = current_euid(); + fl->owner = current_euid(); break; default: err = -EINVAL; @@ -564,10 +561,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) err = -EPERM; if (fl1->share == IPV6_FL_S_EXCL || fl1->share != fl->share || - ((fl1->share == IPV6_FL_S_PROCESS) && - (fl1->owner.pid == fl->owner.pid)) || - ((fl1->share == IPV6_FL_S_USER) && - uid_eq(fl1->owner.uid, fl->owner.uid))) + fl1->owner != fl->owner) goto release; err = -EINVAL; @@ -627,7 +621,6 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) struct ip6fl_iter_state { struct seq_net_private p; - struct pid_namespace *pid_ns; int bucket; }; @@ -706,7 +699,6 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) static int ip6fl_seq_show(struct seq_file *seq, void *v) { - struct ip6fl_iter_state *state = ip6fl_seq_private(seq); if (v == SEQ_START_TOKEN) seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); @@ -716,11 +708,7 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v) "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", (unsigned int)ntohl(fl->label), fl->share, - ((fl->share == IPV6_FL_S_PROCESS) ? - pid_nr_ns(fl->owner.pid, state->pid_ns) : - ((fl->share == IPV6_FL_S_USER) ? - from_kuid_munged(seq_user_ns(seq), fl->owner.uid) : - 0)), + (int)fl->owner, atomic_read(&fl->users), fl->linger/HZ, (long)(fl->expires - jiffies)/HZ, @@ -739,29 +727,8 @@ static const struct seq_operations ip6fl_seq_ops = { static int ip6fl_seq_open(struct inode *inode, struct file *file) { - struct seq_file *seq; - struct ip6fl_iter_state *state; - int err; - - err = seq_open_net(inode, file, &ip6fl_seq_ops, - sizeof(struct ip6fl_iter_state)); - - if (!err) { - seq = file->private_data; - state = ip6fl_seq_private(seq); - rcu_read_lock(); - state->pid_ns = get_pid_ns(task_active_pid_ns(current)); - rcu_read_unlock(); - } - return err; -} - -static int ip6fl_seq_release(struct inode *inode, struct file *file) -{ - struct seq_file *seq = file->private_data; - struct ip6fl_iter_state *state = ip6fl_seq_private(seq); - put_pid_ns(state->pid_ns); - return seq_release_net(inode, file); + return seq_open_net(inode, file, &ip6fl_seq_ops, + sizeof(struct ip6fl_iter_state)); } static const struct file_operations ip6fl_seq_fops = { @@ -769,7 +736,7 @@ static const struct file_operations ip6fl_seq_fops = { .open = ip6fl_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = ip6fl_seq_release, + .release = seq_release_net, }; static int __net_init ip6_flowlabel_proc_init(struct net *net) diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index 7af88ef01657..ef0579d5bca6 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -1251,8 +1251,7 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) sk_wmem_alloc_get(sp), sk_rmem_alloc_get(sp), 0, 0L, 0, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), - 0, + sock_i_uid(sp), 0, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); } diff --git a/trunk/net/ipv6/syncookies.c b/trunk/net/ipv6/syncookies.c index 182ab9a85d6c..bb46061c813a 100644 --- a/trunk/net/ipv6/syncookies.c +++ b/trunk/net/ipv6/syncookies.c @@ -190,7 +190,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) ireq = inet_rsk(req); ireq6 = inet6_rsk(req); treq = tcp_rsk(req); - treq->listener = NULL; if (security_inet_conn_request(sk, skb, req)) goto out_free; diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 09078b9bc6f6..cd49de3678fb 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -475,7 +475,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) goto done; - skb = tcp_make_synack(sk, dst, req, rvp, NULL); + skb = tcp_make_synack(sk, dst, req, rvp); if (skb) { __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); @@ -987,7 +987,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, inet6_iif(skb)); if (req) - return tcp_check_req(sk, skb, req, prev, false); + return tcp_check_req(sk, skb, req, prev); nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source, @@ -1179,7 +1179,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) want_cookie) goto drop_and_free; - tcp_rsk(req)->listener = NULL; inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); return 0; @@ -1829,7 +1828,7 @@ static void tcp_v6_destroy_sock(struct sock *sk) #ifdef CONFIG_PROC_FS /* Proc filesystem TCPv6 sock list dumping. */ static void get_openreq6(struct seq_file *seq, - const struct sock *sk, struct request_sock *req, int i, kuid_t uid) + const struct sock *sk, struct request_sock *req, int i, int uid) { int ttd = req->expires - jiffies; const struct in6_addr *src = &inet6_rsk(req)->loc_addr; @@ -1853,7 +1852,7 @@ static void get_openreq6(struct seq_file *seq, 1, /* timers active (only the expire timer) */ jiffies_to_clock_t(ttd), req->retrans, - from_kuid_munged(seq_user_ns(seq), uid), + uid, 0, /* non standard timer */ 0, /* open_requests have no inode */ 0, req); @@ -1903,7 +1902,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) timer_active, jiffies_delta_to_clock_t(timer_expires - jiffies), icsk->icsk_retransmits, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), + sock_i_uid(sp), icsk->icsk_probes_out, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index bbdff07eebe1..99d0077b56b8 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -1458,8 +1458,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket sk_wmem_alloc_get(sp), sk_rmem_alloc_get(sp), 0, 0L, 0, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), - 0, + sock_i_uid(sp), 0, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); diff --git a/trunk/net/ipx/ipx_proc.c b/trunk/net/ipx/ipx_proc.c index 02ff7f2f60d4..f8ba30dfecae 100644 --- a/trunk/net/ipx/ipx_proc.c +++ b/trunk/net/ipx/ipx_proc.c @@ -217,8 +217,7 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v) seq_printf(seq, "%08X %08X %02X %03d\n", sk_wmem_alloc_get(s), sk_rmem_alloc_get(s), - s->sk_state, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(s))); + s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); out: return 0; } diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 334f93b8cfcb..ec7d161c129b 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -3661,7 +3661,7 @@ static int pfkey_seq_show(struct seq_file *f, void *v) atomic_read(&s->sk_refcnt), sk_rmem_alloc_get(s), sk_wmem_alloc_get(s), - from_kuid_munged(seq_user_ns(f), sock_i_uid(s)), + sock_i_uid(s), sock_i_ino(s) ); return 0; diff --git a/trunk/net/l2tp/l2tp_core.c b/trunk/net/l2tp/l2tp_core.c index 513cab08a986..393355d37b47 100644 --- a/trunk/net/l2tp/l2tp_core.c +++ b/trunk/net/l2tp/l2tp_core.c @@ -1347,10 +1347,11 @@ static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel) /* Remove from tunnel list */ spin_lock_bh(&pn->l2tp_tunnel_list_lock); list_del_rcu(&tunnel->list); - kfree_rcu(tunnel, rcu); spin_unlock_bh(&pn->l2tp_tunnel_list_lock); + synchronize_rcu(); atomic_dec(&l2tp_tunnel_count); + kfree(tunnel); } /* Create a socket for the tunnel, if one isn't set up by diff --git a/trunk/net/l2tp/l2tp_core.h b/trunk/net/l2tp/l2tp_core.h index 56d583e083a7..a38ec6cdeee1 100644 --- a/trunk/net/l2tp/l2tp_core.h +++ b/trunk/net/l2tp/l2tp_core.h @@ -163,7 +163,6 @@ struct l2tp_tunnel_cfg { struct l2tp_tunnel { int magic; /* Should be L2TP_TUNNEL_MAGIC */ - struct rcu_head rcu; rwlock_t hlist_lock; /* protect session_hlist */ struct hlist_head session_hlist[L2TP_HASH_SIZE]; /* hashed list of sessions, diff --git a/trunk/net/llc/llc_proc.c b/trunk/net/llc/llc_proc.c index 7b4799cfbf8d..a1839c004357 100644 --- a/trunk/net/llc/llc_proc.c +++ b/trunk/net/llc/llc_proc.c @@ -151,7 +151,7 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v) sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk) - llc->copied_seq, sk->sk_state, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), + sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, llc->link); out: return 0; diff --git a/trunk/net/mac80211/aes_cmac.c b/trunk/net/mac80211/aes_cmac.c index a04752e91023..8dfd70d8fcfb 100644 --- a/trunk/net/mac80211/aes_cmac.c +++ b/trunk/net/mac80211/aes_cmac.c @@ -38,10 +38,14 @@ static void gf_mulx(u8 *pad) static void aes_128_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { - u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; + u8 scratch[2 * AES_BLOCK_SIZE]; + u8 *cbc, *pad; const u8 *pos, *end; size_t i, e, left, total_len; + cbc = scratch; + pad = scratch + AES_BLOCK_SIZE; + memset(cbc, 0, AES_BLOCK_SIZE); total_len = 0; diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 929f897a8ded..d41974aacf51 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -102,18 +102,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, return 0; } -static int ieee80211_start_p2p_device(struct wiphy *wiphy, - struct wireless_dev *wdev) -{ - return ieee80211_do_open(wdev, true); -} - -static void ieee80211_stop_p2p_device(struct wiphy *wiphy, - struct wireless_dev *wdev) -{ - ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev)); -} - static int ieee80211_set_noack_map(struct wiphy *wiphy, struct net_device *dev, u16 noack_map) @@ -342,7 +330,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { struct ieee80211_supported_band *sband; sband = sta->local->hw.wiphy->bands[ - sta->local->oper_channel->band]; + sta->local->hw.conf.channel->band]; rate->legacy = sband->bitrates[idx].bitrate; } else rate->mcs = idx; @@ -737,23 +725,25 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, const u8 *resp, size_t resp_len) { - struct probe_resp *new, *old; + struct sk_buff *new, *old; if (!resp || !resp_len) return 1; old = rtnl_dereference(sdata->u.ap.probe_resp); - new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); + new = dev_alloc_skb(resp_len); if (!new) return -ENOMEM; - new->len = resp_len; - memcpy(new->data, resp, resp_len); + memcpy(skb_put(new, resp_len), resp, resp_len); rcu_assign_pointer(sdata->u.ap.probe_resp, new); - if (old) - kfree_rcu(old, rcu_head); + if (old) { + /* TODO: use call_rcu() */ + synchronize_rcu(); + dev_kfree_skb(old); + } return 0; } @@ -960,7 +950,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta) /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ - eth_broadcast_addr(msg->da); + memset(msg->da, 0xff, ETH_ALEN); memcpy(msg->sa, sta->sta.addr, ETH_ALEN); msg->len = htons(6); msg->dsap = 0; @@ -1295,10 +1285,9 @@ static int ieee80211_change_station(struct wiphy *wiphy, mutex_unlock(&local->sta_mtx); if (sdata->vif.type == NL80211_IFTYPE_STATION && - params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { + params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) ieee80211_recalc_ps(local, -1); - ieee80211_recalc_ps_vif(sdata); - } + return 0; } @@ -1672,7 +1661,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy, } if (!sdata->vif.bss_conf.use_short_slot && - sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) { + sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) { sdata->vif.bss_conf.use_short_slot = true; changed |= BSS_CHANGED_ERP_SLOT; } @@ -1786,7 +1775,6 @@ static int ieee80211_scan(struct wiphy *wiphy, case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_P2P_DEVICE: break; case NL80211_IFTYPE_P2P_GO: if (sdata->local->ops->hw_scan) @@ -1939,7 +1927,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int mbm) { struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_channel *chan = local->oper_channel; + struct ieee80211_channel *chan = local->hw.conf.channel; u32 changes = 0; switch (type) { @@ -2091,7 +2079,6 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); ieee80211_recalc_ps(local, -1); - ieee80211_recalc_ps_vif(sdata); return 0; } @@ -2474,9 +2461,6 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, if (!sdata->u.mgd.associated) need_offchan = true; break; - case NL80211_IFTYPE_P2P_DEVICE: - need_offchan = true; - break; default: return -EOPNOTSUPP; } @@ -2669,7 +2653,6 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, u16 status_code, struct sk_buff *skb) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; struct ieee80211_tdls_data *tf; tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); @@ -2689,10 +2672,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_req.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false, - local->oper_channel->band); - ieee80211_add_ext_srates_ie(sdata, skb, false, - local->oper_channel->band); + ieee80211_add_srates_ie(sdata, skb, false); + ieee80211_add_ext_srates_ie(sdata, skb, false); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_RESPONSE: @@ -2705,10 +2686,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false, - local->oper_channel->band); - ieee80211_add_ext_srates_ie(sdata, skb, false, - local->oper_channel->band); + ieee80211_add_srates_ie(sdata, skb, false); + ieee80211_add_ext_srates_ie(sdata, skb, false); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_CONFIRM: @@ -2746,7 +2725,6 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, u16 status_code, struct sk_buff *skb) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; struct ieee80211_mgmt *mgmt; mgmt = (void *)skb_put(skb, 24); @@ -2769,10 +2747,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, mgmt->u.action.u.tdls_discover_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false, - local->oper_channel->band); - ieee80211_add_ext_srates_ie(sdata, skb, false, - local->oper_channel->band); + ieee80211_add_srates_ie(sdata, skb, false); + ieee80211_add_ext_srates_ie(sdata, skb, false); ieee80211_tdls_add_ext_capab(skb); break; default: @@ -3029,8 +3005,6 @@ struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, .change_virtual_intf = ieee80211_change_iface, - .start_p2p_device = ieee80211_start_p2p_device, - .stop_p2p_device = ieee80211_stop_p2p_device, .add_key = ieee80211_add_key, .del_key = ieee80211_del_key, .get_key = ieee80211_get_key, diff --git a/trunk/net/mac80211/debugfs.c b/trunk/net/mac80211/debugfs.c index 97173f8144d4..b8dfb440c8ef 100644 --- a/trunk/net/mac80211/debugfs.c +++ b/trunk/net/mac80211/debugfs.c @@ -63,6 +63,8 @@ DEBUGFS_READONLY_FILE(user_power, "%d", local->user_power_level); DEBUGFS_READONLY_FILE(power, "%d", local->hw.conf.power_level); +DEBUGFS_READONLY_FILE(frequency, "%d", + local->hw.conf.channel->center_freq); DEBUGFS_READONLY_FILE(total_ps_buffered, "%d", local->total_ps_buffered); DEBUGFS_READONLY_FILE(wep_iv, "%#08x", @@ -89,6 +91,33 @@ static const struct file_operations reset_ops = { .llseek = noop_llseek, }; +static ssize_t channel_type_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ieee80211_local *local = file->private_data; + const char *buf; + + switch (local->hw.conf.channel_type) { + case NL80211_CHAN_NO_HT: + buf = "no ht\n"; + break; + case NL80211_CHAN_HT20: + buf = "ht20\n"; + break; + case NL80211_CHAN_HT40MINUS: + buf = "ht40-\n"; + break; + case NL80211_CHAN_HT40PLUS: + buf = "ht40+\n"; + break; + default: + buf = "???"; + break; + } + + return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); +} + static ssize_t hwflags_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -176,6 +205,7 @@ static ssize_t queues_read(struct file *file, char __user *user_buf, } DEBUGFS_READONLY_FILE_OPS(hwflags); +DEBUGFS_READONLY_FILE_OPS(channel_type); DEBUGFS_READONLY_FILE_OPS(queues); /* statistics stuff */ @@ -242,10 +272,12 @@ void debugfs_hw_add(struct ieee80211_local *local) local->debugfs.keys = debugfs_create_dir("keys", phyd); + DEBUGFS_ADD(frequency); DEBUGFS_ADD(total_ps_buffered); DEBUGFS_ADD(wep_iv); DEBUGFS_ADD(queues); DEBUGFS_ADD_MODE(reset, 0200); + DEBUGFS_ADD(channel_type); DEBUGFS_ADD(hwflags); DEBUGFS_ADD(user_power); DEBUGFS_ADD(power); diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h index da9003b20004..df9203199102 100644 --- a/trunk/net/mac80211/driver-ops.h +++ b/trunk/net/mac80211/driver-ops.h @@ -9,7 +9,7 @@ static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) { WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", - sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); + sdata->dev->name, sdata->flags); } static inline struct ieee80211_sub_if_data * @@ -22,11 +22,9 @@ get_bss_sdata(struct ieee80211_sub_if_data *sdata) return sdata; } -static inline void drv_tx(struct ieee80211_local *local, - struct ieee80211_tx_control *control, - struct sk_buff *skb) +static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) { - local->ops->tx(&local->hw, control, skb); + local->ops->tx(&local->hw, skb); } static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, @@ -528,9 +526,6 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local, sdata = get_bss_sdata(sdata); check_sdata_in_driver(sdata); - WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && - sdata->vif.type != NL80211_IFTYPE_ADHOC); - trace_drv_sta_rc_update(local, sdata, sta, changed); if (local->ops->sta_rc_update) local->ops->sta_rc_update(&local->hw, &sdata->vif, diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index a9d93285dba7..5746d62faba1 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -109,7 +109,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); - eth_broadcast_addr(mgmt->da); + memset(mgmt->da, 0xff, ETH_ALEN); memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int); @@ -205,7 +205,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, mod_timer(&ifibss->timer, round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); - bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, + bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, mgmt, skb->len, 0, GFP_KERNEL); cfg80211_put_bss(bss); netif_carrier_on(sdata->dev); @@ -294,7 +294,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - int band = local->oper_channel->band; + int band = local->hw.conf.channel->band; /* * XXX: Consider removing the least recently used entry and @@ -459,11 +459,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, } } - if (sta && rates_updated) { - drv_sta_rc_update(local, sdata, &sta->sta, - IEEE80211_RC_SUPP_RATES_CHANGED); + if (sta && rates_updated) rate_control_rate_init(sta); - } rcu_read_unlock(); } @@ -564,7 +561,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - int band = local->oper_channel->band; + int band = local->hw.conf.channel->band; /* * XXX: Consider removing the least recently used entry and @@ -762,7 +759,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) return; } sdata_info(sdata, "IBSS not allowed on %d MHz\n", - local->oper_channel->center_freq); + local->hw.conf.channel->center_freq); /* No IBSS found - decrease scan interval and continue * scanning. */ diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 204bfedba306..bb61f7718c4c 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -193,6 +193,8 @@ struct ieee80211_tx_data { struct sta_info *sta; struct ieee80211_key *key; + struct ieee80211_channel *channel; + unsigned int flags; }; @@ -272,15 +274,9 @@ struct beacon_data { struct rcu_head rcu_head; }; -struct probe_resp { - struct rcu_head rcu_head; - int len; - u8 data[0]; -}; - struct ieee80211_if_ap { struct beacon_data __rcu *beacon; - struct probe_resp __rcu *probe_resp; + struct sk_buff __rcu *probe_resp; struct list_head vlans; @@ -363,7 +359,6 @@ enum ieee80211_sta_flags { IEEE80211_STA_NULLFUNC_ACKED = BIT(8), IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9), IEEE80211_STA_DISABLE_40MHZ = BIT(10), - IEEE80211_STA_DISABLE_VHT = BIT(11), }; struct ieee80211_mgd_auth_data { @@ -1080,8 +1075,6 @@ struct ieee80211_local { struct idr ack_status_frames; spinlock_t ack_status_lock; - struct ieee80211_sub_if_data __rcu *p2p_sdata; - /* dummy netdev for use w/ NAPI */ struct net_device napi_dev; @@ -1138,7 +1131,7 @@ struct ieee802_11_elems { u8 *prep; u8 *perr; struct ieee80211_rann_ie *rann; - struct ieee80211_channel_sw_ie *ch_switch_ie; + u8 *ch_switch_elem; u8 *country_elem; u8 *pwr_constr_elem; u8 *quiet_elem; /* first quite element */ @@ -1164,6 +1157,7 @@ struct ieee802_11_elems { u8 preq_len; u8 prep_len; u8 perr_len; + u8 ch_switch_elem_len; u8 country_elem_len; u8 pwr_constr_elem_len; u8 quiet_elem_len; @@ -1208,7 +1202,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, void ieee80211_send_pspoll(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); -void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata); int ieee80211_max_network_latency(struct notifier_block *nb, unsigned long data, void *dummy); int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata); @@ -1298,8 +1291,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local); void ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, const int offset); -int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up); -void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata); static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) { @@ -1434,6 +1425,7 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr); void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_hdr *hdr, bool ack); +void ieee80211_beacon_connection_loss_work(struct work_struct *work); void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, enum queue_stop_reason reason); @@ -1465,15 +1457,13 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, u8 channel); struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, u32 ratemask, - struct ieee80211_channel *chan, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, bool directed); void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, - u32 ratemask, bool directed, bool no_cck, - struct ieee80211_channel *channel); + u32 ratemask, bool directed, bool no_cck); void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, const size_t supp_rates_len, @@ -1497,11 +1487,9 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, u32 cap); int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool need_basic, - enum ieee80211_band band); + struct sk_buff *skb, bool need_basic); int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool need_basic, - enum ieee80211_band band); + struct sk_buff *skb, bool need_basic); /* channel management */ enum ieee80211_chan_mode { diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 59f8adc2aa5f..bfb57dcc1538 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -100,10 +100,6 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) sdata->vif.bss_conf.idle = true; continue; } - - if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) - continue; - /* count everything else */ sdata->vif.bss_conf.idle = false; count++; @@ -125,8 +121,7 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type == NL80211_IFTYPE_MONITOR || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN || - sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) continue; if (sdata->old_idle == sdata->vif.bss_conf.idle) continue; @@ -209,8 +204,6 @@ static inline int identical_mac_addr_allowed(int type1, int type2) { return type1 == NL80211_IFTYPE_MONITOR || type2 == NL80211_IFTYPE_MONITOR || - type1 == NL80211_IFTYPE_P2P_DEVICE || - type2 == NL80211_IFTYPE_P2P_DEVICE || (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_WDS) || (type1 == NL80211_IFTYPE_WDS && (type2 == NL80211_IFTYPE_WDS || @@ -413,10 +406,9 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) * an error on interface type changes that have been pre-checked, so most * checks should be in ieee80211_check_concurrent_iface. */ -int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) +static int ieee80211_do_open(struct net_device *dev, bool coming_up) { - struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - struct net_device *dev = wdev->netdev; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; struct sta_info *sta; u32 changed = 0; @@ -451,7 +443,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_P2P_DEVICE: /* no special treatment */ break; case NL80211_IFTYPE_UNSPECIFIED: @@ -480,7 +471,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) * Copy the hopefully now-present MAC address to * this interface, if it has the special null one. */ - if (dev && is_zero_ether_addr(dev->dev_addr)) { + if (is_zero_ether_addr(dev->dev_addr)) { memcpy(dev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); @@ -545,23 +536,15 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) local->fif_probe_req++; } - if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) - changed |= ieee80211_reset_erp_info(sdata); + changed |= ieee80211_reset_erp_info(sdata); ieee80211_bss_info_change_notify(sdata, changed); - switch (sdata->vif.type) { - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_MESH_POINT: + if (sdata->vif.type == NL80211_IFTYPE_STATION || + sdata->vif.type == NL80211_IFTYPE_ADHOC || + sdata->vif.type == NL80211_IFTYPE_AP) netif_carrier_off(dev); - break; - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_P2P_DEVICE: - break; - default: + else netif_carrier_on(dev); - } /* * set default queue parameters so drivers don't @@ -593,9 +576,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) } rate_control_rate_init(sta); - netif_carrier_on(dev); - } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { - rcu_assign_pointer(local->p2p_sdata, sdata); } /* @@ -621,8 +601,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) ieee80211_recalc_ps(local, -1); - if (dev) - netif_tx_start_all_queues(dev); + netif_tx_start_all_queues(dev); return 0; err_del_interface: @@ -652,7 +631,7 @@ static int ieee80211_open(struct net_device *dev) if (err) return err; - return ieee80211_do_open(&sdata->wdev, true); + return ieee80211_do_open(dev, true); } static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, @@ -673,8 +652,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, /* * Stop TX on this interface first. */ - if (sdata->dev) - netif_tx_stop_all_queues(sdata->dev); + netif_tx_stop_all_queues(sdata->dev); ieee80211_roc_purge(sdata); @@ -713,16 +691,14 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, local->fif_probe_req--; } - if (sdata->dev) { - netif_addr_lock_bh(sdata->dev); - spin_lock_bh(&local->filter_lock); - __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, - sdata->dev->addr_len); - spin_unlock_bh(&local->filter_lock); - netif_addr_unlock_bh(sdata->dev); + netif_addr_lock_bh(sdata->dev); + spin_lock_bh(&local->filter_lock); + __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, + sdata->dev->addr_len); + spin_unlock_bh(&local->filter_lock); + netif_addr_unlock_bh(sdata->dev); - ieee80211_configure_filter(local); - } + ieee80211_configure_filter(local); del_timer_sync(&local->dynamic_ps_timer); cancel_work_sync(&local->dynamic_ps_enable_work); @@ -732,7 +708,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, struct ieee80211_sub_if_data *vlan, *tmpsdata; struct beacon_data *old_beacon = rtnl_dereference(sdata->u.ap.beacon); - struct probe_resp *old_probe_resp = + struct sk_buff *old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); /* sdata_running will return false, so this will disable */ @@ -744,7 +720,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL); synchronize_rcu(); kfree(old_beacon); - kfree(old_probe_resp); + kfree_skb(old_probe_resp); /* down all dependent devices, that is VLANs */ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, @@ -783,10 +759,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_adjust_monitor_flags(sdata, -1); ieee80211_configure_filter(local); break; - case NL80211_IFTYPE_P2P_DEVICE: - /* relies on synchronize_rcu() below */ - rcu_assign_pointer(local->p2p_sdata, NULL); - /* fall through */ default: flush_work(&sdata->work); /* @@ -798,6 +770,14 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, synchronize_rcu(); skb_queue_purge(&sdata->skb_queue); + /* + * Disable beaconing here for mesh only, AP and IBSS + * are already taken care of. + */ + if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_BEACON_ENABLED); + /* * Free all remaining keys, there shouldn't be any, * except maybe group keys in AP more or WDS? @@ -897,8 +877,9 @@ static void ieee80211_set_multicast_list(struct net_device *dev) * Called when the netdev is removed or, by the code below, before * the interface type changes. */ -static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) +static void ieee80211_teardown_sdata(struct net_device *dev) { + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; int flushed; int i; @@ -919,11 +900,6 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) WARN_ON(flushed); } -static void ieee80211_uninit(struct net_device *dev) -{ - ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); -} - static u16 ieee80211_netdev_select_queue(struct net_device *dev, struct sk_buff *skb) { @@ -933,7 +909,7 @@ static u16 ieee80211_netdev_select_queue(struct net_device *dev, static const struct net_device_ops ieee80211_dataif_ops = { .ndo_open = ieee80211_open, .ndo_stop = ieee80211_stop, - .ndo_uninit = ieee80211_uninit, + .ndo_uninit = ieee80211_teardown_sdata, .ndo_start_xmit = ieee80211_subif_start_xmit, .ndo_set_rx_mode = ieee80211_set_multicast_list, .ndo_change_mtu = ieee80211_change_mtu, @@ -964,7 +940,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev, static const struct net_device_ops ieee80211_monitorif_ops = { .ndo_open = ieee80211_open, .ndo_stop = ieee80211_stop, - .ndo_uninit = ieee80211_uninit, + .ndo_uninit = ieee80211_teardown_sdata, .ndo_start_xmit = ieee80211_monitor_start_xmit, .ndo_set_rx_mode = ieee80211_set_multicast_list, .ndo_change_mtu = ieee80211_change_mtu, @@ -1123,6 +1099,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, /* and set some type-dependent values */ sdata->vif.type = type; sdata->vif.p2p = false; + sdata->dev->netdev_ops = &ieee80211_dataif_ops; sdata->wdev.iftype = type; sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); @@ -1130,11 +1107,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, sdata->noack_map = 0; - /* only monitor/p2p-device differ */ - if (sdata->dev) { - sdata->dev->netdev_ops = &ieee80211_dataif_ops; - sdata->dev->type = ARPHRD_ETHER; - } + /* only monitor differs */ + sdata->dev->type = ARPHRD_ETHER; skb_queue_head_init(&sdata->skb_queue); INIT_WORK(&sdata->work, ieee80211_iface_work); @@ -1172,7 +1146,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, break; case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_P2P_DEVICE: break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: @@ -1183,6 +1156,18 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, ieee80211_debugfs_add_netdev(sdata); } +static void ieee80211_clean_sdata(struct ieee80211_sub_if_data *sdata) +{ + switch (sdata->vif.type) { + case NL80211_IFTYPE_MESH_POINT: + mesh_path_flush_by_iface(sdata); + break; + + default: + break; + } +} + static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type) { @@ -1240,7 +1225,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, ieee80211_do_stop(sdata, false); - ieee80211_teardown_sdata(sdata); + ieee80211_teardown_sdata(sdata->dev); ret = drv_change_interface(local, sdata, internal_type, p2p); if (ret) @@ -1255,7 +1240,7 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, ieee80211_setup_sdata(sdata, type); - err = ieee80211_do_open(&sdata->wdev, false); + err = ieee80211_do_open(sdata->dev, false); WARN(err, "type change: do_open returned %d", err); return ret; @@ -1282,14 +1267,14 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, return ret; } else { /* Purge and reset type-dependent state. */ - ieee80211_teardown_sdata(sdata); + ieee80211_teardown_sdata(sdata->dev); ieee80211_setup_sdata(sdata, type); } /* reset some values that shouldn't be kept across type changes */ sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sdata->local, - sdata->local->oper_channel->band); + sdata->local->hw.conf.channel->band); sdata->drop_unencrypted = 0; if (type == NL80211_IFTYPE_STATION) sdata->u.mgd.use_4addr = false; @@ -1298,7 +1283,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, } static void ieee80211_assign_perm_addr(struct ieee80211_local *local, - u8 *perm_addr, enum nl80211_iftype type) + struct net_device *dev, + enum nl80211_iftype type) { struct ieee80211_sub_if_data *sdata; u64 mask, start, addr, val, inc; @@ -1307,12 +1293,13 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, int i; /* default ... something at least */ - memcpy(perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN); + memcpy(dev->perm_addr, local->hw.wiphy->perm_addr, ETH_ALEN); if (is_zero_ether_addr(local->hw.wiphy->addr_mask) && local->hw.wiphy->n_addresses <= 1) return; + mutex_lock(&local->iflist_mtx); switch (type) { @@ -1325,24 +1312,11 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_AP) continue; - memcpy(perm_addr, sdata->vif.addr, ETH_ALEN); + memcpy(dev->perm_addr, sdata->vif.addr, ETH_ALEN); break; } /* keep default if no AP interface present */ break; - case NL80211_IFTYPE_P2P_CLIENT: - case NL80211_IFTYPE_P2P_GO: - if (local->hw.flags & IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF) { - list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) - continue; - if (!ieee80211_sdata_running(sdata)) - continue; - memcpy(perm_addr, sdata->vif.addr, ETH_ALEN); - goto out_unlock; - } - } - /* otherwise fall through */ default: /* assign a new address if possible -- try n_addresses first */ for (i = 0; i < local->hw.wiphy->n_addresses; i++) { @@ -1357,7 +1331,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, } if (!used) { - memcpy(perm_addr, + memcpy(dev->perm_addr, local->hw.wiphy->addresses[i].addr, ETH_ALEN); break; @@ -1408,7 +1382,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, } if (!used) { - memcpy(perm_addr, tmp_addr, ETH_ALEN); + memcpy(dev->perm_addr, tmp_addr, ETH_ALEN); break; } addr = (start & ~mask) | (val & mask); @@ -1417,7 +1391,6 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, break; } - out_unlock: mutex_unlock(&local->iflist_mtx); } @@ -1425,68 +1398,49 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, struct wireless_dev **new_wdev, enum nl80211_iftype type, struct vif_params *params) { - struct net_device *ndev = NULL; + struct net_device *ndev; struct ieee80211_sub_if_data *sdata = NULL; int ret, i; int txqs = 1; ASSERT_RTNL(); - if (type == NL80211_IFTYPE_P2P_DEVICE) { - struct wireless_dev *wdev; - - sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, - GFP_KERNEL); - if (!sdata) - return -ENOMEM; - wdev = &sdata->wdev; - - sdata->dev = NULL; - strlcpy(sdata->name, name, IFNAMSIZ); - ieee80211_assign_perm_addr(local, wdev->address, type); - memcpy(sdata->vif.addr, wdev->address, ETH_ALEN); - } else { - if (local->hw.queues >= IEEE80211_NUM_ACS) - txqs = IEEE80211_NUM_ACS; - - ndev = alloc_netdev_mqs(sizeof(*sdata) + - local->hw.vif_data_size, - name, ieee80211_if_setup, txqs, 1); - if (!ndev) - return -ENOMEM; - dev_net_set(ndev, wiphy_net(local->hw.wiphy)); - - ndev->needed_headroom = local->tx_headroom + - 4*6 /* four MAC addresses */ - + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ - + 6 /* mesh */ - + 8 /* rfc1042/bridge tunnel */ - - ETH_HLEN /* ethernet hard_header_len */ - + IEEE80211_ENCRYPT_HEADROOM; - ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; - - ret = dev_alloc_name(ndev, ndev->name); - if (ret < 0) { - free_netdev(ndev); - return ret; - } - - ieee80211_assign_perm_addr(local, ndev->perm_addr, type); - memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); - SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); - - /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */ - sdata = netdev_priv(ndev); - ndev->ieee80211_ptr = &sdata->wdev; - memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); - memcpy(sdata->name, ndev->name, IFNAMSIZ); - - sdata->dev = ndev; - } + if (local->hw.queues >= IEEE80211_NUM_ACS) + txqs = IEEE80211_NUM_ACS; + + ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, + name, ieee80211_if_setup, txqs, 1); + if (!ndev) + return -ENOMEM; + dev_net_set(ndev, wiphy_net(local->hw.wiphy)); + + ndev->needed_headroom = local->tx_headroom + + 4*6 /* four MAC addresses */ + + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */ + + 6 /* mesh */ + + 8 /* rfc1042/bridge tunnel */ + - ETH_HLEN /* ethernet hard_header_len */ + + IEEE80211_ENCRYPT_HEADROOM; + ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; + + ret = dev_alloc_name(ndev, ndev->name); + if (ret < 0) + goto fail; + + ieee80211_assign_perm_addr(local, ndev, type); + memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); + SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); + + /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ + sdata = netdev_priv(ndev); + ndev->ieee80211_ptr = &sdata->wdev; + memcpy(sdata->vif.addr, ndev->dev_addr, ETH_ALEN); + memcpy(sdata->name, ndev->name, IFNAMSIZ); /* initialise type-independent data */ sdata->wdev.wiphy = local->hw.wiphy; sdata->local = local; + sdata->dev = ndev; #ifdef CONFIG_INET sdata->arp_filter_state = true; #endif @@ -1515,21 +1469,17 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, /* setup type-dependent data */ ieee80211_setup_sdata(sdata, type); - if (ndev) { - if (params) { - ndev->ieee80211_ptr->use_4addr = params->use_4addr; - if (type == NL80211_IFTYPE_STATION) - sdata->u.mgd.use_4addr = params->use_4addr; - } + if (params) { + ndev->ieee80211_ptr->use_4addr = params->use_4addr; + if (type == NL80211_IFTYPE_STATION) + sdata->u.mgd.use_4addr = params->use_4addr; + } - ndev->features |= local->hw.netdev_features; + ndev->features |= local->hw.netdev_features; - ret = register_netdevice(ndev); - if (ret) { - free_netdev(ndev); - return ret; - } - } + ret = register_netdevice(ndev); + if (ret) + goto fail; mutex_lock(&local->iflist_mtx); list_add_tail_rcu(&sdata->list, &local->interfaces); @@ -1539,6 +1489,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, *new_wdev = &sdata->wdev; return 0; + + fail: + free_netdev(ndev); + return ret; } void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) @@ -1549,22 +1503,11 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) list_del_rcu(&sdata->list); mutex_unlock(&sdata->local->iflist_mtx); - synchronize_rcu(); - - if (sdata->dev) { - unregister_netdevice(sdata->dev); - } else { - cfg80211_unregister_wdev(&sdata->wdev); - kfree(sdata); - } -} + /* clean up type-dependent data */ + ieee80211_clean_sdata(sdata); -void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata) -{ - if (WARN_ON_ONCE(!test_bit(SDATA_STATE_RUNNING, &sdata->state))) - return; - ieee80211_do_stop(sdata, true); - ieee80211_teardown_sdata(sdata); + synchronize_rcu(); + unregister_netdevice(sdata->dev); } /* @@ -1575,7 +1518,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata, *tmp; LIST_HEAD(unreg_list); - LIST_HEAD(wdev_list); ASSERT_RTNL(); @@ -1583,20 +1525,13 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { list_del(&sdata->list); - if (sdata->dev) - unregister_netdevice_queue(sdata->dev, &unreg_list); - else - list_add(&sdata->list, &wdev_list); + ieee80211_clean_sdata(sdata); + + unregister_netdevice_queue(sdata->dev, &unreg_list); } mutex_unlock(&local->iflist_mtx); unregister_netdevice_many(&unreg_list); list_del(&unreg_list); - - list_for_each_entry_safe(sdata, tmp, &wdev_list, list) { - list_del(&sdata->list); - cfg80211_unregister_wdev(&sdata->wdev); - kfree(sdata); - } } static int netdev_notify(struct notifier_block *nb, diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index bd7529363193..c26e231c733a 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -207,10 +207,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.bssid = NULL; else if (ieee80211_vif_is_mesh(&sdata->vif)) { sdata->vif.bss_conf.bssid = zero; - } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { - sdata->vif.bss_conf.bssid = sdata->vif.addr; - WARN_ONCE(changed & ~(BSS_CHANGED_IDLE), - "P2P Device BSS changed %#x", changed); } else { WARN_ON(1); return; @@ -518,11 +514,6 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { BIT(IEEE80211_STYPE_AUTH >> 4) | BIT(IEEE80211_STYPE_DEAUTH >> 4), }, - [NL80211_IFTYPE_P2P_DEVICE] = { - .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4), - }, }; static const struct ieee80211_ht_cap mac80211_ht_capa_mod_mask = { @@ -545,11 +536,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, int priv_size, i; struct wiphy *wiphy; - if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || - !ops->add_interface || !ops->remove_interface || - !ops->configure_filter)) - return NULL; - if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove))) return NULL; @@ -602,6 +588,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); + BUG_ON(!ops->tx); + BUG_ON(!ops->start); + BUG_ON(!ops->stop); + BUG_ON(!ops->config); + BUG_ON(!ops->add_interface); + BUG_ON(!ops->remove_interface); + BUG_ON(!ops->configure_filter); local->ops = ops; /* set up some defaults */ diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c index ff0296c7bab8..0e2f83e71277 100644 --- a/trunk/net/mac80211/mesh.c +++ b/trunk/net/mac80211/mesh.c @@ -109,11 +109,11 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, /* Disallow HT40+/- mismatch */ if (ie->ht_operation && - (sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40MINUS || - sdata->vif.bss_conf.channel_type == NL80211_CHAN_HT40PLUS) && + (local->_oper_channel_type == NL80211_CHAN_HT40MINUS || + local->_oper_channel_type == NL80211_CHAN_HT40PLUS) && (sta_channel_type == NL80211_CHAN_HT40MINUS || sta_channel_type == NL80211_CHAN_HT40PLUS) && - sdata->vif.bss_conf.channel_type != sta_channel_type) + local->_oper_channel_type != sta_channel_type) goto mismatch; return true; @@ -355,18 +355,17 @@ int mesh_add_ds_params_ie(struct sk_buff *skb, { struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; - struct ieee80211_channel *chan = local->oper_channel; u8 *pos; if (skb_tailroom(skb) < 3) return -ENOMEM; - sband = local->hw.wiphy->bands[chan->band]; + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; if (sband->band == IEEE80211_BAND_2GHZ) { pos = skb_put(skb, 2 + 1); *pos++ = WLAN_EID_DS_PARAMS; *pos++ = 1; - *pos++ = ieee80211_frequency_to_channel(chan->center_freq); + *pos++ = ieee80211_frequency_to_channel(local->hw.conf.channel->center_freq); } return 0; @@ -381,7 +380,7 @@ int mesh_add_ht_cap_ie(struct sk_buff *skb, sband = local->hw.wiphy->bands[local->oper_channel->band]; if (!sband->ht_cap.ht_supported || - sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) + local->_oper_channel_type == NL80211_CHAN_NO_HT) return 0; if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap)) @@ -398,8 +397,7 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb, { struct ieee80211_local *local = sdata->local; struct ieee80211_channel *channel = local->oper_channel; - enum nl80211_channel_type channel_type = - sdata->vif.bss_conf.channel_type; + enum nl80211_channel_type channel_type = local->_oper_channel_type; struct ieee80211_supported_band *sband = local->hw.wiphy->bands[channel->band]; struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; @@ -610,14 +608,12 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sdata->local, - sdata->local->oper_channel->band); + sdata->local->hw.conf.channel->band); ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_HT | BSS_CHANGED_BASIC_RATES | BSS_CHANGED_BEACON_INT); - - netif_carrier_on(sdata->dev); } void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) @@ -625,15 +621,9 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) struct ieee80211_local *local = sdata->local; struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - netif_carrier_off(sdata->dev); - - /* stop the beacon */ ifmsh->mesh_id_len = 0; ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); - - /* flush STAs and mpaths on this iface */ - sta_info_flush(sdata->local, sdata); - mesh_path_flush_by_iface(sdata); + sta_info_flush(local, NULL); del_timer_sync(&sdata->u.mesh.housekeeping_timer); del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); diff --git a/trunk/net/mac80211/mesh.h b/trunk/net/mac80211/mesh.h index 25d0f17dec71..13fd5b5fdb0a 100644 --- a/trunk/net/mac80211/mesh.h +++ b/trunk/net/mac80211/mesh.h @@ -215,9 +215,6 @@ struct mesh_rmc { /* Maximum number of paths per interface */ #define MESH_MAX_MPATHS 1024 -/* Number of frames buffered per destination for unresolved destinations */ -#define MESH_FRAME_QUEUE_LEN 10 - /* Public interfaces */ /* Various */ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, diff --git a/trunk/net/mac80211/mesh_hwmp.c b/trunk/net/mac80211/mesh_hwmp.c index 47aeee2d8db1..494bc39f61a4 100644 --- a/trunk/net/mac80211/mesh_hwmp.c +++ b/trunk/net/mac80211/mesh_hwmp.c @@ -17,6 +17,8 @@ #define MAX_METRIC 0xffffffff #define ARITH_SHIFT 8 +/* Number of frames buffered per destination for unresolved destinations */ +#define MESH_FRAME_QUEUE_LEN 10 #define MAX_PREQ_QUEUE_LEN 64 /* Destination only */ diff --git a/trunk/net/mac80211/mesh_pathtbl.c b/trunk/net/mac80211/mesh_pathtbl.c index aa749818860e..075bc535c601 100644 --- a/trunk/net/mac80211/mesh_pathtbl.c +++ b/trunk/net/mac80211/mesh_pathtbl.c @@ -203,17 +203,23 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) { struct sk_buff *skb; struct ieee80211_hdr *hdr; + struct sk_buff_head tmpq; unsigned long flags; rcu_assign_pointer(mpath->next_hop, sta); + __skb_queue_head_init(&tmpq); + spin_lock_irqsave(&mpath->frame_queue.lock, flags); - skb_queue_walk(&mpath->frame_queue, skb) { + + while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) { hdr = (struct ieee80211_hdr *) skb->data; memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); memcpy(hdr->addr2, mpath->sdata->vif.addr, ETH_ALEN); + __skb_queue_tail(&tmpq, skb); } + skb_queue_splice(&tmpq, &mpath->frame_queue); spin_unlock_irqrestore(&mpath->frame_queue.lock, flags); } @@ -279,42 +285,40 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath, struct mesh_path *from_mpath, bool copy) { - struct sk_buff *skb, *fskb, *tmp; - struct sk_buff_head failq; + struct sk_buff *skb, *cp_skb = NULL; + struct sk_buff_head gateq, failq; unsigned long flags; + int num_skbs; BUG_ON(gate_mpath == from_mpath); BUG_ON(!gate_mpath->next_hop); + __skb_queue_head_init(&gateq); __skb_queue_head_init(&failq); spin_lock_irqsave(&from_mpath->frame_queue.lock, flags); skb_queue_splice_init(&from_mpath->frame_queue, &failq); spin_unlock_irqrestore(&from_mpath->frame_queue.lock, flags); - skb_queue_walk_safe(&failq, fskb, tmp) { - if (skb_queue_len(&gate_mpath->frame_queue) >= - MESH_FRAME_QUEUE_LEN) { - mpath_dbg(gate_mpath->sdata, "mpath queue full!\n"); - break; - } + num_skbs = skb_queue_len(&failq); - skb = skb_copy(fskb, GFP_ATOMIC); - if (WARN_ON(!skb)) - break; + while (num_skbs--) { + skb = __skb_dequeue(&failq); + if (copy) { + cp_skb = skb_copy(skb, GFP_ATOMIC); + if (cp_skb) + __skb_queue_tail(&failq, cp_skb); + } prepare_for_gate(skb, gate_mpath->dst, gate_mpath); - skb_queue_tail(&gate_mpath->frame_queue, skb); - - if (copy) - continue; - - __skb_unlink(fskb, &failq); - kfree_skb(fskb); + __skb_queue_tail(&gateq, skb); } + spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags); + skb_queue_splice(&gateq, &gate_mpath->frame_queue); mpath_dbg(gate_mpath->sdata, "Mpath queue for gate %pM has %d frames\n", gate_mpath->dst, skb_queue_len(&gate_mpath->frame_queue)); + spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags); if (!copy) return; @@ -527,7 +531,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) read_lock_bh(&pathtbl_resize_lock); memcpy(new_mpath->dst, dst, ETH_ALEN); - eth_broadcast_addr(new_mpath->rann_snd_addr); + memset(new_mpath->rann_snd_addr, 0xff, ETH_ALEN); new_mpath->is_root = false; new_mpath->sdata = sdata; new_mpath->flags = 0; diff --git a/trunk/net/mac80211/mesh_plink.c b/trunk/net/mac80211/mesh_plink.c index 9d7ad366ef09..f20e9f26d137 100644 --- a/trunk/net/mac80211/mesh_plink.c +++ b/trunk/net/mac80211/mesh_plink.c @@ -117,7 +117,7 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) u16 ht_opmode; bool non_ht_sta = false, ht20_sta = false; - if (sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) + if (local->_oper_channel_type == NL80211_CHAN_NO_HT) return 0; rcu_read_lock(); @@ -147,8 +147,7 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) if (non_ht_sta) ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED; - else if (ht20_sta && - sdata->vif.bss_conf.channel_type > NL80211_CHAN_HT20) + else if (ht20_sta && local->_oper_channel_type > NL80211_CHAN_HT20) ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ; else ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE; @@ -216,14 +215,12 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, u8 *da, __le16 llid, __le16 plid, __le16 reason) { struct ieee80211_local *local = sdata->local; struct sk_buff *skb; - struct ieee80211_tx_info *info; struct ieee80211_mgmt *mgmt; bool include_plid = false; u16 peering_proto = 0; u8 *pos, ie_len = 4; int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) + sizeof(mgmt->u.action.u.self_prot); - int err = -ENOMEM; skb = dev_alloc_skb(local->tx_headroom + hdr_len + @@ -239,7 +236,6 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, sdata->u.mesh.ie_len); if (!skb) return -1; - info = IEEE80211_SKB_CB(skb); skb_reserve(skb, local->tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); memset(mgmt, 0, hdr_len); @@ -260,18 +256,15 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, pos = skb_put(skb, 2); memcpy(pos + 2, &plid, 2); } - if (ieee80211_add_srates_ie(sdata, skb, true, - local->oper_channel->band) || - ieee80211_add_ext_srates_ie(sdata, skb, true, - local->oper_channel->band) || + if (ieee80211_add_srates_ie(sdata, skb, true) || + ieee80211_add_ext_srates_ie(sdata, skb, true) || mesh_add_rsn_ie(skb, sdata) || mesh_add_meshid_ie(skb, sdata) || mesh_add_meshconf_ie(skb, sdata)) - goto free; + return -1; } else { /* WLAN_SP_MESH_PEERING_CLOSE */ - info->flags |= IEEE80211_TX_CTL_NO_ACK; if (mesh_add_meshid_ie(skb, sdata)) - goto free; + return -1; } /* Add Mesh Peering Management element */ @@ -290,12 +283,11 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, ie_len += 2; /* reason code */ break; default: - err = -EINVAL; - goto free; + return -EINVAL; } if (WARN_ON(skb_tailroom(skb) < 2 + ie_len)) - goto free; + return -ENOMEM; pos = skb_put(skb, 2 + ie_len); *pos++ = WLAN_EID_PEER_MGMT; @@ -316,17 +308,14 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, if (action != WLAN_SP_MESH_PEERING_CLOSE) { if (mesh_add_ht_cap_ie(skb, sdata) || mesh_add_ht_oper_ie(skb, sdata)) - goto free; + return -1; } if (mesh_add_vendor_ies(skb, sdata)) - goto free; + return -1; ieee80211_tx_skb(sdata, skb); return 0; -free: - kfree_skb(skb); - return err; } /** @@ -371,14 +360,9 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata, spin_lock_bh(&sta->lock); sta->last_rx = jiffies; - if (sta->plink_state == NL80211_PLINK_ESTAB) { - spin_unlock_bh(&sta->lock); - return sta; - } - sta->sta.supp_rates[band] = rates; if (elems->ht_cap_elem && - sdata->vif.bss_conf.channel_type != NL80211_CHAN_NO_HT) + sdata->local->_oper_channel_type != NL80211_CHAN_NO_HT) ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, elems->ht_cap_elem, &sta->sta.ht_cap); diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index a8cf70bf1cba..a4a5acdbaa4d 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -146,9 +146,6 @@ void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER) return; - if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) - return; - mod_timer(&sdata->u.mgd.bcn_mon_timer, round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout)); } @@ -185,15 +182,15 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata, u16 ht_opmode; bool disable_40 = false; - sband = local->hw.wiphy->bands[local->oper_channel->band]; + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; switch (sdata->vif.bss_conf.channel_type) { case NL80211_CHAN_HT40PLUS: - if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40PLUS) + if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40PLUS) disable_40 = true; break; case NL80211_CHAN_HT40MINUS: - if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40MINUS) + if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40MINUS) disable_40 = true; break; default: @@ -329,26 +326,6 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, ieee80211_ie_build_ht_cap(pos, &ht_cap, cap); } -static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, - struct ieee80211_supported_band *sband) -{ - u8 *pos; - u32 cap; - struct ieee80211_sta_vht_cap vht_cap; - - BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap)); - - memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap)); - - /* determine capability flags */ - cap = vht_cap.cap; - - /* reserve and fill IE */ - pos = skb_put(skb, sizeof(struct ieee80211_vht_capabilities) + 2); - ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); -} - static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; @@ -394,7 +371,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 4 + /* power capability */ 2 + 2 * sband->n_channels + /* supported channels */ 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ - 2 + sizeof(struct ieee80211_vht_capabilities) + /* VHT */ assoc_data->ie_len + /* extra IEs */ 9, /* WMM */ GFP_KERNEL); @@ -527,9 +503,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, sband, local->oper_channel, ifmgd->ap_smps); - if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) - ieee80211_add_vht_ie(sdata, skb, sband); - /* if present, add any custom non-vendor IEs that go after HT */ if (assoc_data->ie_len && assoc_data->ie) { noffset = ieee80211_ie_split_vendor(assoc_data->ie, @@ -610,6 +583,8 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + drv_mgd_prepare_tx(local, sdata); + ieee80211_tx_skb(sdata, skb); } } @@ -712,7 +687,6 @@ static void ieee80211_chswitch_work(struct work_struct *work) /* XXX: shouldn't really modify cfg80211-owned data! */ ifmgd->associated->channel = sdata->local->oper_channel; - /* XXX: wait for a beacon first? */ ieee80211_wake_queues_by_reason(&sdata->local->hw, IEEE80211_QUEUE_STOP_REASON_CSA); out: @@ -789,32 +763,36 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, sdata->local->csa_channel = new_ch; - ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; - - if (sw_elem->mode) - ieee80211_stop_queues_by_reason(&sdata->local->hw, - IEEE80211_QUEUE_STOP_REASON_CSA); - if (sdata->local->ops->channel_switch) { /* use driver's channel switch callback */ - struct ieee80211_channel_switch ch_switch = { - .timestamp = timestamp, - .block_tx = sw_elem->mode, - .channel = new_ch, - .count = sw_elem->count, - }; - + struct ieee80211_channel_switch ch_switch; + memset(&ch_switch, 0, sizeof(ch_switch)); + ch_switch.timestamp = timestamp; + if (sw_elem->mode) { + ch_switch.block_tx = true; + ieee80211_stop_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CSA); + } + ch_switch.channel = new_ch; + ch_switch.count = sw_elem->count; + ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; drv_channel_switch(sdata->local, &ch_switch); return; } /* channel switch handled in software */ - if (sw_elem->count <= 1) + if (sw_elem->count <= 1) { ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work); - else + } else { + if (sw_elem->mode) + ieee80211_stop_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CSA); + ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; mod_timer(&ifmgd->chswitch_timer, - TU_TO_EXP_TIME(sw_elem->count * - cbss->beacon_interval)); + jiffies + + msecs_to_jiffies(sw_elem->count * + cbss->beacon_interval)); + } } static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, @@ -1029,16 +1007,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) ieee80211_change_ps(local); } -void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata) -{ - bool ps_allowed = ieee80211_powersave_allowed(sdata); - - if (sdata->vif.bss_conf.ps != ps_allowed) { - sdata->vif.bss_conf.ps = ps_allowed; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_PS); - } -} - void ieee80211_dynamic_ps_disable_work(struct work_struct *work) { struct ieee80211_local *local = @@ -1271,7 +1239,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, } use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); - if (sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) + if (sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) use_short_slot = true; if (use_protection != bss_conf->use_cts_prot) { @@ -1342,8 +1310,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ieee80211_recalc_smps(local); mutex_unlock(&local->iflist_mtx); - ieee80211_recalc_ps_vif(sdata); - netif_tx_start_all_queues(sdata->dev); netif_carrier_on(sdata->dev); } @@ -1405,9 +1371,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, } local->ps_sdata = NULL; - /* disable per-vif ps */ - ieee80211_recalc_ps_vif(sdata); - /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ if (tx) drv_flush(local, false); @@ -1579,8 +1542,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) ssid_len = ssid[1]; ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, - 0, (u32) -1, true, false, - ifmgd->associated->channel); + 0, (u32) -1, true, false); } ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); @@ -1683,9 +1645,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, ssid_len = ssid[1]; skb = ieee80211_build_probe_req(sdata, cbss->bssid, - (u32) -1, - sdata->local->oper_channel, - ssid + 2, ssid_len, + (u32) -1, ssid + 2, ssid_len, NULL, 0, true); return skb; @@ -1696,6 +1656,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; + u8 bssid[ETH_ALEN]; u8 frame_buf[DEAUTH_DISASSOC_LEN]; mutex_lock(&ifmgd->mtx); @@ -1704,8 +1665,9 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) return; } - sdata_info(sdata, "Connection to AP %pM lost\n", - ifmgd->associated->bssid); + memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); + + sdata_info(sdata, "Connection to AP %pM lost\n", bssid); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, @@ -1723,7 +1685,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) mutex_unlock(&local->mtx); } -static void ieee80211_beacon_connection_loss_work(struct work_struct *work) +void ieee80211_beacon_connection_loss_work(struct work_struct *work) { struct ieee80211_sub_if_data *sdata = container_of(work, struct ieee80211_sub_if_data, @@ -2270,10 +2232,14 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, mutex_unlock(&local->iflist_mtx); } - if (elems->ch_switch_ie && - memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, ETH_ALEN) == 0) - ieee80211_sta_process_chanswitch(sdata, elems->ch_switch_ie, + if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) && + (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, + ETH_ALEN) == 0)) { + struct ieee80211_channel_sw_ie *sw_elem = + (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem; + ieee80211_sta_process_chanswitch(sdata, sw_elem, bss, rx_status->mactime); + } } @@ -2360,7 +2326,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, if (baselen > len) return; - if (rx_status->freq != local->oper_channel->center_freq) + if (rx_status->freq != local->hw.conf.channel->center_freq) return; if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon && @@ -2524,7 +2490,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) { struct ieee80211_supported_band *sband; - sband = local->hw.wiphy->bands[local->oper_channel->band]; + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, bssid, true); @@ -2707,8 +2673,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) * will not answer to direct packet in unassociated state. */ ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], - NULL, 0, (u32) -1, true, false, - auth_data->bss->channel); + NULL, 0, (u32) -1, true, false); } auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; @@ -3035,17 +3000,41 @@ int ieee80211_max_network_latency(struct notifier_block *nb, return 0; } -static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, - struct cfg80211_bss *cbss) +static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, + struct cfg80211_bss *cbss, bool assoc) { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_bss *bss = (void *)cbss->priv; + struct sta_info *sta = NULL; + bool have_sta = false; + int err; int ht_cfreq; enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; const u8 *ht_oper_ie; const struct ieee80211_ht_operation *ht_oper = NULL; struct ieee80211_supported_band *sband; + if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) + return -EINVAL; + + if (assoc) { + rcu_read_lock(); + have_sta = sta_info_get(sdata, cbss->bssid); + rcu_read_unlock(); + } + + if (!have_sta) { + sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); + if (!sta) + return -ENOMEM; + } + + mutex_lock(&local->mtx); + ieee80211_recalc_idle(sdata->local); + mutex_unlock(&local->mtx); + + /* switch to the right channel */ sband = local->hw.wiphy->bands[cbss->channel->band]; ifmgd->flags &= ~IEEE80211_STA_DISABLE_40MHZ; @@ -3108,51 +3097,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, local->oper_channel = cbss->channel; ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - return 0; -} - -static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, - struct cfg80211_bss *cbss, bool assoc) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - struct ieee80211_bss *bss = (void *)cbss->priv; - struct sta_info *new_sta = NULL; - bool have_sta = false; - int err; - - if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) - return -EINVAL; - - if (assoc) { - rcu_read_lock(); - have_sta = sta_info_get(sdata, cbss->bssid); - rcu_read_unlock(); - } - - if (!have_sta) { - new_sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL); - if (!new_sta) - return -ENOMEM; - } - - mutex_lock(&local->mtx); - ieee80211_recalc_idle(sdata->local); - mutex_unlock(&local->mtx); - - if (new_sta) { + if (sta) { u32 rates = 0, basic_rates = 0; bool have_higher_than_11mbit; int min_rate = INT_MAX, min_rate_index = -1; - struct ieee80211_supported_band *sband; - - sband = local->hw.wiphy->bands[cbss->channel->band]; - - err = ieee80211_prep_channel(sdata, cbss); - if (err) { - sta_info_free(local, new_sta); - return err; - } ieee80211_get_rates(sband, bss->supp_rates, bss->supp_rates_len, @@ -3174,7 +3122,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, basic_rates = BIT(min_rate_index); } - new_sta->sta.supp_rates[cbss->channel->band] = rates; + sta->sta.supp_rates[cbss->channel->band] = rates; sdata->vif.bss_conf.basic_rates = basic_rates; /* cf. IEEE 802.11 9.2.12 */ @@ -3197,10 +3145,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, BSS_CHANGED_BEACON_INT); if (assoc) - sta_info_pre_move_state(new_sta, IEEE80211_STA_AUTH); + sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); - err = sta_info_insert(new_sta); - new_sta = NULL; + err = sta_info_insert(sta); + sta = NULL; if (err) { sdata_info(sdata, "failed to insert STA entry for the AP (error %d)\n", @@ -3352,13 +3300,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, } /* prepare assoc data */ - - /* - * keep only the 40 MHz disable bit set as it might have - * been set during authentication already, all other bits - * should be reset for a new connection - */ - ifmgd->flags &= IEEE80211_STA_DISABLE_40MHZ; + + ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; + ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; ifmgd->beacon_crc_valid = false; @@ -3374,34 +3318,21 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { ifmgd->flags |= IEEE80211_STA_DISABLE_11N; - ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; netdev_info(sdata->dev, - "disabling HT/VHT due to WEP/TKIP use\n"); + "disabling HT due to WEP/TKIP use\n"); } } - if (req->flags & ASSOC_REQ_DISABLE_HT) { + if (req->flags & ASSOC_REQ_DISABLE_HT) ifmgd->flags |= IEEE80211_STA_DISABLE_11N; - ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; - } /* Also disable HT if we don't support it or the AP doesn't use WMM */ sband = local->hw.wiphy->bands[req->bss->channel->band]; if (!sband->ht_cap.ht_supported || local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { ifmgd->flags |= IEEE80211_STA_DISABLE_11N; - if (!bss->wmm_used) - netdev_info(sdata->dev, - "disabling HT as WMM/QoS is not supported by the AP\n"); - } - - /* disable VHT if we don't support it or the AP doesn't use WMM */ - if (!sband->vht_cap.vht_supported || - local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { - ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; - if (!bss->wmm_used) - netdev_info(sdata->dev, - "disabling VHT as WMM/QoS is not supported by the AP\n"); + netdev_info(sdata->dev, + "disabling HT as WMM/QoS is not supported\n"); } memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); @@ -3536,17 +3467,14 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, req->bssid, req->reason_code); if (ifmgd->associated && - ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { + ether_addr_equal(ifmgd->associated->bssid, req->bssid)) ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, req->reason_code, true, frame_buf); - } else { - drv_mgd_prepare_tx(sdata->local, sdata); + else ieee80211_send_deauth_disassoc(sdata, req->bssid, IEEE80211_STYPE_DEAUTH, req->reason_code, true, frame_buf); - } - mutex_unlock(&ifmgd->mtx); __cfg80211_send_deauth(sdata->dev, frame_buf, DEAUTH_DISASSOC_LEN); diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index 507121dad082..635c3250c668 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -116,9 +116,6 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, if (!ieee80211_sdata_running(sdata)) continue; - if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) - continue; - if (sdata->vif.type != NL80211_IFTYPE_MONITOR) set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); @@ -147,9 +144,6 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, mutex_lock(&local->iflist_mtx); list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) - continue; - if (sdata->vif.type != NL80211_IFTYPE_MONITOR) clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); diff --git a/trunk/net/mac80211/rate.h b/trunk/net/mac80211/rate.h index 10de668eb9f6..6e4fd32c6617 100644 --- a/trunk/net/mac80211/rate.h +++ b/trunk/net/mac80211/rate.h @@ -56,7 +56,7 @@ static inline void rate_control_rate_init(struct sta_info *sta) if (!ref) return; - sband = local->hw.wiphy->bands[local->oper_channel->band]; + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; ref->ops->rate_init(ref->priv, sband, ista, priv_sta); set_sta_flag(sta, WLAN_STA_RATE_CONTROL); diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index b382605c5733..0cb4edee6af5 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -60,9 +60,7 @@ static inline int should_drop_frame(struct sk_buff *skb, struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - if (status->flag & (RX_FLAG_FAILED_FCS_CRC | - RX_FLAG_FAILED_PLCP_CRC | - RX_FLAG_AMPDU_IS_ZEROLEN)) + if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) return 1; if (unlikely(skb->len < 16 + present_fcs_len)) return 1; @@ -93,13 +91,6 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, if (status->flag & RX_FLAG_HT) /* HT info */ len += 3; - if (status->flag & RX_FLAG_AMPDU_DETAILS) { - /* padding */ - while (len & 3) - len++; - len += 8; - } - return len; } @@ -224,37 +215,6 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, pos++; *pos++ = status->rate_idx; } - - if (status->flag & RX_FLAG_AMPDU_DETAILS) { - u16 flags = 0; - - /* ensure 4 byte alignment */ - while ((pos - (u8 *)rthdr) & 3) - pos++; - rthdr->it_present |= - cpu_to_le32(1 << IEEE80211_RADIOTAP_AMPDU_STATUS); - put_unaligned_le32(status->ampdu_reference, pos); - pos += 4; - if (status->flag & RX_FLAG_AMPDU_REPORT_ZEROLEN) - flags |= IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN; - if (status->flag & RX_FLAG_AMPDU_IS_ZEROLEN) - flags |= IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN; - if (status->flag & RX_FLAG_AMPDU_LAST_KNOWN) - flags |= IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN; - if (status->flag & RX_FLAG_AMPDU_IS_LAST) - flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST; - if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_ERROR) - flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR; - if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) - flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN; - put_unaligned_le16(flags, pos); - pos += 2; - if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_KNOWN) - *pos++ = status->ampdu_delimiter_crc; - else - *pos++ = 0; - *pos++ = 0; - } } /* @@ -2308,7 +2268,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) goto queue; case WLAN_CATEGORY_SPECTRUM_MGMT: - if (status->band != IEEE80211_BAND_5GHZ) + if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) break; if (sdata->vif.type != NL80211_IFTYPE_STATION) @@ -2812,7 +2772,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, if (!bssid) { if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) return 0; - } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { + } else if (!ieee80211_bssid_match(bssid, + sdata->vif.addr)) { /* * Accept public action frames even when the * BSSID doesn't match, this is used for P2P @@ -2832,18 +2793,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) return 0; break; - case NL80211_IFTYPE_P2P_DEVICE: - if (!ieee80211_is_public_action(hdr, skb->len) && - !ieee80211_is_probe_req(hdr->frame_control) && - !ieee80211_is_probe_resp(hdr->frame_control) && - !ieee80211_is_beacon(hdr->frame_control)) - return 0; - if (!ether_addr_equal(sdata->vif.addr, hdr->addr1)) - status->rx_flags &= ~IEEE80211_RX_RA_MATCH; - break; default: /* should never get here */ - WARN_ON_ONCE(1); + WARN_ON(1); break; } diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index 740e414d44f4..839dd9737989 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -416,8 +416,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, local->scan_req->ssids[i].ssid_len, local->scan_req->ie, local->scan_req->ie_len, local->scan_req->rates[band], false, - local->scan_req->no_cck, - local->hw.conf.channel); + local->scan_req->no_cck); /* * After sending probe requests, wait for probe responses @@ -480,10 +479,11 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, if (local->ops->hw_scan) { __set_bit(SCAN_HW_SCANNING, &local->scanning); } else if ((req->n_channels == 1) && - (req->channels[0] == local->oper_channel)) { - /* - * If we are scanning only on the operating channel - * then we do not need to stop normal activities + (req->channels[0]->center_freq == + local->hw.conf.channel->center_freq)) { + + /* If we are scanning only on the current channel, then + * we do not need to stop normal activities */ unsigned long next_delay; diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c index b0801b7d572d..8cd72914cdaf 100644 --- a/trunk/net/mac80211/status.c +++ b/trunk/net/mac80211/status.c @@ -519,27 +519,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) u64 cookie = (unsigned long)skb; acked = info->flags & IEEE80211_TX_STAT_ACK; + /* + * TODO: When we have non-netdev frame TX, + * we cannot use skb->dev->ieee80211_ptr + */ + if (ieee80211_is_nullfunc(hdr->frame_control) || - ieee80211_is_qos_nullfunc(hdr->frame_control)) { + ieee80211_is_qos_nullfunc(hdr->frame_control)) cfg80211_probe_status(skb->dev, hdr->addr1, cookie, acked, GFP_ATOMIC); - } else if (skb->dev) { + else cfg80211_mgmt_tx_status( skb->dev->ieee80211_ptr, cookie, skb->data, skb->len, acked, GFP_ATOMIC); - } else { - struct ieee80211_sub_if_data *p2p_sdata; - - rcu_read_lock(); - - p2p_sdata = rcu_dereference(local->p2p_sdata); - if (p2p_sdata) { - cfg80211_mgmt_tx_status( - &p2p_sdata->wdev, cookie, skb->data, - skb->len, acked, GFP_ATOMIC); - } - rcu_read_unlock(); - } } if (unlikely(info->ack_frame_id)) { diff --git a/trunk/net/mac80211/trace.h b/trunk/net/mac80211/trace.h index 18d9c8a52e9e..c6d33b55b2df 100644 --- a/trunk/net/mac80211/trace.h +++ b/trunk/net/mac80211/trace.h @@ -24,7 +24,7 @@ __string(vif_name, sdata->dev ? sdata->dev->name : "") #define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ __entry->p2p = sdata->vif.p2p; \ - __assign_str(vif_name, sdata->dev ? sdata->dev->name : sdata->name) + __assign_str(vif_name, sdata->dev ? sdata->dev->name : "") #define VIF_PR_FMT " vif:%s(%d%s)" #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" @@ -274,12 +274,9 @@ TRACE_EVENT(drv_config, __entry->dynamic_ps_timeout = local->hw.conf.dynamic_ps_timeout; __entry->max_sleep_period = local->hw.conf.max_sleep_period; __entry->listen_interval = local->hw.conf.listen_interval; - __entry->long_frame_max_tx_count = - local->hw.conf.long_frame_max_tx_count; - __entry->short_frame_max_tx_count = - local->hw.conf.short_frame_max_tx_count; - __entry->center_freq = local->hw.conf.channel ? - local->hw.conf.channel->center_freq : 0; + __entry->long_frame_max_tx_count = local->hw.conf.long_frame_max_tx_count; + __entry->short_frame_max_tx_count = local->hw.conf.short_frame_max_tx_count; + __entry->center_freq = local->hw.conf.channel->center_freq; __entry->channel_type = local->hw.conf.channel_type; __entry->smps = local->hw.conf.smps_mode; ), diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 29eb4e678235..acf712ffb5e6 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -55,7 +55,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, if (WARN_ON_ONCE(info->control.rates[0].idx < 0)) return 0; - sband = local->hw.wiphy->bands[info->band]; + sband = local->hw.wiphy->bands[tx->channel->band]; txrate = &sband->bitrates[info->control.rates[0].idx]; erp = txrate->flags & IEEE80211_RATE_ERP_G; @@ -615,7 +615,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) memset(&txrc, 0, sizeof(txrc)); - sband = tx->local->hw.wiphy->bands[info->band]; + sband = tx->local->hw.wiphy->bands[tx->channel->band]; len = min_t(u32, tx->skb->len + FCS_LEN, tx->local->hw.wiphy->frag_threshold); @@ -626,13 +626,13 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) txrc.bss_conf = &tx->sdata->vif.bss_conf; txrc.skb = tx->skb; txrc.reported_rate.idx = -1; - txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band]; + txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[tx->channel->band]; if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1) txrc.max_rate_idx = -1; else txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; memcpy(txrc.rate_idx_mcs_mask, - tx->sdata->rc_rateidx_mcs_mask[info->band], + tx->sdata->rc_rateidx_mcs_mask[tx->channel->band], sizeof(txrc.rate_idx_mcs_mask)); txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || @@ -667,7 +667,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) "scanning and associated. Target station: " "%pM on %d GHz band\n", tx->sdata->name, hdr->addr1, - info->band ? 5 : 2)) + tx->channel->band ? 5 : 2)) return TX_DROP; /* @@ -1131,6 +1131,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, tx->skb = skb; tx->local = local; tx->sdata = sdata; + tx->channel = local->hw.conf.channel; __skb_queue_head_init(&tx->skbs); /* @@ -1203,7 +1204,6 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, struct sk_buff_head *skbs, bool txpending) { - struct ieee80211_tx_control control; struct sk_buff *skb, *tmp; unsigned long flags; @@ -1240,10 +1240,10 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); info->control.vif = vif; - control.sta = sta; + info->control.sta = sta; __skb_unlink(skb, skbs); - drv_tx(local, &control, skb); + drv_tx(local, skb); } return true; @@ -1399,7 +1399,8 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, goto out; } - info->band = local->hw.conf.channel->band; + tx.channel = local->hw.conf.channel; + info->band = tx.channel->band; /* set up hw_queue value early */ if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) || @@ -1719,7 +1720,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info; - int head_need; + int ret = NETDEV_TX_BUSY, head_need; u16 ethertype, hdrlen, meshhdrlen = 0; __le16 fc; struct ieee80211_hdr hdr; @@ -1735,8 +1736,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, u32 info_flags = 0; u16 info_id = 0; - if (unlikely(skb->len < ETH_HLEN)) + if (unlikely(skb->len < ETH_HLEN)) { + ret = NETDEV_TX_OK; goto fail; + } /* convert Ethernet header to proper 802.11 header (based on * operation mode) */ @@ -1784,6 +1787,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { /* Do not send frames with mesh_ttl == 0 */ sdata->u.mesh.mshstats.dropped_frames_ttl++; + ret = NETDEV_TX_OK; goto fail; } rcu_read_lock(); @@ -1807,31 +1811,37 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata, NULL, NULL); } else { - /* DS -> MBSS (802.11-2012 13.11.3.3). - * For unicast with unknown forwarding information, - * destination might be in the MBSS or if that fails - * forwarded to another mesh gate. In either case - * resolution will be handled in ieee80211_xmit(), so - * leave the original DA. This also works for mcast */ - const u8 *mesh_da = skb->data; - - if (mppath) - mesh_da = mppath->mpp; - else if (mpath) - mesh_da = mpath->dst; - rcu_read_unlock(); + int is_mesh_mcast = 1; + const u8 *mesh_da; + if (is_multicast_ether_addr(skb->data)) + /* DA TA mSA AE:SA */ + mesh_da = skb->data; + else { + static const u8 bcast[ETH_ALEN] = + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + if (mppath) { + /* RA TA mDA mSA AE:DA SA */ + mesh_da = mppath->mpp; + is_mesh_mcast = 0; + } else if (mpath) { + mesh_da = mpath->dst; + is_mesh_mcast = 0; + } else { + /* DA TA mSA AE:SA */ + mesh_da = bcast; + } + } hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, mesh_da, sdata->vif.addr); - if (is_multicast_ether_addr(mesh_da)) - /* DA TA mSA AE:SA */ + rcu_read_unlock(); + if (is_mesh_mcast) meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata, skb->data + ETH_ALEN, NULL); else - /* RA TA mDA mSA AE:DA SA */ meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata, @@ -1870,8 +1880,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, if (tdls_direct) { /* link during setup - throw out frames to peer */ - if (!tdls_auth) + if (!tdls_auth) { + ret = NETDEV_TX_OK; goto fail; + } /* DA SA BSSID */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -1905,6 +1917,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, hdrlen = 24; break; default: + ret = NETDEV_TX_OK; goto fail; } @@ -1949,6 +1962,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, I802_DEBUG_INC(local->tx_handlers_drop_unauth_port); + ret = NETDEV_TX_OK; goto fail; } @@ -2003,8 +2017,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, skb = skb_clone(skb, GFP_ATOMIC); kfree_skb(tmp_skb); - if (!skb) + if (!skb) { + ret = NETDEV_TX_OK; goto fail; + } } hdr.frame_control = fc; @@ -2107,8 +2123,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; fail: - dev_kfree_skb(skb); - return NETDEV_TX_OK; + if (ret == NETDEV_TX_OK) + dev_kfree_skb(skb); + + return ret; } @@ -2283,9 +2301,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, struct ieee80211_sub_if_data *sdata = NULL; struct ieee80211_if_ap *ap = NULL; struct beacon_data *beacon; - enum ieee80211_band band = local->oper_channel->band; + struct ieee80211_supported_band *sband; + enum ieee80211_band band = local->hw.conf.channel->band; struct ieee80211_tx_rate_control txrc; + sband = local->hw.wiphy->bands[band]; + rcu_read_lock(); sdata = vif_to_sdata(vif); @@ -2395,7 +2416,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, memset(mgmt, 0, hdr_len); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); - eth_broadcast_addr(mgmt->da); + memset(mgmt->da, 0xff, ETH_ALEN); memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); mgmt->u.beacon.beacon_int = @@ -2407,9 +2428,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, *pos++ = WLAN_EID_SSID; *pos++ = 0x0; - if (ieee80211_add_srates_ie(sdata, skb, true, band) || + if (ieee80211_add_srates_ie(sdata, skb, true) || mesh_add_ds_params_ie(skb, sdata) || - ieee80211_add_ext_srates_ie(sdata, skb, true, band) || + ieee80211_add_ext_srates_ie(sdata, skb, true) || mesh_add_rsn_ie(skb, sdata) || mesh_add_ht_cap_ie(skb, sdata) || mesh_add_ht_oper_ie(skb, sdata) || @@ -2432,12 +2453,12 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, memset(&txrc, 0, sizeof(txrc)); txrc.hw = hw; - txrc.sband = local->hw.wiphy->bands[band]; + txrc.sband = sband; txrc.bss_conf = &sdata->vif.bss_conf; txrc.skb = skb; txrc.reported_rate.idx = -1; txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; - if (txrc.rate_idx_mask == (1 << txrc.sband->n_bitrates) - 1) + if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1) txrc.max_rate_idx = -1; else txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; @@ -2461,8 +2482,7 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ieee80211_if_ap *ap = NULL; - struct sk_buff *skb = NULL; - struct probe_resp *presp = NULL; + struct sk_buff *presp = NULL, *skb = NULL; struct ieee80211_hdr *hdr; struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); @@ -2476,12 +2496,10 @@ struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw, if (!presp) goto out; - skb = dev_alloc_skb(presp->len); + skb = skb_copy(presp, GFP_ATOMIC); if (!skb) goto out; - memcpy(skb_put(skb, presp->len), presp->data, presp->len); - hdr = (struct ieee80211_hdr *) skb->data; memset(hdr->addr1, 0, sizeof(hdr->addr1)); @@ -2592,9 +2610,9 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, memset(hdr, 0, sizeof(*hdr)); hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); - eth_broadcast_addr(hdr->addr1); + memset(hdr->addr1, 0xff, ETH_ALEN); memcpy(hdr->addr2, vif->addr, ETH_ALEN); - eth_broadcast_addr(hdr->addr3); + memset(hdr->addr3, 0xff, ETH_ALEN); pos = skb_put(skb, ie_ssid_len); *pos++ = WLAN_EID_SSID; @@ -2691,7 +2709,8 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, info = IEEE80211_SKB_CB(skb); tx.flags |= IEEE80211_TX_PS_BUFFERED; - info->band = local->oper_channel->band; + tx.channel = local->hw.conf.channel; + info->band = tx.channel->band; if (invoke_tx_handlers(&tx)) skb = NULL; diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 471fb0516c99..39b82fee4904 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -276,9 +276,6 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) list_for_each_entry_rcu(sdata, &local->interfaces, list) { int ac; - if (!sdata->dev) - continue; - if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) continue; @@ -367,9 +364,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, list_for_each_entry_rcu(sdata, &local->interfaces, list) { int ac; - if (!sdata->dev) - continue; - for (ac = 0; ac < n_acs; ac++) { if (sdata->vif.hw_queue[ac] == queue || sdata->vif.cab_queue == queue) @@ -774,11 +768,8 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, elem_parse_failed = true; break; case WLAN_EID_CHANNEL_SWITCH: - if (elen != sizeof(struct ieee80211_channel_sw_ie)) { - elem_parse_failed = true; - break; - } - elems->ch_switch_ie = (void *)pos; + elems->ch_switch_elem = pos; + elems->ch_switch_elem_len = elen; break; case WLAN_EID_QUIET: if (!elems->quiet_elem) { @@ -841,7 +832,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, memset(&qparam, 0, sizeof(qparam)); - use_11b = (local->oper_channel->band == IEEE80211_BAND_2GHZ) && + use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) && !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); /* @@ -908,8 +899,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, drv_conf_tx(local, sdata, ac, &qparam); } - if (sdata->vif.type != NL80211_IFTYPE_MONITOR && - sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) { + if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { sdata->vif.bss_conf.qos = enable_qos; if (bss_notify) ieee80211_bss_info_change_notify(sdata, @@ -929,7 +919,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, if ((supp_rates[i] & 0x7f) * 5 > 110) have_higher_than_11mbit = 1; - if (local->oper_channel->band == IEEE80211_BAND_2GHZ && + if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && have_higher_than_11mbit) sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; else @@ -1110,7 +1100,6 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, u32 ratemask, - struct ieee80211_channel *chan, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, bool directed) @@ -1120,7 +1109,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt; size_t buf_len; u8 *buf; - u8 chan_no; + u8 chan; /* FIXME: come up with a proper value */ buf = kmalloc(200 + ie_len, GFP_KERNEL); @@ -1133,12 +1122,14 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, * badly-behaved APs don't respond when this parameter is included. */ if (directed) - chan_no = 0; + chan = 0; else - chan_no = ieee80211_frequency_to_channel(chan->center_freq); + chan = ieee80211_frequency_to_channel( + local->hw.conf.channel->center_freq); - buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, chan->band, - ratemask, chan_no); + buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, + local->hw.conf.channel->band, + ratemask, chan); skb = ieee80211_probereq_get(&local->hw, &sdata->vif, ssid, ssid_len, @@ -1163,13 +1154,11 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, - u32 ratemask, bool directed, bool no_cck, - struct ieee80211_channel *channel) + u32 ratemask, bool directed, bool no_cck) { struct sk_buff *skb; - skb = ieee80211_build_probe_req(sdata, dst, ratemask, channel, - ssid, ssid_len, + skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len, ie, ie_len, directed); if (skb) { if (no_cck) @@ -1370,8 +1359,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) switch (sdata->vif.type) { case NL80211_IFTYPE_STATION: changed |= BSS_CHANGED_ASSOC | - BSS_CHANGED_ARP_FILTER | - BSS_CHANGED_PS; + BSS_CHANGED_ARP_FILTER; mutex_lock(&sdata->u.mgd.mtx); ieee80211_bss_info_change_notify(sdata, changed); mutex_unlock(&sdata->u.mgd.mtx); @@ -1397,9 +1385,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) case NL80211_IFTYPE_MONITOR: /* ignore virtual */ break; - case NL80211_IFTYPE_P2P_DEVICE: - changed = BSS_CHANGED_IDLE; - break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_P2P_CLIENT: @@ -1586,8 +1571,6 @@ void ieee80211_recalc_smps(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; - if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) - continue; if (sdata->vif.type != NL80211_IFTYPE_STATION) goto set; @@ -1826,8 +1809,7 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper) } int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool need_basic, - enum ieee80211_band band) + struct sk_buff *skb, bool need_basic) { struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; @@ -1835,7 +1817,7 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, u8 i, rates, *pos; u32 basic_rates = sdata->vif.bss_conf.basic_rates; - sband = local->hw.wiphy->bands[band]; + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; rates = sband->n_bitrates; if (rates > 8) rates = 8; @@ -1858,8 +1840,7 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, } int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool need_basic, - enum ieee80211_band band) + struct sk_buff *skb, bool need_basic) { struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; @@ -1867,7 +1848,7 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, u8 i, exrates, *pos; u32 basic_rates = sdata->vif.bss_conf.basic_rates; - sband = local->hw.wiphy->bands[band]; + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; exrates = sband->n_bitrates; if (exrates > 8) exrates -= 8; diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index 767cc12da0fe..3c601378d27e 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -1171,10 +1171,8 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u, goto out_err; } svc->stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); - if (!svc->stats.cpustats) { - ret = -ENOMEM; + if (!svc->stats.cpustats) goto out_err; - } /* I'm the first user of the service */ atomic_set(&svc->usecnt, 0); diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index 2ceec64b19f9..cf4875565d67 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -249,15 +249,12 @@ static void death_by_event(unsigned long ul_conntrack) { struct nf_conn *ct = (void *)ul_conntrack; struct net *net = nf_ct_net(ct); - struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); - - BUG_ON(ecache == NULL); if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) { /* bad luck, let's retry again */ - ecache->timeout.expires = jiffies + + ct->timeout.expires = jiffies + (random32() % net->ct.sysctl_events_retry_timeout); - add_timer(&ecache->timeout); + add_timer(&ct->timeout); return; } /* we've got the event delivered, now it's dying */ @@ -271,9 +268,6 @@ static void death_by_event(unsigned long ul_conntrack) void nf_ct_insert_dying_list(struct nf_conn *ct) { struct net *net = nf_ct_net(ct); - struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); - - BUG_ON(ecache == NULL); /* add this conntrack to the dying list */ spin_lock_bh(&nf_conntrack_lock); @@ -281,10 +275,10 @@ void nf_ct_insert_dying_list(struct nf_conn *ct) &net->ct.dying); spin_unlock_bh(&nf_conntrack_lock); /* set a new timer to retry event delivery */ - setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct); - ecache->timeout.expires = jiffies + + setup_timer(&ct->timeout, death_by_event, (unsigned long)ct); + ct->timeout.expires = jiffies + (random32() % net->ct.sysctl_events_retry_timeout); - add_timer(&ecache->timeout); + add_timer(&ct->timeout); } EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list); diff --git a/trunk/net/netfilter/nf_conntrack_netlink.c b/trunk/net/netfilter/nf_conntrack_netlink.c index 9807f3278fcb..da4fc37a8578 100644 --- a/trunk/net/netfilter/nf_conntrack_netlink.c +++ b/trunk/net/netfilter/nf_conntrack_netlink.c @@ -2790,8 +2790,7 @@ static int __init ctnetlink_init(void) goto err_unreg_subsys; } - ret = register_pernet_subsys(&ctnetlink_net_ops); - if (ret < 0) { + if (register_pernet_subsys(&ctnetlink_net_ops)) { pr_err("ctnetlink_init: cannot register pernet operations\n"); goto err_unreg_exp_subsys; } diff --git a/trunk/net/netfilter/nfnetlink_log.c b/trunk/net/netfilter/nfnetlink_log.c index be194b144297..169ab59ed9d4 100644 --- a/trunk/net/netfilter/nfnetlink_log.c +++ b/trunk/net/netfilter/nfnetlink_log.c @@ -55,7 +55,6 @@ struct nfulnl_instance { unsigned int qlen; /* number of nlmsgs in skb */ struct sk_buff *skb; /* pre-allocatd skb */ struct timer_list timer; - struct user_namespace *peer_user_ns; /* User namespace of the peer process */ int peer_pid; /* PID of the peer process */ /* configurable parameters */ @@ -133,7 +132,7 @@ instance_put(struct nfulnl_instance *inst) static void nfulnl_timer(unsigned long data); static struct nfulnl_instance * -instance_create(u_int16_t group_num, int pid, struct user_namespace *user_ns) +instance_create(u_int16_t group_num, int pid) { struct nfulnl_instance *inst; int err; @@ -163,7 +162,6 @@ instance_create(u_int16_t group_num, int pid, struct user_namespace *user_ns) setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst); - inst->peer_user_ns = user_ns; inst->peer_pid = pid; inst->group_num = group_num; @@ -482,7 +480,7 @@ __build_packet_message(struct nfulnl_instance *inst, } if (indev && skb_mac_header_was_set(skb)) { - if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || + if (nla_put_be32(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || nla_put_be16(inst->skb, NFULA_HWLEN, htons(skb->dev->hard_header_len)) || nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, @@ -505,11 +503,8 @@ __build_packet_message(struct nfulnl_instance *inst, read_lock_bh(&skb->sk->sk_callback_lock); if (skb->sk->sk_socket && skb->sk->sk_socket->file) { struct file *file = skb->sk->sk_socket->file; - __be32 uid = htonl(from_kuid_munged(inst->peer_user_ns, - file->f_cred->fsuid)); - __be32 gid = htonl(from_kgid_munged(inst->peer_user_ns, - file->f_cred->fsgid)); - /* need to unlock here since NLA_PUT may goto */ + __be32 uid = htonl(file->f_cred->fsuid); + __be32 gid = htonl(file->f_cred->fsgid); read_unlock_bh(&skb->sk->sk_callback_lock); if (nla_put_be32(inst->skb, NFULA_UID, uid) || nla_put_be32(inst->skb, NFULA_GID, gid)) @@ -788,8 +783,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, } inst = instance_create(group_num, - NETLINK_CB(skb).pid, - sk_user_ns(NETLINK_CB(skb).ssk)); + NETLINK_CB(skb).pid); if (IS_ERR(inst)) { ret = PTR_ERR(inst); goto out; @@ -1002,10 +996,8 @@ static int __init nfnetlink_log_init(void) #ifdef CONFIG_PROC_FS if (!proc_create("nfnetlink_log", 0440, - proc_net_netfilter, &nful_file_ops)) { - status = -ENOMEM; + proc_net_netfilter, &nful_file_ops)) goto cleanup_logger; - } #endif return status; diff --git a/trunk/net/netfilter/xt_LOG.c b/trunk/net/netfilter/xt_LOG.c index 02a2bf49dcbd..ff5f75fddb15 100644 --- a/trunk/net/netfilter/xt_LOG.c +++ b/trunk/net/netfilter/xt_LOG.c @@ -363,12 +363,10 @@ static void dump_ipv4_packet(struct sbuff *m, /* Max length: 15 "UID=4294967295 " */ if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) { read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->sk->sk_socket && skb->sk->sk_socket->file) { - const struct cred *cred = skb->sk->sk_socket->file->f_cred; + if (skb->sk->sk_socket && skb->sk->sk_socket->file) sb_add(m, "UID=%u GID=%u ", - from_kuid_munged(&init_user_ns, cred->fsuid), - from_kgid_munged(&init_user_ns, cred->fsgid)); - } + skb->sk->sk_socket->file->f_cred->fsuid, + skb->sk->sk_socket->file->f_cred->fsgid); read_unlock_bh(&skb->sk->sk_callback_lock); } @@ -721,12 +719,10 @@ static void dump_ipv6_packet(struct sbuff *m, /* Max length: 15 "UID=4294967295 " */ if ((logflags & XT_LOG_UID) && recurse && skb->sk) { read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->sk->sk_socket && skb->sk->sk_socket->file) { - const struct cred *cred = skb->sk->sk_socket->file->f_cred; + if (skb->sk->sk_socket && skb->sk->sk_socket->file) sb_add(m, "UID=%u GID=%u ", - from_kuid_munged(&init_user_ns, cred->fsuid), - from_kgid_munged(&init_user_ns, cred->fsgid)); - } + skb->sk->sk_socket->file->f_cred->fsuid, + skb->sk->sk_socket->file->f_cred->fsgid); read_unlock_bh(&skb->sk->sk_callback_lock); } diff --git a/trunk/net/netfilter/xt_owner.c b/trunk/net/netfilter/xt_owner.c index ca2e577ed8ac..772d7389b337 100644 --- a/trunk/net/netfilter/xt_owner.c +++ b/trunk/net/netfilter/xt_owner.c @@ -17,17 +17,6 @@ #include #include -static int owner_check(const struct xt_mtchk_param *par) -{ - struct xt_owner_match_info *info = par->matchinfo; - - /* For now only allow adding matches from the initial user namespace */ - if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) && - (current_user_ns() != &init_user_ns)) - return -EINVAL; - return 0; -} - static bool owner_mt(const struct sk_buff *skb, struct xt_action_param *par) { @@ -48,23 +37,17 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) return ((info->match ^ info->invert) & (XT_OWNER_UID | XT_OWNER_GID)) == 0; - if (info->match & XT_OWNER_UID) { - kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min); - kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max); - if ((uid_gte(filp->f_cred->fsuid, uid_min) && - uid_lte(filp->f_cred->fsuid, uid_max)) ^ + if (info->match & XT_OWNER_UID) + if ((filp->f_cred->fsuid >= info->uid_min && + filp->f_cred->fsuid <= info->uid_max) ^ !(info->invert & XT_OWNER_UID)) return false; - } - if (info->match & XT_OWNER_GID) { - kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min); - kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max); - if ((gid_gte(filp->f_cred->fsgid, gid_min) && - gid_lte(filp->f_cred->fsgid, gid_max)) ^ + if (info->match & XT_OWNER_GID) + if ((filp->f_cred->fsgid >= info->gid_min && + filp->f_cred->fsgid <= info->gid_max) ^ !(info->invert & XT_OWNER_GID)) return false; - } return true; } @@ -73,7 +56,6 @@ static struct xt_match owner_mt_reg __read_mostly = { .name = "owner", .revision = 1, .family = NFPROTO_UNSPEC, - .checkentry = owner_check, .match = owner_mt, .matchsize = sizeof(struct xt_owner_match_info), .hooks = (1 << NF_INET_LOCAL_OUT) | diff --git a/trunk/net/netfilter/xt_recent.c b/trunk/net/netfilter/xt_recent.c index 4635c9b00459..ae2ad1eec8d0 100644 --- a/trunk/net/netfilter/xt_recent.c +++ b/trunk/net/netfilter/xt_recent.c @@ -317,8 +317,6 @@ static int recent_mt_check(const struct xt_mtchk_param *par, struct recent_table *t; #ifdef CONFIG_PROC_FS struct proc_dir_entry *pde; - kuid_t uid; - kgid_t gid; #endif unsigned int i; int ret = -EINVAL; @@ -374,13 +372,6 @@ static int recent_mt_check(const struct xt_mtchk_param *par, for (i = 0; i < ip_list_hash_size; i++) INIT_LIST_HEAD(&t->iphash[i]); #ifdef CONFIG_PROC_FS - uid = make_kuid(&init_user_ns, ip_list_uid); - gid = make_kgid(&init_user_ns, ip_list_gid); - if (!uid_valid(uid) || !gid_valid(gid)) { - kfree(t); - ret = -EINVAL; - goto out; - } pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent, &recent_mt_fops, t); if (pde == NULL) { @@ -388,8 +379,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ret = -ENOMEM; goto out; } - pde->uid = uid; - pde->gid = gid; + pde->uid = ip_list_uid; + pde->gid = ip_list_gid; #endif spin_lock_bh(&recent_lock); list_add_tail(&t->list, &recent_net->tables); diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 382119917166..1445d73533ed 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -912,8 +912,7 @@ static void netlink_rcv_wake(struct sock *sk) wake_up_interruptible(&nlk->wait); } -static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb, - struct sock *ssk) +static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb) { int ret; struct netlink_sock *nlk = nlk_sk(sk); @@ -922,7 +921,6 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb, if (nlk->netlink_rcv != NULL) { ret = skb->len; skb_set_owner_r(skb, sk); - NETLINK_CB(skb).ssk = ssk; nlk->netlink_rcv(skb); consume_skb(skb); } else { @@ -949,7 +947,7 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb, return PTR_ERR(sk); } if (netlink_is_kernel(sk)) - return netlink_unicast_kernel(sk, skb, ssk); + return netlink_unicast_kernel(sk, skb); if (sk_filter(sk, skb)) { err = skb->len; @@ -1375,8 +1373,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, dst_pid = addr->nl_pid; dst_group = ffs(addr->nl_groups); err = -EPERM; - if ((dst_group || dst_pid) && - !netlink_capable(sock, NL_NONROOT_SEND)) + if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND)) goto out; } else { dst_pid = nlk->dst_pid; @@ -2150,7 +2147,6 @@ static void __init netlink_add_usersock_entry(void) rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners); nl_table[NETLINK_USERSOCK].module = THIS_MODULE; nl_table[NETLINK_USERSOCK].registered = 1; - nl_table[NETLINK_USERSOCK].nl_nonroot = NL_NONROOT_SEND; netlink_table_ungrab(); } diff --git a/trunk/net/openvswitch/flow.c b/trunk/net/openvswitch/flow.c index c7bf2f26525a..b7f38b161909 100644 --- a/trunk/net/openvswitch/flow.c +++ b/trunk/net/openvswitch/flow.c @@ -427,11 +427,19 @@ void ovs_flow_deferred_free(struct sw_flow *flow) call_rcu(&flow->rcu, rcu_free_flow_callback); } +/* RCU callback used by ovs_flow_deferred_free_acts. */ +static void rcu_free_acts_callback(struct rcu_head *rcu) +{ + struct sw_flow_actions *sf_acts = container_of(rcu, + struct sw_flow_actions, rcu); + kfree(sf_acts); +} + /* Schedules 'sf_acts' to be freed after the next RCU grace period. * The caller must hold rcu_read_lock for this to be sensible. */ void ovs_flow_deferred_free_acts(struct sw_flow_actions *sf_acts) { - kfree_rcu(sf_acts, rcu); + call_rcu(&sf_acts->rcu, rcu_free_acts_callback); } static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index 94060edbbd70..f220c5bdb71f 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -1162,7 +1162,7 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) spin_unlock(&f->lock); } -static bool match_fanout_group(struct packet_type *ptype, struct sock * sk) +bool match_fanout_group(struct packet_type *ptype, struct sock * sk) { if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout) return true; @@ -3749,7 +3749,7 @@ static int packet_seq_show(struct seq_file *seq, void *v) po->ifindex, po->running, atomic_read(&s->sk_rmem_alloc), - from_kuid_munged(seq_user_ns(seq), sock_i_uid(s)), + sock_i_uid(s), sock_i_ino(s)); } diff --git a/trunk/net/phonet/socket.c b/trunk/net/phonet/socket.c index b7e982782255..0acc943f713a 100644 --- a/trunk/net/phonet/socket.c +++ b/trunk/net/phonet/socket.c @@ -612,8 +612,7 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v) sk->sk_protocol, pn->sobject, pn->dobject, pn->resource, sk->sk_state, sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk), - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), - sock_i_ino(sk), + sock_i_uid(sk), sock_i_ino(sk), atomic_read(&sk->sk_refcnt), sk, atomic_read(&sk->sk_drops), &len); } @@ -797,8 +796,7 @@ static int pn_res_seq_show(struct seq_file *seq, void *v) struct sock *sk = *psk; seq_printf(seq, "%02X %5d %lu%n", - (int) (psk - pnres.sk), - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), + (int) (psk - pnres.sk), sock_i_uid(sk), sock_i_ino(sk), &len); } seq_printf(seq, "%*s\n", 63 - len, ""); diff --git a/trunk/net/rfkill/core.c b/trunk/net/rfkill/core.c index c275bad12068..752b72360ebc 100644 --- a/trunk/net/rfkill/core.c +++ b/trunk/net/rfkill/core.c @@ -150,20 +150,6 @@ static void rfkill_led_trigger_activate(struct led_classdev *led) 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 diff --git a/trunk/net/sched/cls_api.c b/trunk/net/sched/cls_api.c index dc3ef5aef355..6dd1131f2ec1 100644 --- a/trunk/net/sched/cls_api.c +++ b/trunk/net/sched/cls_api.c @@ -319,7 +319,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) } } - err = tp->ops->change(skb, tp, cl, t->tcm_handle, tca, &fh); + err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); if (err == 0) { if (tp_created) { spin_lock_bh(root_lock); diff --git a/trunk/net/sched/cls_basic.c b/trunk/net/sched/cls_basic.c index 344a11b342e5..590960a22a77 100644 --- a/trunk/net/sched/cls_basic.c +++ b/trunk/net/sched/cls_basic.c @@ -162,8 +162,7 @@ static int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f, return err; } -static int basic_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, u32 handle, +static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) { int err; diff --git a/trunk/net/sched/cls_cgroup.c b/trunk/net/sched/cls_cgroup.c index 91de66695b4a..7743ea8d1d38 100644 --- a/trunk/net/sched/cls_cgroup.c +++ b/trunk/net/sched/cls_cgroup.c @@ -151,8 +151,7 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = { [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, }; -static int cls_cgroup_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, +static int cls_cgroup_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) { diff --git a/trunk/net/sched/cls_flow.c b/trunk/net/sched/cls_flow.c index ce82d0cb1b47..ccd08c8dc6a7 100644 --- a/trunk/net/sched/cls_flow.c +++ b/trunk/net/sched/cls_flow.c @@ -193,19 +193,15 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb) static u32 flow_get_skuid(const struct sk_buff *skb) { - if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { - kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid; - return from_kuid(&init_user_ns, skuid); - } + if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) + return skb->sk->sk_socket->file->f_cred->fsuid; return 0; } static u32 flow_get_skgid(const struct sk_buff *skb) { - if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { - kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid; - return from_kgid(&init_user_ns, skgid); - } + if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) + return skb->sk->sk_socket->file->f_cred->fsgid; return 0; } @@ -351,8 +347,7 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, }; -static int flow_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, +static int flow_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) { @@ -391,10 +386,6 @@ static int flow_change(struct sk_buff *in_skb, if (fls(keymask) - 1 > FLOW_KEY_MAX) return -EOPNOTSUPP; - - if ((keymask & (FLOW_KEY_SKUID|FLOW_KEY_SKGID)) && - sk_user_ns(NETLINK_CB(in_skb).ssk) != &init_user_ns) - return -EOPNOTSUPP; } err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); diff --git a/trunk/net/sched/cls_fw.c b/trunk/net/sched/cls_fw.c index 4075a0aef2aa..8384a4797240 100644 --- a/trunk/net/sched/cls_fw.c +++ b/trunk/net/sched/cls_fw.c @@ -233,8 +233,7 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, return err; } -static int fw_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, +static int fw_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) diff --git a/trunk/net/sched/cls_route.c b/trunk/net/sched/cls_route.c index c10d57bf98f2..44f405cb9aaf 100644 --- a/trunk/net/sched/cls_route.c +++ b/trunk/net/sched/cls_route.c @@ -427,8 +427,7 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, return err; } -static int route4_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, +static int route4_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) diff --git a/trunk/net/sched/cls_rsvp.h b/trunk/net/sched/cls_rsvp.h index 494bbb90924a..18ab93ec8d7e 100644 --- a/trunk/net/sched/cls_rsvp.h +++ b/trunk/net/sched/cls_rsvp.h @@ -416,8 +416,7 @@ static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, }; -static int rsvp_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, +static int rsvp_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) diff --git a/trunk/net/sched/cls_tcindex.c b/trunk/net/sched/cls_tcindex.c index a1293b4ab7a1..fe29420d0b0e 100644 --- a/trunk/net/sched/cls_tcindex.c +++ b/trunk/net/sched/cls_tcindex.c @@ -332,8 +332,7 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, } static int -tcindex_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, u32 handle, +tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) { struct nlattr *opt = tca[TCA_OPTIONS]; diff --git a/trunk/net/sched/cls_u32.c b/trunk/net/sched/cls_u32.c index c7c27bc91b5a..d45373fb00b9 100644 --- a/trunk/net/sched/cls_u32.c +++ b/trunk/net/sched/cls_u32.c @@ -544,8 +544,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base, return err; } -static int u32_change(struct sk_buff *in_skb, - struct tcf_proto *tp, unsigned long base, u32 handle, +static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct nlattr **tca, unsigned long *arg) { diff --git a/trunk/net/sctp/proc.c b/trunk/net/sctp/proc.c index c3bea269faf4..d9cb2ab149fe 100644 --- a/trunk/net/sctp/proc.c +++ b/trunk/net/sctp/proc.c @@ -220,8 +220,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, sctp_sk(sk)->type, sk->sk_state, hash, epb->bind_addr.port, - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), - sock_i_ino(sk)); + sock_i_uid(sk), sock_i_ino(sk)); sctp_seq_dump_local_addrs(seq, epb); seq_printf(seq, "\n"); @@ -333,8 +332,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) assoc->assoc_id, assoc->sndbuf_used, atomic_read(&assoc->rmem_alloc), - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), - sock_i_ino(sk), + sock_i_uid(sk), sock_i_ino(sk), epb->bind_addr.port, assoc->peer.port); seq_printf(seq, " "); diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 8a84ab64cafd..c5ee4ff61364 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -2060,14 +2060,10 @@ static int unix_shutdown(struct socket *sock, int mode) struct sock *sk = sock->sk; struct sock *other; - if (mode < SHUT_RD || mode > SHUT_RDWR) - return -EINVAL; - /* This maps: - * SHUT_RD (0) -> RCV_SHUTDOWN (1) - * SHUT_WR (1) -> SEND_SHUTDOWN (2) - * SHUT_RDWR (2) -> SHUTDOWN_MASK (3) - */ - ++mode; + mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); + + if (!mode) + return 0; unix_state_lock(sk); sk->sk_shutdown |= mode; diff --git a/trunk/net/wireless/chan.c b/trunk/net/wireless/chan.c index 2f876b9ee344..d355f67d0cdd 100644 --- a/trunk/net/wireless/chan.c +++ b/trunk/net/wireless/chan.c @@ -105,7 +105,7 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, ASSERT_WDEV_LOCK(wdev); - if (wdev->netdev && !netif_running(wdev->netdev)) + if (!netif_running(wdev->netdev)) return; switch (wdev->iftype) { @@ -143,11 +143,6 @@ cfg80211_get_chan_state(struct wireless_dev *wdev, case NL80211_IFTYPE_WDS: /* these interface types don't really have a channel */ return; - case NL80211_IFTYPE_P2P_DEVICE: - if (wdev->wiphy->features & - NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL) - *chanmode = CHAN_MODE_EXCLUSIVE; - return; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: WARN_ON(1); diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 443d4d7deea2..dcd64d5b07aa 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -230,24 +230,9 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) rtnl_lock(); mutex_lock(&rdev->devlist_mtx); - list_for_each_entry(wdev, &rdev->wdev_list, list) { - if (wdev->netdev) { + list_for_each_entry(wdev, &rdev->wdev_list, list) + if (wdev->netdev) dev_close(wdev->netdev); - continue; - } - /* otherwise, check iftype */ - switch (wdev->iftype) { - case NL80211_IFTYPE_P2P_DEVICE: - if (!wdev->p2p_started) - break; - rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); - wdev->p2p_started = false; - rdev->opencount--; - break; - default: - break; - } - } mutex_unlock(&rdev->devlist_mtx); rtnl_unlock(); @@ -422,11 +407,6 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) if (WARN_ON(wiphy->software_iftypes & types)) return -EINVAL; - /* Only a single P2P_DEVICE can be allowed */ - if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && - c->limits[j].max > 1)) - return -EINVAL; - cnt += c->limits[j].max; /* * Don't advertise an unsupported type @@ -754,35 +734,6 @@ static void wdev_cleanup_work(struct work_struct *work) dev_put(wdev->netdev); } -void cfg80211_unregister_wdev(struct wireless_dev *wdev) -{ - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); - - ASSERT_RTNL(); - - if (WARN_ON(wdev->netdev)) - return; - - mutex_lock(&rdev->devlist_mtx); - list_del_rcu(&wdev->list); - rdev->devlist_generation++; - - switch (wdev->iftype) { - case NL80211_IFTYPE_P2P_DEVICE: - if (!wdev->p2p_started) - break; - rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); - wdev->p2p_started = false; - rdev->opencount--; - break; - default: - WARN_ON_ONCE(1); - break; - } - mutex_unlock(&rdev->devlist_mtx); -} -EXPORT_SYMBOL(cfg80211_unregister_wdev); - static struct device_type wiphy_type = { .name = "wlan", }; diff --git a/trunk/net/wireless/mlme.c b/trunk/net/wireless/mlme.c index 8fd0242ee169..1cdb1d5e6b0f 100644 --- a/trunk/net/wireless/mlme.c +++ b/trunk/net/wireless/mlme.c @@ -736,6 +736,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, const u8 *buf, size_t len, bool no_cck, bool dont_wait_for_ack, u64 *cookie) { + struct net_device *dev = wdev->netdev; const struct ieee80211_mgmt *mgmt; u16 stype; @@ -795,7 +796,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_AP_VLAN: - if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev))) + if (!ether_addr_equal(mgmt->bssid, dev->dev_addr)) err = -EINVAL; break; case NL80211_IFTYPE_MESH_POINT: @@ -808,11 +809,6 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, * cfg80211 doesn't track the stations */ break; - case NL80211_IFTYPE_P2P_DEVICE: - /* - * fall through, P2P device only supports - * public action frames - */ default: err = -EOPNOTSUPP; break; @@ -823,7 +819,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, return err; } - if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) + if (!ether_addr_equal(mgmt->sa, dev->dev_addr)) return -EINVAL; /* Transmit the Action frame as requested by user space */ diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 787aeaa902fe..97026f3b215a 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1100,7 +1100,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) goto nla_put_failure; } - CMD(start_p2p_device, START_P2P_DEVICE); #ifdef CONFIG_NL80211_TESTMODE CMD(testmode_cmd, TESTMODE); @@ -1749,13 +1748,13 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev && (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || - nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name))) + nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) || + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dev->dev_addr))) goto nla_put_failure; if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) || nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || - nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) || nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->devlist_generation ^ (cfg80211_rdev_list_generation << 2))) @@ -2022,10 +2021,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) return PTR_ERR(wdev); } - switch (type) { - case NL80211_IFTYPE_MESH_POINT: - if (!info->attrs[NL80211_ATTR_MESH_ID]) - break; + if (type == NL80211_IFTYPE_MESH_POINT && + info->attrs[NL80211_ATTR_MESH_ID]) { wdev_lock(wdev); BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); @@ -2034,26 +2031,6 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), wdev->mesh_id_up_len); wdev_unlock(wdev); - break; - case NL80211_IFTYPE_P2P_DEVICE: - /* - * P2P Device doesn't have a netdev, so doesn't go - * through the netdev notifier and must be added here - */ - mutex_init(&wdev->mtx); - INIT_LIST_HEAD(&wdev->event_list); - spin_lock_init(&wdev->event_lock); - INIT_LIST_HEAD(&wdev->mgmt_registrations); - spin_lock_init(&wdev->mgmt_registrations_lock); - - mutex_lock(&rdev->devlist_mtx); - wdev->identifier = ++rdev->wdev_id; - list_add_rcu(&wdev->list, &rdev->wdev_list); - rdev->devlist_generation++; - mutex_unlock(&rdev->devlist_mtx); - break; - default: - break; } if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, @@ -6076,7 +6053,6 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_P2P_DEVICE: break; default: return -EOPNOTSUPP; @@ -6123,7 +6099,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_P2P_DEVICE: break; default: return -EOPNOTSUPP; @@ -6220,7 +6195,6 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_P2P_DEVICE: break; default: return -EOPNOTSUPP; @@ -6836,68 +6810,6 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) return 0; } -static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct wireless_dev *wdev = info->user_ptr[1]; - int err; - - if (!rdev->ops->start_p2p_device) - return -EOPNOTSUPP; - - if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) - return -EOPNOTSUPP; - - if (wdev->p2p_started) - return 0; - - mutex_lock(&rdev->devlist_mtx); - err = cfg80211_can_add_interface(rdev, wdev->iftype); - mutex_unlock(&rdev->devlist_mtx); - if (err) - return err; - - err = rdev->ops->start_p2p_device(&rdev->wiphy, wdev); - if (err) - return err; - - wdev->p2p_started = true; - mutex_lock(&rdev->devlist_mtx); - rdev->opencount++; - mutex_unlock(&rdev->devlist_mtx); - - return 0; -} - -static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev = info->user_ptr[0]; - struct wireless_dev *wdev = info->user_ptr[1]; - - if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) - return -EOPNOTSUPP; - - if (!rdev->ops->stop_p2p_device) - return -EOPNOTSUPP; - - if (!wdev->p2p_started) - return 0; - - rdev->ops->stop_p2p_device(&rdev->wiphy, wdev); - wdev->p2p_started = false; - - mutex_lock(&rdev->devlist_mtx); - rdev->opencount--; - mutex_unlock(&rdev->devlist_mtx); - - if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { - rdev->scan_req->aborted = true; - ___cfg80211_scan_done(rdev, true); - } - - return 0; -} - #define NL80211_FLAG_NEED_WIPHY 0x01 #define NL80211_FLAG_NEED_NETDEV 0x02 #define NL80211_FLAG_NEED_RTNL 0x04 @@ -6905,7 +6817,7 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ NL80211_FLAG_CHECK_NETDEV_UP) #define NL80211_FLAG_NEED_WDEV 0x10 -/* If a netdev is associated, it must be UP, P2P must be started */ +/* If a netdev is associated, it must be UP */ #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ NL80211_FLAG_CHECK_NETDEV_UP) @@ -6966,13 +6878,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, } dev_hold(dev); - } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { - if (!wdev->p2p_started) { - mutex_unlock(&cfg80211_mutex); - if (rtnl) - rtnl_unlock(); - return -ENETDOWN; - } } cfg80211_lock_rdev(rdev); @@ -7534,22 +7439,7 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, - { - .cmd = NL80211_CMD_START_P2P_DEVICE, - .doit = nl80211_start_p2p_device, - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_WDEV | - NL80211_FLAG_NEED_RTNL, - }, - { - .cmd = NL80211_CMD_STOP_P2P_DEVICE, - .doit = nl80211_stop_p2p_device, - .policy = nl80211_policy, - .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_WDEV_UP | - NL80211_FLAG_NEED_RTNL, - }, + }; static struct genl_multicast_group nl80211_mlme_mcgrp = { diff --git a/trunk/net/wireless/radiotap.c b/trunk/net/wireless/radiotap.c index 7d604c06c3dc..c4ad7958af52 100644 --- a/trunk/net/wireless/radiotap.c +++ b/trunk/net/wireless/radiotap.c @@ -41,8 +41,6 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = { [IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, }, [IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, }, [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, }, - [IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, }, - [IEEE80211_RADIOTAP_AMPDU_STATUS] = { .align = 4, .size = 8, }, /* * add more here as they are defined in radiotap.h */ diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index ef35f4ef2aa6..994e2f0cc7a8 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -684,10 +684,22 @@ EXPORT_SYMBOL(cfg80211_classify8021d); const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie) { - if (bss->information_elements == NULL) + u8 *end, *pos; + + pos = bss->information_elements; + if (pos == NULL) return NULL; - return cfg80211_find_ie(ie, bss->information_elements, - bss->len_information_elements); + end = pos + bss->len_information_elements; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + break; + if (pos[0] == ie) + return pos; + pos += 2 + pos[1]; + } + + return NULL; } EXPORT_SYMBOL(ieee80211_bss_get_ie); @@ -800,10 +812,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (otype == NL80211_IFTYPE_AP_VLAN) return -EOPNOTSUPP; - /* cannot change into P2P device type */ - if (ntype == NL80211_IFTYPE_P2P_DEVICE) - return -EOPNOTSUPP; - if (!rdev->ops->change_virtual_intf || !(rdev->wiphy.interface_modes & (1 << ntype))) return -EOPNOTSUPP; @@ -881,9 +889,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, case NUM_NL80211_IFTYPES: /* not happening */ break; - case NL80211_IFTYPE_P2P_DEVICE: - WARN_ON(1); - break; } } @@ -1048,15 +1053,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { if (wdev_iter == wdev) continue; - if (wdev_iter->netdev) { - if (!netif_running(wdev_iter->netdev)) - continue; - } else if (wdev_iter->iftype == NL80211_IFTYPE_P2P_DEVICE) { - if (!wdev_iter->p2p_started) - continue; - } else { - WARN_ON(1); - } + if (!netif_running(wdev_iter->netdev)) + continue; if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) continue;