From 14a815b56351331e80bb0c119f532ada5515d09b Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 20 Apr 2009 01:31:05 -0300 Subject: [PATCH] --- yaml --- r: 150849 b: refs/heads/master c: 8db4dc46dcff7568896aa1eae4bd07620ce3dd93 h: refs/heads/master i: 150847: 773e615debdd0719cfab87dfe8e7d81bcc47dfff v: v3 --- [refs] | 2 +- trunk/Documentation/isdn/INTERFACE.CAPI | 94 +-- trunk/Documentation/networking/ieee802154.txt | 76 -- trunk/MAINTAINERS | 12 - trunk/drivers/Makefile | 1 - trunk/drivers/ieee802154/Kconfig | 22 - trunk/drivers/ieee802154/Makefile | 3 - trunk/drivers/ieee802154/fakehard.c | 270 ------- trunk/drivers/isdn/capi/capiutil.c | 67 +- trunk/drivers/isdn/capi/kcapi.c | 8 +- trunk/drivers/isdn/hardware/avm/b1.c | 2 +- trunk/drivers/isdn/hardware/avm/b1dma.c | 2 +- trunk/drivers/isdn/hardware/avm/c4.c | 4 +- trunk/drivers/isdn/hardware/avm/t1isa.c | 2 +- trunk/drivers/isdn/hysdn/hycapi.c | 4 +- trunk/drivers/net/Kconfig | 9 +- trunk/drivers/net/Makefile | 1 - trunk/drivers/net/atl1c/atl1c_ethtool.c | 2 +- trunk/drivers/net/benet/be_main.c | 129 ++- trunk/drivers/net/bnx2.c | 12 +- trunk/drivers/net/bonding/bond_sysfs.c | 1 - .../net/can/sja1000/sja1000_of_platform.c | 10 +- trunk/drivers/net/cxgb3/adapter.h | 2 - trunk/drivers/net/cxgb3/cxgb3_main.c | 78 +- trunk/drivers/net/cxgb3/cxgb3_offload.c | 27 +- trunk/drivers/net/cxgb3/cxgb3_offload.h | 3 - trunk/drivers/net/declance.c | 5 - trunk/drivers/net/e100.c | 199 +---- trunk/drivers/net/e1000/e1000_main.c | 4 +- trunk/drivers/net/e1000e/82571.c | 86 +- trunk/drivers/net/e1000e/defines.h | 2 - trunk/drivers/net/e1000e/ethtool.c | 9 - trunk/drivers/net/e1000e/hw.h | 2 - trunk/drivers/net/e1000e/netdev.c | 8 +- trunk/drivers/net/igb/igb_main.c | 5 +- trunk/drivers/net/igbvf/netdev.c | 5 +- trunk/drivers/net/ixgb/ixgb_main.c | 4 +- trunk/drivers/net/ixgbe/ixgbe_fcoe.c | 6 +- trunk/drivers/net/ixgbe/ixgbe_fcoe.h | 1 - trunk/drivers/net/ixgbe/ixgbe_main.c | 44 +- trunk/drivers/net/ks8842.c | 732 ------------------ trunk/drivers/net/macvlan.c | 1 - trunk/drivers/net/mdio.c | 17 - trunk/drivers/net/mlx4/eq.c | 4 +- trunk/drivers/net/netxen/netxen_nic_init.c | 9 +- trunk/drivers/net/qlge/qlge.h | 31 +- trunk/drivers/net/qlge/qlge_ethtool.c | 6 +- trunk/drivers/net/qlge/qlge_main.c | 133 +--- trunk/drivers/net/qlge/qlge_mpi.c | 58 +- trunk/drivers/net/r8169.c | 2 +- trunk/drivers/net/s2io.c | 22 +- trunk/drivers/net/s2io.h | 9 + trunk/drivers/net/sfc/tenxpress.c | 11 +- trunk/drivers/net/sis190.c | 57 +- trunk/drivers/net/smsc911x.c | 2 +- trunk/drivers/net/tehuti.c | 9 +- trunk/drivers/net/tg3.c | 10 +- trunk/drivers/net/tulip/Kconfig | 12 - trunk/drivers/net/tulip/de2104x.c | 13 +- trunk/drivers/net/tun.c | 13 +- trunk/drivers/net/usb/hso.c | 5 +- trunk/drivers/net/virtio_net.c | 2 +- trunk/drivers/net/vxge/vxge-config.c | 12 +- trunk/drivers/net/wireless/Kconfig | 2 +- .../drivers/net/wireless/ath/ar9170/ar9170.h | 34 +- trunk/drivers/net/wireless/ath/ar9170/hw.h | 3 - trunk/drivers/net/wireless/ath/ar9170/main.c | 676 ++++++---------- trunk/drivers/net/wireless/ath/ar9170/usb.c | 122 +-- trunk/drivers/net/wireless/ath/ar9170/usb.h | 7 +- trunk/drivers/net/wireless/ath/ath5k/Makefile | 1 - trunk/drivers/net/wireless/ath/ath5k/ath5k.h | 4 - trunk/drivers/net/wireless/ath/ath5k/base.c | 7 - trunk/drivers/net/wireless/ath/ath5k/base.h | 12 - trunk/drivers/net/wireless/ath/ath5k/reset.c | 17 + trunk/drivers/net/wireless/ath/ath5k/rfkill.c | 121 --- trunk/drivers/net/wireless/ath/ath9k/xmit.c | 1 - trunk/drivers/net/wireless/b43/Kconfig | 7 + trunk/drivers/net/wireless/b43/Makefile | 2 +- trunk/drivers/net/wireless/b43/b43.h | 17 +- trunk/drivers/net/wireless/b43/dma.c | 2 +- trunk/drivers/net/wireless/b43/leds.c | 7 +- trunk/drivers/net/wireless/b43/main.c | 83 +- trunk/drivers/net/wireless/b43/main.h | 1 + trunk/drivers/net/wireless/b43/phy_common.h | 2 +- trunk/drivers/net/wireless/b43/pio.c | 2 +- trunk/drivers/net/wireless/b43/rfkill.c | 113 ++- trunk/drivers/net/wireless/b43/rfkill.h | 44 +- trunk/drivers/net/wireless/b43/xmit.c | 5 +- trunk/drivers/net/wireless/b43legacy/Kconfig | 8 + trunk/drivers/net/wireless/b43legacy/Makefile | 2 +- .../net/wireless/b43legacy/b43legacy.h | 3 + trunk/drivers/net/wireless/b43legacy/leds.c | 7 +- trunk/drivers/net/wireless/b43legacy/main.c | 17 +- trunk/drivers/net/wireless/b43legacy/rfkill.c | 115 ++- trunk/drivers/net/wireless/b43legacy/rfkill.h | 50 +- trunk/drivers/net/wireless/iwlwifi/Kconfig | 4 + trunk/drivers/net/wireless/iwlwifi/Makefile | 1 + trunk/drivers/net/wireless/iwlwifi/iwl-3945.h | 5 + trunk/drivers/net/wireless/iwlwifi/iwl-agn.c | 42 +- trunk/drivers/net/wireless/iwlwifi/iwl-core.c | 138 ++++ trunk/drivers/net/wireless/iwlwifi/iwl-core.h | 16 +- .../net/wireless/iwlwifi/iwl-debugfs.c | 2 + trunk/drivers/net/wireless/iwlwifi/iwl-dev.h | 5 + .../drivers/net/wireless/iwlwifi/iwl-rfkill.c | 131 ++++ .../drivers/net/wireless/iwlwifi/iwl-rfkill.h | 48 ++ .../net/wireless/iwlwifi/iwl3945-base.c | 41 +- trunk/drivers/net/wireless/libertas/if_spi.c | 92 +-- trunk/drivers/net/wireless/rndis_wlan.c | 292 +++---- trunk/drivers/platform/x86/acer-wmi.c | 3 + trunk/drivers/platform/x86/eeepc-laptop.c | 8 +- trunk/drivers/platform/x86/hp-wmi.c | 4 + trunk/drivers/platform/x86/sony-laptop.c | 4 +- trunk/drivers/platform/x86/thinkpad_acpi.c | 31 +- trunk/include/linux/ethtool.h | 8 +- trunk/include/linux/if_arp.h | 2 - trunk/include/linux/if_ether.h | 1 - trunk/include/linux/isdn/capilli.h | 2 +- trunk/include/linux/mdio.h | 9 - trunk/include/linux/netdevice.h | 2 +- trunk/include/linux/nl802154.h | 119 --- trunk/include/linux/rfkill.h | 36 +- trunk/include/linux/skbuff.h | 33 +- trunk/include/linux/socket.h | 4 +- trunk/include/linux/spi/libertas_spi.h | 3 + trunk/include/net/bluetooth/bluetooth.h | 9 + trunk/include/net/bluetooth/l2cap.h | 6 + trunk/include/net/ieee802154/af_ieee802154.h | 60 -- trunk/include/net/ieee802154/mac_def.h | 160 ---- trunk/include/net/ieee802154/netdevice.h | 115 --- trunk/include/net/ieee802154/nl802154.h | 41 - trunk/include/net/mac80211.h | 3 - trunk/include/net/pkt_sched.h | 7 +- trunk/include/net/sock.h | 6 +- trunk/net/8021q/vlan.c | 2 +- trunk/net/Kconfig | 1 - trunk/net/Makefile | 1 - trunk/net/appletalk/ddp.c | 31 +- trunk/net/bluetooth/cmtp/capi.c | 2 +- trunk/net/bluetooth/l2cap.c | 18 +- trunk/net/can/af_can.c | 2 - trunk/net/core/datagram.c | 181 +++-- trunk/net/core/dev.c | 14 +- trunk/net/core/iovec.c | 4 +- trunk/net/core/neighbour.c | 46 +- trunk/net/core/pktgen.c | 6 +- trunk/net/core/skb_dma_map.c | 13 +- trunk/net/core/skbuff.c | 237 +++--- trunk/net/core/sock.c | 32 +- trunk/net/core/user_dma.c | 46 +- trunk/net/ieee802154/Kconfig | 12 - trunk/net/ieee802154/Makefile | 5 - trunk/net/ieee802154/af802154.h | 36 - trunk/net/ieee802154/af_ieee802154.c | 372 --------- trunk/net/ieee802154/dgram.c | 394 ---------- trunk/net/ieee802154/netlink.c | 523 ------------- trunk/net/ieee802154/nl_policy.c | 52 -- trunk/net/ieee802154/raw.c | 254 ------ trunk/net/ipv4/ip_fragment.c | 4 +- trunk/net/ipv4/ip_output.c | 7 +- trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c | 5 +- trunk/net/ipv6/ip6_output.c | 7 +- trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 4 +- trunk/net/ipv6/reassembly.c | 4 +- trunk/net/mac80211/agg-tx.c | 6 +- trunk/net/mac80211/cfg.c | 4 +- trunk/net/mac80211/ieee80211_i.h | 5 - trunk/net/mac80211/main.c | 61 +- trunk/net/mac80211/mlme.c | 57 +- trunk/net/mac80211/rc80211_minstrel.c | 2 +- trunk/net/mac80211/rx.c | 27 +- trunk/net/mac80211/tx.c | 19 +- trunk/net/mac80211/util.c | 46 -- trunk/net/mac80211/wme.c | 2 +- trunk/net/netfilter/nfnetlink_queue.c | 4 +- trunk/net/phonet/pep-gprs.c | 4 +- trunk/net/phonet/pep.c | 4 +- trunk/net/rfkill/Kconfig | 2 +- trunk/net/rfkill/core.c | 93 ++- trunk/net/sched/sch_hfsc.c | 8 +- trunk/net/sctp/input.c | 4 +- trunk/net/sctp/protocol.c | 2 - trunk/net/sctp/socket.c | 6 +- trunk/net/sctp/ulpevent.c | 7 +- trunk/net/sunrpc/auth_gss/auth_gss.c | 1 - trunk/net/wireless/core.c | 19 +- trunk/net/wireless/reg.c | 7 +- trunk/net/xfrm/xfrm_algo.c | 41 +- 187 files changed, 2139 insertions(+), 5987 deletions(-) delete mode 100644 trunk/Documentation/networking/ieee802154.txt delete mode 100644 trunk/drivers/ieee802154/Kconfig delete mode 100644 trunk/drivers/ieee802154/Makefile delete mode 100644 trunk/drivers/ieee802154/fakehard.c delete mode 100644 trunk/drivers/net/ks8842.c delete mode 100644 trunk/drivers/net/wireless/ath/ath5k/rfkill.c create mode 100644 trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c create mode 100644 trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h delete mode 100644 trunk/include/linux/nl802154.h delete mode 100644 trunk/include/net/ieee802154/af_ieee802154.h delete mode 100644 trunk/include/net/ieee802154/mac_def.h delete mode 100644 trunk/include/net/ieee802154/netdevice.h delete mode 100644 trunk/include/net/ieee802154/nl802154.h delete mode 100644 trunk/net/ieee802154/Kconfig delete mode 100644 trunk/net/ieee802154/Makefile delete mode 100644 trunk/net/ieee802154/af802154.h delete mode 100644 trunk/net/ieee802154/af_ieee802154.c delete mode 100644 trunk/net/ieee802154/dgram.c delete mode 100644 trunk/net/ieee802154/netlink.c delete mode 100644 trunk/net/ieee802154/nl_policy.c delete mode 100644 trunk/net/ieee802154/raw.c diff --git a/[refs] b/[refs] index 77313d4d2c08..d6919042a797 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 130aa61a77b8518f1ea618e1b7d214d60b405f10 +refs/heads/master: 8db4dc46dcff7568896aa1eae4bd07620ce3dd93 diff --git a/trunk/Documentation/isdn/INTERFACE.CAPI b/trunk/Documentation/isdn/INTERFACE.CAPI index 686e107923ec..786d619b36e5 100644 --- a/trunk/Documentation/isdn/INTERFACE.CAPI +++ b/trunk/Documentation/isdn/INTERFACE.CAPI @@ -45,7 +45,7 @@ From then on, Kernel CAPI may call the registered callback functions for the device. If the device becomes unusable for any reason (shutdown, disconnect ...), the -driver has to call capi_ctr_down(). This will prevent further calls to the +driver has to call capi_ctr_reseted(). This will prevent further calls to the callback functions by Kernel CAPI. @@ -114,36 +114,20 @@ char *driver_name int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata) (optional) pointer to a callback function for sending firmware and configuration data to the device - Return value: 0 on success, error code on error - Called in process context. void (*reset_ctr)(struct capi_ctr *ctrlr) - (optional) pointer to a callback function for performing a reset on - the device, releasing all registered applications - Called in process context. + pointer to a callback function for performing a reset on the device, + releasing all registered applications void (*register_appl)(struct capi_ctr *ctrlr, u16 applid, capi_register_params *rparam) void (*release_appl)(struct capi_ctr *ctrlr, u16 applid) pointers to callback functions for registration and deregistration of applications with the device - Calls to these functions are serialized by Kernel CAPI so that only - one call to any of them is active at any time. u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb) pointer to a callback function for sending a CAPI message to the device - Return value: CAPI error code - If the method returns 0 (CAPI_NOERROR) the driver has taken ownership - of the skb and the caller may no longer access it. If it returns a - non-zero (error) value then ownership of the skb returns to the caller - who may reuse or free it. - The return value should only be used to signal problems with respect - to accepting or queueing the message. Errors occurring during the - actual processing of the message should be signaled with an - appropriate reply message. - Calls to this function are not serialized by Kernel CAPI, ie. it must - be prepared to be re-entered. char *(*procinfo)(struct capi_ctr *ctrlr) pointer to a callback function returning the entry for the device in @@ -154,8 +138,6 @@ read_proc_t *ctr_read_proc system entry, /proc/capi/controllers/; will be called with a pointer to the device's capi_ctr structure as the last (data) argument -Note: Callback functions are never called in interrupt context. - - to be filled in before calling capi_ctr_ready(): u8 manu[CAPI_MANUFACTURER_LEN] @@ -171,45 +153,6 @@ u8 serial[CAPI_SERIAL_LEN] value to return for CAPI_GET_SERIAL -4.3 The _cmsg Structure - -(declared in ) - -The _cmsg structure stores the contents of a CAPI 2.0 message in an easily -accessible form. It contains members for all possible CAPI 2.0 parameters, of -which only those appearing in the message type currently being processed are -actually used. Unused members should be set to zero. - -Members are named after the CAPI 2.0 standard names of the parameters they -represent. See for the exact spelling. Member data -types are: - -u8 for CAPI parameters of type 'byte' - -u16 for CAPI parameters of type 'word' - -u32 for CAPI parameters of type 'dword' - -_cstruct for CAPI parameters of type 'struct' not containing any - variably-sized (struct) subparameters (eg. 'Called Party Number') - The member is a pointer to a buffer containing the parameter in - CAPI encoding (length + content). It may also be NULL, which will - be taken to represent an empty (zero length) parameter. - -_cmstruct for CAPI parameters of type 'struct' containing 'struct' - subparameters ('Additional Info' and 'B Protocol') - The representation is a single byte containing one of the values: - CAPI_DEFAULT: the parameter is empty - CAPI_COMPOSE: the values of the subparameters are stored - individually in the corresponding _cmsg structure members - -Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert -messages between their transport encoding described in the CAPI 2.0 standard -and their _cmsg structure representation. Note that capi_cmsg2message() does -not know or check the size of its destination buffer. The caller must make -sure it is big enough to accomodate the resulting CAPI message. - - 5. Lower Layer Interface Functions (declared in ) @@ -223,7 +166,7 @@ int detach_capi_ctr(struct capi_ctr *ctrlr) register/unregister a device (controller) with Kernel CAPI void capi_ctr_ready(struct capi_ctr *ctrlr) -void capi_ctr_down(struct capi_ctr *ctrlr) +void capi_ctr_reseted(struct capi_ctr *ctrlr) signal controller ready/not ready void capi_ctr_suspend_output(struct capi_ctr *ctrlr) @@ -268,32 +211,3 @@ CAPIMSG_CONTROL(m) CAPIMSG_SETCONTROL(m, contr) Controller/PLCI/NCCI (u32) CAPIMSG_DATALEN(m) CAPIMSG_SETDATALEN(m, len) Data Length (u16) - -Library functions for working with _cmsg structures -(from ): - -unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg) - Assembles a CAPI 2.0 message from the parameters in *cmsg, storing the - result in *msg. - -unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg) - Disassembles the CAPI 2.0 message in *msg, storing the parameters in - *cmsg. - -unsigned capi_cmsg_header(_cmsg *cmsg, u16 ApplId, u8 Command, u8 Subcommand, - u16 Messagenumber, u32 Controller) - Fills the header part and address field of the _cmsg structure *cmsg - with the given values, zeroing the remainder of the structure so only - parameters with non-default values need to be changed before sending - the message. - -void capi_cmsg_answer(_cmsg *cmsg) - Sets the low bit of the Subcommand field in *cmsg, thereby converting - _REQ to _CONF and _IND to _RESP. - -char *capi_cmd2str(u8 Command, u8 Subcommand) - Returns the CAPI 2.0 message name corresponding to the given command - and subcommand values, as a static ASCII string. The return value may - be NULL if the command/subcommand is not one of those defined in the - CAPI 2.0 standard. - diff --git a/trunk/Documentation/networking/ieee802154.txt b/trunk/Documentation/networking/ieee802154.txt deleted file mode 100644 index a0280ad2edc9..000000000000 --- a/trunk/Documentation/networking/ieee802154.txt +++ /dev/null @@ -1,76 +0,0 @@ - - Linux IEEE 802.15.4 implementation - - -Introduction -============ - -The Linux-ZigBee project goal is to provide complete implementation -of IEEE 802.15.4 / ZigBee / 6LoWPAN protocols. IEEE 802.15.4 is a stack -of protocols for organizing Low-Rate Wireless Personal Area Networks. - -Currently only IEEE 802.15.4 layer is implemented. We have choosen -to use plain Berkeley socket API, the generic Linux networking stack -to transfer IEEE 802.15.4 messages and a special protocol over genetlink -for configuration/management - - -Socket API -========== - -int sd = socket(PF_IEEE802154, SOCK_DGRAM, 0); -..... - -The address family, socket addresses etc. are defined in the -include/net/ieee802154/af_ieee802154.h header or in the special header -in our userspace package (see either linux-zigbee sourceforge download page -or git tree at git://linux-zigbee.git.sourceforge.net/gitroot/linux-zigbee). - -One can use SOCK_RAW for passing raw data towards device xmit function. YMMV. - - -MLME - MAC Level Management -============================ - -Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands. -See the include/net/ieee802154/nl802154.h header. Our userspace tools package -(see above) provides CLI configuration utility for radio interfaces and simple -coordinator for IEEE 802.15.4 networks as an example users of MLME protocol. - - -Kernel side -============= - -Like with WiFi, there are several types of devices implementing IEEE 802.15.4. -1) 'HardMAC'. The MAC layer is implemented in the device itself, the device - exports MLME and data API. -2) 'SoftMAC' or just radio. These types of devices are just radio transceivers - possibly with some kinds of acceleration like automatic CRC computation and - comparation, automagic ACK handling, address matching, etc. - -Those types of devices require different approach to be hooked into Linux kernel. - - -HardMAC -======= - -See the header include/net/ieee802154/netdevice.h. You have to implement Linux -net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family -code via plain sk_buffs. The control block of sk_buffs will contain additional -info as described in the struct ieee802154_mac_cb. - -To hook the MLME interface you have to populate the ml_priv field of your -net_device with a pointer to struct ieee802154_mlme_ops instance. All fields are -required. - -We provide an example of simple HardMAC driver at drivers/ieee802154/fakehard.c - - -SoftMAC -======= - -We are going to provide intermediate layer impelementing IEEE 802.15.4 MAC -in software. This is currently WIP. - -See header include/net/ieee802154/mac802154.h and several drivers in -drivers/ieee802154/ diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a6df68fad9ba..2f6a8fcfb1f2 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2819,18 +2819,6 @@ L: linux1394-devel@lists.sourceforge.net S: Maintained F: drivers/ieee1394/raw1394* -IEEE 802.15.4 SUBSYSTEM -P: Dmitry Eremin-Solenikov -M: dbaryshkov@gmail.com -P: Sergey Lapin -M: slapin@ossfans.org -L: linux-zigbee-devel@lists.sourceforge.net -W: http://apps.sourceforge.net/trac/linux-zigbee -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lumag/lowpan.git -S: Maintained -F: net/ieee802154/ -F: drivers/ieee801254/ - INTEGRITY MEASUREMENT ARCHITECTURE (IMA) P: Mimi Zohar M: zohar@us.ibm.com diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index 9e7d4e56c85b..1266ead6ace0 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -107,4 +107,3 @@ obj-$(CONFIG_SSB) += ssb/ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ -obj-y += ieee802154/ diff --git a/trunk/drivers/ieee802154/Kconfig b/trunk/drivers/ieee802154/Kconfig deleted file mode 100644 index 25740bd54975..000000000000 --- a/trunk/drivers/ieee802154/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -menuconfig IEEE802154_DRIVERS - bool "IEEE 802.15.4 drivers" - depends on NETDEVICES && IEEE802154 - default y - ---help--- - Say Y here to get to see options for IEEE 802.15.4 Low-Rate - Wireless Personal Area Network device drivers. This option alone - does not add any kernel code. - - If you say N, all options in this submenu will be skipped and - disabled. - -config IEEE802154_FAKEHARD - tristate "Fake LR-WPAN driver with several interconnected devices" - depends on IEEE802154_DRIVERS - ---help--- - Say Y here to enable the fake driver that serves as an example - of HardMAC device driver. - - This driver can also be built as a module. To do so say M here. - The module will be called 'fakehard'. - diff --git a/trunk/drivers/ieee802154/Makefile b/trunk/drivers/ieee802154/Makefile deleted file mode 100644 index e0e8e1a184ff..000000000000 --- a/trunk/drivers/ieee802154/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o - -EXTRA_CFLAGS += -DDEBUG -DCONFIG_FFD diff --git a/trunk/drivers/ieee802154/fakehard.c b/trunk/drivers/ieee802154/fakehard.c deleted file mode 100644 index 0384144c0b34..000000000000 --- a/trunk/drivers/ieee802154/fakehard.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Sample driver for HardMAC IEEE 802.15.4 devices - * - * Copyright (C) 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Dmitry Eremin-Solenikov - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static u16 fake_get_pan_id(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0xeba1; -} - -static u16 fake_get_short_addr(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0x1; -} - -static u8 fake_get_dsn(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0x00; /* DSN are implemented in HW, so return just 0 */ -} - -static u8 fake_get_bsn(struct net_device *dev) -{ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - return 0x00; /* BSN are implemented in HW, so return just 0 */ -} - -static int fake_assoc_req(struct net_device *dev, - struct ieee802154_addr *addr, u8 channel, u8 cap) -{ - /* We simply emulate it here */ - return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev), - IEEE802154_SUCCESS); -} - -static int fake_assoc_resp(struct net_device *dev, - struct ieee802154_addr *addr, u16 short_addr, u8 status) -{ - return 0; -} - -static int fake_disassoc_req(struct net_device *dev, - struct ieee802154_addr *addr, u8 reason) -{ - return ieee802154_nl_disassoc_confirm(dev, IEEE802154_SUCCESS); -} - -static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, - u8 channel, - u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, - u8 coord_realign) -{ - return 0; -} - -static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, - u8 duration) -{ - u8 edl[27] = {}; - return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, - channels, - type == IEEE802154_MAC_SCAN_ED ? edl : NULL); -} - -static struct ieee802154_mlme_ops fake_mlme = { - .assoc_req = fake_assoc_req, - .assoc_resp = fake_assoc_resp, - .disassoc_req = fake_disassoc_req, - .start_req = fake_start_req, - .scan_req = fake_scan_req, - - .get_pan_id = fake_get_pan_id, - .get_short_addr = fake_get_short_addr, - .get_dsn = fake_get_dsn, - .get_bsn = fake_get_bsn, -}; - -static int ieee802154_fake_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; -} - -static int ieee802154_fake_close(struct net_device *dev) -{ - netif_stop_queue(dev); - return 0; -} - -static int ieee802154_fake_xmit(struct sk_buff *skb, struct net_device *dev) -{ - skb->iif = dev->ifindex; - skb->dev = dev; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - - dev->trans_start = jiffies; - - /* FIXME: do hardware work here ... */ - - return 0; -} - - -static int ieee802154_fake_ioctl(struct net_device *dev, struct ifreq *ifr, - int cmd) -{ - struct sockaddr_ieee802154 *sa = - (struct sockaddr_ieee802154 *)&ifr->ifr_addr; - u16 pan_id, short_addr; - - switch (cmd) { - case SIOCGIFADDR: - /* FIXME: fixed here, get from device IRL */ - pan_id = fake_get_pan_id(dev); - short_addr = fake_get_short_addr(dev); - if (pan_id == IEEE802154_PANID_BROADCAST || - short_addr == IEEE802154_ADDR_BROADCAST) - return -EADDRNOTAVAIL; - - sa->family = AF_IEEE802154; - sa->addr.addr_type = IEEE802154_ADDR_SHORT; - sa->addr.pan_id = pan_id; - sa->addr.short_addr = short_addr; - return 0; - } - return -ENOIOCTLCMD; -} - -static int ieee802154_fake_mac_addr(struct net_device *dev, void *p) -{ - return -EBUSY; /* HW address is built into the device */ -} - -static const struct net_device_ops fake_ops = { - .ndo_open = ieee802154_fake_open, - .ndo_stop = ieee802154_fake_close, - .ndo_start_xmit = ieee802154_fake_xmit, - .ndo_do_ioctl = ieee802154_fake_ioctl, - .ndo_set_mac_address = ieee802154_fake_mac_addr, -}; - - -static void ieee802154_fake_setup(struct net_device *dev) -{ - dev->addr_len = IEEE802154_ADDR_LEN; - memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN); - dev->features = NETIF_F_NO_CSUM; - dev->needed_tailroom = 2; /* FCS */ - dev->mtu = 127; - dev->tx_queue_len = 10; - dev->type = ARPHRD_IEEE802154; - dev->flags = IFF_NOARP | IFF_BROADCAST; - dev->watchdog_timeo = 0; -} - - -static int __devinit ieee802154fake_probe(struct platform_device *pdev) -{ - struct net_device *dev = - alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup); - int err; - - if (!dev) - return -ENOMEM; - - memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef", - dev->addr_len); - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - - dev->netdev_ops = &fake_ops; - dev->ml_priv = &fake_mlme; - - /* - * If the name is a format string the caller wants us to do a - * name allocation. - */ - if (strchr(dev->name, '%')) { - err = dev_alloc_name(dev, dev->name); - if (err < 0) - goto out; - } - - SET_NETDEV_DEV(dev, &pdev->dev); - - platform_set_drvdata(pdev, dev); - - err = register_netdev(dev); - if (err < 0) - goto out; - - - dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n"); - return 0; - -out: - unregister_netdev(dev); - return err; -} - -static int __devexit ieee802154fake_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - unregister_netdev(dev); - free_netdev(dev); - return 0; -} - -static struct platform_device *ieee802154fake_dev; - -static struct platform_driver ieee802154fake_driver = { - .probe = ieee802154fake_probe, - .remove = __devexit_p(ieee802154fake_remove), - .driver = { - .name = "ieee802154hardmac", - .owner = THIS_MODULE, - }, -}; - -static __init int fake_init(void) -{ - ieee802154fake_dev = platform_device_register_simple( - "ieee802154hardmac", -1, NULL, 0); - return platform_driver_register(&ieee802154fake_driver); -} - -static __exit void fake_exit(void) -{ - platform_driver_unregister(&ieee802154fake_driver); - platform_device_unregister(ieee802154fake_dev); -} - -module_init(fake_init); -module_exit(fake_exit); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/isdn/capi/capiutil.c b/trunk/drivers/isdn/capi/capiutil.c index 16f2e465e5f9..29419a8d31dc 100644 --- a/trunk/drivers/isdn/capi/capiutil.c +++ b/trunk/drivers/isdn/capi/capiutil.c @@ -490,14 +490,7 @@ static void pars_2_message(_cmsg * cmsg) } } -/** - * capi_cmsg2message() - assemble CAPI 2.0 message from _cmsg structure - * @cmsg: _cmsg structure - * @msg: buffer for assembled message - * - * Return value: 0 for success - */ - +/*-------------------------------------------------------*/ unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg) { cmsg->m = msg; @@ -560,14 +553,7 @@ static void message_2_pars(_cmsg * cmsg) } } -/** - * capi_message2cmsg() - disassemble CAPI 2.0 message into _cmsg structure - * @cmsg: _cmsg structure - * @msg: buffer for assembled message - * - * Return value: 0 for success - */ - +/*-------------------------------------------------------*/ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) { memset(cmsg, 0, sizeof(_cmsg)); @@ -587,18 +573,7 @@ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) return 0; } -/** - * capi_cmsg_header() - initialize header part of _cmsg structure - * @cmsg: _cmsg structure - * @_ApplId: ApplID field value - * @_Command: Command field value - * @_Subcommand: Subcommand field value - * @_Messagenumber: Message Number field value - * @_Controller: Controller/PLCI/NCCI field value - * - * Return value: 0 for success - */ - +/*-------------------------------------------------------*/ unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId, u8 _Command, u8 _Subcommand, u16 _Messagenumber, u32 _Controller) @@ -666,14 +641,6 @@ static char *mnames[] = [0x4e] = "MANUFACTURER_RESP" }; -/** - * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name - * @cmd: command number - * @subcmd: subcommand number - * - * Return value: static string, NULL if command/subcommand unknown - */ - char *capi_cmd2str(u8 cmd, u8 subcmd) { return mnames[command_2_index(cmd, subcmd)]; @@ -912,11 +879,6 @@ static _cdebbuf *cdebbuf_alloc(void) return cdb; } -/** - * cdebbuf_free() - free CAPI debug buffer - * @cdb: buffer to free - */ - void cdebbuf_free(_cdebbuf *cdb) { if (likely(cdb == g_debbuf)) { @@ -929,16 +891,6 @@ void cdebbuf_free(_cdebbuf *cdb) } -/** - * capi_message2str() - format CAPI 2.0 message for printing - * @msg: CAPI 2.0 message - * - * Allocates a CAPI debug buffer and fills it with a printable representation - * of the CAPI 2.0 message in @msg. - * Return value: allocated debug buffer, NULL on error - * The returned buffer should be freed by a call to cdebbuf_free() after use. - */ - _cdebbuf *capi_message2str(u8 * msg) { _cdebbuf *cdb; @@ -974,23 +926,10 @@ _cdebbuf *capi_message2str(u8 * msg) return cdb; } -/** - * capi_cmsg2str() - format _cmsg structure for printing - * @cmsg: _cmsg structure - * - * Allocates a CAPI debug buffer and fills it with a printable representation - * of the CAPI 2.0 message stored in @cmsg by a previous call to - * capi_cmsg2message() or capi_message2cmsg(). - * Return value: allocated debug buffer, NULL on error - * The returned buffer should be freed by a call to cdebbuf_free() after use. - */ - _cdebbuf *capi_cmsg2str(_cmsg * cmsg) { _cdebbuf *cdb; - if (!cmsg->m) - return NULL; /* no message */ cdb = cdebbuf_alloc(); if (!cdb) return NULL; diff --git a/trunk/drivers/isdn/capi/kcapi.c b/trunk/drivers/isdn/capi/kcapi.c index 57d26360f64e..f33170368cd1 100644 --- a/trunk/drivers/isdn/capi/kcapi.c +++ b/trunk/drivers/isdn/capi/kcapi.c @@ -377,14 +377,14 @@ void capi_ctr_ready(struct capi_ctr * card) EXPORT_SYMBOL(capi_ctr_ready); /** - * capi_ctr_down() - signal CAPI controller not ready + * capi_ctr_reseted() - signal CAPI controller reset * @card: controller descriptor structure. * * Called by hardware driver to signal that the controller is down and * unavailable for use. */ -void capi_ctr_down(struct capi_ctr * card) +void capi_ctr_reseted(struct capi_ctr * card) { u16 appl; @@ -413,7 +413,7 @@ void capi_ctr_down(struct capi_ctr * card) notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); } -EXPORT_SYMBOL(capi_ctr_down); +EXPORT_SYMBOL(capi_ctr_reseted); /** * capi_ctr_suspend_output() - suspend controller @@ -517,7 +517,7 @@ EXPORT_SYMBOL(attach_capi_ctr); int detach_capi_ctr(struct capi_ctr *card) { if (card->cardstate != CARD_DETECTED) - capi_ctr_down(card); + capi_ctr_reseted(card); ncards--; diff --git a/trunk/drivers/isdn/hardware/avm/b1.c b/trunk/drivers/isdn/hardware/avm/b1.c index a7c0083e78a7..abf05ec31760 100644 --- a/trunk/drivers/isdn/hardware/avm/b1.c +++ b/trunk/drivers/isdn/hardware/avm/b1.c @@ -330,7 +330,7 @@ void b1_reset_ctr(struct capi_ctr *ctrl) spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } void b1_register_appl(struct capi_ctr *ctrl, diff --git a/trunk/drivers/isdn/hardware/avm/b1dma.c b/trunk/drivers/isdn/hardware/avm/b1dma.c index 0e84aaae43fd..da34b98e3de7 100644 --- a/trunk/drivers/isdn/hardware/avm/b1dma.c +++ b/trunk/drivers/isdn/hardware/avm/b1dma.c @@ -759,7 +759,7 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl) memset(cinfo->version, 0, sizeof(cinfo->version)); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } /* ------------------------------------------------------------- */ diff --git a/trunk/drivers/isdn/hardware/avm/c4.c b/trunk/drivers/isdn/hardware/avm/c4.c index 6833301a45fc..9df1d3f66c87 100644 --- a/trunk/drivers/isdn/hardware/avm/c4.c +++ b/trunk/drivers/isdn/hardware/avm/c4.c @@ -681,7 +681,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(&cinfo->capi_ctrl); + capi_ctr_reseted(&cinfo->capi_ctrl); } card->nlogcontr = 0; return IRQ_HANDLED; @@ -909,7 +909,7 @@ static void c4_reset_ctr(struct capi_ctr *ctrl) for (i=0; i < card->nr_controllers; i++) { cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); - capi_ctr_down(&cinfo->capi_ctrl); + capi_ctr_reseted(&cinfo->capi_ctrl); } card->nlogcontr = 0; } diff --git a/trunk/drivers/isdn/hardware/avm/t1isa.c b/trunk/drivers/isdn/hardware/avm/t1isa.c index 1c53fd49adb6..e7724493738c 100644 --- a/trunk/drivers/isdn/hardware/avm/t1isa.c +++ b/trunk/drivers/isdn/hardware/avm/t1isa.c @@ -339,7 +339,7 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl) spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); spin_unlock_irqrestore(&card->lock, flags); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } static void t1isa_remove(struct pci_dev *pdev) diff --git a/trunk/drivers/isdn/hysdn/hycapi.c b/trunk/drivers/isdn/hysdn/hycapi.c index 4ffaa14b9fc4..53f6ad1235db 100644 --- a/trunk/drivers/isdn/hysdn/hycapi.c +++ b/trunk/drivers/isdn/hysdn/hycapi.c @@ -67,7 +67,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl) printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n"); #endif capilib_release(&cinfo->ncci_head); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } /****************************** @@ -347,7 +347,7 @@ int hycapi_capi_stop(hysdn_card *card) if(cinfo) { ctrl = &cinfo->capi_ctrl; /* ctrl->suspend_output(ctrl); */ - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); } return 0; } diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 3f739cfd92fa..3df8fc4376dd 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1001,7 +1001,7 @@ config SMC911X config SMSC911X tristate "SMSC LAN911x/LAN921x families embedded ethernet support" - depends on ARM || SUPERH || BLACKFIN + depends on ARM || SUPERH select CRC32 select MII select PHYLIB @@ -1723,11 +1723,6 @@ config TLAN Please email feedback to . -config KS8842 - tristate "Micrel KSZ8842" - help - This platform driver is for Micrel KSZ8842 chip. - config VIA_RHINE tristate "VIA Rhine support" depends on NET_PCI && PCI @@ -2725,8 +2720,6 @@ source "drivers/net/wan/Kconfig" source "drivers/atm/Kconfig" -source "drivers/ieee802154/Kconfig" - source "drivers/s390/net/Kconfig" config XEN_NETDEV_FRONTEND diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 1c378dd5933e..774c2b45bdb8 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -86,7 +86,6 @@ obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKY2) += sky2.o obj-$(CONFIG_SKFP) += skfp/ -obj-$(CONFIG_KS8842) += ks8842.o obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o diff --git a/trunk/drivers/net/atl1c/atl1c_ethtool.c b/trunk/drivers/net/atl1c/atl1c_ethtool.c index e4afbd628c23..45c5b7332cd3 100644 --- a/trunk/drivers/net/atl1c/atl1c_ethtool.c +++ b/trunk/drivers/net/atl1c/atl1c_ethtool.c @@ -271,7 +271,7 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) struct atl1c_adapter *adapter = netdev_priv(netdev); if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE | - WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) + WAKE_MCAST | WAKE_BCAST | WAKE_MCAST)) return -EOPNOTSUPP; /* these settings will always override what we currently have */ adapter->wol = 0; diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 66bb56874d9b..5f17d80300ae 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -168,7 +168,6 @@ static void netdev_stats_update(struct be_adapter *adapter) struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; struct net_device_stats *dev_stats = &adapter->stats.net_stats; - struct be_erx_stats *erx_stats = &hw_stats->erx; dev_stats->rx_packets = port_stats->rx_total_frames; dev_stats->tx_packets = port_stats->tx_unicastframes + @@ -182,33 +181,29 @@ static void netdev_stats_update(struct be_adapter *adapter) dev_stats->rx_errors = port_stats->rx_crc_errors + port_stats->rx_alignment_symbol_errors + port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + - port_stats->rx_frame_too_long + - port_stats->rx_dropped_too_small + - port_stats->rx_dropped_too_short + - port_stats->rx_dropped_header_too_small + - port_stats->rx_dropped_tcp_length + - port_stats->rx_dropped_runt + - port_stats->rx_tcp_checksum_errs + - port_stats->rx_ip_checksum_errs + - port_stats->rx_udp_checksum_errs; - - /* no space in linux buffers: best possible approximation */ - dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0]; + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; + + /* packet transmit problems */ + dev_stats->tx_errors = 0; + + /* no space in linux buffers */ + dev_stats->rx_dropped = 0; + + /* no space available in linux */ + dev_stats->tx_dropped = 0; + + dev_stats->multicast = port_stats->tx_multicastframes; + dev_stats->collisions = 0; /* detailed rx errors */ dev_stats->rx_length_errors = port_stats->rx_in_range_errors + - port_stats->rx_out_range_errors + - port_stats->rx_frame_too_long; - + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; /* receive ring buffer overflow */ dev_stats->rx_over_errors = 0; - dev_stats->rx_crc_errors = port_stats->rx_crc_errors; /* frame alignment errors */ dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; - /* receiver fifo overrun */ /* drops_no_pbuf is no per i/f, it's per BE card */ dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + @@ -216,16 +211,6 @@ static void netdev_stats_update(struct be_adapter *adapter) rxf_stats->rx_drops_no_pbuf; /* receiver missed packetd */ dev_stats->rx_missed_errors = 0; - - /* packet transmit problems */ - dev_stats->tx_errors = 0; - - /* no space available in linux */ - dev_stats->tx_dropped = 0; - - dev_stats->multicast = port_stats->tx_multicastframes; - dev_stats->collisions = 0; - /* detailed tx_errors */ dev_stats->tx_aborted_errors = 0; dev_stats->tx_carrier_errors = 0; @@ -352,10 +337,13 @@ static void be_tx_stats_update(struct be_adapter *adapter, /* Determine number of WRB entries needed to xmit data in an skb */ static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) { - int cnt = (skb->len > skb->data_len); - - cnt += skb_shinfo(skb)->nr_frags; - + int cnt = 0; + while (skb) { + if (skb->len > skb->data_len) + cnt++; + cnt += skb_shinfo(skb)->nr_frags; + skb = skb_shinfo(skb)->frag_list; + } /* to account for hdr wrb */ cnt++; if (cnt & 1) { @@ -421,28 +409,31 @@ static int make_tx_wrbs(struct be_adapter *adapter, hdr = queue_head_node(txq); queue_head_inc(txq); - if (skb->len > skb->data_len) { - int len = skb->len - skb->data_len; - busaddr = pci_map_single(pdev, skb->data, len, - PCI_DMA_TODEVICE); - wrb = queue_head_node(txq); - wrb_fill(wrb, busaddr, len); - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - queue_head_inc(txq); - copied += len; - } + while (skb) { + if (skb->len > skb->data_len) { + int len = skb->len - skb->data_len; + busaddr = pci_map_single(pdev, skb->data, len, + PCI_DMA_TODEVICE); + wrb = queue_head_node(txq); + wrb_fill(wrb, busaddr, len); + be_dws_cpu_to_le(wrb, sizeof(*wrb)); + queue_head_inc(txq); + copied += len; + } - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - struct skb_frag_struct *frag = - &skb_shinfo(skb)->frags[i]; - busaddr = pci_map_page(pdev, frag->page, - frag->page_offset, - frag->size, PCI_DMA_TODEVICE); - wrb = queue_head_node(txq); - wrb_fill(wrb, busaddr, frag->size); - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - queue_head_inc(txq); - copied += frag->size; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + struct skb_frag_struct *frag = + &skb_shinfo(skb)->frags[i]; + busaddr = pci_map_page(pdev, frag->page, + frag->page_offset, + frag->size, PCI_DMA_TODEVICE); + wrb = queue_head_node(txq); + wrb_fill(wrb, busaddr, frag->size); + be_dws_cpu_to_le(wrb, sizeof(*wrb)); + queue_head_inc(txq); + copied += frag->size; + } + skb = skb_shinfo(skb)->frag_list; } if (dummy_wrb) { @@ -743,7 +734,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, if (pktsize <= rx_frag_size) { BUG_ON(num_rcvd != 1); - goto done; + return; } /* More frags present for this completion */ @@ -765,7 +756,6 @@ static void skb_fill_rx_data(struct be_adapter *adapter, memset(page_info, 0, sizeof(*page_info)); } -done: be_rx_stats_update(adapter, pktsize, num_rcvd); return; } @@ -876,19 +866,12 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); + rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; + queue_tail_inc(&adapter->rx_obj.cq); return rxcp; } -/* To reset the valid bit, we need to reset the whole word as - * when walking the queue the valid entries are little-endian - * and invalid entries are host endian - */ -static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp) -{ - rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; -} - static inline struct page *be_alloc_pages(u32 size) { gfp_t alloc_flags = GFP_ATOMIC; @@ -1020,7 +1003,6 @@ static void be_rx_q_clean(struct be_adapter *adapter) /* First cleanup pending rx completions */ while ((rxcp = be_rx_compl_get(adapter)) != NULL) { be_rx_compl_discard(adapter, rxcp); - be_rx_compl_reset(rxcp); be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1); } @@ -1056,13 +1038,8 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) struct be_queue_info *q; q = &adapter->tx_obj.q; - if (q->created) { + if (q->created) be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ); - - /* No more tx completions can be rcvd now; clean up if there - * are any pending completions or pending tx requests */ - be_tx_q_clean(adapter); - } be_queue_free(adapter, q); q = &adapter->tx_obj.cq; @@ -1070,6 +1047,10 @@ static void be_tx_queues_destroy(struct be_adapter *adapter) be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ); be_queue_free(adapter, q); + /* No more tx completions can be rcvd now; clean up if there are + * any pending completions or pending tx requests */ + be_tx_q_clean(adapter); + q = &adapter->tx_eq.q; if (q->created) be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ); @@ -1303,8 +1284,6 @@ int be_poll_rx(struct napi_struct *napi, int budget) be_rx_compl_process_lro(adapter, rxcp); else be_rx_compl_process(adapter, rxcp); - - be_rx_compl_reset(rxcp); } lro_flush_all(&adapter->rx_obj.lro_mgr); @@ -1560,7 +1539,7 @@ static int be_close(struct net_device *netdev) struct be_eq_obj *tx_eq = &adapter->tx_eq; int vec; - cancel_delayed_work_sync(&adapter->work); + cancel_delayed_work(&adapter->work); netif_stop_queue(netdev); netif_carrier_off(netdev); diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index f99e17e0a319..f53017250e09 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -546,7 +546,8 @@ bnx2_free_rx_mem(struct bnx2 *bp) rxr->rx_desc_mapping[j]); rxr->rx_desc_ring[j] = NULL; } - vfree(rxr->rx_buf_ring); + if (rxr->rx_buf_ring) + vfree(rxr->rx_buf_ring); rxr->rx_buf_ring = NULL; for (j = 0; j < bp->rx_max_pg_ring; j++) { @@ -556,7 +557,8 @@ bnx2_free_rx_mem(struct bnx2 *bp) rxr->rx_pg_desc_mapping[j]); rxr->rx_pg_desc_ring[j] = NULL; } - vfree(rxr->rx_pg_ring); + if (rxr->rx_pg_ring) + vfree(rxr->rx_pg_ring); rxr->rx_pg_ring = NULL; } } @@ -5485,7 +5487,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) dev_kfree_skb(skb); return -EIO; } - map = skb_shinfo(skb)->dma_head; + map = skb_shinfo(skb)->dma_maps[0]; REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); @@ -6165,7 +6167,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) } sp = skb_shinfo(skb); - mapping = sp->dma_head; + mapping = sp->dma_maps[0]; tx_buf = &txr->tx_buf_ring[ring_prod]; tx_buf->skb = skb; @@ -6189,7 +6191,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) txbd = &txr->tx_desc_ring[ring_prod]; len = frag->size; - mapping = sp->dma_maps[i]; + mapping = sp->dma_maps[i + 1]; txbd->tx_bd_haddr_hi = (u64) mapping >> 32; txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff; diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index 5fb861a08664..3a1b7b04eb79 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -1541,7 +1541,6 @@ int bond_create_sysfs(void) printk(KERN_ERR "network device named %s already exists in sysfs", class_attr_bonding_masters.attr.name); - ret = 0; } return ret; diff --git a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c index 3373560405ba..aa953fb4b8d0 100644 --- a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c @@ -108,17 +108,15 @@ static int __devinit sja1000_ofp_probe(struct of_device *ofdev, res_size = resource_size(&res); if (!request_mem_region(res.start, res_size, DRV_NAME)) { - dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); + dev_err(&ofdev->dev, "couldn't request %#x..%#x\n", + res.start, res.end); return -EBUSY; } base = ioremap_nocache(res.start, res_size); if (!base) { - dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); + dev_err(&ofdev->dev, "couldn't ioremap %#x..%#x\n", + res.start, res.end); err = -ENOMEM; goto exit_release_mem; } diff --git a/trunk/drivers/net/cxgb3/adapter.h b/trunk/drivers/net/cxgb3/adapter.h index 1694fad38720..e48e508b9632 100644 --- a/trunk/drivers/net/cxgb3/adapter.h +++ b/trunk/drivers/net/cxgb3/adapter.h @@ -253,8 +253,6 @@ struct adapter { struct mutex mdio_lock; spinlock_t stats_lock; spinlock_t work_lock; - - struct sk_buff *nofail_skb; }; static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr) diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 538dda4422dc..aef3ab21f5f7 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -433,78 +433,40 @@ static int init_tp_parity(struct adapter *adap) for (i = 0; i < 16; i++) { struct cpl_smt_write_req *req; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i)); req->iff = i; t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - await_mgmt_replies(adap, cnt, i + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!adap->nofail_skb) - goto alloc_skb_fail; - } } for (i = 0; i < 2048; i++) { struct cpl_l2t_write_req *req; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i)); req->params = htonl(V_L2T_W_IDX(i)); t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - await_mgmt_replies(adap, cnt, 16 + i + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!adap->nofail_skb) - goto alloc_skb_fail; - } } for (i = 0; i < 2048; i++) { struct cpl_rte_write_req *req; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req)); memset(req, 0, sizeof(*req)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i)); req->l2t_idx = htonl(V_L2T_W_IDX(i)); t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!adap->nofail_skb) - goto alloc_skb_fail; - } } - skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - goto alloc_skb_fail; - + skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL); greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq)); memset(greq, 0, sizeof(*greq)); greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); @@ -513,17 +475,8 @@ static int init_tp_parity(struct adapter *adap) t3_mgmt_tx(adap, skb); i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); - if (skb == adap->nofail_skb) { - i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); - adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL); - } - t3_tp_set_offload_mode(adap, 0); return i; - -alloc_skb_fail: - t3_tp_set_offload_mode(adap, 0); - return -ENOMEM; } /** @@ -918,12 +871,7 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, struct mngt_pktsched_wr *req; int ret; - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - skb = adap->nofail_skb; - if (!skb) - return -ENOMEM; - + skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT)); req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET; @@ -933,12 +881,6 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, req->max = hi; req->binding = port; ret = t3_mgmt_tx(adap, skb); - if (skb == adap->nofail_skb) { - adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field), - GFP_KERNEL); - if (!adap->nofail_skb) - ret = -ENOMEM; - } return ret; } @@ -3078,14 +3020,6 @@ static int __devinit init_one(struct pci_dev *pdev, goto out_disable_device; } - adapter->nofail_skb = - alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL); - if (!adapter->nofail_skb) { - dev_err(&pdev->dev, "cannot allocate nofail buffer\n"); - err = -ENOMEM; - goto out_free_adapter; - } - adapter->regs = ioremap_nocache(mmio_start, mmio_len); if (!adapter->regs) { dev_err(&pdev->dev, "cannot map device registers\n"); @@ -3242,8 +3176,6 @@ static void __devexit remove_one(struct pci_dev *pdev) free_netdev(adapter->port[i]); iounmap(adapter->regs); - if (adapter->nofail_skb) - kfree_skb(adapter->nofail_skb); kfree(adapter); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c index f9f54b57b28c..620d80be6aac 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.c @@ -566,31 +566,13 @@ static void t3_process_tid_release_list(struct work_struct *work) spin_unlock_bh(&td->tid_release_lock); skb = alloc_skb(sizeof(struct cpl_tid_release), - GFP_KERNEL); - if (!skb) - skb = td->nofail_skb; - if (!skb) { - spin_lock_bh(&td->tid_release_lock); - p->ctx = (void *)td->tid_release_list; - td->tid_release_list = (struct t3c_tid_entry *)p; - break; - } + GFP_KERNEL | __GFP_NOFAIL); mk_tid_release(skb, p - td->tid_maps.tid_tab); cxgb3_ofld_send(tdev, skb); p->ctx = NULL; - if (skb == td->nofail_skb) - td->nofail_skb = - alloc_skb(sizeof(struct cpl_tid_release), - GFP_KERNEL); spin_lock_bh(&td->tid_release_lock); } - td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1; spin_unlock_bh(&td->tid_release_lock); - - if (!td->nofail_skb) - td->nofail_skb = - alloc_skb(sizeof(struct cpl_tid_release), - GFP_KERNEL); } /* use ctx as a next pointer in the tid release list */ @@ -603,7 +585,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid) p->ctx = (void *)td->tid_release_list; p->client = NULL; td->tid_release_list = p; - if (!p->ctx || td->release_list_incomplete) + if (!p->ctx) schedule_work(&td->tid_release_task); spin_unlock_bh(&td->tid_release_lock); } @@ -1292,9 +1274,6 @@ int cxgb3_offload_activate(struct adapter *adapter) if (list_empty(&adapter_list)) register_netevent_notifier(&nb); - t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL); - t->release_list_incomplete = 0; - add_adapter(adapter); return 0; @@ -1319,8 +1298,6 @@ void cxgb3_offload_deactivate(struct adapter *adapter) T3C_DATA(tdev) = NULL; t3_free_l2t(L2DATA(tdev)); L2DATA(tdev) = NULL; - if (t->nofail_skb) - kfree_skb(t->nofail_skb); kfree(t); } diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.h b/trunk/drivers/net/cxgb3/cxgb3_offload.h index 55945f422aec..a8e8e5fcdf84 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.h +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.h @@ -191,9 +191,6 @@ struct t3c_data { struct t3c_tid_entry *tid_release_list; spinlock_t tid_release_lock; struct work_struct tid_release_task; - - struct sk_buff *nofail_skb; - unsigned int release_list_incomplete; }; /* diff --git a/trunk/drivers/net/declance.c b/trunk/drivers/net/declance.c index 2b22e580c4de..b62405a69180 100644 --- a/trunk/drivers/net/declance.c +++ b/trunk/drivers/net/declance.c @@ -895,7 +895,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; volatile u16 *ib = (volatile u16 *)dev->mem_start; - unsigned long flags; int entry, len; len = skb->len; @@ -908,8 +907,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_bytes += len; - spin_lock_irqsave(&lp->lock, flags); - entry = lp->tx_new; *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; @@ -928,8 +925,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Kick the lance: transmit now */ writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD); - spin_unlock_irqrestore(&lp->lock, flags); - dev->trans_start = jiffies; dev_kfree_skb(skb); diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 119dc5300f9d..0f9ee1348552 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -143,8 +143,6 @@ * FIXES: * 2005/12/02 - Michael O'Donnell * - Stratus87247: protect MDI control register manipulations - * 2009/06/01 - Andreas Mohr - * - add clean lowlevel I/O emulation for cards with MII-lacking PHYs */ #include @@ -374,7 +372,6 @@ enum eeprom_op { enum eeprom_offsets { eeprom_cnfg_mdix = 0x03, - eeprom_phy_iface = 0x06, eeprom_id = 0x0A, eeprom_config_asf = 0x0D, eeprom_smbus_addr = 0x90, @@ -384,18 +381,6 @@ enum eeprom_cnfg_mdix { eeprom_mdix_enabled = 0x0080, }; -enum eeprom_phy_iface { - NoSuchPhy = 0, - I82553AB, - I82553C, - I82503, - DP83840, - S80C240, - S80C24, - I82555, - DP83840A = 10, -}; - enum eeprom_id { eeprom_id_wol = 0x0020, }; @@ -560,7 +545,6 @@ struct nic { u32 msg_enable ____cacheline_aligned; struct net_device *netdev; struct pci_dev *pdev; - u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data); struct rx *rxs ____cacheline_aligned; struct rx *rx_to_use; @@ -915,21 +899,7 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, return err; } -static int mdio_read(struct net_device *netdev, int addr, int reg) -{ - struct nic *nic = netdev_priv(netdev); - return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0); -} - -static void mdio_write(struct net_device *netdev, int addr, int reg, int data) -{ - struct nic *nic = netdev_priv(netdev); - - nic->mdio_ctrl(nic, addr, mdi_write, reg, data); -} - -/* the standard mdio_ctrl() function for usual MII-compliant hardware */ -static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) +static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) { u32 data_out = 0; unsigned int i; @@ -968,83 +938,30 @@ static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data) return (u16)data_out; } -/* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */ -static u16 mdio_ctrl_phy_82552_v(struct nic *nic, - u32 addr, - u32 dir, - u32 reg, - u16 data) -{ - if ((reg == MII_BMCR) && (dir == mdi_write)) { - if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) { - u16 advert = mdio_read(nic->netdev, nic->mii.phy_id, - MII_ADVERTISE); - - /* - * Workaround Si issue where sometimes the part will not - * autoneg to 100Mbps even when advertised. - */ - if (advert & ADVERTISE_100FULL) - data |= BMCR_SPEED100 | BMCR_FULLDPLX; - else if (advert & ADVERTISE_100HALF) - data |= BMCR_SPEED100; - } - } - return mdio_ctrl_hw(nic, addr, dir, reg, data); +static int mdio_read(struct net_device *netdev, int addr, int reg) +{ + return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0); } -/* Fully software-emulated mdio_ctrl() function for cards without - * MII-compliant PHYs. - * For now, this is mainly geared towards 80c24 support; in case of further - * requirements for other types (i82503, ...?) either extend this mechanism - * or split it, whichever is cleaner. - */ -static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic, - u32 addr, - u32 dir, - u32 reg, - u16 data) -{ - /* might need to allocate a netdev_priv'ed register array eventually - * to be able to record state changes, but for now - * some fully hardcoded register handling ought to be ok I guess. */ - - if (dir == mdi_read) { - switch (reg) { - case MII_BMCR: - /* Auto-negotiation, right? */ - return BMCR_ANENABLE | - BMCR_FULLDPLX; - case MII_BMSR: - return BMSR_LSTATUS /* for mii_link_ok() */ | - BMSR_ANEGCAPABLE | - BMSR_10FULL; - case MII_ADVERTISE: - /* 80c24 is a "combo card" PHY, right? */ - return ADVERTISE_10HALF | - ADVERTISE_10FULL; - default: - DPRINTK(HW, DEBUG, - "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n", - dir == mdi_read ? "READ" : "WRITE", addr, reg, data); - return 0xFFFF; - } - } else { - switch (reg) { - default: - DPRINTK(HW, DEBUG, - "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n", - dir == mdi_read ? "READ" : "WRITE", addr, reg, data); - return 0xFFFF; - } - } -} -static inline int e100_phy_supports_mii(struct nic *nic) +static void mdio_write(struct net_device *netdev, int addr, int reg, int data) { - /* for now, just check it by comparing whether we - are using MII software emulation. - */ - return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated); + struct nic *nic = netdev_priv(netdev); + + if ((nic->phy == phy_82552_v) && (reg == MII_BMCR) && + (data & (BMCR_ANRESTART | BMCR_ANENABLE))) { + u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE); + + /* + * Workaround Si issue where sometimes the part will not + * autoneg to 100Mbps even when advertised. + */ + if (advert & ADVERTISE_100FULL) + data |= BMCR_SPEED100 | BMCR_FULLDPLX; + else if (advert & ADVERTISE_100HALF) + data |= BMCR_SPEED100; + } + + mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data); } static void e100_get_defaults(struct nic *nic) @@ -1096,8 +1013,7 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) config->standard_stat_counter = 0x1; /* 1=standard, 0=extended */ config->rx_discard_short_frames = 0x1; /* 1=discard, 0=pass */ config->tx_underrun_retry = 0x3; /* # of underrun retries */ - if (e100_phy_supports_mii(nic)) - config->mii_mode = 1; /* 1=MII mode, 0=i82503 mode */ + config->mii_mode = 0x1; /* 1=MII mode, 0=503 mode */ config->pad10 = 0x6; config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */ config->preamble_length = 0x2; /* 0=1, 1=3, 2=7, 3=15 bytes */ @@ -1354,42 +1270,6 @@ static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb) offsetof(struct mem, dump_buf)); } -static int e100_phy_check_without_mii(struct nic *nic) -{ - u8 phy_type; - int without_mii; - - phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f; - - switch (phy_type) { - case NoSuchPhy: /* Non-MII PHY; UNTESTED! */ - case I82503: /* Non-MII PHY; UNTESTED! */ - case S80C24: /* Non-MII PHY; tested and working */ - /* paragraph from the FreeBSD driver, "FXP_PHY_80C24": - * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter - * doesn't have a programming interface of any sort. The - * media is sensed automatically based on how the link partner - * is configured. This is, in essence, manual configuration. - */ - DPRINTK(PROBE, INFO, - "found MII-less i82503 or 80c24 or other PHY\n"); - - nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated; - nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */ - - /* these might be needed for certain MII-less cards... - * nic->flags |= ich; - * nic->flags |= ich_10h_workaround; */ - - without_mii = 1; - break; - default: - without_mii = 0; - break; - } - return without_mii; -} - #define NCONFIG_AUTO_SWITCH 0x0080 #define MII_NSC_CONG MII_RESV1 #define NSC_CONG_ENABLE 0x0100 @@ -1410,21 +1290,9 @@ static int e100_phy_init(struct nic *nic) if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) break; } - if (addr == 32) { - /* uhoh, no PHY detected: check whether we seem to be some - * weird, rare variant which is *known* to not have any MII. - * But do this AFTER MII checking only, since this does - * lookup of EEPROM values which may easily be unreliable. */ - if (e100_phy_check_without_mii(nic)) - return 0; /* simply return and hope for the best */ - else { - /* for unknown cases log a fatal error */ - DPRINTK(HW, ERR, - "Failed to locate any known PHY, aborting.\n"); - return -EAGAIN; - } - } else - DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); + DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id); + if (addr == 32) + return -EAGAIN; /* Isolate all the PHY ids */ for (addr = 0; addr < 32; addr++) @@ -1452,9 +1320,6 @@ static int e100_phy_init(struct nic *nic) if (nic->phy == phy_82552_v) { u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE); - /* assign special tweaked mdio_ctrl() function */ - nic->mdio_ctrl = mdio_ctrl_phy_82552_v; - /* Workaround Si not advertising flow-control during autoneg */ advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert); @@ -2720,7 +2585,6 @@ static int __devinit e100_probe(struct pci_dev *pdev, nic->netdev = netdev; nic->pdev = pdev; nic->msg_enable = (1 << debug) - 1; - nic->mdio_ctrl = mdio_ctrl_hw; pci_set_drvdata(pdev, netdev); if ((err = pci_enable_device(pdev))) { @@ -2958,13 +2822,12 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - netif_device_detach(netdev); + /* Similar to calling e100_down(), but avoids adapter I/O. */ + e100_close(netdev); - if (state == pci_channel_io_perm_failure) - return PCI_ERS_RESULT_DISCONNECT; - - if (netif_running(netdev)) - e100_down(nic); + /* Detach; put netif into a state similar to hotplug unplug. */ + napi_enable(&nic->napi); + netif_device_detach(netdev); pci_disable_device(pdev); /* Request a slot reset. */ diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index 8d36743c8140..05e87a59f1c6 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -2998,7 +2998,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, size -= 4; buffer_info->length = size; - buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + buffer_info->dma = map[0] + offset; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; @@ -3039,7 +3039,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, size -= 4; buffer_info->length = size; - buffer_info->dma = map[f] + offset; + buffer_info->dma = map[f + 1] + offset; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; diff --git a/trunk/drivers/net/e1000e/82571.c b/trunk/drivers/net/e1000e/82571.c index b53b40ba88a8..c4b3f4fe91ae 100644 --- a/trunk/drivers/net/e1000e/82571.c +++ b/trunk/drivers/net/e1000e/82571.c @@ -71,7 +71,6 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw); static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); static s32 e1000_led_on_82574(struct e1000_hw *hw); -static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); /** * e1000_init_phy_params_82571 - Init PHY func ptrs. @@ -213,9 +212,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct e1000_mac_info *mac = &hw->mac; struct e1000_mac_operations *func = &mac->ops; - u32 swsm = 0; - u32 swsm2 = 0; - bool force_clear_smbi = false; /* Set media type */ switch (adapter->pdev->device) { @@ -280,50 +276,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) break; } - /* - * Ensure that the inter-port SWSM.SMBI lock bit is clear before - * first NVM or PHY acess. This should be done for single-port - * devices, and for one port only on dual-port devices so that - * for those devices we can still use the SMBI lock to synchronize - * inter-port accesses to the PHY & NVM. - */ - switch (hw->mac.type) { - case e1000_82571: - case e1000_82572: - swsm2 = er32(SWSM2); - - if (!(swsm2 & E1000_SWSM2_LOCK)) { - /* Only do this for the first interface on this card */ - ew32(SWSM2, - swsm2 | E1000_SWSM2_LOCK); - force_clear_smbi = true; - } else - force_clear_smbi = false; - break; - default: - force_clear_smbi = true; - break; - } - - if (force_clear_smbi) { - /* Make sure SWSM.SMBI is clear */ - swsm = er32(SWSM); - if (swsm & E1000_SWSM_SMBI) { - /* This bit should not be set on a first interface, and - * indicates that the bootagent or EFI code has - * improperly left this bit enabled - */ - hw_dbg(hw, "Please update your 82571 Bootagent\n"); - } - ew32(SWSM, swsm & ~E1000_SWSM_SMBI); - } - - /* - * Initialze device specific counter of SMBI acquisition - * timeouts. - */ - hw->dev_spec.e82571.smb_counter = 0; - return 0; } @@ -461,37 +413,11 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; - s32 sw_timeout = hw->nvm.word_size + 1; - s32 fw_timeout = hw->nvm.word_size + 1; + s32 timeout = hw->nvm.word_size + 1; s32 i = 0; - /* - * If we have timedout 3 times on trying to acquire - * the inter-port SMBI semaphore, there is old code - * operating on the other port, and it is not - * releasing SMBI. Modify the number of times that - * we try for the semaphore to interwork with this - * older code. - */ - if (hw->dev_spec.e82571.smb_counter > 2) - sw_timeout = 1; - - /* Get the SW semaphore */ - while (i < sw_timeout) { - swsm = er32(SWSM); - if (!(swsm & E1000_SWSM_SMBI)) - break; - - udelay(50); - i++; - } - - if (i == sw_timeout) { - hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n"); - hw->dev_spec.e82571.smb_counter++; - } /* Get the FW semaphore. */ - for (i = 0; i < fw_timeout; i++) { + for (i = 0; i < timeout; i++) { swsm = er32(SWSM); ew32(SWSM, swsm | E1000_SWSM_SWESMBI); @@ -502,9 +428,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) udelay(50); } - if (i == fw_timeout) { + if (i == timeout) { /* Release semaphores */ - e1000_put_hw_semaphore_82571(hw); + e1000e_put_hw_semaphore(hw); hw_dbg(hw, "Driver can't access the NVM\n"); return -E1000_ERR_NVM; } @@ -523,7 +449,9 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) u32 swsm; swsm = er32(SWSM); - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + + swsm &= ~E1000_SWSM_SWESMBI; + ew32(SWSM, swsm); } diff --git a/trunk/drivers/net/e1000e/defines.h b/trunk/drivers/net/e1000e/defines.h index 8890c97e1120..674a47e43034 100644 --- a/trunk/drivers/net/e1000e/defines.h +++ b/trunk/drivers/net/e1000e/defines.h @@ -376,8 +376,6 @@ #define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ #define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ -#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */ - /* Interrupt Cause Read */ #define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ #define E1000_ICR_LSC 0x00000004 /* Link Status Change */ diff --git a/trunk/drivers/net/e1000e/ethtool.c b/trunk/drivers/net/e1000e/ethtool.c index 1bf4d2a5d34f..3d6435617527 100644 --- a/trunk/drivers/net/e1000e/ethtool.c +++ b/trunk/drivers/net/e1000e/ethtool.c @@ -167,15 +167,6 @@ static int e1000_get_settings(struct net_device *netdev, ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; - - /* MDI-X => 2; MDI =>1; Invalid =>0 */ - if ((hw->phy.media_type == e1000_media_type_copper) && - !hw->mac.get_link_status) - ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : - ETH_TP_MDI; - else - ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; - return 0; } diff --git a/trunk/drivers/net/e1000e/hw.h b/trunk/drivers/net/e1000e/hw.h index 163c1c0cfee7..fce3f0529e4c 100644 --- a/trunk/drivers/net/e1000e/hw.h +++ b/trunk/drivers/net/e1000e/hw.h @@ -214,7 +214,6 @@ enum e1e_registers { E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ E1000_SWSM = 0x05B50, /* SW Semaphore */ E1000_FWSM = 0x05B54, /* FW Semaphore */ - E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */ E1000_HICR = 0x08F00, /* Host Interface Control */ }; @@ -884,7 +883,6 @@ struct e1000_fc_info { struct e1000_dev_spec_82571 { bool laa_is_present; bool alt_mac_addr_is_present; - u32 smb_counter; }; struct e1000_shadow_ram { diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 677f60490f67..38694c79edcc 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -2256,6 +2256,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) ew32(TARC(1), tarc); } + e1000e_config_collision_dist(hw); + /* Setup Transmit Descriptor Settings for eop descriptor */ adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; @@ -2268,8 +2270,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) ew32(TCTL, tctl); - e1000e_config_collision_dist(hw); - adapter->tx_queue_len = adapter->netdev->tx_queue_len; } @@ -3916,7 +3916,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, buffer_info->length = size; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + buffer_info->dma = map[0] + offset; count++; len -= size; @@ -3947,7 +3947,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, buffer_info->length = size; buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = map[f] + offset; + buffer_info->dma = map[f + 1] + offset; len -= size; offset += size; diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index ea17319624aa..958b2879da48 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -3139,7 +3139,8 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = skb_shinfo(skb)->dma_head; + buffer_info->dma = map[count]; + count++; for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { struct skb_frag_struct *frag; @@ -3163,7 +3164,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[first].next_to_watch = i; - return count + 1; + return count; } static inline void igb_tx_queue_adv(struct igb_adapter *adapter, diff --git a/trunk/drivers/net/igbvf/netdev.c b/trunk/drivers/net/igbvf/netdev.c index 22aadb7884fa..5f7ba1a4990b 100644 --- a/trunk/drivers/net/igbvf/netdev.c +++ b/trunk/drivers/net/igbvf/netdev.c @@ -2119,7 +2119,8 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; buffer_info->next_to_watch = i; - buffer_info->dma = skb_shinfo(skb)->dma_head; + buffer_info->dma = map[count]; + count++; for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) { struct skb_frag_struct *frag; @@ -2143,7 +2144,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter, tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[first].next_to_watch = i; - return count + 1; + return count; } static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter, diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index 9c897cf86b9f..6eb7f37a113b 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -1300,7 +1300,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, buffer_info->length = size; WARN_ON(buffer_info->dma != 0); buffer_info->time_stamp = jiffies; - buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + buffer_info->dma = map[0] + offset; pci_map_single(adapter->pdev, skb->data + offset, size, @@ -1340,7 +1340,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, buffer_info->length = size; buffer_info->time_stamp = jiffies; - buffer_info->dma = map[f] + offset; + buffer_info->dma = map[f + 1] + offset; buffer_info->next_to_watch = 0; len -= size; diff --git a/trunk/drivers/net/ixgbe/ixgbe_fcoe.c b/trunk/drivers/net/ixgbe/ixgbe_fcoe.c index 3c3bf1f07b81..d5939de8ba28 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/trunk/drivers/net/ixgbe/ixgbe_fcoe.c @@ -280,9 +280,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, * * This checks ddp status. * - * Returns : < 0 indicates an error or not a FCiE ddp, 0 indicates - * not passing the skb to ULD, > 0 indicates is the length of data - * being ddped. + * Returns : 0 for success and skb will not be delivered to ULD */ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc, @@ -336,8 +334,6 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, /* return 0 to bypass going to ULD for DDPed data */ if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP) rc = 0; - else - rc = ddp->len; } ddp_out: diff --git a/trunk/drivers/net/ixgbe/ixgbe_fcoe.h b/trunk/drivers/net/ixgbe/ixgbe_fcoe.h index c5b50026a897..b7f9b63aa49f 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/trunk/drivers/net/ixgbe/ixgbe_fcoe.h @@ -28,7 +28,6 @@ #ifndef _IXGBE_FCOE_H #define _IXGBE_FCOE_H -#include #include /* shift bits within STAT fo FCSTAT */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index a551a96ce676..d36003cbb6d4 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -293,24 +293,12 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, if (cleaned && skb) { unsigned int segs, bytecount; - unsigned int hlen = skb_headlen(skb); /* gso_segs is currently only valid for tcp */ segs = skb_shinfo(skb)->gso_segs ?: 1; -#ifdef IXGBE_FCOE - /* adjust for FCoE Sequence Offload */ - if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) - && (skb->protocol == htons(ETH_P_FCOE)) && - skb_is_gso(skb)) { - hlen = skb_transport_offset(skb) + - sizeof(struct fc_frame_header) + - sizeof(struct fcoe_crc_eof); - segs = DIV_ROUND_UP(skb->len - hlen, - skb_shinfo(skb)->gso_size); - } -#endif /* IXGBE_FCOE */ /* multiply data chunks by size of headers */ - bytecount = ((segs - 1) * hlen) + skb->len; + bytecount = ((segs - 1) * skb_headlen(skb)) + + skb->len; total_packets += segs; total_bytes += bytecount; } @@ -695,9 +683,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, bool cleaned = false; int cleaned_count = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0; -#ifdef IXGBE_FCOE - int ddp_bytes = 0; -#endif /* IXGBE_FCOE */ i = rx_ring->next_to_clean; rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); @@ -808,11 +793,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, skb->protocol = eth_type_trans(skb, adapter->netdev); #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { - ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); - if (!ddp_bytes) + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) + if (!ixgbe_fcoe_ddp(adapter, rx_desc, skb)) goto next_desc; - } #endif /* IXGBE_FCOE */ ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc); @@ -838,21 +821,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (cleaned_count) ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); -#ifdef IXGBE_FCOE - /* include DDPed FCoE data */ - if (ddp_bytes > 0) { - unsigned int mss; - - mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) - - sizeof(struct fc_frame_header) - - sizeof(struct fcoe_crc_eof); - if (mss > 512) - mss &= ~511; - total_rx_bytes += ddp_bytes; - total_rx_packets += DIV_ROUND_UP(ddp_bytes, mss); - } -#endif /* IXGBE_FCOE */ - rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; adapter->net_stats.rx_bytes += total_rx_bytes; @@ -4869,7 +4837,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); tx_buffer_info->length = size; - tx_buffer_info->dma = skb_shinfo(skb)->dma_head + offset; + tx_buffer_info->dma = map[0] + offset; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -4901,7 +4869,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); tx_buffer_info->length = size; - tx_buffer_info->dma = map[f] + offset; + tx_buffer_info->dma = map[f + 1] + offset; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; diff --git a/trunk/drivers/net/ks8842.c b/trunk/drivers/net/ks8842.c deleted file mode 100644 index 39b0aea2aab3..000000000000 --- a/trunk/drivers/net/ks8842.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - * ks8842_main.c timberdale KS8842 ethernet driver - * Copyright (c) 2009 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Supports: - * The Micrel KS8842 behind the timberdale FPGA - */ - -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "ks8842" - -/* Timberdale specific Registers */ -#define REG_TIMB_RST 0x1c - -/* KS8842 registers */ - -#define REG_SELECT_BANK 0x0e - -/* bank 0 registers */ -#define REG_QRFCR 0x04 - -/* bank 2 registers */ -#define REG_MARL 0x00 -#define REG_MARM 0x02 -#define REG_MARH 0x04 - -/* bank 3 registers */ -#define REG_GRR 0x06 - -/* bank 16 registers */ -#define REG_TXCR 0x00 -#define REG_TXSR 0x02 -#define REG_RXCR 0x04 -#define REG_TXMIR 0x08 -#define REG_RXMIR 0x0A - -/* bank 17 registers */ -#define REG_TXQCR 0x00 -#define REG_RXQCR 0x02 -#define REG_TXFDPR 0x04 -#define REG_RXFDPR 0x06 -#define REG_QMU_DATA_LO 0x08 -#define REG_QMU_DATA_HI 0x0A - -/* bank 18 registers */ -#define REG_IER 0x00 -#define IRQ_LINK_CHANGE 0x8000 -#define IRQ_TX 0x4000 -#define IRQ_RX 0x2000 -#define IRQ_RX_OVERRUN 0x0800 -#define IRQ_TX_STOPPED 0x0200 -#define IRQ_RX_STOPPED 0x0100 -#define IRQ_RX_ERROR 0x0080 -#define ENABLED_IRQS (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \ - IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR) -#define REG_ISR 0x02 -#define REG_RXSR 0x04 -#define RXSR_VALID 0x8000 -#define RXSR_BROADCAST 0x80 -#define RXSR_MULTICAST 0x40 -#define RXSR_UNICAST 0x20 -#define RXSR_FRAMETYPE 0x08 -#define RXSR_TOO_LONG 0x04 -#define RXSR_RUNT 0x02 -#define RXSR_CRC_ERROR 0x01 -#define RXSR_ERROR (RXSR_TOO_LONG | RXSR_RUNT | RXSR_CRC_ERROR) - -/* bank 32 registers */ -#define REG_SW_ID_AND_ENABLE 0x00 -#define REG_SGCR1 0x02 -#define REG_SGCR2 0x04 -#define REG_SGCR3 0x06 - -/* bank 39 registers */ -#define REG_MACAR1 0x00 -#define REG_MACAR2 0x02 -#define REG_MACAR3 0x04 - -/* bank 45 registers */ -#define REG_P1MBCR 0x00 -#define REG_P1MBSR 0x02 - -/* bank 46 registers */ -#define REG_P2MBCR 0x00 -#define REG_P2MBSR 0x02 - -/* bank 48 registers */ -#define REG_P1CR2 0x02 - -/* bank 49 registers */ -#define REG_P1CR4 0x02 -#define REG_P1SR 0x04 - -struct ks8842_adapter { - void __iomem *hw_addr; - int irq; - struct tasklet_struct tasklet; - spinlock_t lock; /* spinlock to be interrupt safe */ - struct platform_device *pdev; -}; - -static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank) -{ - iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK); -} - -static inline void ks8842_write8(struct ks8842_adapter *adapter, u16 bank, - u8 value, int offset) -{ - ks8842_select_bank(adapter, bank); - iowrite8(value, adapter->hw_addr + offset); -} - -static inline void ks8842_write16(struct ks8842_adapter *adapter, u16 bank, - u16 value, int offset) -{ - ks8842_select_bank(adapter, bank); - iowrite16(value, adapter->hw_addr + offset); -} - -static inline void ks8842_enable_bits(struct ks8842_adapter *adapter, u16 bank, - u16 bits, int offset) -{ - u16 reg; - ks8842_select_bank(adapter, bank); - reg = ioread16(adapter->hw_addr + offset); - reg |= bits; - iowrite16(reg, adapter->hw_addr + offset); -} - -static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank, - u16 bits, int offset) -{ - u16 reg; - ks8842_select_bank(adapter, bank); - reg = ioread16(adapter->hw_addr + offset); - reg &= ~bits; - iowrite16(reg, adapter->hw_addr + offset); -} - -static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank, - u32 value, int offset) -{ - ks8842_select_bank(adapter, bank); - iowrite32(value, adapter->hw_addr + offset); -} - -static inline u8 ks8842_read8(struct ks8842_adapter *adapter, u16 bank, - int offset) -{ - ks8842_select_bank(adapter, bank); - return ioread8(adapter->hw_addr + offset); -} - -static inline u16 ks8842_read16(struct ks8842_adapter *adapter, u16 bank, - int offset) -{ - ks8842_select_bank(adapter, bank); - return ioread16(adapter->hw_addr + offset); -} - -static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank, - int offset) -{ - ks8842_select_bank(adapter, bank); - return ioread32(adapter->hw_addr + offset); -} - -static void ks8842_reset(struct ks8842_adapter *adapter) -{ - /* The KS8842 goes haywire when doing softare reset - * a work around in the timberdale IP is implemented to - * do a hardware reset instead - ks8842_write16(adapter, 3, 1, REG_GRR); - msleep(10); - iowrite16(0, adapter->hw_addr + REG_GRR); - */ - iowrite16(32, adapter->hw_addr + REG_SELECT_BANK); - iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST); - msleep(20); -} - -static void ks8842_update_link_status(struct net_device *netdev, - struct ks8842_adapter *adapter) -{ - /* check the status of the link */ - if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) { - netif_carrier_on(netdev); - netif_wake_queue(netdev); - } else { - netif_stop_queue(netdev); - netif_carrier_off(netdev); - } -} - -static void ks8842_enable_tx(struct ks8842_adapter *adapter) -{ - ks8842_enable_bits(adapter, 16, 0x01, REG_TXCR); -} - -static void ks8842_disable_tx(struct ks8842_adapter *adapter) -{ - ks8842_clear_bits(adapter, 16, 0x01, REG_TXCR); -} - -static void ks8842_enable_rx(struct ks8842_adapter *adapter) -{ - ks8842_enable_bits(adapter, 16, 0x01, REG_RXCR); -} - -static void ks8842_disable_rx(struct ks8842_adapter *adapter) -{ - ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR); -} - -static void ks8842_reset_hw(struct ks8842_adapter *adapter) -{ - /* reset the HW */ - ks8842_reset(adapter); - - /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */ - ks8842_write16(adapter, 16, 0x000E, REG_TXCR); - - /* enable the receiver, uni + multi + broadcast + flow ctrl - + crc strip */ - ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400, - REG_RXCR); - - /* TX frame pointer autoincrement */ - ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR); - - /* RX frame pointer autoincrement */ - ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR); - - /* RX 2 kb high watermark */ - ks8842_write16(adapter, 0, 0x1000, REG_QRFCR); - - /* aggresive back off in half duplex */ - ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1); - - /* enable no excessive collison drop */ - ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2); - - /* Enable port 1 force flow control / back pressure / transmit / recv */ - ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2); - - /* restart port auto-negotiation */ - ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4); - /* only advertise 10Mbps */ - ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4); - - /* Enable the transmitter */ - ks8842_enable_tx(adapter); - - /* Enable the receiver */ - ks8842_enable_rx(adapter); - - /* clear all interrupts */ - ks8842_write16(adapter, 18, 0xffff, REG_ISR); - - /* enable interrupts */ - ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); - - /* enable the switch */ - ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE); -} - -static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest) -{ - int i; - u16 mac; - - for (i = 0; i < ETH_ALEN; i++) - dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i); - - /* make sure the switch port uses the same MAC as the QMU */ - mac = ks8842_read16(adapter, 2, REG_MARL); - ks8842_write16(adapter, 39, mac, REG_MACAR1); - mac = ks8842_read16(adapter, 2, REG_MARM); - ks8842_write16(adapter, 39, mac, REG_MACAR2); - mac = ks8842_read16(adapter, 2, REG_MARH); - ks8842_write16(adapter, 39, mac, REG_MACAR3); -} - -static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter) -{ - return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff; -} - -static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - int len = skb->len; - u32 *ptr = (u32 *)skb->data; - u32 ctrl; - - dev_dbg(&adapter->pdev->dev, - "%s: len %u head %p data %p tail %p end %p\n", - __func__, skb->len, skb->head, skb->data, - skb_tail_pointer(skb), skb_end_pointer(skb)); - - /* check FIFO buffer space, we need space for CRC and command bits */ - if (ks8842_tx_fifo_space(adapter) < len + 8) - return NETDEV_TX_BUSY; - - /* the control word, enable IRQ, port 1 and the length */ - ctrl = 0x8000 | 0x100 | (len << 16); - ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO); - - netdev->stats.tx_bytes += len; - - /* copy buffer */ - while (len > 0) { - iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO); - len -= sizeof(u32); - ptr++; - } - - /* enqueue packet */ - ks8842_write16(adapter, 17, 1, REG_TXQCR); - - dev_kfree_skb(skb); - - return NETDEV_TX_OK; -} - -static void ks8842_rx_frame(struct net_device *netdev, - struct ks8842_adapter *adapter) -{ - u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO); - int len = (status >> 16) & 0x7ff; - - status &= 0xffff; - - dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n", - __func__, status); - - /* check the status */ - if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) { - struct sk_buff *skb = netdev_alloc_skb(netdev, len + 2); - - dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n", - __func__, len); - if (skb) { - u32 *data; - - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += len; - if (status & RXSR_MULTICAST) - netdev->stats.multicast++; - - /* Align socket buffer in 4-byte boundary for - better performance. */ - skb_reserve(skb, 2); - data = (u32 *)skb_put(skb, len); - - ks8842_select_bank(adapter, 17); - while (len > 0) { - *data++ = ioread32(adapter->hw_addr + - REG_QMU_DATA_LO); - len -= sizeof(u32); - } - - skb->protocol = eth_type_trans(skb, netdev); - netif_rx(skb); - } else - netdev->stats.rx_dropped++; - } else { - dev_dbg(&adapter->pdev->dev, "RX error, status: %x\n", status); - netdev->stats.rx_errors++; - if (status & RXSR_TOO_LONG) - netdev->stats.rx_length_errors++; - if (status & RXSR_CRC_ERROR) - netdev->stats.rx_crc_errors++; - if (status & RXSR_RUNT) - netdev->stats.rx_frame_errors++; - } - - /* set high watermark to 3K */ - ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR); - - /* release the frame */ - ks8842_write16(adapter, 17, 0x01, REG_RXQCR); - - /* set high watermark to 2K */ - ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR); -} - -void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter) -{ - u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; - dev_dbg(&adapter->pdev->dev, "%s Entry - rx_data: %d\n", - __func__, rx_data); - while (rx_data) { - ks8842_rx_frame(netdev, adapter); - rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff; - } -} - -void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter) -{ - u16 sr = ks8842_read16(adapter, 16, REG_TXSR); - dev_dbg(&adapter->pdev->dev, "%s - entry, sr: %x\n", __func__, sr); - netdev->stats.tx_packets++; - if (netif_queue_stopped(netdev)) - netif_wake_queue(netdev); -} - -void ks8842_handle_rx_overrun(struct net_device *netdev, - struct ks8842_adapter *adapter) -{ - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - netdev->stats.rx_errors++; - netdev->stats.rx_fifo_errors++; -} - -void ks8842_tasklet(unsigned long arg) -{ - struct net_device *netdev = (struct net_device *)arg; - struct ks8842_adapter *adapter = netdev_priv(netdev); - u16 isr; - unsigned long flags; - u16 entry_bank; - - /* read current bank to be able to set it back */ - spin_lock_irqsave(&adapter->lock, flags); - entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); - spin_unlock_irqrestore(&adapter->lock, flags); - - isr = ks8842_read16(adapter, 18, REG_ISR); - dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr); - - /* Ack */ - ks8842_write16(adapter, 18, isr, REG_ISR); - - if (!netif_running(netdev)) - return; - - if (isr & IRQ_LINK_CHANGE) - ks8842_update_link_status(netdev, adapter); - - if (isr & (IRQ_RX | IRQ_RX_ERROR)) - ks8842_handle_rx(netdev, adapter); - - if (isr & IRQ_TX) - ks8842_handle_tx(netdev, adapter); - - if (isr & IRQ_RX_OVERRUN) - ks8842_handle_rx_overrun(netdev, adapter); - - if (isr & IRQ_TX_STOPPED) { - ks8842_disable_tx(adapter); - ks8842_enable_tx(adapter); - } - - if (isr & IRQ_RX_STOPPED) { - ks8842_disable_rx(adapter); - ks8842_enable_rx(adapter); - } - - /* re-enable interrupts, put back the bank selection register */ - spin_lock_irqsave(&adapter->lock, flags); - ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER); - iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); - spin_unlock_irqrestore(&adapter->lock, flags); -} - -static irqreturn_t ks8842_irq(int irq, void *devid) -{ - struct ks8842_adapter *adapter = devid; - u16 isr; - u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK); - irqreturn_t ret = IRQ_NONE; - - isr = ks8842_read16(adapter, 18, REG_ISR); - dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr); - - if (isr) { - /* disable IRQ */ - ks8842_write16(adapter, 18, 0x00, REG_IER); - - /* schedule tasklet */ - tasklet_schedule(&adapter->tasklet); - - ret = IRQ_HANDLED; - } - - iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK); - - return ret; -} - - -/* Netdevice operations */ - -static int ks8842_open(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - int err; - - dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__); - - /* reset the HW */ - ks8842_reset_hw(adapter); - - ks8842_update_link_status(netdev, adapter); - - err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME, - adapter); - if (err) { - printk(KERN_ERR "Failed to request IRQ: %d: %d\n", - adapter->irq, err); - return err; - } - - return 0; -} - -static int ks8842_close(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - - dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__); - - /* free the irq */ - free_irq(adapter->irq, adapter); - - /* disable the switch */ - ks8842_write16(adapter, 32, 0x0, REG_SW_ID_AND_ENABLE); - - return 0; -} - -static int ks8842_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - int ret; - struct ks8842_adapter *adapter = netdev_priv(netdev); - - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - - ret = ks8842_tx_frame(skb, netdev); - - if (ks8842_tx_fifo_space(adapter) < netdev->mtu + 8) - netif_stop_queue(netdev); - - return ret; -} - -static int ks8842_set_mac(struct net_device *netdev, void *p) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - struct sockaddr *addr = p; - char *mac = (u8 *)addr->sa_data; - int i; - - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(netdev->dev_addr, mac, netdev->addr_len); - - spin_lock_irqsave(&adapter->lock, flags); - for (i = 0; i < ETH_ALEN; i++) { - ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i); - ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1], - REG_MACAR1 + i); - } - spin_unlock_irqrestore(&adapter->lock, flags); - return 0; -} - -static void ks8842_tx_timeout(struct net_device *netdev) -{ - struct ks8842_adapter *adapter = netdev_priv(netdev); - unsigned long flags; - - dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__); - - spin_lock_irqsave(&adapter->lock, flags); - /* disable interrupts */ - ks8842_write16(adapter, 18, 0, REG_IER); - ks8842_write16(adapter, 18, 0xFFFF, REG_ISR); - spin_unlock_irqrestore(&adapter->lock, flags); - - ks8842_reset_hw(adapter); - - ks8842_update_link_status(netdev, adapter); -} - -static const struct net_device_ops ks8842_netdev_ops = { - .ndo_open = ks8842_open, - .ndo_stop = ks8842_close, - .ndo_start_xmit = ks8842_xmit_frame, - .ndo_set_mac_address = ks8842_set_mac, - .ndo_tx_timeout = ks8842_tx_timeout, - .ndo_validate_addr = eth_validate_addr -}; - -static struct ethtool_ops ks8842_ethtool_ops = { - .get_link = ethtool_op_get_link, -}; - -static int __devinit ks8842_probe(struct platform_device *pdev) -{ - int err = -ENOMEM; - struct resource *iomem; - struct net_device *netdev; - struct ks8842_adapter *adapter; - u16 id; - - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME)) - goto err_mem_region; - - netdev = alloc_etherdev(sizeof(struct ks8842_adapter)); - if (!netdev) - goto err_alloc_etherdev; - - SET_NETDEV_DEV(netdev, &pdev->dev); - - adapter = netdev_priv(netdev); - adapter->hw_addr = ioremap(iomem->start, resource_size(iomem)); - if (!adapter->hw_addr) - goto err_ioremap; - - adapter->irq = platform_get_irq(pdev, 0); - if (adapter->irq < 0) { - err = adapter->irq; - goto err_get_irq; - } - - adapter->pdev = pdev; - - tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev); - spin_lock_init(&adapter->lock); - - netdev->netdev_ops = &ks8842_netdev_ops; - netdev->ethtool_ops = &ks8842_ethtool_ops; - - ks8842_read_mac_addr(adapter, netdev->dev_addr); - - id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE); - - strcpy(netdev->name, "eth%d"); - err = register_netdev(netdev); - if (err) - goto err_register; - - platform_set_drvdata(pdev, netdev); - - printk(KERN_INFO DRV_NAME - " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n", - (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); - - return 0; - -err_register: -err_get_irq: - iounmap(adapter->hw_addr); -err_ioremap: - free_netdev(netdev); -err_alloc_etherdev: - release_mem_region(iomem->start, resource_size(iomem)); -err_mem_region: - return err; -} - -static int __devexit ks8842_remove(struct platform_device *pdev) -{ - struct net_device *netdev = platform_get_drvdata(pdev); - struct ks8842_adapter *adapter = netdev_priv(netdev); - struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - unregister_netdev(netdev); - tasklet_kill(&adapter->tasklet); - iounmap(adapter->hw_addr); - free_netdev(netdev); - release_mem_region(iomem->start, resource_size(iomem)); - platform_set_drvdata(pdev, NULL); - return 0; -} - - -static struct platform_driver ks8842_platform_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ks8842_probe, - .remove = ks8842_remove, -}; - -static int __init ks8842_init(void) -{ - return platform_driver_register(&ks8842_platform_driver); -} - -static void __exit ks8842_exit(void) -{ - platform_driver_unregister(&ks8842_platform_driver); -} - -module_init(ks8842_init); -module_exit(ks8842_exit); - -MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver"); -MODULE_AUTHOR("Mocean Laboratories "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:ks8842"); - diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 99eed9f37c84..021d9941c292 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -359,7 +359,6 @@ static int macvlan_init(struct net_device *dev) (lowerdev->state & MACVLAN_STATE_MASK); dev->features = lowerdev->features & MACVLAN_FEATURES; dev->iflink = lowerdev->ifindex; - dev->hard_header_len = lowerdev->hard_header_len; macvlan_set_lockdep_class(dev); diff --git a/trunk/drivers/net/mdio.c b/trunk/drivers/net/mdio.c index dc45e9856c35..66483035f683 100644 --- a/trunk/drivers/net/mdio.c +++ b/trunk/drivers/net/mdio.c @@ -296,23 +296,6 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || ecmd->speed == SPEED_10000); } - - /* 10GBASE-T MDI/MDI-X */ - if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) { - switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, - MDIO_PMA_10GBT_SWAPPOL)) { - case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: - ecmd->eth_tp_mdix = ETH_TP_MDI; - break; - case 0: - ecmd->eth_tp_mdix = ETH_TP_MDI_X; - break; - default: - /* It's complicated... */ - ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID; - break; - } - } } EXPORT_SYMBOL(mdio45_ethtool_gset_npage); diff --git a/trunk/drivers/net/mlx4/eq.c b/trunk/drivers/net/mlx4/eq.c index dee188761a3c..8830dcb92ec8 100644 --- a/trunk/drivers/net/mlx4/eq.c +++ b/trunk/drivers/net/mlx4/eq.c @@ -623,10 +623,8 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE, (dev->flags & MLX4_FLAG_MSI_X) ? i : 0, &priv->eq_table.eq[i]); - if (err) { - --i; + if (err) goto err_out_unmap; - } } err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE, diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index 6f77ad58e3b3..4a51c31330da 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -178,8 +178,10 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; - vfree(rds_ring->rx_buf_arr); - rds_ring->rx_buf_arr = NULL; + if (rds_ring->rx_buf_arr) { + vfree(rds_ring->rx_buf_arr); + rds_ring->rx_buf_arr = NULL; + } } kfree(recv_ctx->rds_rings); @@ -188,7 +190,8 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) return; tx_ring = adapter->tx_ring; - vfree(tx_ring->cmd_buf_arr); + if (tx_ring->cmd_buf_arr) + vfree(tx_ring->cmd_buf_arr); } int netxen_alloc_sw_resources(struct netxen_adapter *adapter) diff --git a/trunk/drivers/net/qlge/qlge.h b/trunk/drivers/net/qlge/qlge.h index 156e02e8905d..fcb159e4df54 100644 --- a/trunk/drivers/net/qlge/qlge.h +++ b/trunk/drivers/net/qlge/qlge.h @@ -27,8 +27,6 @@ "%s: " fmt, __func__, ##args); \ } while (0) -#define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ - #define QLGE_VENDOR_ID 0x1077 #define QLGE_DEVICE_ID_8012 0x8012 #define QLGE_DEVICE_ID_8000 0x8000 @@ -41,18 +39,7 @@ #define NUM_SMALL_BUFFERS 512 #define NUM_LARGE_BUFFERS 512 -#define DB_PAGE_SIZE 4096 - -/* Calculate the number of (4k) pages required to - * contain a buffer queue of the given length. - */ -#define MAX_DB_PAGES_PER_BQ(x) \ - (((x * sizeof(u64)) / DB_PAGE_SIZE) + \ - (((x * sizeof(u64)) % DB_PAGE_SIZE) ? 1 : 0)) -#define RX_RING_SHADOW_SPACE (sizeof(u64) + \ - MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \ - MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64)) #define SMALL_BUFFER_SIZE 256 #define LARGE_BUFFER_SIZE PAGE_SIZE #define MAX_SPLIT_SIZE 1023 @@ -63,7 +50,7 @@ #define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */ #define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2) #define UDELAY_COUNT 3 -#define UDELAY_DELAY 100 +#define UDELAY_DELAY 10 #define TX_DESC_PER_IOCB 8 @@ -76,16 +63,7 @@ #define TX_DESC_PER_OAL 0 #endif -/* MPI test register definitions. This register - * is used for determining alternate NIC function's - * PCI->func number. - */ -enum { - MPI_TEST_FUNC_PORT_CFG = 0x1002, - MPI_TEST_NIC1_FUNC_SHIFT = 1, - MPI_TEST_NIC2_FUNC_SHIFT = 5, - MPI_TEST_NIC_FUNC_MASK = 0x00000007, -}; +#define DB_PAGE_SIZE 4096 /* * Processor Address Register (PROC_ADDR) bit definitions. @@ -1452,10 +1430,7 @@ struct ql_adapter { /* Hardware information */ u32 chip_rev_id; - u32 fw_rev_id; u32 func; /* PCI function for this adapter */ - u32 alt_func; /* PCI function for alternate adapter */ - u32 port; /* Port number this adapter */ spinlock_t adapter_lock; spinlock_t hw_lock; @@ -1605,8 +1580,6 @@ void ql_mpi_idc_work(struct work_struct *work); void ql_mpi_port_cfg_work(struct work_struct *work); int ql_mb_get_fw_state(struct ql_adapter *qdev); int ql_cam_route_initialize(struct ql_adapter *qdev); -int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data); -int ql_mb_about_fw(struct ql_adapter *qdev); #if 1 #define QL_ALL_DUMP diff --git a/trunk/drivers/net/qlge/qlge_ethtool.c b/trunk/drivers/net/qlge/qlge_ethtool.c index 37c99fe79770..913b2a5fafc9 100644 --- a/trunk/drivers/net/qlge/qlge_ethtool.c +++ b/trunk/drivers/net/qlge/qlge_ethtool.c @@ -293,10 +293,7 @@ static void ql_get_drvinfo(struct net_device *ndev, struct ql_adapter *qdev = netdev_priv(ndev); strncpy(drvinfo->driver, qlge_driver_name, 32); strncpy(drvinfo->version, qlge_driver_version, 32); - snprintf(drvinfo->fw_version, 32, "v%d.%d.%d", - (qdev->fw_rev_id & 0x00ff0000) >> 16, - (qdev->fw_rev_id & 0x0000ff00) >> 8, - (qdev->fw_rev_id & 0x000000ff)); + strncpy(drvinfo->fw_version, "N/A", 32); strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); drvinfo->n_stats = 0; drvinfo->testinfo_len = 0; @@ -404,7 +401,6 @@ const struct ethtool_ops qlge_ethtool_ops = { .get_rx_csum = ql_get_rx_csum, .set_rx_csum = ql_set_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_tso = ethtool_op_get_tso, diff --git a/trunk/drivers/net/qlge/qlge_main.c b/trunk/drivers/net/qlge/qlge_main.c index b9a5f59d6c9b..0b0778d9919c 100644 --- a/trunk/drivers/net/qlge/qlge_main.c +++ b/trunk/drivers/net/qlge/qlge_main.c @@ -675,12 +675,11 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev) int status; __le32 *p = (__le32 *)&qdev->flash; u32 offset; - u8 mac_addr[6]; /* Get flash offset for function and adjust * for dword access. */ - if (!qdev->port) + if (!qdev->func) offset = FUNC0_FLASH_OFFSET / sizeof(u32); else offset = FUNC1_FLASH_OFFSET / sizeof(u32); @@ -706,26 +705,14 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev) goto exit; } - /* Extract either manufacturer or BOFM modified - * MAC address. - */ - if (qdev->flash.flash_params_8000.data_type1 == 2) - memcpy(mac_addr, - qdev->flash.flash_params_8000.mac_addr1, - qdev->ndev->addr_len); - else - memcpy(mac_addr, - qdev->flash.flash_params_8000.mac_addr, - qdev->ndev->addr_len); - - if (!is_valid_ether_addr(mac_addr)) { + if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) { QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n"); status = -EINVAL; goto exit; } memcpy(qdev->ndev->dev_addr, - mac_addr, + qdev->flash.flash_params_8000.mac_addr, qdev->ndev->addr_len); exit: @@ -744,7 +731,7 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev) /* Second function's parameters follow the first * function's. */ - if (qdev->port) + if (qdev->func) offset = size; if (ql_sem_spinlock(qdev, SEM_FLASH_MASK)) @@ -850,13 +837,6 @@ int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data) static int ql_8000_port_initialize(struct ql_adapter *qdev) { int status; - /* - * Get MPI firmware version for driver banner - * and ethool info. - */ - status = ql_mb_about_fw(qdev); - if (status) - goto exit; status = ql_mb_get_fw_state(qdev); if (status) goto exit; @@ -1538,22 +1518,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, return; } - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n", - ib_mac_rsp->flags2); - dev_kfree_skb_any(skb); - return; - } - - /* The max framesize filter on this chip is set higher than - * MTU since FCoE uses 2k frames. - */ - if (skb->len > ndev->mtu + ETH_HLEN) { - dev_kfree_skb_any(skb); - return; - } - prefetch(skb->data); skb->dev = ndev; if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) { @@ -1576,6 +1540,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, * csum or frame errors. */ if (qdev->rx_csum && + !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { /* TCP frame. */ if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { @@ -2237,7 +2202,7 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev, &tx_ring->wq_base_dma); if ((tx_ring->wq_base == NULL) - || tx_ring->wq_base_dma & WQ_ADDR_ALIGN) { + || tx_ring->wq_base_dma & (tx_ring->wq_size - 1)) { QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n"); return -ENOMEM; } @@ -2552,16 +2517,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) { struct cqicb *cqicb = &rx_ring->cqicb; void *shadow_reg = qdev->rx_ring_shadow_reg_area + - (rx_ring->cq_id * RX_RING_SHADOW_SPACE); + (rx_ring->cq_id * sizeof(u64) * 4); u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma + - (rx_ring->cq_id * RX_RING_SHADOW_SPACE); + (rx_ring->cq_id * sizeof(u64) * 4); void __iomem *doorbell_area = qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id)); int err = 0; u16 bq_len; u64 tmp; - __le64 *base_indirect_ptr; - int page_entries; /* Set up the shadow registers for this ring. */ rx_ring->prod_idx_sh_reg = shadow_reg; @@ -2570,8 +2533,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) shadow_reg_dma += sizeof(u64); rx_ring->lbq_base_indirect = shadow_reg; rx_ring->lbq_base_indirect_dma = shadow_reg_dma; - shadow_reg += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); - shadow_reg_dma += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); + shadow_reg += sizeof(u64); + shadow_reg_dma += sizeof(u64); rx_ring->sbq_base_indirect = shadow_reg; rx_ring->sbq_base_indirect_dma = shadow_reg_dma; @@ -2608,14 +2571,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->lbq_len) { cqicb->flags |= FLAGS_LL; /* Load lbq values */ tmp = (u64)rx_ring->lbq_base_dma;; - base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect; - page_entries = 0; - do { - *base_indirect_ptr = cpu_to_le64(tmp); - tmp += DB_PAGE_SIZE; - base_indirect_ptr++; - page_entries++; - } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len)); + *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp); cqicb->lbq_addr = cpu_to_le64(rx_ring->lbq_base_indirect_dma); bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 : @@ -2632,14 +2588,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring) if (rx_ring->sbq_len) { cqicb->flags |= FLAGS_LS; /* Load sbq values */ tmp = (u64)rx_ring->sbq_base_dma;; - base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect; - page_entries = 0; - do { - *base_indirect_ptr = cpu_to_le64(tmp); - tmp += DB_PAGE_SIZE; - base_indirect_ptr++; - page_entries++; - } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->sbq_len)); + *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp); cqicb->sbq_addr = cpu_to_le64(rx_ring->sbq_base_indirect_dma); cqicb->sbq_buf_size = @@ -3236,10 +3185,9 @@ static void ql_display_dev_info(struct net_device *ndev) struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); QPRINTK(qdev, PROBE, INFO, - "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " + "Function #%d, NIC Roll %d, NIC Rev = %d, " "XG Roll = %d, XG Rev = %d.\n", qdev->func, - qdev->port, qdev->chip_rev_id & 0x0000000f, qdev->chip_rev_id >> 4 & 0x0000000f, qdev->chip_rev_id >> 8 & 0x0000000f, @@ -3315,6 +3263,7 @@ static int ql_adapter_up(struct ql_adapter *qdev) err = ql_adapter_initialize(qdev); if (err) { QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n"); + spin_unlock(&qdev->hw_lock); goto err_init; } set_bit(QL_ADAPTER_UP, &qdev->flags); @@ -3411,6 +3360,7 @@ static int ql_configure_rings(struct ql_adapter *qdev) * completion handler rx_rings. */ qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1; + netif_set_gso_max_size(qdev->ndev, 65536); for (i = 0; i < qdev->tx_ring_count; i++) { tx_ring = &qdev->tx_ring[i]; @@ -3693,53 +3643,12 @@ static struct nic_operations qla8000_nic_ops = { .port_initialize = ql_8000_port_initialize, }; -/* Find the pcie function number for the other NIC - * on this chip. Since both NIC functions share a - * common firmware we have the lowest enabled function - * do any common work. Examples would be resetting - * after a fatal firmware error, or doing a firmware - * coredump. - */ -static int ql_get_alt_pcie_func(struct ql_adapter *qdev) -{ - int status = 0; - u32 temp; - u32 nic_func1, nic_func2; - - status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG, - &temp); - if (status) - return status; - - nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) & - MPI_TEST_NIC_FUNC_MASK); - nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) & - MPI_TEST_NIC_FUNC_MASK); - - if (qdev->func == nic_func1) - qdev->alt_func = nic_func2; - else if (qdev->func == nic_func2) - qdev->alt_func = nic_func1; - else - status = -EIO; - - return status; -} -static int ql_get_board_info(struct ql_adapter *qdev) +static void ql_get_board_info(struct ql_adapter *qdev) { - int status; qdev->func = (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT; - if (qdev->func > 3) - return -EIO; - - status = ql_get_alt_pcie_func(qdev); - if (status) - return status; - - qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1; - if (qdev->port) { + if (qdev->func) { qdev->xg_sem_mask = SEM_XGMAC1_MASK; qdev->port_link_up = STS_PL1; qdev->port_init = STS_PI1; @@ -3758,7 +3667,6 @@ static int ql_get_board_info(struct ql_adapter *qdev) qdev->nic_ops = &qla8012_nic_ops; else if (qdev->device_id == QLGE_DEVICE_ID_8000) qdev->nic_ops = &qla8000_nic_ops; - return status; } static void ql_release_all(struct pci_dev *pdev) @@ -3853,12 +3761,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, qdev->ndev = ndev; qdev->pdev = pdev; - err = ql_get_board_info(qdev); - if (err) { - dev_err(&pdev->dev, "Register access failed.\n"); - err = -EIO; - goto err_out; - } + ql_get_board_info(qdev); qdev->msg_enable = netif_msg_init(debug, default_msg); spin_lock_init(&qdev->hw_lock); spin_lock_init(&qdev->stats_lock); diff --git a/trunk/drivers/net/qlge/qlge_mpi.c b/trunk/drivers/net/qlge/qlge_mpi.c index a67c14a7befd..9f81b797f10b 100644 --- a/trunk/drivers/net/qlge/qlge_mpi.c +++ b/trunk/drivers/net/qlge/qlge_mpi.c @@ -90,14 +90,14 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp) */ static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev) { - int count = 100; + int count = 50; /* TODO: arbitrary for now. */ u32 value; do { value = ql_read32(qdev, STS); if (value & STS_PI) return 0; - mdelay(UDELAY_DELAY); /* 100ms */ + udelay(UDELAY_DELAY); /* 10us */ } while (--count); return -ETIMEDOUT; } @@ -453,13 +453,6 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp) } end: ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT); - /* Restore the original mailbox count to - * what the caller asked for. This can get - * changed when a mailbox command is waiting - * for a response and an AEN arrives and - * is handled. - * */ - mbcp->out_count = orig_count; return status; } @@ -547,40 +540,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) return status; } - -/* Get MPI firmware version. This will be used for - * driver banner and for ethtool info. - * Returns zero on success. - */ -int ql_mb_about_fw(struct ql_adapter *qdev) -{ - struct mbox_params mbc; - struct mbox_params *mbcp = &mbc; - int status = 0; - - memset(mbcp, 0, sizeof(struct mbox_params)); - - mbcp->in_count = 1; - mbcp->out_count = 3; - - mbcp->mbox_in[0] = MB_CMD_ABOUT_FW; - - status = ql_mailbox_command(qdev, mbcp); - if (status) - return status; - - if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) { - QPRINTK(qdev, DRV, ERR, - "Failed about firmware command\n"); - status = -EIO; - } - - /* Store the firmware version */ - qdev->fw_rev_id = mbcp->mbox_out[1]; - - return status; -} - /* Get functional state for MPI firmware. * Returns zero on success. */ @@ -795,6 +754,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) { struct ql_adapter *qdev = container_of(work, struct ql_adapter, mpi_port_cfg_work.work); + struct net_device *ndev = qdev->ndev; int status; status = ql_mb_get_port_cfg(qdev); @@ -804,7 +764,9 @@ void ql_mpi_port_cfg_work(struct work_struct *work) goto err; } - if (qdev->link_config & CFG_JUMBO_FRAME_SIZE && + if (ndev->mtu <= 2500) + goto end; + else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE && qdev->max_frame_size == CFG_DEFAULT_MAX_FRAME_SIZE) goto end; @@ -869,19 +831,13 @@ void ql_mpi_work(struct work_struct *work) container_of(work, struct ql_adapter, mpi_work.work); struct mbox_params mbc; struct mbox_params *mbcp = &mbc; - int err = 0; mutex_lock(&qdev->mpi_mutex); while (ql_read32(qdev, STS) & STS_PI) { memset(mbcp, 0, sizeof(struct mbox_params)); mbcp->out_count = 1; - /* Don't continue if an async event - * did not complete properly. - */ - err = ql_mpi_handler(qdev, mbcp); - if (err) - break; + ql_mpi_handler(qdev, mbcp); } mutex_unlock(&qdev->mpi_mutex); diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 007c881896d2..e94316b7868b 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -3379,7 +3379,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev, rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); if (status & LastFrag) { - dev_kfree_skb(tx_skb->skb); + dev_kfree_skb_irq(tx_skb->skb); tx_skb->skb = NULL; } dirty_tx++; diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 458daa06ed41..2bc73ede4312 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -1764,7 +1764,7 @@ static int init_nic(struct s2io_nic *nic) * by then we return error. */ time = 0; - while (true) { + while (TRUE) { val64 = readq(&bar0->rti_command_mem); if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) break; @@ -2137,7 +2137,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) herc = (sp->device_type == XFRAME_II_DEVICE); - if (flag == false) { + if (flag == FALSE) { if ((!herc && (sp->pdev->revision >= 4)) || herc) { if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE)) ret = 1; @@ -3587,7 +3587,7 @@ static void s2io_reset(struct s2io_nic * sp) writeq(val64, &bar0->pcc_err_reg); } - sp->device_enabled_once = false; + sp->device_enabled_once = FALSE; } /** @@ -5572,10 +5572,10 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, val64 = readq(&bar0->rmac_pause_cfg); if (val64 & RMAC_PAUSE_GEN_ENABLE) - ep->tx_pause = true; + ep->tx_pause = TRUE; if (val64 & RMAC_PAUSE_RX_ENABLE) - ep->rx_pause = true; - ep->autoneg = false; + ep->rx_pause = TRUE; + ep->autoneg = FALSE; } /** @@ -6806,7 +6806,7 @@ static void s2io_set_link(struct work_struct *work) val64 |= ADAPTER_LED_ON; writeq(val64, &bar0->adapter_control); } - nic->device_enabled_once = true; + nic->device_enabled_once = TRUE; } else { DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); @@ -7754,7 +7754,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) struct s2io_nic *sp; struct net_device *dev; int i, j, ret; - int dma_flag = false; + int dma_flag = FALSE; u32 mac_up, mac_down; u64 val64 = 0, tmp64 = 0; struct XENA_dev_config __iomem *bar0 = NULL; @@ -7777,7 +7777,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); - dma_flag = true; + dma_flag = TRUE; if (pci_set_consistent_dma_mask (pdev, DMA_BIT_MASK(64))) { DBG_PRINT(ERR_DBG, @@ -7818,7 +7818,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) sp->dev = dev; sp->pdev = pdev; sp->high_dma_flag = dma_flag; - sp->device_enabled_once = false; + sp->device_enabled_once = FALSE; if (rx_ring_mode == 1) sp->rxd_mode = RXD_MODE_1; if (rx_ring_mode == 2) @@ -7964,7 +7964,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - if (sp->high_dma_flag == true) + if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; dev->features |= NETIF_F_TSO; dev->features |= NETIF_F_TSO6; diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index d5c5be6c07b9..55cb943f23f8 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -18,6 +18,15 @@ #define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz)) #define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff) +#ifndef BOOL +#define BOOL int +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + #undef SUCCESS #define SUCCESS 0 #define FAILURE -1 diff --git a/trunk/drivers/net/sfc/tenxpress.c b/trunk/drivers/net/sfc/tenxpress.c index f4d509015f75..db723c58f6f1 100644 --- a/trunk/drivers/net/sfc/tenxpress.c +++ b/trunk/drivers/net/sfc/tenxpress.c @@ -63,7 +63,6 @@ /* extended status register */ #define PMA_PMD_XSTATUS_REG 49153 -#define PMA_PMD_XSTAT_MDIX_LBN 14 #define PMA_PMD_XSTAT_FLP_LBN (12) /* LED control register */ @@ -742,17 +741,9 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); - if (efx->phy_type != PHY_TYPE_SFX7101) { + if (efx->phy_type != PHY_TYPE_SFX7101) ecmd->supported |= (SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full); - if (ecmd->speed != SPEED_10000) { - ecmd->eth_tp_mdix = - (efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XSTATUS_REG) & - (1 << PMA_PMD_XSTAT_MDIX_LBN)) - ? ETH_TP_MDI_X : ETH_TP_MDI; - } - } /* In loopback, the PHY automatically brings up the correct interface, * but doesn't advertise the correct speed. So override it */ diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index e2247669a495..13b8ca41d571 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -47,7 +47,7 @@ #define PHY_ID_ANY 0x1f #define MII_REG_ANY 0x1f -#define DRV_VERSION "1.3" +#define DRV_VERSION "1.2" #define DRV_NAME "sis190" #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION #define PFX DRV_NAME ": " @@ -317,7 +317,6 @@ static struct mii_chip_info { unsigned int type; u32 feature; } mii_chip_table[] = { - { "Atheros PHY", { 0x004d, 0xd010 }, LAN, 0 }, { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 }, { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, @@ -348,7 +347,7 @@ static struct { u32 msg_enable; } debug = { -1 }; -MODULE_DESCRIPTION("SiS sis190/191 Gigabit Ethernet driver"); +MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver"); module_param(rx_copybreak, int, 0); MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param_named(debug, debug.msg_enable, int, 0); @@ -540,8 +539,8 @@ static bool sis190_try_rx_copy(struct sis190_private *tp, if (!skb) goto out; - pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); + pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size, + PCI_DMA_FROMDEVICE); skb_reserve(skb, 2); skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); *sk_buff = skb; @@ -943,9 +942,9 @@ static void sis190_phy_task(struct work_struct *work) u32 ctl; const char *msg; } reg31[] = { - { LPA_1000FULL, 0x07000c00 | 0x00001000, + { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000, "1000 Mbps Full Duplex" }, - { LPA_1000HALF, 0x07000c00, + { LPA_1000XHALF | LPA_SLCT, 0x07000c00, "1000 Mbps Half Duplex" }, { LPA_100FULL, 0x04000800 | 0x00001000, "100 Mbps Full Duplex" }, @@ -956,35 +955,22 @@ static void sis190_phy_task(struct work_struct *work) { LPA_10HALF, 0x04000400, "10 Mbps Half Duplex" }, { 0, 0x04000400, "unknown" } - }, *p = NULL; - u16 adv, autoexp, gigadv, gigrec; + }, *p; + u16 adv; val = mdio_read(ioaddr, phy_id, 0x1f); net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); val = mdio_read(ioaddr, phy_id, MII_LPA); adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); - autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION); - net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n", - dev->name, val, adv, autoexp); - - if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) { - /* check for gigabit speed */ - gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000); - gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000); - val = (gigadv & (gigrec >> 2)); - if (val & ADVERTISE_1000FULL) - p = reg31; - else if (val & ADVERTISE_1000HALF) - p = reg31 + 1; - } - if (!p) { - val &= adv; + net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n", + dev->name, val, adv); - for (p = reg31; p->val; p++) { - if ((val & p->val) == p->val) - break; - } + val &= adv; + + for (p = reg31; p->val; p++) { + if ((val & p->val) == p->val) + break; } p->ctl |= SIS_R32(StationControl) & ~0x0f001c00; @@ -1327,15 +1313,12 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp, ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? LAN : HOME) : p->type; tp->features |= p->feature; - net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", - pci_name(tp->pci_dev), p->name, phy_id); - } else { + } else phy->type = UNKNOWN; - net_probe(tp, KERN_INFO - "%s: unknown PHY 0x%x:0x%x transceiver at address %d\n", - pci_name(tp->pci_dev), - phy->id[0], (phy->id[1] & 0xfff0), phy_id); - } + + net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", + pci_name(tp->pci_dev), + (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); } static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp) diff --git a/trunk/drivers/net/smsc911x.c b/trunk/drivers/net/smsc911x.c index b60639bd181b..3cff84078a9e 100644 --- a/trunk/drivers/net/smsc911x.c +++ b/trunk/drivers/net/smsc911x.c @@ -2155,7 +2155,7 @@ static int smsc911x_resume(struct platform_device *pdev) static struct platform_driver smsc911x_driver = { .probe = smsc911x_drv_probe, - .remove = __devexit_p(smsc911x_drv_remove), + .remove = smsc911x_drv_remove, .driver = { .name = SMSC_CHIPNAME, }, diff --git a/trunk/drivers/net/tehuti.c b/trunk/drivers/net/tehuti.c index 3c2679cd196b..093807a182f2 100644 --- a/trunk/drivers/net/tehuti.c +++ b/trunk/drivers/net/tehuti.c @@ -948,7 +948,8 @@ static void print_rxfd(struct rxf_desc *rxfd); static void bdx_rxdb_destroy(struct rxdb *db) { - vfree(db); + if (db) + vfree(db); } static struct rxdb *bdx_rxdb_create(int nelem) @@ -1481,8 +1482,10 @@ static void bdx_tx_db_close(struct txdb *d) { BDX_ASSERT(d == NULL); - vfree(d->start); - d->start = NULL; + if (d->start) { + vfree(d->start); + d->start = NULL; + } } /************************************************************************* diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 46a3f86125be..a39b534fb43e 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -5021,7 +5021,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, /* New SKB is guaranteed to be linear. */ entry = *start; ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE); - new_addr = skb_shinfo(new_skb)->dma_head; + new_addr = skb_shinfo(new_skb)->dma_maps[0]; /* Make sure new skb does not cross any 4G boundaries. * Drop the packet if it does. @@ -5155,7 +5155,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) sp = skb_shinfo(skb); - mapping = sp->dma_head; + mapping = sp->dma_maps[0]; tp->tx_buffers[entry].skb = skb; @@ -5173,7 +5173,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; len = frag->size; - mapping = sp->dma_maps[i]; + mapping = sp->dma_maps[i + 1]; tp->tx_buffers[entry].skb = NULL; tg3_set_txd(tp, entry, mapping, len, @@ -5331,7 +5331,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) sp = skb_shinfo(skb); - mapping = sp->dma_head; + mapping = sp->dma_maps[0]; tp->tx_buffers[entry].skb = skb; @@ -5356,7 +5356,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; len = frag->size; - mapping = sp->dma_maps[i]; + mapping = sp->dma_maps[i + 1]; tp->tx_buffers[entry].skb = NULL; diff --git a/trunk/drivers/net/tulip/Kconfig b/trunk/drivers/net/tulip/Kconfig index 1cc8cf4425d1..d913405bc393 100644 --- a/trunk/drivers/net/tulip/Kconfig +++ b/trunk/drivers/net/tulip/Kconfig @@ -27,18 +27,6 @@ config DE2104X To compile this driver as a module, choose M here. The module will be called de2104x. -config DE2104X_DSL - int "Descriptor Skip Length in 32 bit longwords" - depends on DE2104X - range 0 31 - default 0 - help - Setting this value allows to align ring buffer descriptors into their - own cache lines. Value of 4 corresponds to the typical 32 byte line - (the descriptor is 16 bytes). This is necessary on systems that lack - cache coherence, an example is PowerMac 5500. Otherwise 0 is safe. - Default is 0, and range is 0 to 31. - config TULIP tristate "DECchip Tulip (dc2114x) PCI support" depends on PCI diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index e7609a05032d..d4c5ecc51f77 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -82,13 +82,6 @@ MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copi NETIF_MSG_RX_ERR | \ NETIF_MSG_TX_ERR) -/* Descriptor skip length in 32 bit longwords. */ -#ifndef CONFIG_DE2104X_DSL -#define DSL 0 -#else -#define DSL CONFIG_DE2104X_DSL -#endif - #define DE_RX_RING_SIZE 64 #define DE_TX_RING_SIZE 64 #define DE_RING_BYTES \ @@ -160,7 +153,6 @@ enum { CmdReset = (1 << 0), CacheAlign16 = 0x00008000, BurstLen4 = 0x00000400, - DescSkipLen = (DSL << 2), /* Rx/TxPoll bits */ NormalTxPoll = (1 << 0), @@ -254,7 +246,7 @@ static const u32 de_intr_mask = * Set the programmable burst length to 4 longwords for all: * DMA errors result without these values. Cache align 16 long. */ -static const u32 de_bus_mode = CacheAlign16 | BurstLen4 | DescSkipLen; +static const u32 de_bus_mode = CacheAlign16 | BurstLen4; struct de_srom_media_block { u8 opts; @@ -274,9 +266,6 @@ struct de_desc { __le32 opts2; __le32 addr1; __le32 addr2; -#if DSL - __le32 skip[DSL]; -#endif }; struct media_info { diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 811d3517fce0..3f0cdc14be82 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -565,13 +565,9 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) return -EFAULT; - if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && - gso.csum_start + gso.csum_offset + 2 > gso.hdr_len) - gso.hdr_len = gso.csum_start + gso.csum_offset + 2; - if (gso.hdr_len > len) return -EINVAL; - offset += sizeof(gso); + offset += sizeof(pi); } if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { @@ -1322,22 +1318,21 @@ static int tun_chr_open(struct inode *inode, struct file * file) static int tun_chr_close(struct inode *inode, struct file *file) { struct tun_file *tfile = file->private_data; - struct tun_struct *tun; + struct tun_struct *tun = __tun_get(tfile); - rtnl_lock(); - tun = __tun_get(tfile); if (tun) { DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); + rtnl_lock(); __tun_detach(tun); /* If desireable, unregister the netdevice. */ if (!(tun->flags & TUN_PERSIST)) unregister_netdevice(tun->dev); + rtnl_unlock(); } - rtnl_unlock(); tun = tfile->tun; if (tun) diff --git a/trunk/drivers/net/usb/hso.c b/trunk/drivers/net/usb/hso.c index e3580f42c899..5ddd8c4f9019 100644 --- a/trunk/drivers/net/usb/hso.c +++ b/trunk/drivers/net/usb/hso.c @@ -899,14 +899,15 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, continue; } /* Allocate an sk_buff */ - odev->skb_rx_buf = netdev_alloc_skb(odev->net, - frame_len); + odev->skb_rx_buf = dev_alloc_skb(frame_len); if (!odev->skb_rx_buf) { /* We got no receive buffer. */ D1("could not allocate memory"); odev->rx_parse_state = WAIT_SYNC; return; } + /* Here's where it came from */ + odev->skb_rx_buf->dev = odev->net; /* Copy what we got so far. make room for iphdr * after tail. */ diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 09bd4410fa65..0c9ca67f66e6 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -470,7 +470,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) } if (skb_is_gso(skb)) { - hdr->hdr_len = skb_headlen(skb); + hdr->hdr_len = skb_transport_header(skb) - skb->data; hdr->gso_size = skb_shinfo(skb)->gso_size; if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4; diff --git a/trunk/drivers/net/vxge/vxge-config.c b/trunk/drivers/net/vxge/vxge-config.c index 26cde573af43..6b41c884a337 100644 --- a/trunk/drivers/net/vxge/vxge-config.c +++ b/trunk/drivers/net/vxge/vxge-config.c @@ -1884,13 +1884,17 @@ void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) mempool->memblock_size, dma_object); } - vfree(mempool->items_arr); + if (mempool->items_arr) + vfree(mempool->items_arr); - vfree(mempool->memblocks_dma_arr); + if (mempool->memblocks_dma_arr) + vfree(mempool->memblocks_dma_arr); - vfree(mempool->memblocks_priv_arr); + if (mempool->memblocks_priv_arr) + vfree(mempool->memblocks_priv_arr); - vfree(mempool->memblocks_arr); + if (mempool->memblocks_arr) + vfree(mempool->memblocks_arr); vfree(mempool); } diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index fb7541c28e58..daf4c805be58 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -153,7 +153,7 @@ config LIBERTAS_SDIO config LIBERTAS_SPI tristate "Marvell Libertas 8686 SPI 802.11b/g cards" - depends on LIBERTAS && SPI + depends on LIBERTAS && SPI && GENERIC_GPIO ---help--- A driver for Marvell Libertas 8686 SPI devices. diff --git a/trunk/drivers/net/wireless/ath/ar9170/ar9170.h b/trunk/drivers/net/wireless/ath/ar9170/ar9170.h index bb97981fb248..c7cba66b63cb 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/trunk/drivers/net/wireless/ath/ar9170/ar9170.h @@ -109,11 +109,6 @@ struct ar9170_rxstream_mpdu_merge { bool has_plcp; }; -#define AR9170_QUEUE_TIMEOUT 64 -#define AR9170_TX_TIMEOUT 8 -#define AR9170_JANITOR_DELAY 128 -#define AR9170_TX_INVALID_RATE 0xffffffff - struct ar9170 { struct ieee80211_hw *hw; struct mutex mutex; @@ -122,11 +117,10 @@ struct ar9170 { int (*open)(struct ar9170 *); void (*stop)(struct ar9170 *); - int (*tx)(struct ar9170 *, struct sk_buff *); + int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int); int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , void *, u32 , void *); void (*callback_cmd)(struct ar9170 *, u32 , void *); - int (*flush)(struct ar9170 *); /* interface mode settings */ struct ieee80211_vif *vif; @@ -183,10 +177,10 @@ struct ar9170 { struct ar9170_eeprom eeprom; struct ath_regulatory regulatory; - /* tx queues - as seen by hw - */ - struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; - struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; - struct delayed_work tx_janitor; + /* global tx status for unregistered Stations. */ + struct sk_buff_head global_tx_status; + struct sk_buff_head global_tx_status_waste; + struct delayed_work tx_status_janitor; /* rxstream mpdu merge */ struct ar9170_rxstream_mpdu_merge rx_mpdu; @@ -195,19 +189,11 @@ struct ar9170 { }; struct ar9170_sta_info { + struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; }; -#define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) -#define AR9170_TX_FLAG_NO_ACK BIT(1) -#define AR9170_TX_FLAG_BLOCK_ACK BIT(2) - -struct ar9170_tx_info { - unsigned long timeout; - unsigned int flags; -}; - -#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) -#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) +#define IS_STARTED(a) (a->state >= AR9170_STARTED) +#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) #define AR9170_FILTER_CHANGED_MODE BIT(0) #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) @@ -218,9 +204,9 @@ void *ar9170_alloc(size_t priv_size); int ar9170_register(struct ar9170 *ar, struct device *pdev); void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); void ar9170_unregister(struct ar9170 *ar); -void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); +void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, + bool update_statistics, u16 tx_status); void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); -int ar9170_nag_limiter(struct ar9170 *ar); /* MAC */ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); diff --git a/trunk/drivers/net/wireless/ath/ar9170/hw.h b/trunk/drivers/net/wireless/ath/ar9170/hw.h index 6cbfb2f83391..3c8004fb7307 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/hw.h +++ b/trunk/drivers/net/wireless/ath/ar9170/hw.h @@ -420,7 +420,4 @@ enum ar9170_txq { __AR9170_NUM_TXQ, }; -#define AR9170_TXQ_DEPTH 32 -#define AR9170_TX_MAX_PENDING 128 - #endif /* __AR9170_HW_H */ diff --git a/trunk/drivers/net/wireless/ath/ar9170/main.c b/trunk/drivers/net/wireless/ath/ar9170/main.c index 9d38cf60a0db..b104d7efd676 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/main.c +++ b/trunk/drivers/net/wireless/ath/ar9170/main.c @@ -173,122 +173,59 @@ static struct ieee80211_supported_band ar9170_band_5GHz = { .ht_cap = AR9170_HT_CAP, }; -static void ar9170_tx(struct ar9170 *ar); - #ifdef AR9170_QUEUE_DEBUG +/* + * In case some wants works with AR9170's crazy tx_status queueing techniques. + * He might need this rather useful probing function. + * + * NOTE: caller must hold the queue's spinlock! + */ + static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) { struct ar9170_tx_control *txc = (void *) skb->data; - struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); - struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; - struct ieee80211_hdr *hdr = (void *) txc->frame_data; + struct ieee80211_hdr *hdr = (void *)txc->frame_data; - printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x " - "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", + printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] " + "mac_control:%04x, phy_control:%08x]\n", wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), - ieee80211_get_DA(hdr), arinfo->flags, - le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), - jiffies_to_msecs(arinfo->timeout - jiffies)); + ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control), + le32_to_cpu(txc->phy_control)); } -static void __ar9170_dump_txqueue(struct ar9170 *ar, - struct sk_buff_head *queue) +static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar, + struct sk_buff_head *queue) { struct sk_buff *skb; int i = 0; printk(KERN_DEBUG "---[ cut here ]---\n"); - printk(KERN_DEBUG "%s: %d entries in queue.\n", + printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n", wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); skb_queue_walk(queue, skb) { - printk(KERN_DEBUG "index:%d => \n", i++); + struct ar9170_tx_control *txc = (void *) skb->data; + struct ieee80211_hdr *hdr = (void *)txc->frame_data; + + printk(KERN_DEBUG "index:%d => \n", i); ar9170_print_txheader(ar, skb); } - if (i != skb_queue_len(queue)) - printk(KERN_DEBUG "WARNING: queue frame counter " - "mismatch %d != %d\n", skb_queue_len(queue), i); printk(KERN_DEBUG "---[ end ]---\n"); } +#endif /* AR9170_QUEUE_DEBUG */ -static void ar9170_dump_txqueue(struct ar9170 *ar, - struct sk_buff_head *queue) -{ - unsigned long flags; - - spin_lock_irqsave(&queue->lock, flags); - __ar9170_dump_txqueue(ar, queue); - spin_unlock_irqrestore(&queue->lock, flags); -} - -static void __ar9170_dump_txstats(struct ar9170 *ar) -{ - int i; - - printk(KERN_DEBUG "%s: QoS queue stats\n", - wiphy_name(ar->hw->wiphy)); - - for (i = 0; i < __AR9170_NUM_TXQ; i++) - printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n", - wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit, - ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i])); -} - -static void ar9170_dump_txstats(struct ar9170 *ar) +void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, + bool valid_status, u16 tx_status) { + struct ieee80211_tx_info *txinfo; + unsigned int retries = 0, queue = skb_get_queue_mapping(skb); unsigned long flags; spin_lock_irqsave(&ar->tx_stats_lock, flags); - __ar9170_dump_txstats(ar); + ar->tx_stats[queue].len--; + if (ieee80211_queue_stopped(ar->hw, queue)) + ieee80211_wake_queue(ar->hw, queue); spin_unlock_irqrestore(&ar->tx_stats_lock, flags); -} -#endif /* AR9170_QUEUE_DEBUG */ - -/* caller must guarantee exclusive access for _bin_ queue. */ -static void ar9170_recycle_expired(struct ar9170 *ar, - struct sk_buff_head *queue, - struct sk_buff_head *bin) -{ - struct sk_buff *skb, *old = NULL; - unsigned long flags; - - spin_lock_irqsave(&queue->lock, flags); - while ((skb = skb_peek(queue))) { - struct ieee80211_tx_info *txinfo; - struct ar9170_tx_info *arinfo; - - txinfo = IEEE80211_SKB_CB(skb); - arinfo = (void *) txinfo->rate_driver_data; - - if (time_is_before_jiffies(arinfo->timeout)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " - "recycle \n", wiphy_name(ar->hw->wiphy), - jiffies, arinfo->timeout); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - __skb_unlink(skb, queue); - __skb_queue_tail(bin, skb); - } else { - break; - } - - if (unlikely(old == skb)) { - /* bail out - queue is shot. */ - - WARN_ON(1); - break; - } - old = skb; - } - spin_unlock_irqrestore(&queue->lock, flags); -} - -static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, - u16 tx_status) -{ - struct ieee80211_tx_info *txinfo; - unsigned int retries = 0; txinfo = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(txinfo); @@ -310,61 +247,45 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, break; } - txinfo->status.rates[0].count = retries + 1; + if (valid_status) + txinfo->status.rates[0].count = retries + 1; + skb_pull(skb, sizeof(struct ar9170_tx_control)); ieee80211_tx_status_irqsafe(ar->hw, skb); } -void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) +static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar, + const u8 *mac, + const u32 queue, + struct sk_buff_head *q) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data; - unsigned int queue = skb_get_queue_mapping(skb); unsigned long flags; + struct sk_buff *skb; - spin_lock_irqsave(&ar->tx_stats_lock, flags); - ar->tx_stats[queue].len--; - - if (skb_queue_empty(&ar->tx_pending[queue])) { -#ifdef AR9170_QUEUE_STOP_DEBUG - printk(KERN_DEBUG "%s: wake queue %d\n", - wiphy_name(ar->hw->wiphy), queue); - __ar9170_dump_txstats(ar); -#endif /* AR9170_QUEUE_STOP_DEBUG */ - ieee80211_wake_queue(ar->hw, queue); - } - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - - if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { - dev_kfree_skb_any(skb); - } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) { - arinfo->timeout = jiffies + - msecs_to_jiffies(AR9170_TX_TIMEOUT); + spin_lock_irqsave(&q->lock, flags); + skb_queue_walk(q, skb) { + struct ar9170_tx_control *txc = (void *) skb->data; + struct ieee80211_hdr *hdr = (void *) txc->frame_data; + u32 txc_queue = (le32_to_cpu(txc->phy_control) & + AR9170_TX_PHY_QOS_MASK) >> + AR9170_TX_PHY_QOS_SHIFT; - skb_queue_tail(&ar->tx_status[queue], skb); - } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) { - ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); - } else { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: unsupported frame flags!\n", - wiphy_name(ar->hw->wiphy)); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - dev_kfree_skb_any(skb); - } + if ((queue != txc_queue) || + (compare_ether_addr(ieee80211_get_DA(hdr), mac))) + continue; - if (!ar->tx_stats[queue].len && - !skb_queue_empty(&ar->tx_pending[queue])) { - ar9170_tx(ar); + __skb_unlink(skb, q); + spin_unlock_irqrestore(&q->lock, flags); + return skb; } + spin_unlock_irqrestore(&q->lock, flags); + return NULL; } -static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, - const u8 *mac, - struct sk_buff_head *queue, - const u32 rate) +static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac, + const u32 queue) { - unsigned long flags; + struct ieee80211_sta *sta; struct sk_buff *skb; /* @@ -375,91 +296,78 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, * the firmware provided (-> destination MAC, and phy_control) - * and hope that we picked the right one... */ - - spin_lock_irqsave(&queue->lock, flags); - skb_queue_walk(queue, skb) { - struct ar9170_tx_control *txc = (void *) skb->data; - struct ieee80211_hdr *hdr = (void *) txc->frame_data; - u32 r; - - if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", - wiphy_name(ar->hw->wiphy), mac, - ieee80211_get_DA(hdr)); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - continue; - } - - r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >> - AR9170_TX_PHY_MCS_SHIFT; - - if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", - wiphy_name(ar->hw->wiphy), rate, r); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - continue; - } - - __skb_unlink(skb, queue); - spin_unlock_irqrestore(&queue->lock, flags); - return skb; + rcu_read_lock(); + sta = ieee80211_find_sta(ar->hw, mac); + + if (likely(sta)) { + struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv; + skb = skb_dequeue(&sta_priv->tx_status[queue]); + rcu_read_unlock(); + if (likely(skb)) + return skb; + } else + rcu_read_unlock(); + + /* scan the waste queue for candidates */ + skb = ar9170_find_skb_in_queue(ar, mac, queue, + &ar->global_tx_status_waste); + if (!skb) { + /* so it still _must_ be in the global list. */ + skb = ar9170_find_skb_in_queue(ar, mac, queue, + &ar->global_tx_status); } #ifdef AR9170_QUEUE_DEBUG - printk(KERN_ERR "%s: ESS:[%pM] does not have any " - "outstanding frames in queue.\n", - wiphy_name(ar->hw->wiphy), mac); - __ar9170_dump_txqueue(ar, queue); + if (unlikely((!skb) && net_ratelimit())) { + printk(KERN_ERR "%s: ESS:[%pM] does not have any " + "outstanding frames in this queue (%d).\n", + wiphy_name(ar->hw->wiphy), mac, queue); + } #endif /* AR9170_QUEUE_DEBUG */ - spin_unlock_irqrestore(&queue->lock, flags); - - return NULL; + return skb; } /* - * This worker tries to keeps an maintain tx_status queues. - * So we can guarantee that incoming tx_status reports are - * actually for a pending frame. + * This worker tries to keep the global tx_status queue empty. + * So we can guarantee that incoming tx_status reports for + * unregistered stations are always synced with the actual + * frame - which we think - belongs to. */ -static void ar9170_tx_janitor(struct work_struct *work) +static void ar9170_tx_status_janitor(struct work_struct *work) { struct ar9170 *ar = container_of(work, struct ar9170, - tx_janitor.work); - struct sk_buff_head waste; - unsigned int i; - bool resched = false; + tx_status_janitor.work); + struct sk_buff *skb; if (unlikely(!IS_STARTED(ar))) return ; - skb_queue_head_init(&waste); - - for (i = 0; i < __AR9170_NUM_TXQ; i++) { + /* recycle the garbage back to mac80211... one by one. */ + while ((skb = skb_dequeue(&ar->global_tx_status_waste))) { #ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", - wiphy_name(ar->hw->wiphy), i); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); - ar9170_dump_txqueue(ar, &ar->tx_status[i]); + printk(KERN_DEBUG "%s: dispose queued frame =>\n", + wiphy_name(ar->hw->wiphy)); + ar9170_print_txheader(ar, skb); #endif /* AR9170_QUEUE_DEBUG */ + ar9170_handle_tx_status(ar, skb, false, + AR9170_TX_STATUS_FAILED); + } - ar9170_recycle_expired(ar, &ar->tx_status[i], &waste); - ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste); - skb_queue_purge(&waste); + while ((skb = skb_dequeue(&ar->global_tx_status))) { +#ifdef AR9170_QUEUE_DEBUG + printk(KERN_DEBUG "%s: moving frame into waste queue =>\n", + wiphy_name(ar->hw->wiphy)); - if (!skb_queue_empty(&ar->tx_status[i]) || - !skb_queue_empty(&ar->tx_pending[i])) - resched = true; + ar9170_print_txheader(ar, skb); +#endif /* AR9170_QUEUE_DEBUG */ + skb_queue_tail(&ar->global_tx_status_waste, skb); } - if (resched) - queue_delayed_work(ar->hw->workqueue, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); + /* recall the janitor in 100ms - if there's garbage in the can. */ + if (skb_queue_len(&ar->global_tx_status_waste) > 0) + queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, + msecs_to_jiffies(100)); } void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) @@ -486,21 +394,15 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) */ struct sk_buff *skb; - u32 phy = le32_to_cpu(cmd->tx_status.rate); - u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> - AR9170_TX_PHY_QOS_SHIFT; -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n", - wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q); -#endif /* AR9170_QUEUE_DEBUG */ + u32 queue = (le32_to_cpu(cmd->tx_status.rate) & + AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT; - skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, - &ar->tx_status[q], - AR9170_TX_INVALID_RATE); + skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue); if (unlikely(!skb)) return ; - ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status)); + ar9170_handle_tx_status(ar, skb, true, + le16_to_cpu(cmd->tx_status.status)); break; } @@ -540,38 +442,6 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) /* retransmission issue / SIFS/EIFS collision ?! */ break; - /* firmware debug */ - case 0xca: - printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4); - break; - case 0xcb: - len -= 4; - - switch (len) { - case 1: - printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n", - *((char *)buf + 4)); - break; - case 2: - printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n", - le16_to_cpup((__le16 *)((char *)buf + 4))); - break; - case 4: - printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n", - le32_to_cpup((__le32 *)((char *)buf + 4))); - break; - case 8: - printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n", - (unsigned long)le64_to_cpup( - (__le64 *)((char *)buf + 4))); - break; - } - break; - case 0xcc: - print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE, - (char *)buf + 4, len - 4); - break; - default: printk(KERN_INFO "received unhandled event %x\n", cmd->type); print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); @@ -585,7 +455,7 @@ static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) ar->rx_mpdu.has_plcp = false; } -int ar9170_nag_limiter(struct ar9170 *ar) +static int ar9170_nag_limiter(struct ar9170 *ar) { bool print_message; @@ -1086,8 +956,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw) /* reinitialize queues statistics */ memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); - for (i = 0; i < __AR9170_NUM_TXQ; i++) - ar->tx_stats[i].limit = AR9170_TXQ_DEPTH; + for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++) + ar->tx_stats[i].limit = 8; /* reset QoS defaults */ AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ @@ -1133,17 +1003,18 @@ static int ar9170_op_start(struct ieee80211_hw *hw) static void ar9170_op_stop(struct ieee80211_hw *hw) { struct ar9170 *ar = hw->priv; - unsigned int i; if (IS_STARTED(ar)) ar->state = AR9170_IDLE; flush_workqueue(ar->hw->workqueue); - cancel_delayed_work_sync(&ar->tx_janitor); + cancel_delayed_work_sync(&ar->tx_status_janitor); cancel_work_sync(&ar->filter_config_work); cancel_work_sync(&ar->beacon_work); mutex_lock(&ar->mutex); + skb_queue_purge(&ar->global_tx_status_waste); + skb_queue_purge(&ar->global_tx_status); if (IS_ACCEPTING_CMD(ar)) { ar9170_set_leds_state(ar, 0); @@ -1153,32 +1024,51 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) ar->stop(ar); } - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - skb_queue_purge(&ar->tx_pending[i]); - skb_queue_purge(&ar->tx_status[i]); - } mutex_unlock(&ar->mutex); } -static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) +int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { + struct ar9170 *ar = hw->priv; struct ieee80211_hdr *hdr; struct ar9170_tx_control *txc; struct ieee80211_tx_info *info; + struct ieee80211_rate *rate = NULL; struct ieee80211_tx_rate *txrate; - struct ar9170_tx_info *arinfo; unsigned int queue = skb_get_queue_mapping(skb); + unsigned long flags = 0; + struct ar9170_sta_info *sta_info = NULL; + u32 power, chains; u16 keytype = 0; u16 len, icv = 0; + int err; + bool tx_status; - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); + if (unlikely(!IS_STARTED(ar))) + goto err_free; hdr = (void *)skb->data; info = IEEE80211_SKB_CB(skb); len = skb->len; + spin_lock_irqsave(&ar->tx_stats_lock, flags); + if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) { + spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + return NETDEV_TX_OK; + } + + ar->tx_stats[queue].len++; + ar->tx_stats[queue].count++; + if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len) + ieee80211_stop_queue(hw, queue); + + spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + txc = (void *)skb_push(skb, sizeof(*txc)); + tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) || + ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0)); + if (info->control.hw_key) { icv = info->control.hw_key->icv_len; @@ -1194,7 +1084,7 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) break; default: WARN_ON(1); - goto err_out; + goto err_dequeue; } } @@ -1211,65 +1101,16 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_NO_ACK) txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); + txrate = &info->control.rates[0]; + if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); - arinfo = (void *)info->rate_driver_data; - arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT); - - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && - (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - if (unlikely(!info->control.sta)) - goto err_out; - - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); - arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK; - goto out; - } - - txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); - /* - * WARNING: - * Putting the QoS queue bits into an unexplored territory is - * certainly not elegant. - * - * In my defense: This idea provides a reasonable way to - * smuggle valuable information to the tx_status callback. - * Also, the idea behind this bit-abuse came straight from - * the original driver code. - */ - - txc->phy_control |= - cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); - arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; - } else { - arinfo->flags = AR9170_TX_FLAG_NO_ACK; - } - -out: - return 0; - -err_out: - skb_pull(skb, sizeof(*txc)); - return -EINVAL; -} - -static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) -{ - struct ar9170_tx_control *txc; - struct ieee80211_tx_info *info; - struct ieee80211_rate *rate = NULL; - struct ieee80211_tx_rate *txrate; - u32 power, chains; - - txc = (void *) skb->data; - info = IEEE80211_SKB_CB(skb); - txrate = &info->control.rates[0]; - if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); @@ -1289,12 +1130,9 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) u32 r = txrate->idx; u8 *txpower; - /* heavy clip control */ - txc->phy_control |= cpu_to_le32((r & 0x7) << 7); - r <<= AR9170_TX_PHY_MCS_SHIFT; - BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK); - + if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK)) + goto err_dequeue; txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); @@ -1356,154 +1194,53 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) chains = AR9170_TX_PHY_TXCHAIN_1; } txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); -} - -static void ar9170_tx(struct ar9170 *ar) -{ - struct sk_buff *skb; - unsigned long flags; - struct ieee80211_tx_info *info; - struct ar9170_tx_info *arinfo; - unsigned int i, frames, frames_failed, remaining_space; - int err; - bool schedule_garbagecollector = false; - - BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); - - if (unlikely(!IS_STARTED(ar))) - return ; - - remaining_space = AR9170_TX_MAX_PENDING; - - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - spin_lock_irqsave(&ar->tx_stats_lock, flags); - if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: queue %d full\n", - wiphy_name(ar->hw->wiphy), i); - - __ar9170_dump_txstats(ar); - printk(KERN_DEBUG "stuck frames: ===> \n"); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); - ar9170_dump_txqueue(ar, &ar->tx_status[i]); -#endif /* AR9170_QUEUE_DEBUG */ - ieee80211_stop_queue(ar->hw, i); - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - continue; - } - - frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, - skb_queue_len(&ar->tx_pending[i])); - - if (remaining_space < frames) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: tx quota reached queue:%d, " - "remaining slots:%d, needed:%d\n", - wiphy_name(ar->hw->wiphy), i, remaining_space, - frames); - - ar9170_dump_txstats(ar); -#endif /* AR9170_QUEUE_DEBUG */ - frames = remaining_space; - } - - ar->tx_stats[i].len += frames; - ar->tx_stats[i].count += frames; - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); - - if (!frames) - continue; - - frames_failed = 0; - while (frames) { - skb = skb_dequeue(&ar->tx_pending[i]); - if (unlikely(!skb)) { - frames_failed += frames; - frames = 0; - break; - } - - info = IEEE80211_SKB_CB(skb); - arinfo = (void *) info->rate_driver_data; - - /* TODO: cancel stuck frames */ - arinfo->timeout = jiffies + - msecs_to_jiffies(AR9170_TX_TIMEOUT); - -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: send frame q:%d =>\n", - wiphy_name(ar->hw->wiphy), i); - ar9170_print_txheader(ar, skb); -#endif /* AR9170_QUEUE_DEBUG */ - err = ar->tx(ar, skb); - if (unlikely(err)) { - frames_failed++; - dev_kfree_skb_any(skb); - } else { - remaining_space--; - schedule_garbagecollector = true; - } - - frames--; - } - -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", - wiphy_name(ar->hw->wiphy), i); + if (tx_status) { + txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); + /* + * WARNING: + * Putting the QoS queue bits into an unexplored territory is + * certainly not elegant. + * + * In my defense: This idea provides a reasonable way to + * smuggle valuable information to the tx_status callback. + * Also, the idea behind this bit-abuse came straight from + * the original driver code. + */ - printk(KERN_DEBUG "%s: unprocessed pending frames left:\n", - wiphy_name(ar->hw->wiphy)); - ar9170_dump_txqueue(ar, &ar->tx_pending[i]); -#endif /* AR9170_QUEUE_DEBUG */ + txc->phy_control |= + cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); - if (unlikely(frames_failed)) { -#ifdef AR9170_QUEUE_DEBUG - printk(KERN_DEBUG "%s: frames failed =>\n", - wiphy_name(ar->hw->wiphy), frames_failed); -#endif /* AR9170_QUEUE_DEBUG */ + if (info->control.sta) { + sta_info = (void *) info->control.sta->drv_priv; + skb_queue_tail(&sta_info->tx_status[queue], skb); + } else { + skb_queue_tail(&ar->global_tx_status, skb); - spin_lock_irqsave(&ar->tx_stats_lock, flags); - ar->tx_stats[i].len -= frames_failed; - ar->tx_stats[i].count -= frames_failed; - ieee80211_wake_queue(ar->hw, i); - spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + queue_delayed_work(ar->hw->workqueue, + &ar->tx_status_janitor, + msecs_to_jiffies(100)); } } - if (schedule_garbagecollector) - queue_delayed_work(ar->hw->workqueue, - &ar->tx_janitor, - msecs_to_jiffies(AR9170_JANITOR_DELAY)); -} - -int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct ar9170 *ar = hw->priv; - struct ieee80211_tx_info *info; - - if (unlikely(!IS_STARTED(ar))) - goto err_free; - - if (unlikely(ar9170_tx_prepare(ar, skb))) - goto err_free; - - info = IEEE80211_SKB_CB(skb); - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - /* drop frame, we do not allow TX A-MPDU aggregation yet. */ - goto err_free; - } else { - unsigned int queue = skb_get_queue_mapping(skb); - - ar9170_tx_prepare_phy(ar, skb); - skb_queue_tail(&ar->tx_pending[queue], skb); + err = ar->tx(ar, skb, tx_status, 0); + if (unlikely(tx_status && err)) { + if (info->control.sta) + skb_unlink(skb, &sta_info->tx_status[queue]); + else + skb_unlink(skb, &ar->global_tx_status); } - ar9170_tx(ar); return NETDEV_TX_OK; +err_dequeue: + spin_lock_irqsave(&ar->tx_stats_lock, flags); + ar->tx_stats[queue].len--; + ar->tx_stats[queue].count--; + spin_unlock_irqrestore(&ar->tx_stats_lock, flags); + err_free: - dev_kfree_skb_any(skb); + dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -1929,6 +1666,43 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { + struct ar9170 *ar = hw->priv; + struct ar9170_sta_info *info = (void *) sta->drv_priv; + struct sk_buff *skb; + unsigned int i; + + switch (cmd) { + case STA_NOTIFY_ADD: + for (i = 0; i < ar->hw->queues; i++) + skb_queue_head_init(&info->tx_status[i]); + break; + + case STA_NOTIFY_REMOVE: + + /* + * transfer all outstanding frames that need a tx_status + * reports to the global tx_status queue + */ + + for (i = 0; i < ar->hw->queues; i++) { + while ((skb = skb_dequeue(&info->tx_status[i]))) { +#ifdef AR9170_QUEUE_DEBUG + printk(KERN_DEBUG "%s: queueing frame in " + "global tx_status queue =>\n", + wiphy_name(ar->hw->wiphy)); + + ar9170_print_txheader(ar, skb); +#endif /* AR9170_QUEUE_DEBUG */ + skb_queue_tail(&ar->global_tx_status, skb); + } + } + queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, + msecs_to_jiffies(100)); + break; + + default: + break; + } } static int ar9170_get_stats(struct ieee80211_hw *hw, @@ -1967,7 +1741,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, int ret; mutex_lock(&ar->mutex); - if ((param) && !(queue > __AR9170_NUM_TXQ)) { + if ((param) && !(queue > ar->hw->queues)) { memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], param, sizeof(*param)); @@ -2043,14 +1817,12 @@ void *ar9170_alloc(size_t priv_size) mutex_init(&ar->mutex); spin_lock_init(&ar->cmdlock); spin_lock_init(&ar->tx_stats_lock); - for (i = 0; i < __AR9170_NUM_TXQ; i++) { - skb_queue_head_init(&ar->tx_status[i]); - skb_queue_head_init(&ar->tx_pending[i]); - } + skb_queue_head_init(&ar->global_tx_status); + skb_queue_head_init(&ar->global_tx_status_waste); ar9170_rx_reset_rx_mpdu(ar); INIT_WORK(&ar->filter_config_work, ar9170_set_filters); INIT_WORK(&ar->beacon_work, ar9170_new_beacon); - INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); + INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); /* all hw supports 2.4 GHz, so set channel to 1 by default */ ar->channel = &ar9170_2ghz_chantable[0]; diff --git a/trunk/drivers/net/wireless/ath/ar9170/usb.c b/trunk/drivers/net/wireless/ath/ar9170/usb.c index 754b1f8d8da9..f752698669d2 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/usb.c +++ b/trunk/drivers/net/wireless/ath/ar9170/usb.c @@ -96,49 +96,7 @@ static struct usb_device_id ar9170_usb_ids[] = { }; MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); -static void ar9170_usb_submit_urb(struct ar9170_usb *aru) -{ - struct urb *urb; - unsigned long flags; - int err; - - if (unlikely(!IS_STARTED(&aru->common))) - return ; - - spin_lock_irqsave(&aru->tx_urb_lock, flags); - if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) { - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - return ; - } - aru->tx_submitted_urbs++; - - urb = usb_get_from_anchor(&aru->tx_pending); - if (!urb) { - aru->tx_submitted_urbs--; - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - - return ; - } - spin_unlock_irqrestore(&aru->tx_urb_lock, flags); - - aru->tx_pending_urbs--; - usb_anchor_urb(urb, &aru->tx_submitted); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) { - if (ar9170_nag_limiter(&aru->common)) - dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", - err); - - usb_unanchor_urb(urb); - aru->tx_submitted_urbs--; - ar9170_tx_callback(&aru->common, urb->context); - } - - usb_free_urb(urb); -} - -static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) +static void ar9170_usb_tx_urb_complete_free(struct urb *urb) { struct sk_buff *skb = urb->context; struct ar9170_usb *aru = (struct ar9170_usb *) @@ -149,11 +107,8 @@ static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) return ; } - aru->tx_submitted_urbs--; - - ar9170_tx_callback(&aru->common, skb); - - ar9170_usb_submit_urb(aru); + ar9170_handle_tx_status(&aru->common, skb, false, + AR9170_TX_STATUS_COMPLETE); } static void ar9170_usb_tx_urb_complete(struct urb *urb) @@ -335,47 +290,21 @@ static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru) return err; } -static int ar9170_usb_flush(struct ar9170 *ar) +static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) { - struct ar9170_usb *aru = (void *) ar; - struct urb *urb; - int ret, err = 0; + int ret; - if (IS_STARTED(ar)) - aru->common.state = AR9170_IDLE; + aru->common.state = AR9170_UNKNOWN_STATE; - usb_wait_anchor_empty_timeout(&aru->tx_pending, - msecs_to_jiffies(800)); - while ((urb = usb_get_from_anchor(&aru->tx_pending))) { - ar9170_tx_callback(&aru->common, (void *) urb->context); - usb_free_urb(urb); - } + usb_unlink_anchored_urbs(&aru->tx_submitted); - /* lets wait a while until the tx - queues are dried out */ + /* give the LED OFF command and the deauth frame a chance to air. */ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, msecs_to_jiffies(100)); if (ret == 0) - err = -ETIMEDOUT; - - usb_kill_anchored_urbs(&aru->tx_submitted); - - if (IS_ACCEPTING_CMD(ar)) - aru->common.state = AR9170_STARTED; - - return err; -} - -static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) -{ - int err; - - aru->common.state = AR9170_UNKNOWN_STATE; - - err = ar9170_usb_flush(&aru->common); - if (err) - dev_err(&aru->udev->dev, "stuck tx urbs!\n"); - + dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); + usb_poison_anchored_urbs(&aru->rx_submitted); } @@ -459,10 +388,12 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, return err; } -static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) +static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, + bool txstatus_needed, unsigned int extra_len) { struct ar9170_usb *aru = (struct ar9170_usb *) ar; struct urb *urb; + int err; if (unlikely(!IS_STARTED(ar))) { /* Seriously, what were you drink... err... thinking!? */ @@ -475,17 +406,18 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) usb_fill_bulk_urb(urb, aru->udev, usb_sndbulkpipe(aru->udev, AR9170_EP_TX), - skb->data, skb->len, - ar9170_usb_tx_urb_complete_frame, skb); + skb->data, skb->len + extra_len, (txstatus_needed ? + ar9170_usb_tx_urb_complete : + ar9170_usb_tx_urb_complete_free), skb); urb->transfer_flags |= URB_ZERO_PACKET; - usb_anchor_urb(urb, &aru->tx_pending); - aru->tx_pending_urbs++; + usb_anchor_urb(urb, &aru->tx_submitted); + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) + usb_unanchor_urb(urb); usb_free_urb(urb); - - ar9170_usb_submit_urb(aru); - return 0; + return err; } static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) @@ -685,8 +617,10 @@ static void ar9170_usb_stop(struct ar9170 *ar) if (IS_ACCEPTING_CMD(ar)) aru->common.state = AR9170_STOPPED; - ret = ar9170_usb_flush(ar); - if (ret) + /* lets wait a while until the tx - queues are dried out */ + ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, + msecs_to_jiffies(1000)); + if (ret == 0) dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); @@ -782,16 +716,10 @@ static int ar9170_usb_probe(struct usb_interface *intf, SET_IEEE80211_DEV(ar->hw, &udev->dev); init_usb_anchor(&aru->rx_submitted); - init_usb_anchor(&aru->tx_pending); init_usb_anchor(&aru->tx_submitted); init_completion(&aru->cmd_wait); - spin_lock_init(&aru->tx_urb_lock); - - aru->tx_pending_urbs = 0; - aru->tx_submitted_urbs = 0; aru->common.stop = ar9170_usb_stop; - aru->common.flush = ar9170_usb_flush; aru->common.open = ar9170_usb_open; aru->common.tx = ar9170_usb_tx; aru->common.exec_cmd = ar9170_usb_exec_cmd; diff --git a/trunk/drivers/net/wireless/ath/ar9170/usb.h b/trunk/drivers/net/wireless/ath/ar9170/usb.h index d098f4d5d2f2..69f4bceb0af3 100644 --- a/trunk/drivers/net/wireless/ath/ar9170/usb.h +++ b/trunk/drivers/net/wireless/ath/ar9170/usb.h @@ -51,7 +51,6 @@ #include "ar9170.h" #define AR9170_NUM_RX_URBS 16 -#define AR9170_NUM_TX_URBS 8 struct firmware; @@ -61,15 +60,11 @@ struct ar9170_usb { struct usb_interface *intf; struct usb_anchor rx_submitted; - struct usb_anchor tx_pending; struct usb_anchor tx_submitted; bool req_one_stage_fw; - spinlock_t tx_urb_lock; - unsigned int tx_submitted_urbs; - unsigned int tx_pending_urbs; - + spinlock_t cmdlock; struct completion cmd_wait; int readlen; u8 *readbuf; diff --git a/trunk/drivers/net/wireless/ath/ath5k/Makefile b/trunk/drivers/net/wireless/ath/ath5k/Makefile index 090dc6d268a3..84a74c5248e5 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/Makefile +++ b/trunk/drivers/net/wireless/ath/ath5k/Makefile @@ -11,6 +11,5 @@ ath5k-y += reset.o ath5k-y += attach.o ath5k-y += base.o ath5k-y += led.o -ath5k-y += rfkill.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/trunk/drivers/net/wireless/ath/ath5k/ath5k.h b/trunk/drivers/net/wireless/ath/ath5k/ath5k.h index 6358233bac99..813718210338 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/trunk/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1256,10 +1256,6 @@ extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); -/* rfkill Functions */ -extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); -extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); - /* Misc functions */ int ath5k_hw_set_capabilities(struct ath5k_hw *ah); extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 55f7de09d134..85a00db4867d 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -2360,8 +2360,6 @@ ath5k_init(struct ath5k_softc *sc) if (ret) goto done; - ath5k_rfkill_hw_start(ah); - /* * Reset the key cache since some parts do not reset the * contents on initial power up or resume from suspend. @@ -2470,8 +2468,6 @@ ath5k_stop_hw(struct ath5k_softc *sc) tasklet_kill(&sc->restq); tasklet_kill(&sc->beacontq); - ath5k_rfkill_hw_stop(sc->ah); - return ret; } @@ -2530,9 +2526,6 @@ ath5k_intr(int irq, void *dev_id) */ ath5k_hw_update_mib_counters(ah, &sc->ll_stats); } - if (status & AR5K_INT_GPIO) - tasklet_schedule(&sc->rf_kill.toggleq); - } } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.h b/trunk/drivers/net/wireless/ath/ath5k/base.h index f9b7f2f819b7..852b2c189fd8 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.h +++ b/trunk/drivers/net/wireless/ath/ath5k/base.h @@ -46,7 +46,6 @@ #include #include #include -#include #include "ath5k.h" #include "debug.h" @@ -92,15 +91,6 @@ struct ath5k_led struct led_classdev led_dev; /* led classdev */ }; -/* Rfkill */ -struct ath5k_rfkill { - /* GPIO PIN for rfkill */ - u16 gpio; - /* polarity of rfkill GPIO PIN */ - bool polarity; - /* RFKILL toggle tasklet */ - struct tasklet_struct toggleq; -}; #if CHAN_DEBUG #define ATH_CHAN_MAX (26+26+26+200+200) @@ -177,8 +167,6 @@ struct ath5k_softc { struct tasklet_struct txtq; /* tx intr tasklet */ struct ath5k_led tx_led; /* tx led */ - struct ath5k_rfkill rf_kill; - spinlock_t block; /* protects beacon */ struct tasklet_struct beacontq; /* beacon intr tasklet */ struct ath5k_buf *bbuf; /* beacon buffer */ diff --git a/trunk/drivers/net/wireless/ath/ath5k/reset.c b/trunk/drivers/net/wireless/ath/ath5k/reset.c index bd0a97a38d34..66067733ddd3 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/reset.c +++ b/trunk/drivers/net/wireless/ath/ath5k/reset.c @@ -1304,6 +1304,23 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, if (ah->ah_version != AR5K_AR5210) ath5k_hw_set_imr(ah, ah->ah_imr); + /* + * Setup RFKill interrupt if rfkill flag is set on eeprom. + * TODO: Use gpio pin and polarity infos from eeprom + * TODO: Handle this in ath5k_intr because it'll result + * a nasty interrupt storm. + */ +#if 0 + if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { + ath5k_hw_set_gpio_input(ah, 0); + ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); + if (ah->ah_gpio[0] == 0) + ath5k_hw_set_gpio_intr(ah, 0, 1); + else + ath5k_hw_set_gpio_intr(ah, 0, 0); + } +#endif + /* Enable 32KHz clock function for AR5212+ chips * Set clocks to 32KHz operation and use an * external 32KHz crystal when sleeping if one diff --git a/trunk/drivers/net/wireless/ath/ath5k/rfkill.c b/trunk/drivers/net/wireless/ath/ath5k/rfkill.c deleted file mode 100644 index 41a877b73fce..000000000000 --- a/trunk/drivers/net/wireless/ath/ath5k/rfkill.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * RFKILL support for ath5k - * - * Copyright (c) 2009 Tobias Doerffel - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGES. - */ - -#include "base.h" - - -static inline void ath5k_rfkill_disable(struct ath5k_softc *sc) -{ - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n", - sc->rf_kill.gpio, sc->rf_kill.polarity); - ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); - ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity); -} - - -static inline void ath5k_rfkill_enable(struct ath5k_softc *sc) -{ - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n", - sc->rf_kill.gpio, sc->rf_kill.polarity); - ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); - ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity); -} - -static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable) -{ - struct ath5k_hw *ah = sc->ah; - u32 curval; - - ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio); - curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio); - ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ? - !!curval : !curval); -} - -static bool -ath5k_is_rfkill_set(struct ath5k_softc *sc) -{ - /* configuring GPIO for input for some reason disables rfkill */ - /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/ - return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) == - sc->rf_kill.polarity; -} - -static void -ath5k_tasklet_rfkill_toggle(unsigned long data) -{ - struct ath5k_softc *sc = (void *)data; - bool blocked; - - blocked = ath5k_is_rfkill_set(sc); - wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked); -} - - -void -ath5k_rfkill_hw_start(struct ath5k_hw *ah) -{ - struct ath5k_softc *sc = ah->ah_sc; - - /* read rfkill GPIO configuration from EEPROM header */ - sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin; - sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol; - - tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle, - (unsigned long)sc); - - ath5k_rfkill_disable(sc); - - /* enable interrupt for rfkill switch */ - if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) - ath5k_rfkill_set_intr(sc, true); -} - - -void -ath5k_rfkill_hw_stop(struct ath5k_hw *ah) -{ - struct ath5k_softc *sc = ah->ah_sc; - - /* disable interrupt for rfkill switch */ - if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) - ath5k_rfkill_set_intr(sc, false); - - tasklet_kill(&sc->rf_kill.toggleq); - - /* enable RFKILL when stopping HW so Wifi LED is turned off */ - ath5k_rfkill_enable(sc); -} - diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index b61a071788a5..a8def4fa449c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -711,7 +711,6 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) return 0; if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { - txtid->state &= ~AGGR_ADDBA_PROGRESS; txtid->addba_exchangeattempts = 0; return 0; } diff --git a/trunk/drivers/net/wireless/b43/Kconfig b/trunk/drivers/net/wireless/b43/Kconfig index 67f564e37225..07a99e3faf94 100644 --- a/trunk/drivers/net/wireless/b43/Kconfig +++ b/trunk/drivers/net/wireless/b43/Kconfig @@ -98,6 +98,13 @@ config B43_LEDS depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43) default y +# This config option automatically enables b43 RFKILL support, +# if it's possible. +config B43_RFKILL + bool + depends on B43 && (RFKILL = y || RFKILL = B43) + default y + # This config option automatically enables b43 HW-RNG support, # if the HW-RNG core is enabled. config B43_HWRNG diff --git a/trunk/drivers/net/wireless/b43/Makefile b/trunk/drivers/net/wireless/b43/Makefile index da379f4b0c3a..281ef8310350 100644 --- a/trunk/drivers/net/wireless/b43/Makefile +++ b/trunk/drivers/net/wireless/b43/Makefile @@ -13,7 +13,7 @@ b43-y += lo.o b43-y += wa.o b43-y += dma.o b43-$(CONFIG_B43_PIO) += pio.o -b43-y += rfkill.o +b43-$(CONFIG_B43_RFKILL) += rfkill.o b43-$(CONFIG_B43_LEDS) += leds.o b43-$(CONFIG_B43_PCMCIA) += pcmcia.o b43-$(CONFIG_B43_DEBUG) += debugfs.o diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h index f580c2812d91..4e8ad841c3c5 100644 --- a/trunk/drivers/net/wireless/b43/b43.h +++ b/trunk/drivers/net/wireless/b43/b43.h @@ -163,7 +163,6 @@ enum { #define B43_SHM_SH_WLCOREREV 0x0016 /* 802.11 core revision */ #define B43_SHM_SH_PCTLWDPOS 0x0008 #define B43_SHM_SH_RXPADOFF 0x0034 /* RX Padding data offset (PIO only) */ -#define B43_SHM_SH_FWCAPA 0x0042 /* Firmware capabilities (Opensource firmware only) */ #define B43_SHM_SH_PHYVER 0x0050 /* PHY version */ #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ @@ -298,10 +297,6 @@ enum { #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ -/* Firmware capabilities field in SHM (Opensource firmware only) */ -#define B43_FWCAPA_HWCRYPTO 0x0001 -#define B43_FWCAPA_QOS 0x0002 - /* MacFilter offsets. */ #define B43_MACFILTER_SELF 0x0000 #define B43_MACFILTER_BSSID 0x0003 @@ -601,13 +596,6 @@ struct b43_wl { /* Pointer to the ieee80211 hardware data structure */ struct ieee80211_hw *hw; - /* The number of queues that were registered with the mac80211 subsystem - * initially. This is a backup copy of hw->queues in case hw->queues has - * to be dynamically lowered at runtime (Firmware does not support QoS). - * hw->queues has to be restored to the original value before unregistering - * from the mac80211 subsystem. */ - u16 mac80211_initially_registered_queues; - struct mutex mutex; spinlock_t irq_lock; /* R/W lock for data transmission. @@ -643,6 +631,9 @@ struct b43_wl { char rng_name[30 + 1]; #endif /* CONFIG_B43_HWRNG */ + /* The RF-kill button */ + struct b43_rfkill rfkill; + /* List of all wireless devices on this chip */ struct list_head devlist; u8 nr_devs; @@ -761,8 +752,6 @@ struct b43_wldev { bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ bool radio_hw_enable; /* saved state of radio hardware enabled state */ bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ - bool qos_enabled; /* TRUE, if QoS is used. */ - bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ /* PHY/Radio device. */ struct b43_phy phy; diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 7964cc32b258..eae680b53052 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1285,7 +1285,7 @@ static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev, { struct b43_dmaring *ring; - if (dev->qos_enabled) { + if (b43_modparam_qos) { /* 0 = highest priority */ switch (queue_prio) { default: diff --git a/trunk/drivers/net/wireless/b43/leds.c b/trunk/drivers/net/wireless/b43/leds.c index c8b317094c31..9a498d3fc653 100644 --- a/trunk/drivers/net/wireless/b43/leds.c +++ b/trunk/drivers/net/wireless/b43/leds.c @@ -28,7 +28,6 @@ #include "b43.h" #include "leds.h" -#include "rfkill.h" static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, @@ -165,10 +164,10 @@ static void b43_map_led(struct b43_wldev *dev, snprintf(name, sizeof(name), "b43-%s::radio", wiphy_name(hw->wiphy)); b43_register_led(dev, &dev->led_radio, name, - ieee80211_get_radio_led_name(hw), + b43_rfkill_led_name(dev), led_index, activelow); - /* Sync the RF-kill LED state with radio and switch states. */ - if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) + /* Sync the RF-kill LED state with the switch state. */ + if (dev->radio_hw_enable) b43_led_turn_on(dev, led_index, activelow); break; case B43_LED_WEIRD: diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 6456afebdba1..1d3e40095ada 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -80,8 +80,8 @@ static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); -static int modparam_qos = 1; -module_param_named(qos, modparam_qos, int, 0444); +int b43_modparam_qos = 1; +module_param_named(qos, b43_modparam_qos, int, 0444); MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); static int modparam_btcoex = 1; @@ -538,13 +538,6 @@ void b43_hf_write(struct b43_wldev *dev, u64 value) b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); } -/* Read the firmware capabilities bitmask (Opensource firmware only) */ -static u16 b43_fwcapa_read(struct b43_wldev *dev) -{ - B43_WARN_ON(!dev->fw.opensource); - return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA); -} - void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) { u32 low, high; @@ -2314,34 +2307,12 @@ static int b43_upload_microcode(struct b43_wldev *dev) dev->fw.patch = fwpatch; dev->fw.opensource = (fwdate == 0xFFFF); - /* Default to use-all-queues. */ - dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues; - dev->qos_enabled = !!modparam_qos; - /* Default to firmware/hardware crypto acceleration. */ - dev->hwcrypto_enabled = 1; - if (dev->fw.opensource) { - u16 fwcapa; - /* Patchlevel info is encoded in the "time" field. */ dev->fw.patch = fwtime; - b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n", - dev->fw.rev, dev->fw.patch); - - fwcapa = b43_fwcapa_read(dev); - if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) { - b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n"); - /* Disable hardware crypto and fall back to software crypto. */ - dev->hwcrypto_enabled = 0; - } - if (!(fwcapa & B43_FWCAPA_QOS)) { - b43info(dev->wl, "QoS not supported by firmware\n"); - /* Disable QoS. Tweak hw->queues to 1. It will be restored before - * ieee80211_unregister to make sure the networking core can - * properly free possible resources. */ - dev->wl->hw->queues = 1; - dev->qos_enabled = 0; - } + b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n", + dev->fw.rev, dev->fw.patch, + dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : ""); } else { b43info(dev->wl, "Loading firmware version %u.%u " "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", @@ -3656,7 +3627,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) goto out_unlock; - if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) { + if (dev->fw.pcm_request_failed) { /* We don't have firmware for the crypto engine. * Must use software-crypto. */ err = -EOPNOTSUPP; @@ -4327,6 +4298,7 @@ static int b43_op_start(struct ieee80211_hw *hw) struct b43_wldev *dev = wl->current_dev; int did_init = 0; int err = 0; + bool do_rfkill_exit = 0; /* Kill all old instance specific information to make sure * the card won't use it in the short timeframe between start @@ -4340,12 +4312,18 @@ static int b43_op_start(struct ieee80211_hw *hw) wl->beacon1_uploaded = 0; wl->beacon_templates_virgin = 1; + /* First register RFkill. + * LEDs that are registered later depend on it. */ + b43_rfkill_init(dev); + mutex_lock(&wl->mutex); if (b43_status(dev) < B43_STAT_INITIALIZED) { err = b43_wireless_core_init(dev); - if (err) + if (err) { + do_rfkill_exit = 1; goto out_mutex_unlock; + } did_init = 1; } @@ -4354,16 +4332,17 @@ static int b43_op_start(struct ieee80211_hw *hw) if (err) { if (did_init) b43_wireless_core_exit(dev); + do_rfkill_exit = 1; goto out_mutex_unlock; } } - /* XXX: only do if device doesn't support rfkill irq */ - wiphy_rfkill_start_polling(hw->wiphy); - out_mutex_unlock: mutex_unlock(&wl->mutex); + if (do_rfkill_exit) + b43_rfkill_exit(dev); + return err; } @@ -4372,6 +4351,7 @@ static void b43_op_stop(struct ieee80211_hw *hw) struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; + b43_rfkill_exit(dev); cancel_work_sync(&(wl->beacon_update_trigger)); mutex_lock(&wl->mutex); @@ -4453,7 +4433,6 @@ static const struct ieee80211_ops b43_hw_ops = { .sta_notify = b43_op_sta_notify, .sw_scan_start = b43_op_sw_scan_start_notifier, .sw_scan_complete = b43_op_sw_scan_complete_notifier, - .rfkill_poll = b43_rfkill_poll, }; /* Hard-reset the chip. Do not call this directly. @@ -4756,7 +4735,6 @@ static int b43_wireless_init(struct ssb_device *dev) b43err(NULL, "Could not allocate ieee80211 device\n"); goto out; } - wl = hw_to_b43_wl(hw); /* fill hw info */ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | @@ -4770,8 +4748,7 @@ static int b43_wireless_init(struct ssb_device *dev) BIT(NL80211_IFTYPE_WDS) | BIT(NL80211_IFTYPE_ADHOC); - hw->queues = modparam_qos ? 4 : 1; - wl->mac80211_initially_registered_queues = hw->queues; + hw->queues = b43_modparam_qos ? 4 : 1; hw->max_rates = 2; SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->et1mac)) @@ -4779,7 +4756,9 @@ static int b43_wireless_init(struct ssb_device *dev) else SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); - /* Initialize struct b43_wl */ + /* Get and initialize struct b43_wl */ + wl = hw_to_b43_wl(hw); + memset(wl, 0, sizeof(*wl)); wl->hw = hw; spin_lock_init(&wl->irq_lock); rwlock_init(&wl->tx_lock); @@ -4845,13 +4824,8 @@ static void b43_remove(struct ssb_device *dev) cancel_work_sync(&wldev->restart_work); B43_WARN_ON(!wl); - if (wl->current_dev == wldev) { - /* Restore the queues count before unregistering, because firmware detect - * might have modified it. Restoring is important, so the networking - * stack can properly free resources. */ - wl->hw->queues = wl->mac80211_initially_registered_queues; + if (wl->current_dev == wldev) ieee80211_unregister_hw(wl->hw); - } b43_one_core_detach(dev); @@ -4946,7 +4920,7 @@ static struct ssb_driver b43_ssb_driver = { static void b43_print_driverinfo(void) { const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", - *feat_leds = ""; + *feat_leds = "", *feat_rfkill = ""; #ifdef CONFIG_B43_PCI_AUTOSELECT feat_pci = "P"; @@ -4959,12 +4933,15 @@ static void b43_print_driverinfo(void) #endif #ifdef CONFIG_B43_LEDS feat_leds = "L"; +#endif +#ifdef CONFIG_B43_RFKILL + feat_rfkill = "R"; #endif printk(KERN_INFO "Broadcom 43xx driver loaded " - "[ Features: %s%s%s%s, Firmware-ID: " + "[ Features: %s%s%s%s%s, Firmware-ID: " B43_SUPPORTED_FIRMWARE_ID " ]\n", feat_pci, feat_pcmcia, feat_nphy, - feat_leds); + feat_leds, feat_rfkill); } static int __init b43_init(void) diff --git a/trunk/drivers/net/wireless/b43/main.h b/trunk/drivers/net/wireless/b43/main.h index 950fb1b0546d..40abcf5d1b43 100644 --- a/trunk/drivers/net/wireless/b43/main.h +++ b/trunk/drivers/net/wireless/b43/main.h @@ -39,6 +39,7 @@ #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) +extern int b43_modparam_qos; extern int b43_modparam_verbose; /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if diff --git a/trunk/drivers/net/wireless/b43/phy_common.h b/trunk/drivers/net/wireless/b43/phy_common.h index 44cc918e4fc6..f4c2d79cbc89 100644 --- a/trunk/drivers/net/wireless/b43/phy_common.h +++ b/trunk/drivers/net/wireless/b43/phy_common.h @@ -1,7 +1,7 @@ #ifndef LINUX_B43_PHY_COMMON_H_ #define LINUX_B43_PHY_COMMON_H_ -#include +#include struct b43_wldev; diff --git a/trunk/drivers/net/wireless/b43/pio.c b/trunk/drivers/net/wireless/b43/pio.c index 69138e8c1db6..8cd9776752e6 100644 --- a/trunk/drivers/net/wireless/b43/pio.c +++ b/trunk/drivers/net/wireless/b43/pio.c @@ -313,7 +313,7 @@ static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev, { struct b43_pio_txqueue *q; - if (dev->qos_enabled) { + if (b43_modparam_qos) { /* 0 = highest priority */ switch (queue_prio) { default: diff --git a/trunk/drivers/net/wireless/b43/rfkill.c b/trunk/drivers/net/wireless/b43/rfkill.c index 31e55999893f..96047843cd56 100644 --- a/trunk/drivers/net/wireless/b43/rfkill.c +++ b/trunk/drivers/net/wireless/b43/rfkill.c @@ -22,11 +22,15 @@ */ +#include "rfkill.h" #include "b43.h" +#include "phy_common.h" + +#include /* Returns TRUE, if the radio is enabled in hardware. */ -bool b43_is_hw_radio_enabled(struct b43_wldev *dev) +static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) { if (dev->phy.rev >= 3) { if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) @@ -41,39 +45,110 @@ bool b43_is_hw_radio_enabled(struct b43_wldev *dev) } /* The poll callback for the hardware button. */ -void b43_rfkill_poll(struct ieee80211_hw *hw) +static void b43_rfkill_poll(struct rfkill *rfkill, void *data) { - struct b43_wl *wl = hw_to_b43_wl(hw); - struct b43_wldev *dev = wl->current_dev; - struct ssb_bus *bus = dev->dev->bus; + struct b43_wldev *dev = data; + struct b43_wl *wl = dev->wl; bool enabled; - bool brought_up = false; mutex_lock(&wl->mutex); if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { - if (ssb_bus_powerup(bus, 0)) { - mutex_unlock(&wl->mutex); - return; - } - ssb_device_enable(dev->dev, 0); - brought_up = true; + mutex_unlock(&wl->mutex); + return; } - enabled = b43_is_hw_radio_enabled(dev); - if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; b43info(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); - wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); + enabled = !rfkill_set_hw_state(rfkill, !enabled); if (enabled != dev->phy.radio_on) b43_software_rfkill(dev, !enabled); } + mutex_unlock(&wl->mutex); +} - if (brought_up) { - ssb_device_disable(dev->dev, 0); - ssb_bus_may_powerdown(bus); - } +/* Called when the RFKILL toggled in software. */ +static int b43_rfkill_soft_set(void *data, bool blocked) +{ + struct b43_wldev *dev = data; + struct b43_wl *wl = dev->wl; + int err = -EINVAL; + + if (WARN_ON(!wl->rfkill.registered)) + return -EINVAL; + mutex_lock(&wl->mutex); + + if (b43_status(dev) < B43_STAT_INITIALIZED) + goto out_unlock; + + if (!dev->radio_hw_enable) + goto out_unlock; + + if (!blocked != dev->phy.radio_on) + b43_software_rfkill(dev, blocked); + err = 0; +out_unlock: mutex_unlock(&wl->mutex); + return err; +} + +const char *b43_rfkill_led_name(struct b43_wldev *dev) +{ + struct b43_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return NULL; + return rfkill_get_led_trigger_name(rfk->rfkill); +} + +static const struct rfkill_ops b43_rfkill_ops = { + .set_block = b43_rfkill_soft_set, + .poll = b43_rfkill_poll, +}; + +void b43_rfkill_init(struct b43_wldev *dev) +{ + struct b43_wl *wl = dev->wl; + struct b43_rfkill *rfk = &(wl->rfkill); + int err; + + rfk->registered = 0; + + snprintf(rfk->name, sizeof(rfk->name), + "b43-%s", wiphy_name(wl->hw->wiphy)); + + rfk->rfkill = rfkill_alloc(rfk->name, + dev->dev->dev, + RFKILL_TYPE_WLAN, + &b43_rfkill_ops, dev); + if (!rfk->rfkill) + goto out_error; + + err = rfkill_register(rfk->rfkill); + if (err) + goto err_free; + + rfk->registered = 1; + + return; + err_free: + rfkill_destroy(rfk->rfkill); + out_error: + rfk->registered = 0; + b43warn(wl, "RF-kill button init failed\n"); +} + +void b43_rfkill_exit(struct b43_wldev *dev) +{ + struct b43_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return; + rfk->registered = 0; + + rfkill_unregister(rfk->rfkill); + rfkill_destroy(rfk->rfkill); + rfk->rfkill = NULL; } diff --git a/trunk/drivers/net/wireless/b43/rfkill.h b/trunk/drivers/net/wireless/b43/rfkill.h index f046c3ca0519..da497e01bbb1 100644 --- a/trunk/drivers/net/wireless/b43/rfkill.h +++ b/trunk/drivers/net/wireless/b43/rfkill.h @@ -1,11 +1,49 @@ #ifndef B43_RFKILL_H_ #define B43_RFKILL_H_ -struct ieee80211_hw; struct b43_wldev; -void b43_rfkill_poll(struct ieee80211_hw *hw); -bool b43_is_hw_radio_enabled(struct b43_wldev *dev); +#ifdef CONFIG_B43_RFKILL + +#include + + +struct b43_rfkill { + /* The RFKILL subsystem data structure */ + struct rfkill *rfkill; + /* Did initialization succeed? Used for freeing. */ + bool registered; + /* The unique name of this rfkill switch */ + char name[sizeof("b43-phy4294967295")]; +}; + +/* The init function returns void, because we are not interested + * in failing the b43 init process when rfkill init failed. */ +void b43_rfkill_init(struct b43_wldev *dev); +void b43_rfkill_exit(struct b43_wldev *dev); + +const char *b43_rfkill_led_name(struct b43_wldev *dev); + + +#else /* CONFIG_B43_RFKILL */ +/* No RFKILL support. */ + +struct b43_rfkill { + /* empty */ +}; + +static inline void b43_rfkill_init(struct b43_wldev *dev) +{ +} +static inline void b43_rfkill_exit(struct b43_wldev *dev) +{ +} +static inline char * b43_rfkill_led_name(struct b43_wldev *dev) +{ + return NULL; +} + +#endif /* CONFIG_B43_RFKILL */ #endif /* B43_RFKILL_H_ */ diff --git a/trunk/drivers/net/wireless/b43/xmit.c b/trunk/drivers/net/wireless/b43/xmit.c index 55f36a7254d9..a63d88841df8 100644 --- a/trunk/drivers/net/wireless/b43/xmit.c +++ b/trunk/drivers/net/wireless/b43/xmit.c @@ -118,6 +118,7 @@ u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate) void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, const u16 octets, const u8 bitrate) { + __le32 *data = &(plcp->data); __u8 *raw = plcp->raw; if (b43_is_ofdm_rate(bitrate)) { @@ -126,7 +127,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, d = b43_plcp_get_ratecode_ofdm(bitrate); B43_WARN_ON(octets & 0xF000); d |= (octets << 5); - plcp->data = cpu_to_le32(d); + *data = cpu_to_le32(d); } else { u32 plen; @@ -140,7 +141,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, raw[1] = 0x04; } else raw[1] = 0x04; - plcp->data |= cpu_to_le32(plen << 16); + *data |= cpu_to_le32(plen << 16); raw[0] = b43_plcp_get_ratecode_cck(bitrate); } } diff --git a/trunk/drivers/net/wireless/b43legacy/Kconfig b/trunk/drivers/net/wireless/b43legacy/Kconfig index 94a463478053..6893f439df70 100644 --- a/trunk/drivers/net/wireless/b43legacy/Kconfig +++ b/trunk/drivers/net/wireless/b43legacy/Kconfig @@ -42,6 +42,14 @@ config B43LEGACY_LEDS depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY) default y +# RFKILL support +# This config option automatically enables b43legacy RFKILL support, +# if it's possible. +config B43LEGACY_RFKILL + bool + depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) + default y + # This config option automatically enables b43 HW-RNG support, # if the HW-RNG core is enabled. config B43LEGACY_HWRNG diff --git a/trunk/drivers/net/wireless/b43legacy/Makefile b/trunk/drivers/net/wireless/b43legacy/Makefile index 227a77e84362..80cdb73bd140 100644 --- a/trunk/drivers/net/wireless/b43legacy/Makefile +++ b/trunk/drivers/net/wireless/b43legacy/Makefile @@ -6,7 +6,7 @@ b43legacy-y += radio.o b43legacy-y += sysfs.o b43legacy-y += xmit.o # b43 RFKILL button support -b43legacy-y += rfkill.o +b43legacy-$(CONFIG_B43LEGACY_RFKILL) += rfkill.o # b43legacy LED support b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o # b43legacy debugging diff --git a/trunk/drivers/net/wireless/b43legacy/b43legacy.h b/trunk/drivers/net/wireless/b43legacy/b43legacy.h index 77fda148ac46..19a4b0bc0d87 100644 --- a/trunk/drivers/net/wireless/b43legacy/b43legacy.h +++ b/trunk/drivers/net/wireless/b43legacy/b43legacy.h @@ -602,6 +602,9 @@ struct b43legacy_wl { char rng_name[30 + 1]; #endif + /* The RF-kill button */ + struct b43legacy_rfkill rfkill; + /* List of all wireless devices on this chip */ struct list_head devlist; u8 nr_devs; diff --git a/trunk/drivers/net/wireless/b43legacy/leds.c b/trunk/drivers/net/wireless/b43legacy/leds.c index 37e9be893560..538d3117594b 100644 --- a/trunk/drivers/net/wireless/b43legacy/leds.c +++ b/trunk/drivers/net/wireless/b43legacy/leds.c @@ -28,7 +28,6 @@ #include "b43legacy.h" #include "leds.h" -#include "rfkill.h" static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, @@ -165,10 +164,10 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev, snprintf(name, sizeof(name), "b43legacy-%s::radio", wiphy_name(hw->wiphy)); b43legacy_register_led(dev, &dev->led_radio, name, - ieee80211_get_radio_led_name(hw), + b43legacy_rfkill_led_name(dev), led_index, activelow); - /* Sync the RF-kill LED state with radio and switch states. */ - if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev)) + /* Sync the RF-kill LED state with the switch state. */ + if (dev->radio_hw_enable) b43legacy_led_turn_on(dev, led_index, activelow); break; case B43legacy_LED_WEIRD: diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index e5136fb65ddd..f6f3fbf0a2f4 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -3431,6 +3431,11 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) struct b43legacy_wldev *dev = wl->current_dev; int did_init = 0; int err = 0; + bool do_rfkill_exit = 0; + + /* First register RFkill. + * LEDs that are registered later depend on it. */ + b43legacy_rfkill_init(dev); /* Kill all old instance specific information to make sure * the card won't use it in the short timeframe between start @@ -3446,8 +3451,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { err = b43legacy_wireless_core_init(dev); - if (err) + if (err) { + do_rfkill_exit = 1; goto out_mutex_unlock; + } did_init = 1; } @@ -3456,15 +3463,17 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) if (err) { if (did_init) b43legacy_wireless_core_exit(dev); + do_rfkill_exit = 1; goto out_mutex_unlock; } } - wiphy_rfkill_start_polling(hw->wiphy); - out_mutex_unlock: mutex_unlock(&wl->mutex); + if (do_rfkill_exit) + b43legacy_rfkill_exit(dev); + return err; } @@ -3473,6 +3482,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; + b43legacy_rfkill_exit(dev); cancel_work_sync(&(wl->beacon_update_trigger)); mutex_lock(&wl->mutex); @@ -3508,7 +3518,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = { .start = b43legacy_op_start, .stop = b43legacy_op_stop, .set_tim = b43legacy_op_beacon_set_tim, - .rfkill_poll = b43legacy_rfkill_poll, }; /* Hard-reset the chip. Do not call this directly. diff --git a/trunk/drivers/net/wireless/b43legacy/rfkill.c b/trunk/drivers/net/wireless/b43legacy/rfkill.c index 8783022db11e..c6230a64505a 100644 --- a/trunk/drivers/net/wireless/b43legacy/rfkill.c +++ b/trunk/drivers/net/wireless/b43legacy/rfkill.c @@ -22,12 +22,15 @@ */ +#include "rfkill.h" #include "radio.h" #include "b43legacy.h" +#include + /* Returns TRUE, if the radio is enabled in hardware. */ -bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) +static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) { if (dev->phy.rev >= 3) { if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) @@ -42,31 +45,23 @@ bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) } /* The poll callback for the hardware button. */ -void b43legacy_rfkill_poll(struct ieee80211_hw *hw) +static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data) { - struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); - struct b43legacy_wldev *dev = wl->current_dev; - struct ssb_bus *bus = dev->dev->bus; + struct b43legacy_wldev *dev = data; + struct b43legacy_wl *wl = dev->wl; bool enabled; - bool brought_up = false; mutex_lock(&wl->mutex); if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { - if (ssb_bus_powerup(bus, 0)) { - mutex_unlock(&wl->mutex); - return; - } - ssb_device_enable(dev->dev, 0); - brought_up = true; + mutex_unlock(&wl->mutex); + return; } - enabled = b43legacy_is_hw_radio_enabled(dev); - if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; b43legacyinfo(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); - wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); + enabled = !rfkill_set_hw_state(rfkill, !enabled); if (enabled != dev->phy.radio_on) { if (enabled) b43legacy_radio_turn_on(dev); @@ -74,11 +69,95 @@ void b43legacy_rfkill_poll(struct ieee80211_hw *hw) b43legacy_radio_turn_off(dev, 0); } } + mutex_unlock(&wl->mutex); +} + +/* Called when the RFKILL toggled in software. + * This is called without locking. */ +static int b43legacy_rfkill_soft_set(void *data, bool blocked) +{ + struct b43legacy_wldev *dev = data; + struct b43legacy_wl *wl = dev->wl; + int ret = -EINVAL; - if (brought_up) { - ssb_device_disable(dev->dev, 0); - ssb_bus_may_powerdown(bus); + if (!wl->rfkill.registered) + return -EINVAL; + + mutex_lock(&wl->mutex); + if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) + goto out_unlock; + + if (!dev->radio_hw_enable) + goto out_unlock; + + if (!blocked != dev->phy.radio_on) { + if (!blocked) + b43legacy_radio_turn_on(dev); + else + b43legacy_radio_turn_off(dev, 0); } + ret = 0; +out_unlock: mutex_unlock(&wl->mutex); + return ret; +} + +const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) +{ + struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return NULL; + return rfkill_get_led_trigger_name(rfk->rfkill); } + +static const struct rfkill_ops b43legacy_rfkill_ops = { + .set_block = b43legacy_rfkill_soft_set, + .poll = b43legacy_rfkill_poll, +}; + +void b43legacy_rfkill_init(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + struct b43legacy_rfkill *rfk = &(wl->rfkill); + int err; + + rfk->registered = 0; + + snprintf(rfk->name, sizeof(rfk->name), + "b43legacy-%s", wiphy_name(wl->hw->wiphy)); + rfk->rfkill = rfkill_alloc(rfk->name, + dev->dev->dev, + RFKILL_TYPE_WLAN, + &b43legacy_rfkill_ops, dev); + if (!rfk->rfkill) + goto out_error; + + err = rfkill_register(rfk->rfkill); + if (err) + goto err_free; + + rfk->registered = 1; + + return; + err_free: + rfkill_destroy(rfk->rfkill); + out_error: + rfk->registered = 0; + b43legacywarn(wl, "RF-kill button init failed\n"); +} + +void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) +{ + struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); + + if (!rfk->registered) + return; + rfk->registered = 0; + + rfkill_unregister(rfk->rfkill); + rfkill_destroy(rfk->rfkill); + rfk->rfkill = NULL; +} + diff --git a/trunk/drivers/net/wireless/b43legacy/rfkill.h b/trunk/drivers/net/wireless/b43legacy/rfkill.h index 75585571c544..adffc503a6a1 100644 --- a/trunk/drivers/net/wireless/b43legacy/rfkill.h +++ b/trunk/drivers/net/wireless/b43legacy/rfkill.h @@ -1,11 +1,55 @@ #ifndef B43legacy_RFKILL_H_ #define B43legacy_RFKILL_H_ -struct ieee80211_hw; struct b43legacy_wldev; -void b43legacy_rfkill_poll(struct ieee80211_hw *hw); +#ifdef CONFIG_B43LEGACY_RFKILL -bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev); +#include + + + +struct b43legacy_rfkill { + /* The RFKILL subsystem data structure */ + struct rfkill *rfkill; + /* Did initialization succeed? Used for freeing. */ + bool registered; + /* The unique name of this rfkill switch */ + char name[sizeof("b43legacy-phy4294967295")]; +}; + +/* The init function returns void, because we are not interested + * in failing the b43 init process when rfkill init failed. */ +void b43legacy_rfkill_init(struct b43legacy_wldev *dev); +void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); + +const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); + + +#else /* CONFIG_B43LEGACY_RFKILL */ +/* No RFKILL support. */ + +struct b43legacy_rfkill { + /* empty */ +}; + +static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) +{ +} +static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) +{ + return NULL; +} + +#endif /* CONFIG_B43LEGACY_RFKILL */ #endif /* B43legacy_RFKILL_H_ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/Kconfig b/trunk/drivers/net/wireless/iwlwifi/Kconfig index 029ccb6bdbaa..6fe259fcfb8f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Kconfig +++ b/trunk/drivers/net/wireless/iwlwifi/Kconfig @@ -10,6 +10,10 @@ config IWLWIFI_LEDS bool "Enable LED support in iwlagn and iwl3945 drivers" depends on IWLWIFI +config IWLWIFI_RFKILL + def_bool y + depends on IWLWIFI && RFKILL + config IWLWIFI_SPECTRUM_MEASUREMENT bool "Enable Spectrum Measurement in iwlagn driver" depends on IWLWIFI diff --git a/trunk/drivers/net/wireless/iwlwifi/Makefile b/trunk/drivers/net/wireless/iwlwifi/Makefile index 1d4e0a226fd4..d79d97ad61a5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Makefile +++ b/trunk/drivers/net/wireless/iwlwifi/Makefile @@ -4,6 +4,7 @@ iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o iwlcore-objs += iwl-scan.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o +iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o obj-$(CONFIG_IWLAGN) += iwlagn.o diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h index fbb3a573463e..4d8a325ea9d8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -36,6 +36,10 @@ #include #include +/*used for rfkill*/ +#include +#include + /* Hardware specific file defines the PCI IDs table for that hardware module */ extern struct pci_device_id iwl3945_hw_card_ids[]; @@ -151,6 +155,7 @@ struct iwl3945_frame { #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ #define STATUS_INT_ENABLED 2 #define STATUS_RF_KILL_HW 3 +#define STATUS_RF_KILL_SW 4 #define STATUS_INIT 5 #define STATUS_ALIVE 6 #define STATUS_READY 7 diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index a5637c4aa85d..b77208de92ad 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -737,13 +737,19 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, clear_bit(STATUS_RF_KILL_HW, &priv->status); + if (flags & SW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_SW, &priv->status); + else + clear_bit(STATUS_RF_KILL_SW, &priv->status); + if (!(flags & RXON_CARD_DISABLED)) iwl_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->status))) - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)) || + (test_bit(STATUS_RF_KILL_SW, &status) != + test_bit(STATUS_RF_KILL_SW, &priv->status))) + queue_work(priv->workqueue, &priv->rf_kill); else wake_up_interruptible(&priv->wait_command_queue); } @@ -1039,7 +1045,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) set_bit(STATUS_RF_KILL_HW, &priv->status); else clear_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); + queue_work(priv->workqueue, &priv->rf_kill); } handled |= CSR_INT_BIT_RF_KILL; @@ -1212,7 +1218,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) set_bit(STATUS_RF_KILL_HW, &priv->status); else clear_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); + queue_work(priv->workqueue, &priv->rf_kill); } handled |= CSR_INT_BIT_RF_KILL; @@ -1720,10 +1726,12 @@ static void __iwl_down(struct iwl_priv *priv) ieee80211_stop_queues(priv->hw); /* If we have not previously called iwl_init() then - * clear all bits but the RF Kill bit and return */ + * clear all bits but the RF Kill bits and return */ if (!iwl_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_EXIT_PENDING, &priv->status) << @@ -1732,9 +1740,11 @@ static void __iwl_down(struct iwl_priv *priv) } /* ...otherwise clear out all the status bits but the RF Kill - * bit and continue taking the NIC down. */ + * bits and continue taking the NIC down. */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_FW_ERROR, &priv->status) << @@ -1856,10 +1866,9 @@ static int __iwl_up(struct iwl_priv *priv) set_bit(STATUS_RF_KILL_HW, &priv->status); if (iwl_is_rfkill(priv)) { - wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); - iwl_enable_interrupts(priv); - IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); + IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n", + test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); return 0; } @@ -1992,6 +2001,7 @@ static void iwl_bg_up(struct work_struct *data) mutex_lock(&priv->mutex); __iwl_up(priv); mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); } static void iwl_bg_restart(struct work_struct *data) @@ -2169,6 +2179,8 @@ static int iwl_mac_start(struct ieee80211_hw *hw) mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); + if (ret) return ret; @@ -2763,6 +2775,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->up, iwl_bg_up); INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); + INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); @@ -3033,8 +3046,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) else set_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + err = iwl_rfkill_init(priv); + if (err) + IWL_ERR(priv, "Unable to initialize RFKILL system. " + "Ignoring error: %d\n", err); + else + iwl_rfkill_set_hw_state(priv); iwl_power_initialize(priv); return 0; @@ -3098,6 +3115,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_synchronize_irq(priv); + iwl_rfkill_unregister(priv); iwl_dealloc_ucode_pci(priv); if (priv->rxq.bd) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index f9d16ca5b3d9..51cae4ec26a5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -36,6 +36,7 @@ #include "iwl-debug.h" #include "iwl-core.h" #include "iwl-io.h" +#include "iwl-rfkill.h" #include "iwl-power.h" #include "iwl-sta.h" #include "iwl-helpers.h" @@ -2210,6 +2211,126 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) } EXPORT_SYMBOL(iwl_send_card_state); +void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) +{ + unsigned long flags; + + if (test_bit(STATUS_RF_KILL_SW, &priv->status)) + return; + + IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n"); + + iwl_scan_cancel(priv); + /* FIXME: This is a workaround for AP */ + if (priv->iw_mode != NL80211_IFTYPE_AP) { + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_SW_BIT_RFKILL); + spin_unlock_irqrestore(&priv->lock, flags); + /* call the host command only if no hw rf-kill set */ + if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && + iwl_is_ready(priv)) + iwl_send_card_state(priv, + CARD_STATE_CMD_DISABLE, 0); + set_bit(STATUS_RF_KILL_SW, &priv->status); + /* make sure mac80211 stop sending Tx frame */ + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + } +} +EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio); + +int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) +{ + unsigned long flags; + + if (!test_bit(STATUS_RF_KILL_SW, &priv->status)) + return 0; + + IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n"); + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + + /* If the driver is up it will receive CARD_STATE_NOTIFICATION + * notification where it will clear SW rfkill status. + * Setting it here would break the handler. Only if the + * interface is down we can set here since we don't + * receive any further notification. + */ + if (!priv->is_open) + clear_bit(STATUS_RF_KILL_SW, &priv->status); + spin_unlock_irqrestore(&priv->lock, flags); + + /* wake up ucode */ + msleep(10); + + iwl_read32(priv, CSR_UCODE_DRV_GP1); + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); + + if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { + IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " + "disabled by HW switch\n"); + return 0; + } + + /* when driver is up while rfkill is on, it wont receive + * any CARD_STATE_NOTIFICATION notifications so we have to + * restart it in here + */ + if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) { + clear_bit(STATUS_RF_KILL_SW, &priv->status); + if (!iwl_is_rfkill(priv)) + queue_work(priv->workqueue, &priv->up); + } + + /* If the driver is already loaded, it will receive + * CARD_STATE_NOTIFICATION notifications and the handler will + * call restart to reload the driver. + */ + return 1; +} +EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); + +void iwl_bg_rf_kill(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); + + wake_up_interruptible(&priv->wait_command_queue); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + + if (!iwl_is_rfkill(priv)) { + IWL_DEBUG_RF_KILL(priv, + "HW and/or SW RF Kill no longer active, restarting " + "device\n"); + if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && + priv->is_open) + queue_work(priv->workqueue, &priv->restart); + } else { + /* make sure mac80211 stop sending Tx frame */ + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + + if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) + IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " + "disabled by SW switch\n"); + else + IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n" + "Kill switch must be turned off for " + "wireless networking to work.\n"); + } + mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); +} +EXPORT_SYMBOL(iwl_bg_rf_kill); + void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -2728,6 +2849,23 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv); + if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { + if (conf->radio_enabled && + iwl_radio_kill_sw_enable_radio(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " + "waiting for uCode\n"); + goto out; + } + + if (!conf->radio_enabled) + iwl_radio_kill_sw_disable_radio(priv); + } + + if (!conf->radio_enabled) { + IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); + goto out; + } + if (!iwl_is_ready(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); goto out; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index dabf663e36e5..b52d0fb16060 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -348,6 +348,14 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); ****************************************************/ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); +/***************************************************** + * RF -Kill - here and not in iwl-rfkill.h to be available when + * RF-kill subsystem is not compiled. + ****************************************************/ +void iwl_bg_rf_kill(struct work_struct *work); +void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); +int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); + /******************************************************************************* * Rate ******************************************************************************/ @@ -490,6 +498,7 @@ void iwlcore_free_geos(struct iwl_priv *priv); #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ #define STATUS_INT_ENABLED 2 #define STATUS_RF_KILL_HW 3 +#define STATUS_RF_KILL_SW 4 #define STATUS_INIT 5 #define STATUS_ALIVE 6 #define STATUS_READY 7 @@ -524,6 +533,11 @@ static inline int iwl_is_init(struct iwl_priv *priv) return test_bit(STATUS_INIT, &priv->status); } +static inline int iwl_is_rfkill_sw(struct iwl_priv *priv) +{ + return test_bit(STATUS_RF_KILL_SW, &priv->status); +} + static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) { return test_bit(STATUS_RF_KILL_HW, &priv->status); @@ -531,7 +545,7 @@ static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) static inline int iwl_is_rfkill(struct iwl_priv *priv) { - return iwl_is_rfkill_hw(priv); + return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv); } static inline int iwl_is_ready_rf(struct iwl_priv *priv) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 11e08c068917..af70229144b3 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -449,6 +449,8 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, test_bit(STATUS_INT_ENABLED, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", test_bit(STATUS_RF_KILL_HW, &priv->status)); + pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n", + test_bit(STATUS_RF_KILL_SW, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", test_bit(STATUS_INIT, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h index e2d620f0b6e8..28c39cf8b126 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -41,6 +41,7 @@ #include "iwl-prph.h" #include "iwl-fh.h" #include "iwl-debug.h" +#include "iwl-rfkill.h" #include "iwl-4965-hw.h" #include "iwl-3945-hw.h" #include "iwl-3945-led.h" @@ -935,6 +936,9 @@ struct iwl_priv { * 4965's initialize alive response contains some calibration data. */ struct iwl_init_alive_resp card_alive_init; struct iwl_alive_resp card_alive; +#if defined(CONFIG_IWLWIFI_RFKILL) + struct rfkill *rfkill; +#endif #ifdef CONFIG_IWLWIFI_LEDS unsigned long last_blink_time; @@ -1068,6 +1072,7 @@ struct iwl_priv { struct work_struct calibrated_work; struct work_struct scan_completed; struct work_struct rx_replenish; + struct work_struct rf_kill; struct work_struct abort_scan; struct work_struct update_link_led; struct work_struct auth_work; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c new file mode 100644 index 000000000000..13149936fd26 --- /dev/null +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c @@ -0,0 +1,131 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#include +#include +#include + +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" + +/* software rf-kill from user */ +static int iwl_rfkill_soft_rf_kill(void *data, bool blocked) +{ + struct iwl_priv *priv = data; + + if (!priv->rfkill) + return -EINVAL; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return 0; + + IWL_DEBUG_RF_KILL(priv, "received soft RFKILL: block=%d\n", blocked); + + mutex_lock(&priv->mutex); + + if (iwl_is_rfkill_hw(priv)) + goto out_unlock; + + if (!blocked) + iwl_radio_kill_sw_enable_radio(priv); + else + iwl_radio_kill_sw_disable_radio(priv); + +out_unlock: + mutex_unlock(&priv->mutex); + return 0; +} + +static const struct rfkill_ops iwl_rfkill_ops = { + .set_block = iwl_rfkill_soft_rf_kill, +}; + +int iwl_rfkill_init(struct iwl_priv *priv) +{ + struct device *device = wiphy_dev(priv->hw->wiphy); + int ret = 0; + + BUG_ON(device == NULL); + + IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); + priv->rfkill = rfkill_alloc(priv->cfg->name, + device, + RFKILL_TYPE_WLAN, + &iwl_rfkill_ops, priv); + if (!priv->rfkill) { + IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); + ret = -ENOMEM; + goto error; + } + + ret = rfkill_register(priv->rfkill); + if (ret) { + IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); + goto free_rfkill; + } + + IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); + return 0; + +free_rfkill: + rfkill_destroy(priv->rfkill); + priv->rfkill = NULL; + +error: + IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); + return ret; +} +EXPORT_SYMBOL(iwl_rfkill_init); + +void iwl_rfkill_unregister(struct iwl_priv *priv) +{ + + if (priv->rfkill) { + rfkill_unregister(priv->rfkill); + rfkill_destroy(priv->rfkill); + } + + priv->rfkill = NULL; +} +EXPORT_SYMBOL(iwl_rfkill_unregister); + +/* set RFKILL to the right state. */ +void iwl_rfkill_set_hw_state(struct iwl_priv *priv) +{ + if (!priv->rfkill) + return; + + if (rfkill_set_hw_state(priv->rfkill, + !!iwl_is_rfkill_hw(priv))) + iwl_radio_kill_sw_disable_radio(priv); + else + iwl_radio_kill_sw_enable_radio(priv); +} +EXPORT_SYMBOL(iwl_rfkill_set_hw_state); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h new file mode 100644 index 000000000000..633dafb4bf1b --- /dev/null +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#ifndef __iwl_rf_kill_h__ +#define __iwl_rf_kill_h__ + +struct iwl_priv; + +#include + +#ifdef CONFIG_IWLWIFI_RFKILL + +void iwl_rfkill_set_hw_state(struct iwl_priv *priv); +void iwl_rfkill_unregister(struct iwl_priv *priv); +int iwl_rfkill_init(struct iwl_priv *priv); +#else +static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {} +static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {} +static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; } +#endif + + + +#endif /* __iwl_rf_kill_h__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index 83d31606dd00..92fa1a39c446 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1009,12 +1009,18 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, clear_bit(STATUS_RF_KILL_HW, &priv->status); + if (flags & SW_CARD_DISABLED) + set_bit(STATUS_RF_KILL_SW, &priv->status); + else + clear_bit(STATUS_RF_KILL_SW, &priv->status); + iwl_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->status))) - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)) || + (test_bit(STATUS_RF_KILL_SW, &status) != + test_bit(STATUS_RF_KILL_SW, &priv->status))) + queue_work(priv->workqueue, &priv->rf_kill); else wake_up_interruptible(&priv->wait_command_queue); } @@ -2580,6 +2586,8 @@ static void __iwl3945_down(struct iwl_priv *priv) if (!iwl_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_EXIT_PENDING, &priv->status) << @@ -2588,9 +2596,11 @@ static void __iwl3945_down(struct iwl_priv *priv) } /* ...otherwise clear out all the status bits but the RF Kill - * bit and continue taking the NIC down. */ + * bits and continue taking the NIC down. */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | + test_bit(STATUS_RF_KILL_SW, &priv->status) << + STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | test_bit(STATUS_FW_ERROR, &priv->status) << @@ -2647,6 +2657,12 @@ static int __iwl3945_up(struct iwl_priv *priv) return -EIO; } + if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { + IWL_WARN(priv, "Radio disabled by SW RF kill (module " + "parameter)\n"); + return -ENODEV; + } + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { IWL_ERR(priv, "ucode not available for device bring up\n"); return -EIO; @@ -2763,14 +2779,15 @@ static void iwl3945_rfkill_poll(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, rfkill_poll.work); + unsigned long status = priv->status; if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &priv->status); else set_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->status)); + if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) + queue_work(priv->workqueue, &priv->rf_kill); queue_delayed_work(priv->workqueue, &priv->rfkill_poll, round_jiffies_relative(2 * HZ)); @@ -3002,6 +3019,7 @@ static void iwl3945_bg_up(struct work_struct *data) mutex_lock(&priv->mutex); __iwl3945_up(priv); mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); } static void iwl3945_bg_restart(struct work_struct *data) @@ -3164,6 +3182,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) mutex_unlock(&priv->mutex); + iwl_rfkill_set_hw_state(priv); + if (ret) goto out_release_irq; @@ -3816,6 +3836,7 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->up, iwl3945_bg_up); INIT_WORK(&priv->restart, iwl3945_bg_restart); INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); + INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); @@ -4182,6 +4203,13 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e if (err) IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + err = iwl_rfkill_init(priv); + if (err) + IWL_ERR(priv, "Unable to initialize RFKILL system. " + "Ignoring error: %d\n", err); + else + iwl_rfkill_set_hw_state(priv); + /* Start monitoring the killswitch */ queue_delayed_work(priv->workqueue, &priv->rfkill_poll, 2 * HZ); @@ -4247,6 +4275,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); + iwl_rfkill_unregister(priv); cancel_delayed_work_sync(&priv->rfkill_poll); iwl3945_dealloc_ucode_pci(priv); diff --git a/trunk/drivers/net/wireless/libertas/if_spi.c b/trunk/drivers/net/wireless/libertas/if_spi.c index f8c2898d82b0..ea23c5de1420 100644 --- a/trunk/drivers/net/wireless/libertas/if_spi.c +++ b/trunk/drivers/net/wireless/libertas/if_spi.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -50,6 +51,13 @@ struct if_spi_card { u16 card_id; u8 card_rev; + /* Pin number for our GPIO chip-select. */ + /* TODO: Once the generic SPI layer has some additional features, we + * should take this out and use the normal chip select here. + * We need support for chip select delays, and not dropping chipselect + * after each word. */ + int gpio_cs; + /* The last time that we initiated an SPU operation */ unsigned long prev_xfer_time; @@ -122,10 +130,12 @@ static void spu_transaction_init(struct if_spi_card *card) * If not, we have to busy-wait to be on the safe side. */ ndelay(400); } + gpio_set_value(card->gpio_cs, 0); /* assert CS */ } static void spu_transaction_finish(struct if_spi_card *card) { + gpio_set_value(card->gpio_cs, 1); /* drop CS */ card->prev_xfer_time = jiffies; } @@ -135,13 +145,6 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) { int err = 0; u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); - struct spi_message m; - struct spi_transfer reg_trans; - struct spi_transfer data_trans; - - spi_message_init(&m); - memset(®_trans, 0, sizeof(reg_trans)); - memset(&data_trans, 0, sizeof(data_trans)); /* You must give an even number of bytes to the SPU, even if it * doesn't care about the last one. */ @@ -150,16 +153,13 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) spu_transaction_init(card); /* write SPU register index */ - reg_trans.tx_buf = ®_out; - reg_trans.len = sizeof(reg_out); - - data_trans.tx_buf = buf; - data_trans.len = len; + err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); + if (err) + goto out; - spi_message_add_tail(®_trans, &m); - spi_message_add_tail(&data_trans, &m); + err = spi_write(card->spi, buf, len); - err = spi_sync(card->spi, &m); +out: spu_transaction_finish(card); return err; } @@ -186,13 +186,10 @@ static inline int spu_reg_is_port_reg(u16 reg) static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) { - unsigned int delay; + unsigned int i, delay; int err = 0; + u16 zero = 0; u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); - struct spi_message m; - struct spi_transfer reg_trans; - struct spi_transfer dummy_trans; - struct spi_transfer data_trans; /* You must take an even number of bytes from the SPU, even if you * don't care about the last one. */ @@ -200,34 +197,29 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) spu_transaction_init(card); - spi_message_init(&m); - memset(®_trans, 0, sizeof(reg_trans)); - memset(&dummy_trans, 0, sizeof(dummy_trans)); - memset(&data_trans, 0, sizeof(data_trans)); - /* write SPU register index */ - reg_trans.tx_buf = ®_out; - reg_trans.len = sizeof(reg_out); - spi_message_add_tail(®_trans, &m); + err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); + if (err) + goto out; delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : card->spu_reg_delay; if (card->use_dummy_writes) { /* Clock in dummy cycles while the SPU fills the FIFO */ - dummy_trans.len = delay / 8; - spi_message_add_tail(&dummy_trans, &m); + for (i = 0; i < delay / 16; ++i) { + err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); + if (err) + return err; + } } else { /* Busy-wait while the SPU fills the FIFO */ - reg_trans.delay_usecs = - DIV_ROUND_UP((100 + (delay * 10)), 1000); + ndelay(100 + (delay * 10)); } /* read in data */ - data_trans.rx_buf = buf; - data_trans.len = len; - spi_message_add_tail(&data_trans, &m); + err = spi_read(card->spi, buf, len); - err = spi_sync(card->spi, &m); +out: spu_transaction_finish(card); return err; } @@ -1057,6 +1049,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) spi_set_drvdata(spi, card); card->pdata = pdata; card->spi = spi; + card->gpio_cs = pdata->gpio_cs; card->prev_xfer_time = jiffies; sema_init(&card->spi_ready, 0); @@ -1065,18 +1058,26 @@ static int __devinit if_spi_probe(struct spi_device *spi) INIT_LIST_HEAD(&card->data_packet_list); spin_lock_init(&card->buffer_lock); + /* set up GPIO CS line. TODO: use regular CS line */ + err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); + if (err) + goto free_card; + err = gpio_direction_output(card->gpio_cs, 1); + if (err) + goto free_gpio; + /* Initialize the SPI Interface Unit */ err = spu_init(card, pdata->use_dummy_writes); if (err) - goto free_card; + goto free_gpio; err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); if (err) - goto free_card; + goto free_gpio; /* Firmware load */ err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); if (err) - goto free_card; + goto free_gpio; if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) lbs_deb_spi("Firmware is already loaded for " "Marvell WLAN 802.11 adapter\n"); @@ -1084,7 +1085,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) err = if_spi_calculate_fw_names(card->card_id, card->helper_fw_name, card->main_fw_name); if (err) - goto free_card; + goto free_gpio; lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " "(chip_id = 0x%04x, chip_rev = 0x%02x) " @@ -1095,23 +1096,23 @@ static int __devinit if_spi_probe(struct spi_device *spi) spi->max_speed_hz); err = if_spi_prog_helper_firmware(card); if (err) - goto free_card; + goto free_gpio; err = if_spi_prog_main_firmware(card); if (err) - goto free_card; + goto free_gpio; lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); } err = spu_set_interrupt_mode(card, 0, 1); if (err) - goto free_card; + goto free_gpio; /* Register our card with libertas. * This will call alloc_etherdev */ priv = lbs_add_card(card, &spi->dev); if (!priv) { err = -ENOMEM; - goto free_card; + goto free_gpio; } card->priv = priv; priv->card = card; @@ -1156,6 +1157,8 @@ static int __devinit if_spi_probe(struct spi_device *spi) if_spi_terminate_spi_thread(card); remove_card: lbs_remove_card(priv); /* will call free_netdev */ +free_gpio: + gpio_free(card->gpio_cs); free_card: free_if_spi_card(card); out: @@ -1176,6 +1179,7 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) free_irq(spi->irq, card); if_spi_terminate_spi_thread(card); lbs_remove_card(priv); /* will call free_netdev */ + gpio_free(card->gpio_cs); if (card->pdata->teardown) card->pdata->teardown(spi); free_if_spi_card(card); diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index 7441d5585110..c254fdf446fd 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -157,55 +157,55 @@ MODULE_PARM_DESC(workaround_interval, #define NDIS_802_11_LENGTH_RATES_EX 16 enum ndis_80211_net_type { - NDIS_80211_TYPE_FREQ_HOP, - NDIS_80211_TYPE_DIRECT_SEQ, - NDIS_80211_TYPE_OFDM_A, - NDIS_80211_TYPE_OFDM_G + ndis_80211_type_freq_hop, + ndis_80211_type_direct_seq, + ndis_80211_type_ofdm_a, + ndis_80211_type_ofdm_g }; enum ndis_80211_net_infra { - NDIS_80211_INFRA_ADHOC, - NDIS_80211_INFRA_INFRA, - NDIS_80211_INFRA_AUTO_UNKNOWN + ndis_80211_infra_adhoc, + ndis_80211_infra_infra, + ndis_80211_infra_auto_unknown }; enum ndis_80211_auth_mode { - NDIS_80211_AUTH_OPEN, - NDIS_80211_AUTH_SHARED, - NDIS_80211_AUTH_AUTO_SWITCH, - NDIS_80211_AUTH_WPA, - NDIS_80211_AUTH_WPA_PSK, - NDIS_80211_AUTH_WPA_NONE, - NDIS_80211_AUTH_WPA2, - NDIS_80211_AUTH_WPA2_PSK + ndis_80211_auth_open, + ndis_80211_auth_shared, + ndis_80211_auth_auto_switch, + ndis_80211_auth_wpa, + ndis_80211_auth_wpa_psk, + ndis_80211_auth_wpa_none, + ndis_80211_auth_wpa2, + ndis_80211_auth_wpa2_psk }; enum ndis_80211_encr_status { - NDIS_80211_ENCR_WEP_ENABLED, - NDIS_80211_ENCR_DISABLED, - NDIS_80211_ENCR_WEP_KEY_ABSENT, - NDIS_80211_ENCR_NOT_SUPPORTED, - NDIS_80211_ENCR_TKIP_ENABLED, - NDIS_80211_ENCR_TKIP_KEY_ABSENT, - NDIS_80211_ENCR_CCMP_ENABLED, - NDIS_80211_ENCR_CCMP_KEY_ABSENT + ndis_80211_encr_wep_enabled, + ndis_80211_encr_disabled, + ndis_80211_encr_wep_key_absent, + ndis_80211_encr_not_supported, + ndis_80211_encr_tkip_enabled, + ndis_80211_encr_tkip_key_absent, + ndis_80211_encr_ccmp_enabled, + ndis_80211_encr_ccmp_key_absent }; enum ndis_80211_priv_filter { - NDIS_80211_PRIV_ACCEPT_ALL, - NDIS_80211_PRIV_8021X_WEP + ndis_80211_priv_accept_all, + ndis_80211_priv_8021x_wep }; enum ndis_80211_addkey_bits { - NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28), - NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29), - NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30), - NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31) + ndis_80211_addkey_8021x_auth = cpu_to_le32(1 << 28), + ndis_80211_addkey_set_init_recv_seq = cpu_to_le32(1 << 29), + ndis_80211_addkey_pairwise_key = cpu_to_le32(1 << 30), + ndis_80211_addkey_transmit_key = cpu_to_le32(1 << 31), }; enum ndis_80211_addwep_bits { - NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30), - NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31) + ndis_80211_addwep_perclient_key = cpu_to_le32(1 << 30), + ndis_80211_addwep_transmit_key = cpu_to_le32(1 << 31), }; struct ndis_80211_ssid { @@ -361,7 +361,7 @@ static const struct ieee80211_rate rndis_rates[] = { }; /* RNDIS device private data */ -struct rndis_wlan_private { +struct rndis_wext_private { struct usbnet *usbdev; struct wireless_dev wdev; @@ -441,13 +441,13 @@ static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev) +static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev) { - return (struct rndis_wlan_private *)dev->driver_priv; + return (struct rndis_wext_private *)dev->driver_priv; } -static u32 get_bcm4320_power(struct rndis_wlan_private *priv) +static u32 get_bcm4320_power(struct rndis_wext_private *priv) { return BCM4320_DEFAULT_TXPOWER * bcm4320_power_output[priv->param_power_output] / 100; @@ -480,7 +480,7 @@ static int rndis_error_status(__le32 rndis_status) static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); union { void *buf; struct rndis_msg_hdr *header; @@ -526,7 +526,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); union { void *buf; struct rndis_msg_hdr *header; @@ -747,7 +747,7 @@ static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret; ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); @@ -794,7 +794,7 @@ static int is_associated(struct usbnet *usbdev) static int disassociate(struct usbnet *usbdev, int reset_ssid) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_ssid ssid; int i, ret = 0; @@ -826,7 +826,7 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid) static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; int auth_mode, ret; @@ -835,23 +835,23 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) - auth_mode = NDIS_80211_AUTH_WPA2; + auth_mode = ndis_80211_auth_wpa2; else - auth_mode = NDIS_80211_AUTH_WPA2_PSK; + auth_mode = ndis_80211_auth_wpa2_psk; } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) - auth_mode = NDIS_80211_AUTH_WPA; + auth_mode = ndis_80211_auth_wpa; else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) - auth_mode = NDIS_80211_AUTH_WPA_PSK; + auth_mode = ndis_80211_auth_wpa_psk; else - auth_mode = NDIS_80211_AUTH_WPA_NONE; + auth_mode = ndis_80211_auth_wpa_none; } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) - auth_mode = NDIS_80211_AUTH_AUTO_SWITCH; + auth_mode = ndis_80211_auth_auto_switch; else - auth_mode = NDIS_80211_AUTH_SHARED; + auth_mode = ndis_80211_auth_shared; } else - auth_mode = NDIS_80211_AUTH_OPEN; + auth_mode = ndis_80211_auth_open; tmp = cpu_to_le32(auth_mode); ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, @@ -869,16 +869,16 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) static int set_priv_filter(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) - tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP); + tmp = cpu_to_le32(ndis_80211_priv_8021x_wep); else - tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL); + tmp = cpu_to_le32(ndis_80211_priv_accept_all); return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, sizeof(tmp)); @@ -887,7 +887,7 @@ static int set_priv_filter(struct usbnet *usbdev) static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; int encr_mode, ret; @@ -896,18 +896,18 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) groupwise); if (pairwise & IW_AUTH_CIPHER_CCMP) - encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; + encr_mode = ndis_80211_encr_ccmp_enabled; else if (pairwise & IW_AUTH_CIPHER_TKIP) - encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; + encr_mode = ndis_80211_encr_tkip_enabled; else if (pairwise & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - encr_mode = NDIS_80211_ENCR_WEP_ENABLED; + encr_mode = ndis_80211_encr_wep_enabled; else if (groupwise & IW_AUTH_CIPHER_CCMP) - encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; + encr_mode = ndis_80211_encr_ccmp_enabled; else if (groupwise & IW_AUTH_CIPHER_TKIP) - encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; + encr_mode = ndis_80211_encr_tkip_enabled; else - encr_mode = NDIS_80211_ENCR_DISABLED; + encr_mode = ndis_80211_encr_disabled; tmp = cpu_to_le32(encr_mode); ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, @@ -925,7 +925,7 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) static int set_assoc_params(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg); set_priv_filter(usbdev); @@ -937,7 +937,7 @@ static int set_assoc_params(struct usbnet *usbdev) static int set_infra_mode(struct usbnet *usbdev, int mode) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tmp; int ret, i; @@ -970,12 +970,12 @@ static int set_infra_mode(struct usbnet *usbdev, int mode) static void set_default_iw_params(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); priv->wpa_keymgmt = 0; priv->wpa_version = 0; - set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA); + set_infra_mode(usbdev, ndis_80211_infra_infra); set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, IW_AUTH_ALG_OPEN_SYSTEM); set_priv_filter(usbdev); @@ -996,7 +996,7 @@ static int deauthenticate(struct usbnet *usbdev) /* index must be 0 - N, as per NDIS */ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_wep_key ndis_key; int ret; @@ -1011,7 +1011,7 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) memcpy(&ndis_key.material, key, key_len); if (index == priv->encr_tx_key_index) { - ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY; + ndis_key.index |= ndis_80211_addwep_transmit_key; ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, IW_AUTH_CIPHER_NONE); if (ret) @@ -1039,7 +1039,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, int index, const struct sockaddr *addr, const u8 *rx_seq, int alg, int flags) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_key ndis_key; int ret; @@ -1047,15 +1047,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, return -EINVAL; if (key_len > sizeof(ndis_key.material) || key_len < 0) return -EINVAL; - if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) + if ((flags & ndis_80211_addkey_set_init_recv_seq) && !rx_seq) return -EINVAL; - if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr) + if ((flags & ndis_80211_addkey_pairwise_key) && !addr) return -EINVAL; devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, - !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY), - !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY), - !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)); + !!(flags & ndis_80211_addkey_transmit_key), + !!(flags & ndis_80211_addkey_pairwise_key), + !!(flags & ndis_80211_addkey_set_init_recv_seq)); memset(&ndis_key, 0, sizeof(ndis_key)); @@ -1073,15 +1073,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, } else memcpy(ndis_key.material, key, key_len); - if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) + if (flags & ndis_80211_addkey_set_init_recv_seq) memcpy(ndis_key.rsc, rx_seq, 6); - if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { + if (flags & ndis_80211_addkey_pairwise_key) { /* pairwise key */ memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); } else { /* group key */ - if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) + if (priv->infra_mode == ndis_80211_infra_adhoc) memset(ndis_key.bssid, 0xff, ETH_ALEN); else get_bssid(usbdev, ndis_key.bssid); @@ -1096,7 +1096,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, priv->encr_key_len[index] = key_len; priv->encr_key_wpa[index] = 1; - if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY) + if (flags & ndis_80211_addkey_transmit_key) priv->encr_tx_key_index = index; return 0; @@ -1106,7 +1106,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, /* remove_key is for both wep and wpa */ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ndis_80211_remove_key remove_key; __le32 keyindex; int ret; @@ -1128,7 +1128,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) /* pairwise key */ if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0) remove_key.index |= - NDIS_80211_ADDKEY_PAIRWISE_KEY; + ndis_80211_addkey_pairwise_key; memcpy(remove_key.bssid, bssid, sizeof(remove_key.bssid)); } else @@ -1161,7 +1161,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) static void set_multicast_list(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct dev_mc_list *mclist; __le32 filter; int ret, i, size; @@ -1238,10 +1238,10 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, switch (type) { case NL80211_IFTYPE_ADHOC: - mode = NDIS_80211_INFRA_ADHOC; + mode = ndis_80211_infra_adhoc; break; case NL80211_IFTYPE_STATION: - mode = NDIS_80211_INFRA_INFRA; + mode = ndis_80211_infra_infra; break; default: return -EINVAL; @@ -1256,7 +1256,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret; __le32 tmp; @@ -1286,7 +1286,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, struct ndis_80211_bssid_ex *bssid) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct ieee80211_channel *channel; s32 signal; u64 timestamp; @@ -1371,8 +1371,8 @@ static int rndis_check_bssid_list(struct usbnet *usbdev) static void rndis_get_scan_results(struct work_struct *work) { - struct rndis_wlan_private *priv = - container_of(work, struct rndis_wlan_private, scan_work.work); + struct rndis_wext_private *priv = + container_of(work, struct rndis_wext_private, scan_work.work); struct usbnet *usbdev = priv->usbdev; int ret; @@ -1497,7 +1497,7 @@ static int rndis_iw_set_auth(struct net_device *dev, { struct iw_param *p = &wrqu->param; struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret = -ENOTSUPP; switch (p->flags & IW_AUTH_INDEX) { @@ -1578,7 +1578,7 @@ static int rndis_iw_get_auth(struct net_device *dev, { struct iw_param *p = &wrqu->param; struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); switch (p->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: @@ -1609,7 +1609,7 @@ static int rndis_iw_set_encode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret, index, key_len; u8 *key; @@ -1672,7 +1672,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, { struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int keyidx, flags; keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; @@ -1698,11 +1698,11 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, flags = 0; if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) - flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ; + flags |= ndis_80211_addkey_set_init_recv_seq; if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) - flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY; + flags |= ndis_80211_addkey_pairwise_key; if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) - flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY; + flags |= ndis_80211_addkey_transmit_key; return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, ext->rx_seq, ext->alg, flags); @@ -1713,7 +1713,7 @@ static int rndis_iw_set_genie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); int ret = 0; #ifdef DEBUG @@ -1747,7 +1747,7 @@ static int rndis_iw_get_genie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); devdbg(usbdev, "SIOCGIWGENIE"); @@ -1886,7 +1886,7 @@ static int rndis_iw_get_txpower(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tx_power; if (priv->radio_on) { @@ -1912,7 +1912,7 @@ static int rndis_iw_set_txpower(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); __le32 tx_power = 0; if (!wrqu->txpower.disabled) { @@ -1969,7 +1969,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); struct iw_mlme *mlme = (struct iw_mlme *)extra; unsigned char bssid[ETH_ALEN]; @@ -1994,7 +1994,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); unsigned long flags; spin_lock_irqsave(&priv->stats_lock, flags); @@ -2037,28 +2037,28 @@ static const iw_handler rndis_iw_handler[] = IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme, }; -static const iw_handler rndis_wlan_private_handler[] = { +static const iw_handler rndis_wext_private_handler[] = { }; -static const struct iw_priv_args rndis_wlan_private_args[] = { +static const struct iw_priv_args rndis_wext_private_args[] = { }; static const struct iw_handler_def rndis_iw_handlers = { .num_standard = ARRAY_SIZE(rndis_iw_handler), - .num_private = ARRAY_SIZE(rndis_wlan_private_handler), - .num_private_args = ARRAY_SIZE(rndis_wlan_private_args), + .num_private = ARRAY_SIZE(rndis_wext_private_handler), + .num_private_args = ARRAY_SIZE(rndis_wext_private_args), .standard = (iw_handler *)rndis_iw_handler, - .private = (iw_handler *)rndis_wlan_private_handler, - .private_args = (struct iw_priv_args *)rndis_wlan_private_args, + .private = (iw_handler *)rndis_wext_private_handler, + .private_args = (struct iw_priv_args *)rndis_wext_private_args, .get_wireless_stats = rndis_get_wireless_stats, }; -static void rndis_wlan_worker(struct work_struct *work) +static void rndis_wext_worker(struct work_struct *work) { - struct rndis_wlan_private *priv = - container_of(work, struct rndis_wlan_private, work); + struct rndis_wext_private *priv = + container_of(work, struct rndis_wext_private, work); struct usbnet *usbdev = priv->usbdev; union iwreq_data evt; unsigned char bssid[ETH_ALEN]; @@ -2119,10 +2119,10 @@ static void rndis_wlan_worker(struct work_struct *work) set_multicast_list(usbdev); } -static void rndis_wlan_set_multicast_list(struct net_device *dev) +static void rndis_wext_set_multicast_list(struct net_device *dev) { struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) return; @@ -2131,9 +2131,9 @@ static void rndis_wlan_set_multicast_list(struct net_device *dev) queue_work(priv->workqueue, &priv->work); } -static void rndis_wlan_link_change(struct usbnet *usbdev, int state) +static void rndis_wext_link_change(struct usbnet *usbdev, int state) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* queue work to avoid recursive calls into rndis_command */ set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); @@ -2141,14 +2141,14 @@ static void rndis_wlan_link_change(struct usbnet *usbdev, int state) } -static int rndis_wlan_get_caps(struct usbnet *usbdev) +static int rndis_wext_get_caps(struct usbnet *usbdev) { struct { __le32 num_items; __le32 items[8]; } networks_supported; int len, retval, i, n; - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* determine supported modes */ len = sizeof(networks_supported); @@ -2160,14 +2160,14 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev) n = 8; for (i = 0; i < n; i++) { switch (le32_to_cpu(networks_supported.items[i])) { - case NDIS_80211_TYPE_FREQ_HOP: - case NDIS_80211_TYPE_DIRECT_SEQ: + case ndis_80211_type_freq_hop: + case ndis_80211_type_direct_seq: priv->caps |= CAP_MODE_80211B; break; - case NDIS_80211_TYPE_OFDM_A: + case ndis_80211_type_ofdm_a: priv->caps |= CAP_MODE_80211A; break; - case NDIS_80211_TYPE_OFDM_G: + case ndis_80211_type_ofdm_g: priv->caps |= CAP_MODE_80211G; break; } @@ -2181,8 +2181,8 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev) #define STATS_UPDATE_JIFFIES (HZ) static void rndis_update_wireless_stats(struct work_struct *work) { - struct rndis_wlan_private *priv = - container_of(work, struct rndis_wlan_private, stats_work.work); + struct rndis_wext_private *priv = + container_of(work, struct rndis_wext_private, stats_work.work); struct usbnet *usbdev = priv->usbdev; struct iw_statistics iwstats; __le32 rssi, tmp; @@ -2297,7 +2297,7 @@ static int bcm4320a_early_init(struct usbnet *usbdev) static int bcm4320b_early_init(struct usbnet *usbdev) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); char buf[8]; /* Early initialization settings, setting these won't have effect @@ -2363,21 +2363,21 @@ static int bcm4320b_early_init(struct usbnet *usbdev) } /* same as rndis_netdev_ops but with local multicast handler */ -static const struct net_device_ops rndis_wlan_netdev_ops = { +static const struct net_device_ops rndis_wext_netdev_ops = { .ndo_open = usbnet_open, .ndo_stop = usbnet_stop, .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, - .ndo_set_multicast_list = rndis_wlan_set_multicast_list, + .ndo_set_multicast_list = rndis_wext_set_multicast_list, }; -static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) +static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) { struct wiphy *wiphy; - struct rndis_wlan_private *priv; + struct rndis_wext_private *priv; int retval, len; __le32 tmp; @@ -2385,7 +2385,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) * NOTE: We only support a single virtual interface, so wiphy * and wireless_dev are somewhat synonymous for this device. */ - wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wlan_private)); + wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wext_private)); if (!wiphy) return -ENOMEM; @@ -2395,7 +2395,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) priv->wdev.iftype = NL80211_IFTYPE_STATION; /* These have to be initialized before calling generic_rndis_bind(). - * Otherwise we'll be in big trouble in rndis_wlan_early_init(). + * Otherwise we'll be in big trouble in rndis_wext_early_init(). */ usbdev->driver_priv = priv; usbdev->net->wireless_handlers = &rndis_iw_handlers; @@ -2406,7 +2406,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) /* because rndis_command() sleeps we need to use workqueue */ priv->workqueue = create_singlethread_workqueue("rndis_wlan"); - INIT_WORK(&priv->work, rndis_wlan_worker); + INIT_WORK(&priv->work, rndis_wext_worker); INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); @@ -2420,9 +2420,9 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) * picks up rssi to closest station instead of to access point). * * rndis_host wants to avoid all OID as much as possible - * so do promisc/multicast handling in rndis_wlan. + * so do promisc/multicast handling in rndis_wext. */ - usbdev->net->netdev_ops = &rndis_wlan_netdev_ops; + usbdev->net->netdev_ops = &rndis_wext_netdev_ops; tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, @@ -2455,7 +2455,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) wiphy->max_scan_ssids = 1; /* TODO: fill-out band information based on priv->caps */ - rndis_wlan_get_caps(usbdev); + rndis_wext_get_caps(usbdev); memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); @@ -2497,9 +2497,9 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) } -static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) +static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) { - struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* turn radio off */ disassociate(usbdev, 0); @@ -2520,7 +2520,7 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) } -static int rndis_wlan_reset(struct usbnet *usbdev) +static int rndis_wext_reset(struct usbnet *usbdev) { return deauthenticate(usbdev); } @@ -2529,40 +2529,40 @@ static int rndis_wlan_reset(struct usbnet *usbdev) static const struct driver_info bcm4320b_info = { .description = "Wireless RNDIS device, BCM4320b based", .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .bind = rndis_wlan_bind, - .unbind = rndis_wlan_unbind, + .bind = rndis_wext_bind, + .unbind = rndis_wext_unbind, .status = rndis_status, .rx_fixup = rndis_rx_fixup, .tx_fixup = rndis_tx_fixup, - .reset = rndis_wlan_reset, + .reset = rndis_wext_reset, .early_init = bcm4320b_early_init, - .link_change = rndis_wlan_link_change, + .link_change = rndis_wext_link_change, }; static const struct driver_info bcm4320a_info = { .description = "Wireless RNDIS device, BCM4320a based", .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .bind = rndis_wlan_bind, - .unbind = rndis_wlan_unbind, + .bind = rndis_wext_bind, + .unbind = rndis_wext_unbind, .status = rndis_status, .rx_fixup = rndis_rx_fixup, .tx_fixup = rndis_tx_fixup, - .reset = rndis_wlan_reset, + .reset = rndis_wext_reset, .early_init = bcm4320a_early_init, - .link_change = rndis_wlan_link_change, + .link_change = rndis_wext_link_change, }; -static const struct driver_info rndis_wlan_info = { +static const struct driver_info rndis_wext_info = { .description = "Wireless RNDIS device", .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .bind = rndis_wlan_bind, - .unbind = rndis_wlan_unbind, + .bind = rndis_wext_bind, + .unbind = rndis_wext_unbind, .status = rndis_status, .rx_fixup = rndis_rx_fixup, .tx_fixup = rndis_tx_fixup, - .reset = rndis_wlan_reset, + .reset = rndis_wext_reset, .early_init = bcm4320a_early_init, - .link_change = rndis_wlan_link_change, + .link_change = rndis_wext_link_change, }; /*-------------------------------------------------------------------------*/ @@ -2672,11 +2672,11 @@ static const struct usb_device_id products [] = { { /* RNDIS is MSFT's un-official variant of CDC ACM */ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), - .driver_info = (unsigned long) &rndis_wlan_info, + .driver_info = (unsigned long) &rndis_wext_info, }, { /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), - .driver_info = (unsigned long) &rndis_wlan_info, + .driver_info = (unsigned long) &rndis_wext_info, }, { }, // END }; diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index 09a503e5da6a..b618fa51db2d 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -988,6 +988,7 @@ static struct rfkill *acer_rfkill_register(struct device *dev, char *name, u32 cap) { int err; + u32 state; struct rfkill *rfkill_dev; rfkill_dev = rfkill_alloc(name, dev, type, @@ -995,6 +996,8 @@ static struct rfkill *acer_rfkill_register(struct device *dev, (void *)(unsigned long)cap); if (!rfkill_dev) return ERR_PTR(-ENOMEM); + get_u32(&state, cap); + rfkill_set_sw_state(rfkill_dev, !state); err = rfkill_register(rfkill_dev); if (err) { diff --git a/trunk/drivers/platform/x86/eeepc-laptop.c b/trunk/drivers/platform/x86/eeepc-laptop.c index 03bf522bd7ab..1208d0cedd15 100644 --- a/trunk/drivers/platform/x86/eeepc-laptop.c +++ b/trunk/drivers/platform/x86/eeepc-laptop.c @@ -675,8 +675,8 @@ static int eeepc_hotk_add(struct acpi_device *device) if (!ehotk->eeepc_wlan_rfkill) goto wlan_fail; - rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, - get_acpi(CM_ASL_WLAN) != 1); + rfkill_set_global_sw_state(RFKILL_TYPE_WLAN, + get_acpi(CM_ASL_WLAN) != 1); result = rfkill_register(ehotk->eeepc_wlan_rfkill); if (result) goto wlan_fail; @@ -693,8 +693,8 @@ static int eeepc_hotk_add(struct acpi_device *device) if (!ehotk->eeepc_bluetooth_rfkill) goto bluetooth_fail; - rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, - get_acpi(CM_ASL_BLUETOOTH) != 1); + rfkill_set_global_sw_state(RFKILL_TYPE_BLUETOOTH, + get_acpi(CM_ASL_BLUETOOTH) != 1); result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); if (result) goto bluetooth_fail; diff --git a/trunk/drivers/platform/x86/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c index 16fffe44e333..8d931145cbfa 100644 --- a/trunk/drivers/platform/x86/hp-wmi.c +++ b/trunk/drivers/platform/x86/hp-wmi.c @@ -422,6 +422,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) RFKILL_TYPE_WLAN, &hp_wmi_rfkill_ops, (void *) 0); + rfkill_set_sw_state(wifi_rfkill, hp_wmi_wifi_state()); err = rfkill_register(wifi_rfkill); if (err) goto register_wifi_error; @@ -432,6 +433,8 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) RFKILL_TYPE_BLUETOOTH, &hp_wmi_rfkill_ops, (void *) 1); + rfkill_set_sw_state(bluetooth_rfkill, + hp_wmi_bluetooth_state()); err = rfkill_register(bluetooth_rfkill); if (err) goto register_bluetooth_error; @@ -442,6 +445,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) RFKILL_TYPE_WWAN, &hp_wmi_rfkill_ops, (void *) 2); + rfkill_set_sw_state(wwan_rfkill, hp_wmi_wwan_state()); err = rfkill_register(wwan_rfkill); if (err) goto register_wwan_err; diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index e48d9a4506ff..aec0b27fd774 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -1114,6 +1114,7 @@ static int sony_nc_setup_rfkill(struct acpi_device *device, return err; } sony_rfkill_devices[nc_type] = rfk; + sony_nc_rfkill_set((void *)nc_type, false); return err; } @@ -1134,7 +1135,8 @@ static void sony_nc_rfkill_update() if (hwblock) { if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) - sony_nc_rfkill_set((void *)i, true); + sony_nc_rfkill_set(sony_rfkill_devices[i], + true); continue; } diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index 86e958539f46..cfcafa4e9473 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -1168,6 +1168,21 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); + initial_sw_status = (tp_rfkops->get_status)(); + if (initial_sw_status < 0) { + printk(TPACPI_ERR + "failed to read initial state for %s, error %d; " + "will turn radio off\n", name, initial_sw_status); + } else { + initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF); + if (set_default) { + /* try to set the initial state as the default for the + * rfkill type, since we ask the firmware to preserve + * it across S5 in NVRAM */ + rfkill_set_global_sw_state(rfktype, initial_sw_state); + } + } + atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL); if (atp_rfk) atp_rfk->rfkill = rfkill_alloc(name, @@ -1185,20 +1200,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, atp_rfk->id = id; atp_rfk->ops = tp_rfkops; - initial_sw_status = (tp_rfkops->get_status)(); - if (initial_sw_status < 0) { - printk(TPACPI_ERR - "failed to read initial state for %s, error %d\n", - name, initial_sw_status); - } else { - initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF); - if (set_default) { - /* try to keep the initial state, since we ask the - * firmware to preserve it across S5 in NVRAM */ - rfkill_set_sw_state(atp_rfk->rfkill, initial_sw_state); - } - } - rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state()); + rfkill_set_states(atp_rfk->rfkill, initial_sw_state, + tpacpi_rfk_check_hwblock_state()); res = rfkill_register(atp_rfk->rfkill); if (res < 0) { diff --git a/trunk/include/linux/ethtool.h b/trunk/include/linux/ethtool.h index 9b660bd2e2b3..380b04272bf1 100644 --- a/trunk/include/linux/ethtool.h +++ b/trunk/include/linux/ethtool.h @@ -30,8 +30,7 @@ struct ethtool_cmd { __u32 maxtxpkt; /* Tx pkts before generating tx int */ __u32 maxrxpkt; /* Rx pkts before generating rx int */ __u16 speed_hi; - __u8 eth_tp_mdix; - __u8 reserved2; + __u16 reserved2; __u32 lp_advertising; /* Features the link partner advertises */ __u32 reserved[2]; }; @@ -633,11 +632,6 @@ struct ethtool_ops { #define AUTONEG_DISABLE 0x00 #define AUTONEG_ENABLE 0x01 -/* Mode MDI or MDI-X */ -#define ETH_TP_MDI_INVALID 0x00 -#define ETH_TP_MDI 0x01 -#define ETH_TP_MDI_X 0x02 - /* Wake-On-Lan options. */ #define WAKE_PHY (1 << 0) #define WAKE_UCAST (1 << 1) diff --git a/trunk/include/linux/if_arp.h b/trunk/include/linux/if_arp.h index b554300ef8bf..5ff89809a581 100644 --- a/trunk/include/linux/if_arp.h +++ b/trunk/include/linux/if_arp.h @@ -86,8 +86,6 @@ #define ARPHRD_IEEE80211 801 /* IEEE 802.11 */ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ -#define ARPHRD_IEEE802154 804 -#define ARPHRD_IEEE802154_PHY 805 #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ diff --git a/trunk/include/linux/if_ether.h b/trunk/include/linux/if_ether.h index 11a60e4f0a66..cfe4fe1b7132 100644 --- a/trunk/include/linux/if_ether.h +++ b/trunk/include/linux/if_ether.h @@ -106,7 +106,6 @@ #define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ #define ETH_P_TRAILER 0x001C /* Trailer switch tagging */ #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ -#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */ /* * This is an Ethernet frame header. diff --git a/trunk/include/linux/isdn/capilli.h b/trunk/include/linux/isdn/capilli.h index 7acb87a44872..35e9b0fd014b 100644 --- a/trunk/include/linux/isdn/capilli.h +++ b/trunk/include/linux/isdn/capilli.h @@ -79,7 +79,7 @@ int attach_capi_ctr(struct capi_ctr *); int detach_capi_ctr(struct capi_ctr *); void capi_ctr_ready(struct capi_ctr * card); -void capi_ctr_down(struct capi_ctr * card); +void capi_ctr_reseted(struct capi_ctr * card); void capi_ctr_suspend_output(struct capi_ctr * card); void capi_ctr_resume_output(struct capi_ctr * card); void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb); diff --git a/trunk/include/linux/mdio.h b/trunk/include/linux/mdio.h index cfdf1df2875e..56851646529a 100644 --- a/trunk/include/linux/mdio.h +++ b/trunk/include/linux/mdio.h @@ -45,7 +45,6 @@ #define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */ /* Media-dependent registers. */ -#define MDIO_PMA_10GBT_SWAPPOL 130 /* 10GBASE-T pair swap & polarity */ #define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */ #define MDIO_PMA_10GBT_SNR 133 /* 10GBASE-T SNR margin, lane A. * Lanes B-D are numbered 134-136. */ @@ -196,14 +195,6 @@ #define MDIO_PHYXS_LNSTAT_SYNC3 0x0008 #define MDIO_PHYXS_LNSTAT_ALIGN 0x1000 -/* PMA 10GBASE-T pair swap & polarity */ -#define MDIO_PMA_10GBT_SWAPPOL_ABNX 0x0001 /* Pair A/B uncrossed */ -#define MDIO_PMA_10GBT_SWAPPOL_CDNX 0x0002 /* Pair C/D uncrossed */ -#define MDIO_PMA_10GBT_SWAPPOL_AREV 0x0100 /* Pair A polarity reversed */ -#define MDIO_PMA_10GBT_SWAPPOL_BREV 0x0200 /* Pair B polarity reversed */ -#define MDIO_PMA_10GBT_SWAPPOL_CREV 0x0400 /* Pair C polarity reversed */ -#define MDIO_PMA_10GBT_SWAPPOL_DREV 0x0800 /* Pair D polarity reversed */ - /* PMA 10GBASE-T TX power register. */ #define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 9ea8d6dfe540..2a801380b502 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -1904,7 +1904,7 @@ static inline int net_gso_ok(int features, int gso_type) static inline int skb_gso_ok(struct sk_buff *skb, int features) { return net_gso_ok(features, skb_shinfo(skb)->gso_type) && - (!skb_has_frags(skb) || (features & NETIF_F_FRAGLIST)); + (!skb_shinfo(skb)->frag_list || (features & NETIF_F_FRAGLIST)); } static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) diff --git a/trunk/include/linux/nl802154.h b/trunk/include/linux/nl802154.h deleted file mode 100644 index 2cda00ccfcca..000000000000 --- a/trunk/include/linux/nl802154.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * nl802154.h - * - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef NL802154_H -#define NL802154_H - -#define IEEE802154_NL_NAME "802.15.4 MAC" -#define IEEE802154_MCAST_COORD_NAME "coordinator" -#define IEEE802154_MCAST_BEACON_NAME "beacon" - -enum { - __IEEE802154_ATTR_INVALID, - - IEEE802154_ATTR_DEV_NAME, - IEEE802154_ATTR_DEV_INDEX, - - IEEE802154_ATTR_STATUS, - - IEEE802154_ATTR_SHORT_ADDR, - IEEE802154_ATTR_HW_ADDR, - IEEE802154_ATTR_PAN_ID, - - IEEE802154_ATTR_CHANNEL, - - IEEE802154_ATTR_COORD_SHORT_ADDR, - IEEE802154_ATTR_COORD_HW_ADDR, - IEEE802154_ATTR_COORD_PAN_ID, - - IEEE802154_ATTR_SRC_SHORT_ADDR, - IEEE802154_ATTR_SRC_HW_ADDR, - IEEE802154_ATTR_SRC_PAN_ID, - - IEEE802154_ATTR_DEST_SHORT_ADDR, - IEEE802154_ATTR_DEST_HW_ADDR, - IEEE802154_ATTR_DEST_PAN_ID, - - IEEE802154_ATTR_CAPABILITY, - IEEE802154_ATTR_REASON, - IEEE802154_ATTR_SCAN_TYPE, - IEEE802154_ATTR_CHANNELS, - IEEE802154_ATTR_DURATION, - IEEE802154_ATTR_ED_LIST, - IEEE802154_ATTR_BCN_ORD, - IEEE802154_ATTR_SF_ORD, - IEEE802154_ATTR_PAN_COORD, - IEEE802154_ATTR_BAT_EXT, - IEEE802154_ATTR_COORD_REALIGN, - IEEE802154_ATTR_SEC, - - __IEEE802154_ATTR_MAX, -}; - -#define IEEE802154_ATTR_MAX (__IEEE802154_ATTR_MAX - 1) - -extern struct nla_policy ieee802154_policy[]; - -/* commands */ -/* REQ should be responded with CONF - * and INDIC with RESP - */ -enum { - __IEEE802154_COMMAND_INVALID, - - IEEE802154_ASSOCIATE_REQ, - IEEE802154_ASSOCIATE_CONF, - IEEE802154_DISASSOCIATE_REQ, - IEEE802154_DISASSOCIATE_CONF, - IEEE802154_GET_REQ, - IEEE802154_GET_CONF, - IEEE802154_RESET_REQ, - IEEE802154_RESET_CONF, - IEEE802154_SCAN_REQ, - IEEE802154_SCAN_CONF, - IEEE802154_SET_REQ, - IEEE802154_SET_CONF, - IEEE802154_START_REQ, - IEEE802154_START_CONF, - IEEE802154_SYNC_REQ, - IEEE802154_POLL_REQ, - IEEE802154_POLL_CONF, - - IEEE802154_ASSOCIATE_INDIC, - IEEE802154_ASSOCIATE_RESP, - IEEE802154_DISASSOCIATE_INDIC, - IEEE802154_BEACON_NOTIFY_INDIC, - IEEE802154_ORPHAN_INDIC, - IEEE802154_ORPHAN_RESP, - IEEE802154_COMM_STATUS_INDIC, - IEEE802154_SYNC_LOSS_INDIC, - - IEEE802154_GTS_REQ, /* Not supported yet */ - IEEE802154_GTS_INDIC, /* Not supported yet */ - IEEE802154_GTS_CONF, /* Not supported yet */ - IEEE802154_RX_ENABLE_REQ, /* Not supported yet */ - IEEE802154_RX_ENABLE_CONF, /* Not supported yet */ - - __IEEE802154_CMD_MAX, -}; - -#define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1) - -#endif diff --git a/trunk/include/linux/rfkill.h b/trunk/include/linux/rfkill.h index 16e39c7a67fc..ee3eddea8568 100644 --- a/trunk/include/linux/rfkill.h +++ b/trunk/include/linux/rfkill.h @@ -105,7 +105,6 @@ enum rfkill_user_states { #include #include #include -#include /* this is opaque */ struct rfkill; @@ -157,14 +156,8 @@ struct rfkill * __must_check rfkill_alloc(const char *name, * @rfkill: rfkill structure to be registered * * This function should be called by the transmitter driver to register - * the rfkill structure. Before calling this function the driver needs - * to be ready to service method calls from rfkill. - * - * If the software blocked state is not set before registration, - * set_block will be called to initialize it to a default value. - * - * If the hardware blocked state is not set before registration, - * it is assumed to be unblocked. + * the rfkill structure needs to be registered. Before calling this function + * the driver needs to be ready to service method calls from rfkill. */ int __must_check rfkill_register(struct rfkill *rfkill); @@ -212,7 +205,7 @@ void rfkill_destroy(struct rfkill *rfkill); * * rfkill drivers that get events when the hard-blocked state changes * use this function to notify the rfkill core (and through that also - * userspace) of the current state. They should also use this after + * userspace) of the current state -- they should also use this after * resume if the state could have changed. * * You need not (but may) call this function if poll_state is assigned. @@ -234,9 +227,8 @@ bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); * rfkill drivers that get events when the soft-blocked state changes * (yes, some platforms directly act on input but allow changing again) * use this function to notify the rfkill core (and through that also - * userspace) of the current state. It is not necessary to notify on - * resume; since hibernation can always change the soft-blocked state, - * the rfkill core will unconditionally restore the previous state. + * userspace) of the current state -- they should also use this after + * resume if the state could have changed. * * This function can be called in any context, even from within rfkill * callbacks. @@ -257,6 +249,19 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked); */ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); +/** + * rfkill_set_global_sw_state - set global sw block default + * @type: rfkill type to set default for + * @blocked: default to set + * + * This function sets the global default -- use at boot if your platform has + * an rfkill switch. If not early enough this call may be ignored. + * + * XXX: instead of ignoring -- how about just updating all currently + * registered drivers? + */ +void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked); + /** * rfkill_blocked - query rfkill block * @@ -311,6 +316,11 @@ static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) { } +static inline void rfkill_set_global_sw_state(const enum rfkill_type type, + bool blocked) +{ +} + static inline bool rfkill_blocked(struct rfkill *rfkill) { return false; diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index fa51293f2708..7305da92be8f 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -189,19 +189,19 @@ struct skb_shared_info { atomic_t dataref; unsigned short nr_frags; unsigned short gso_size; -#ifdef CONFIG_HAS_DMA - dma_addr_t dma_head; -#endif /* Warning: this field is not always filled in (UFO)! */ unsigned short gso_segs; unsigned short gso_type; __be32 ip6_frag_id; union skb_shared_tx tx_flags; +#ifdef CONFIG_HAS_DMA + unsigned int num_dma_maps; +#endif struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; skb_frag_t frags[MAX_SKB_FRAGS]; #ifdef CONFIG_HAS_DMA - dma_addr_t dma_maps[MAX_SKB_FRAGS]; + dma_addr_t dma_maps[MAX_SKB_FRAGS + 1]; #endif /* Intermediate layers must ensure that destructor_arg * remains valid until skb destructor */ @@ -304,6 +304,9 @@ typedef unsigned char *sk_buff_data_t; * @tc_verd: traffic control verdict * @ndisc_nodetype: router type (from link layer) * @do_not_encrypt: set to prevent encryption of this frame + * @requeue: set to indicate that the wireless core should attempt + * a software retry on this frame if we failed to + * receive an ACK for it * @dma_cookie: a cookie to one of several possible DMA operations * done by skb DMA functions * @secmark: security marking @@ -377,6 +380,7 @@ struct sk_buff { #endif #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) __u8 do_not_encrypt:1; + __u8 requeue:1; #endif /* 0/13/14 bit hole */ @@ -1073,7 +1077,7 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, int size); #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) -#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frags(skb)) +#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_shinfo(skb)->frag_list) #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) #ifdef NET_SKBUFF_DATA_USES_OFFSET @@ -1712,25 +1716,6 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb = skb->prev) -static inline bool skb_has_frags(const struct sk_buff *skb) -{ - return skb_shinfo(skb)->frag_list != NULL; -} - -static inline void skb_frag_list_init(struct sk_buff *skb) -{ - skb_shinfo(skb)->frag_list = NULL; -} - -static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag) -{ - frag->next = skb_shinfo(skb)->frag_list; - skb_shinfo(skb)->frag_list = frag; -} - -#define skb_walk_frags(skb, iter) \ - for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next) - extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags, int *peeked, int *err); extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index 3b461dffe244..d2310cb45d2f 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -194,8 +194,7 @@ struct ucred { #define AF_RXRPC 33 /* RxRPC sockets */ #define AF_ISDN 34 /* mISDN sockets */ #define AF_PHONET 35 /* Phonet sockets */ -#define AF_IEEE802154 36 /* IEEE802154 sockets */ -#define AF_MAX 37 /* For now.. */ +#define AF_MAX 36 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -234,7 +233,6 @@ struct ucred { #define PF_RXRPC AF_RXRPC #define PF_ISDN AF_ISDN #define PF_PHONET AF_PHONET -#define PF_IEEE802154 AF_IEEE802154 #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ diff --git a/trunk/include/linux/spi/libertas_spi.h b/trunk/include/linux/spi/libertas_spi.h index 1b5d5384fcd3..79506f5f9e67 100644 --- a/trunk/include/linux/spi/libertas_spi.h +++ b/trunk/include/linux/spi/libertas_spi.h @@ -22,6 +22,9 @@ struct libertas_spi_platform_data { * speed, you may want to use 0 here. */ u16 use_dummy_writes; + /* GPIO number to use as chip select */ + u16 gpio_cs; + /* Board specific setup/teardown */ int (*setup)(struct spi_device *spi); int (*teardown)(struct spi_device *spi); diff --git a/trunk/include/net/bluetooth/bluetooth.h b/trunk/include/net/bluetooth/bluetooth.h index 144d1d5dd82f..3ad5390a4dd5 100644 --- a/trunk/include/net/bluetooth/bluetooth.h +++ b/trunk/include/net/bluetooth/bluetooth.h @@ -171,6 +171,15 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l return skb; } +static inline int skb_frags_no(struct sk_buff *skb) +{ + register struct sk_buff *frag = skb_shinfo(skb)->frag_list; + register int n = 1; + + for (; frag; frag=frag->next, n++); + return n; +} + int bt_err(__u16 code); extern int hci_sock_init(void); diff --git a/trunk/include/net/bluetooth/l2cap.h b/trunk/include/net/bluetooth/l2cap.h index f566aa1f0a4c..ed4ba913d94c 100644 --- a/trunk/include/net/bluetooth/l2cap.h +++ b/trunk/include/net/bluetooth/l2cap.h @@ -106,6 +106,12 @@ struct l2cap_conn_rsp { __le16 status; } __attribute__ ((packed)); +/* channel indentifier */ +#define L2CAP_CID_SIGNALING 0x0001 +#define L2CAP_CID_CONN_LESS 0x0002 +#define L2CAP_CID_DYN_START 0x0040 +#define L2CAP_CID_DYN_END 0xffff + /* connect result */ #define L2CAP_CR_SUCCESS 0x0000 #define L2CAP_CR_PEND 0x0001 diff --git a/trunk/include/net/ieee802154/af_ieee802154.h b/trunk/include/net/ieee802154/af_ieee802154.h deleted file mode 100644 index 0d78605fb1a6..000000000000 --- a/trunk/include/net/ieee802154/af_ieee802154.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * IEEE 802.15.4 inteface for userspace - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#ifndef _AF_IEEE802154_H -#define _AF_IEEE802154_H - -#include /* for sa_family_t */ - -enum { - IEEE802154_ADDR_NONE = 0x0, - /* RESERVED = 0x01, */ - IEEE802154_ADDR_SHORT = 0x2, /* 16-bit address + PANid */ - IEEE802154_ADDR_LONG = 0x3, /* 64-bit address + PANid */ -}; - -/* address length, octets */ -#define IEEE802154_ADDR_LEN 8 - -struct ieee802154_addr { - int addr_type; - u16 pan_id; - union { - u8 hwaddr[IEEE802154_ADDR_LEN]; - u16 short_addr; - }; -}; - -#define IEEE802154_PANID_BROADCAST 0xffff -#define IEEE802154_ADDR_BROADCAST 0xffff -#define IEEE802154_ADDR_UNDEF 0xfffe - -struct sockaddr_ieee802154 { - sa_family_t family; /* AF_IEEE802154 */ - struct ieee802154_addr addr; -}; - -/* master device */ -#define IEEE802154_SIOC_ADD_SLAVE (SIOCDEVPRIVATE + 0) - -#endif diff --git a/trunk/include/net/ieee802154/mac_def.h b/trunk/include/net/ieee802154/mac_def.h deleted file mode 100644 index 8cb684635650..000000000000 --- a/trunk/include/net/ieee802154/mac_def.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * IEEE802.15.4-2003 specification - * - * Copyright (C) 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Maxim Osipov - * Dmitry Eremin-Solenikov - */ - -#ifndef IEEE802154_MAC_DEF_H -#define IEEE802154_MAC_DEF_H - -#define IEEE802154_FC_TYPE_BEACON 0x0 /* Frame is beacon */ -#define IEEE802154_FC_TYPE_DATA 0x1 /* Frame is data */ -#define IEEE802154_FC_TYPE_ACK 0x2 /* Frame is acknowledgment */ -#define IEEE802154_FC_TYPE_MAC_CMD 0x3 /* Frame is MAC command */ - -#define IEEE802154_FC_TYPE_SHIFT 0 -#define IEEE802154_FC_TYPE_MASK ((1 << 3) - 1) -#define IEEE802154_FC_TYPE(x) ((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT) -#define IEEE802154_FC_SET_TYPE(v, x) do { \ - v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \ - (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \ - } while (0) - -#define IEEE802154_FC_SECEN (1 << 3) -#define IEEE802154_FC_FRPEND (1 << 4) -#define IEEE802154_FC_ACK_REQ (1 << 5) -#define IEEE802154_FC_INTRA_PAN (1 << 6) - -#define IEEE802154_FC_SAMODE_SHIFT 14 -#define IEEE802154_FC_SAMODE_MASK (3 << IEEE802154_FC_SAMODE_SHIFT) -#define IEEE802154_FC_DAMODE_SHIFT 10 -#define IEEE802154_FC_DAMODE_MASK (3 << IEEE802154_FC_DAMODE_SHIFT) - -#define IEEE802154_FC_SAMODE(x) \ - (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT) - -#define IEEE802154_FC_DAMODE(x) \ - (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) - - -/* MAC's Command Frames Identifiers */ -#define IEEE802154_CMD_ASSOCIATION_REQ 0x01 -#define IEEE802154_CMD_ASSOCIATION_RESP 0x02 -#define IEEE802154_CMD_DISASSOCIATION_NOTIFY 0x03 -#define IEEE802154_CMD_DATA_REQ 0x04 -#define IEEE802154_CMD_PANID_CONFLICT_NOTIFY 0x05 -#define IEEE802154_CMD_ORPHAN_NOTIFY 0x06 -#define IEEE802154_CMD_BEACON_REQ 0x07 -#define IEEE802154_CMD_COORD_REALIGN_NOTIFY 0x08 -#define IEEE802154_CMD_GTS_REQ 0x09 - -/* - * The return values of MAC operations - */ -enum { - /* - * The requested operation was completed successfully. - * For a transmission request, this value indicates - * a successful transmission. - */ - IEEE802154_SUCCESS = 0x0, - - /* The beacon was lost following a synchronization request. */ - IEEE802154_BEACON_LOSS = 0xe0, - /* - * A transmission could not take place due to activity on the - * channel, i.e., the CSMA-CA mechanism has failed. - */ - IEEE802154_CHNL_ACCESS_FAIL = 0xe1, - /* The GTS request has been denied by the PAN coordinator. */ - IEEE802154_DENINED = 0xe2, - /* The attempt to disable the transceiver has failed. */ - IEEE802154_DISABLE_TRX_FAIL = 0xe3, - /* - * The received frame induces a failed security check according to - * the security suite. - */ - IEEE802154_FAILED_SECURITY_CHECK = 0xe4, - /* - * The frame resulting from secure processing has a length that is - * greater than aMACMaxFrameSize. - */ - IEEE802154_FRAME_TOO_LONG = 0xe5, - /* - * The requested GTS transmission failed because the specified GTS - * either did not have a transmit GTS direction or was not defined. - */ - IEEE802154_INVALID_GTS = 0xe6, - /* - * A request to purge an MSDU from the transaction queue was made using - * an MSDU handle that was not found in the transaction table. - */ - IEEE802154_INVALID_HANDLE = 0xe7, - /* A parameter in the primitive is out of the valid range.*/ - IEEE802154_INVALID_PARAMETER = 0xe8, - /* No acknowledgment was received after aMaxFrameRetries. */ - IEEE802154_NO_ACK = 0xe9, - /* A scan operation failed to find any network beacons.*/ - IEEE802154_NO_BEACON = 0xea, - /* No response data were available following a request. */ - IEEE802154_NO_DATA = 0xeb, - /* The operation failed because a short address was not allocated. */ - IEEE802154_NO_SHORT_ADDRESS = 0xec, - /* - * A receiver enable request was unsuccessful because it could not be - * completed within the CAP. - */ - IEEE802154_OUT_OF_CAP = 0xed, - /* - * A PAN identifier conflict has been detected and communicated to the - * PAN coordinator. - */ - IEEE802154_PANID_CONFLICT = 0xee, - /* A coordinator realignment command has been received. */ - IEEE802154_REALIGMENT = 0xef, - /* The transaction has expired and its information discarded. */ - IEEE802154_TRANSACTION_EXPIRED = 0xf0, - /* There is no capacity to store the transaction. */ - IEEE802154_TRANSACTION_OVERFLOW = 0xf1, - /* - * The transceiver was in the transmitter enabled state when the - * receiver was requested to be enabled. - */ - IEEE802154_TX_ACTIVE = 0xf2, - /* The appropriate key is not available in the ACL. */ - IEEE802154_UNAVAILABLE_KEY = 0xf3, - /* - * A SET/GET request was issued with the identifier of a PIB attribute - * that is not supported. - */ - IEEE802154_UNSUPPORTED_ATTR = 0xf4, - /* - * A request to perform a scan operation failed because the MLME was - * in the process of performing a previously initiated scan operation. - */ - IEEE802154_SCAN_IN_PROGRESS = 0xfc, -}; - - -#endif - - diff --git a/trunk/include/net/ieee802154/netdevice.h b/trunk/include/net/ieee802154/netdevice.h deleted file mode 100644 index e2506af3e7c8..000000000000 --- a/trunk/include/net/ieee802154/netdevice.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * An interface between IEEE802.15.4 device and rest of the kernel. - * - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Pavel Smolenskiy - * Maxim Gorbachyov - * Maxim Osipov - * Dmitry Eremin-Solenikov - */ - -#ifndef IEEE802154_NETDEVICE_H -#define IEEE802154_NETDEVICE_H - -/* - * A control block of skb passed between the ARPHRD_IEEE802154 device - * and other stack parts. - */ -struct ieee802154_mac_cb { - u8 lqi; - struct ieee802154_addr sa; - struct ieee802154_addr da; - u8 flags; - u8 seq; -}; - -static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb) -{ - return (struct ieee802154_mac_cb *)skb->cb; -} - -#define MAC_CB_FLAG_TYPEMASK ((1 << 3) - 1) - -#define MAC_CB_FLAG_ACKREQ (1 << 3) -#define MAC_CB_FLAG_SECEN (1 << 4) -#define MAC_CB_FLAG_INTRAPAN (1 << 5) - -static inline int mac_cb_is_ackreq(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ; -} - -static inline int mac_cb_is_secen(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN; -} - -static inline int mac_cb_is_intrapan(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN; -} - -static inline int mac_cb_type(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK; -} - -#define IEEE802154_MAC_SCAN_ED 0 -#define IEEE802154_MAC_SCAN_ACTIVE 1 -#define IEEE802154_MAC_SCAN_PASSIVE 2 -#define IEEE802154_MAC_SCAN_ORPHAN 3 - -/* - * This should be located at net_device->ml_priv - */ -struct ieee802154_mlme_ops { - int (*assoc_req)(struct net_device *dev, - struct ieee802154_addr *addr, - u8 channel, u8 cap); - int (*assoc_resp)(struct net_device *dev, - struct ieee802154_addr *addr, - u16 short_addr, u8 status); - int (*disassoc_req)(struct net_device *dev, - struct ieee802154_addr *addr, - u8 reason); - int (*start_req)(struct net_device *dev, - struct ieee802154_addr *addr, - u8 channel, u8 bcn_ord, u8 sf_ord, - u8 pan_coord, u8 blx, u8 coord_realign); - int (*scan_req)(struct net_device *dev, - u8 type, u32 channels, u8 duration); - - /* - * FIXME: these should become the part of PIB/MIB interface. - * However we still don't have IB interface of any kind - */ - u16 (*get_pan_id)(struct net_device *dev); - u16 (*get_short_addr)(struct net_device *dev); - u8 (*get_dsn)(struct net_device *dev); - u8 (*get_bsn)(struct net_device *dev); -}; - -static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops( - struct net_device *dev) -{ - return dev->ml_priv; -} - -#endif - - diff --git a/trunk/include/net/ieee802154/nl802154.h b/trunk/include/net/ieee802154/nl802154.h deleted file mode 100644 index 78efcdf52b59..000000000000 --- a/trunk/include/net/ieee802154/nl802154.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * nl802154.h - * - * Copyright (C) 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef IEEE802154_NL_H -#define IEEE802154_NL_H - -struct net_device; -struct ieee802154_addr; - -int ieee802154_nl_assoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 cap); -int ieee802154_nl_assoc_confirm(struct net_device *dev, - u16 short_addr, u8 status); -int ieee802154_nl_disassoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 reason); -int ieee802154_nl_disassoc_confirm(struct net_device *dev, - u8 status); -int ieee802154_nl_scan_confirm(struct net_device *dev, - u8 status, u8 scan_type, u32 unscanned, - u8 *edl/*, struct list_head *pan_desc_list */); -int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid, - u16 coord_addr); - -#endif diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index c06104476973..17d61d19d912 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -239,8 +239,6 @@ struct ieee80211_bss_conf { * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, * used to indicate that a pending frame requires TX processing before * it can be sent out. - * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, - * used to indicate that a frame was already retried due to PS */ enum mac80211_tx_control_flags { IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), @@ -258,7 +256,6 @@ enum mac80211_tx_control_flags { IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), IEEE80211_TX_INTFL_RCALGO = BIT(13), IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), - IEEE80211_TX_INTFL_RETRIED = BIT(15), }; /** diff --git a/trunk/include/net/pkt_sched.h b/trunk/include/net/pkt_sched.h index 120935b2abd8..e37fe3129c17 100644 --- a/trunk/include/net/pkt_sched.h +++ b/trunk/include/net/pkt_sched.h @@ -41,10 +41,9 @@ static inline void *qdisc_priv(struct Qdisc *q) typedef u64 psched_time_t; typedef long psched_tdiff_t; -/* Avoid doing 64 bit divide */ -#define PSCHED_SHIFT 6 -#define PSCHED_US2NS(x) ((s64)(x) << PSCHED_SHIFT) -#define PSCHED_NS2US(x) ((x) >> PSCHED_SHIFT) +/* Avoid doing 64 bit divide by 1000 */ +#define PSCHED_US2NS(x) ((s64)(x) << 10) +#define PSCHED_NS2US(x) ((x) >> 10) #define PSCHED_TICKS_PER_SEC PSCHED_NS2US(NSEC_PER_SEC) #define PSCHED_PASTPERFECT 0 diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 010e14a93c92..4bb1ff9fd15b 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -1217,13 +1217,9 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from, static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk) { + sock_hold(sk); skb->sk = sk; skb->destructor = sock_wfree; - /* - * We used to take a refcount on sk, but following operation - * is enough to guarantee sk_free() wont free this sock until - * all in-flight packets are completed - */ atomic_add(skb->truesize, &sk->sk_wmem_alloc); } diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index fe649081fbdc..714e1c3536be 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -758,7 +758,7 @@ static void __exit vlan_cleanup_module(void) BUG_ON(!hlist_empty(&vlan_group_hash[i])); unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ + synchronize_net(); vlan_gvrp_uninit(); } diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index 7051b9710675..c19f549c8e74 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -179,7 +179,6 @@ source "net/lapb/Kconfig" source "net/econet/Kconfig" source "net/wanrouter/Kconfig" source "net/phonet/Kconfig" -source "net/ieee802154/Kconfig" source "net/sched/Kconfig" source "net/dcb/Kconfig" diff --git a/trunk/net/Makefile b/trunk/net/Makefile index ba324aefda73..9e00a55a901b 100644 --- a/trunk/net/Makefile +++ b/trunk/net/Makefile @@ -60,7 +60,6 @@ obj-$(CONFIG_NET_9P) += 9p/ ifneq ($(CONFIG_DCB),) obj-y += dcb/ endif -obj-y += ieee802154/ ifeq ($(CONFIG_NET),y) obj-$(CONFIG_SYSCTL) += sysctl_net.o diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index b603cbacdc58..d6a9243641af 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -939,7 +939,6 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, int len, unsigned long sum) { int start = skb_headlen(skb); - struct sk_buff *frag_iter; int i, copy; /* checksum stuff in header space */ @@ -978,22 +977,26 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - WARN_ON(start > offset + len); + for (; list; list = list->next) { + int end; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - sum = atalk_sum_skb(frag_iter, offset - start, - copy, sum); - if ((len -= copy) == 0) - return sum; - offset += copy; + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + sum = atalk_sum_skb(list, offset - start, + copy, sum); + if ((len -= copy) == 0) + return sum; + offset += copy; + } + start = end; } - start = end; } BUG_ON(len > 0); diff --git a/trunk/net/bluetooth/cmtp/capi.c b/trunk/net/bluetooth/cmtp/capi.c index 97f8d68d574d..78958c0f9a40 100644 --- a/trunk/net/bluetooth/cmtp/capi.c +++ b/trunk/net/bluetooth/cmtp/capi.c @@ -382,7 +382,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) BT_DBG("ctrl %p", ctrl); - capi_ctr_down(ctrl); + capi_ctr_reseted(ctrl); atomic_inc(&session->terminate); cmtp_schedule(session); diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index ca4d3b40d5ce..ff1744e34cd8 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -161,9 +161,9 @@ static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) { - u16 cid = 0x0040; + u16 cid = L2CAP_CID_DYN_START; - for (; cid < 0xffff; cid++) { + for (; cid < L2CAP_CID_DYN_END; cid++) { if(!__l2cap_get_chan_by_scid(l, cid)) return cid; } @@ -215,13 +215,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so l2cap_pi(sk)->scid = l2cap_alloc_cid(l); } else if (sk->sk_type == SOCK_DGRAM) { /* Connectionless socket */ - l2cap_pi(sk)->scid = 0x0002; - l2cap_pi(sk)->dcid = 0x0002; + l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS; + l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS; l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; } else { /* Raw socket can send/recv signalling messages only */ - l2cap_pi(sk)->scid = 0x0001; - l2cap_pi(sk)->dcid = 0x0001; + l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING; + l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING; l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; } @@ -1598,7 +1598,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); - lh->cid = cpu_to_le16(0x0001); + lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); cmd->code = code; @@ -2420,11 +2420,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) BT_DBG("len %d, cid 0x%4.4x", len, cid); switch (cid) { - case 0x0001: + case L2CAP_CID_SIGNALING: l2cap_sig_channel(conn, skb); break; - case 0x0002: + case L2CAP_CID_CONN_LESS: psm = get_unaligned((__le16 *) skb->data); skb_pull(skb, 2); l2cap_conless_channel(conn, psm, skb); diff --git a/trunk/net/can/af_can.c b/trunk/net/can/af_can.c index e733725b11d4..10f0528c3bf5 100644 --- a/trunk/net/can/af_can.c +++ b/trunk/net/can/af_can.c @@ -903,8 +903,6 @@ static __exit void can_exit(void) } spin_unlock(&can_rcvlists_lock); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ - kmem_cache_destroy(rcv_cache); } diff --git a/trunk/net/core/datagram.c b/trunk/net/core/datagram.c index 58abee1f1df1..e2a36f05cdf7 100644 --- a/trunk/net/core/datagram.c +++ b/trunk/net/core/datagram.c @@ -282,7 +282,6 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; /* Copy header. */ if (copy > 0) { @@ -323,24 +322,28 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_iovec(frag_iter, - offset - start, - to, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_iovec(list, + offset - start, + to, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -366,7 +369,6 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; /* Copy header. */ if (copy > 0) { @@ -409,26 +411,30 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_const_iovec(frag_iter, - offset - start, - to, to_offset, - copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - to_offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_const_iovec(list, + offset - start, + to, to_offset, + copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + to_offset += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -455,14 +461,12 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; /* Copy header. */ if (copy > 0) { if (copy > len) copy = len; - if (memcpy_fromiovecend(skb->data + offset, from, from_offset, - copy)) + if (memcpy_fromiovecend(skb->data + offset, from, 0, copy)) goto fault; if ((len -= copy) == 0) return 0; @@ -501,27 +505,31 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_datagram_from_iovec(frag_iter, - offset - start, - from, - from_offset, - copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - from_offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_from_iovec(list, + offset - start, + from, + from_offset, + copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + from_offset += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -536,9 +544,8 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, __wsum *csump) { int start = skb_headlen(skb); - int i, copy = start - offset; - struct sk_buff *frag_iter; int pos = 0; + int i, copy = start - offset; /* Copy header. */ if (copy > 0) { @@ -589,29 +596,33 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - __wsum csum2 = 0; - if (copy > len) - copy = len; - if (skb_copy_and_csum_datagram(frag_iter, - offset - start, - to, copy, - &csum2)) - goto fault; - *csump = csum_block_add(*csump, csum2, pos); - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; - pos += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list=list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + __wsum csum2 = 0; + if (copy > len) + copy = len; + if (skb_copy_and_csum_datagram(list, + offset - start, + to, copy, + &csum2)) + goto fault; + *csump = csum_block_add(*csump, csum2, pos); + if ((len -= copy) == 0) + return 0; + offset += copy; + to += copy; + pos += copy; + } + start = end; } - start = end; } if (!len) return 0; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 11560e3258b5..1f38401fc028 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -269,8 +269,7 @@ static const unsigned short netdev_lock_type[] = ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, - ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY, - ARPHRD_VOID, ARPHRD_NONE}; + ARPHRD_PHONET_PIPE, ARPHRD_VOID, ARPHRD_NONE}; static const char *netdev_lock_name[] = {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", @@ -287,8 +286,7 @@ static const char *netdev_lock_name[] = "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", - "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY", - "_xmit_VOID", "_xmit_NONE"}; + "_xmit_PHONET_PIPE", "_xmit_VOID", "_xmit_NONE"}; static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; @@ -1822,7 +1820,7 @@ int dev_queue_xmit(struct sk_buff *skb) if (netif_needs_gso(dev, skb)) goto gso; - if (skb_has_frags(skb) && + if (skb_shinfo(skb)->frag_list && !(dev->features & NETIF_F_FRAGLIST) && __skb_linearize(skb)) goto out_kfree_skb; @@ -2409,7 +2407,7 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) if (!(skb->dev->features & NETIF_F_GRO)) goto normal; - if (skb_is_gso(skb) || skb_has_frags(skb)) + if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list) goto normal; rcu_read_lock(); @@ -3657,8 +3655,8 @@ static int dev_addr_init(struct net_device *dev) /* rtnl_mutex must be held here */ INIT_LIST_HEAD(&dev->dev_addr_list); - memset(addr, 0, sizeof(addr)); - err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr), + memset(addr, 0, sizeof(*addr)); + err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(*addr), NETDEV_HW_ADDR_T_LAN); if (!err) { /* diff --git a/trunk/net/core/iovec.c b/trunk/net/core/iovec.c index 16ad45d4882b..40a76ce19d9f 100644 --- a/trunk/net/core/iovec.c +++ b/trunk/net/core/iovec.c @@ -112,9 +112,9 @@ int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, continue; } copy = min_t(unsigned int, iov->iov_len - offset, len); - if (copy_to_user(iov->iov_base + offset, kdata, copy)) - return -EFAULT; offset = 0; + if (copy_to_user(iov->iov_base, kdata, copy)) + return -EFAULT; kdata += copy; len -= copy; } diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 163b4f5b0365..c54229befcfe 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -771,28 +771,6 @@ static __inline__ int neigh_max_probes(struct neighbour *n) p->ucast_probes + p->app_probes + p->mcast_probes); } -static void neigh_invalidate(struct neighbour *neigh) -{ - struct sk_buff *skb; - - NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); - NEIGH_PRINTK2("neigh %p is failed.\n", neigh); - neigh->updated = jiffies; - - /* It is very thin place. report_unreachable is very complicated - routine. Particularly, it can hit the same neighbour entry! - - So that, we try to be accurate and avoid dead loop. --ANK - */ - while (neigh->nud_state == NUD_FAILED && - (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { - write_unlock(&neigh->lock); - neigh->ops->error_report(neigh, skb); - write_lock(&neigh->lock); - } - skb_queue_purge(&neigh->arp_queue); -} - /* Called when a timer expires for a neighbour entry. */ static void neigh_timer_handler(unsigned long arg) @@ -857,9 +835,26 @@ static void neigh_timer_handler(unsigned long arg) if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { + struct sk_buff *skb; + neigh->nud_state = NUD_FAILED; + neigh->updated = jiffies; notify = 1; - neigh_invalidate(neigh); + NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); + NEIGH_PRINTK2("neigh %p is failed.\n", neigh); + + /* It is very thin place. report_unreachable is very complicated + routine. Particularly, it can hit the same neighbour entry! + + So that, we try to be accurate and avoid dead loop. --ANK + */ + while (neigh->nud_state == NUD_FAILED && + (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { + write_unlock(&neigh->lock); + neigh->ops->error_report(neigh, skb); + write_lock(&neigh->lock); + } + skb_queue_purge(&neigh->arp_queue); } if (neigh->nud_state & NUD_IN_TIMER) { @@ -1006,11 +1001,6 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, neigh->nud_state = new; err = 0; notify = old & NUD_VALID; - if ((old & (NUD_INCOMPLETE | NUD_PROBE)) && - (new & NUD_FAILED)) { - neigh_invalidate(neigh); - notify = 1; - } goto out; } diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 19b8c20e98a4..b8ccd3c88d63 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -3691,7 +3691,8 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) #ifdef CONFIG_XFRM free_SAs(pkt_dev); #endif - vfree(pkt_dev->flows); + if (pkt_dev->flows) + vfree(pkt_dev->flows); kfree(pkt_dev); return err; } @@ -3790,7 +3791,8 @@ static int pktgen_remove_device(struct pktgen_thread *t, #ifdef CONFIG_XFRM free_SAs(pkt_dev); #endif - vfree(pkt_dev->flows); + if (pkt_dev->flows) + vfree(pkt_dev->flows); kfree(pkt_dev); return 0; } diff --git a/trunk/net/core/skb_dma_map.c b/trunk/net/core/skb_dma_map.c index 79687dfd6957..86234923a3b7 100644 --- a/trunk/net/core/skb_dma_map.c +++ b/trunk/net/core/skb_dma_map.c @@ -20,7 +20,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, if (dma_mapping_error(dev, map)) goto out_err; - sp->dma_head = map; + sp->dma_maps[0] = map; for (i = 0; i < sp->nr_frags; i++) { skb_frag_t *fp = &sp->frags[i]; @@ -28,8 +28,9 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, fp->size, dir); if (dma_mapping_error(dev, map)) goto unwind; - sp->dma_maps[i] = map; + sp->dma_maps[i + 1] = map; } + sp->num_dma_maps = i + 1; return 0; @@ -37,10 +38,10 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb, while (--i >= 0) { skb_frag_t *fp = &sp->frags[i]; - dma_unmap_page(dev, sp->dma_maps[i], + dma_unmap_page(dev, sp->dma_maps[i + 1], fp->size, dir); } - dma_unmap_single(dev, sp->dma_head, + dma_unmap_single(dev, sp->dma_maps[0], skb_headlen(skb), dir); out_err: return -ENOMEM; @@ -53,12 +54,12 @@ void skb_dma_unmap(struct device *dev, struct sk_buff *skb, struct skb_shared_info *sp = skb_shinfo(skb); int i; - dma_unmap_single(dev, sp->dma_head, + dma_unmap_single(dev, sp->dma_maps[0], skb_headlen(skb), dir); for (i = 0; i < sp->nr_frags; i++) { skb_frag_t *fp = &sp->frags[i]; - dma_unmap_page(dev, sp->dma_maps[i], + dma_unmap_page(dev, sp->dma_maps[i + 1], fp->size, dir); } } diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index b94d777e3eb4..6adf19ec95cc 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -210,7 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, shinfo->gso_type = 0; shinfo->ip6_frag_id = 0; shinfo->tx_flags.flags = 0; - skb_frag_list_init(skb); + shinfo->frag_list = NULL; memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); if (fclone) { @@ -323,7 +323,7 @@ static void skb_clone_fraglist(struct sk_buff *skb) { struct sk_buff *list; - skb_walk_frags(skb, list) + for (list = skb_shinfo(skb)->frag_list; list; list = list->next) skb_get(list); } @@ -338,7 +338,7 @@ static void skb_release_data(struct sk_buff *skb) put_page(skb_shinfo(skb)->frags[i].page); } - if (skb_has_frags(skb)) + if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); kfree(skb->head); @@ -503,7 +503,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) shinfo->gso_type = 0; shinfo->ip6_frag_id = 0; shinfo->tx_flags.flags = 0; - skb_frag_list_init(skb); + shinfo->frag_list = NULL; memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps)); memset(skb, 0, offsetof(struct sk_buff, tail)); @@ -552,6 +552,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->vlan_tci = old->vlan_tci; #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) new->do_not_encrypt = old->do_not_encrypt; + new->requeue = old->requeue; #endif skb_copy_secmark(new, old); @@ -757,7 +758,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) skb_shinfo(n)->nr_frags = i; } - if (skb_has_frags(skb)) { + if (skb_shinfo(skb)->frag_list) { skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; skb_clone_fraglist(n); } @@ -820,7 +821,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) get_page(skb_shinfo(skb)->frags[i].page); - if (skb_has_frags(skb)) + if (skb_shinfo(skb)->frag_list) skb_clone_fraglist(skb); skb_release_data(skb); @@ -1092,7 +1093,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) for (; i < nfrags; i++) put_page(skb_shinfo(skb)->frags[i].page); - if (skb_has_frags(skb)) + if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); goto done; } @@ -1187,7 +1188,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) /* Optimization: no fragments, no reasons to preestimate * size of pulled pages. Superb. */ - if (!skb_has_frags(skb)) + if (!skb_shinfo(skb)->frag_list) goto pull_pages; /* Estimate size of pulled pages. */ @@ -1284,9 +1285,8 @@ EXPORT_SYMBOL(__pskb_pull_tail); int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) { - int start = skb_headlen(skb); - struct sk_buff *frag_iter; int i, copy; + int start = skb_headlen(skb); if (offset > (int)skb->len - len) goto fault; @@ -1328,23 +1328,28 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_bits(frag_iter, offset - start, to, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_bits(list, offset - start, + to, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + to += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -1529,7 +1534,6 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, .ops = &sock_pipe_buf_ops, .spd_release = sock_spd_release, }; - struct sk_buff *frag_iter; struct sock *sk = skb->sk; /* @@ -1544,11 +1548,13 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, /* * now see if we have a frag_list to map */ - skb_walk_frags(skb, frag_iter) { - if (!tlen) - break; - if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk)) - break; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list && tlen; list = list->next) { + if (__skb_splice_bits(list, &offset, &tlen, &spd, sk)) + break; + } } done: @@ -1587,9 +1593,8 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) { - int start = skb_headlen(skb); - struct sk_buff *frag_iter; int i, copy; + int start = skb_headlen(skb); if (offset > (int)skb->len - len) goto fault; @@ -1630,24 +1635,28 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_store_bits(frag_iter, offset - start, - from, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - from += copy; + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_store_bits(list, offset - start, + from, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + from += copy; + } + start = end; } - start = end; } if (!len) return 0; @@ -1664,7 +1673,6 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; int pos = 0; /* Checksum header. */ @@ -1704,25 +1712,29 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - __wsum csum2; - if (copy > len) - copy = len; - csum2 = skb_checksum(frag_iter, offset - start, - copy, 0); - csum = csum_block_add(csum, csum2, pos); - if ((len -= copy) == 0) - return csum; - offset += copy; - pos += copy; + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + __wsum csum2; + if (copy > len) + copy = len; + csum2 = skb_checksum(list, offset - start, + copy, 0); + csum = csum_block_add(csum, csum2, pos); + if ((len -= copy) == 0) + return csum; + offset += copy; + pos += copy; + } + start = end; } - start = end; } BUG_ON(len); @@ -1737,7 +1749,6 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; int pos = 0; /* Copy header. */ @@ -1782,27 +1793,31 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, start = end; } - skb_walk_frags(skb, frag_iter) { - __wsum csum2; - int end; - - WARN_ON(start > offset + len); + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - csum2 = skb_copy_and_csum_bits(frag_iter, - offset - start, - to, copy, 0); - csum = csum_block_add(csum, csum2, pos); - if ((len -= copy) == 0) - return csum; - offset += copy; - to += copy; - pos += copy; + for (; list; list = list->next) { + __wsum csum2; + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + csum2 = skb_copy_and_csum_bits(list, + offset - start, + to, copy, 0); + csum = csum_block_add(csum, csum2, pos); + if ((len -= copy) == 0) + return csum; + offset += copy; + to += copy; + pos += copy; + } + start = end; } - start = end; } BUG_ON(len); return csum; @@ -2312,7 +2327,8 @@ unsigned int skb_seq_read(unsigned int consumed, const u8 **data, st->frag_data = NULL; } - if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) { + if (st->root_skb == st->cur_skb && + skb_shinfo(st->root_skb)->frag_list) { st->cur_skb = skb_shinfo(st->root_skb)->frag_list; st->frag_idx = 0; goto next_skb; @@ -2623,7 +2639,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features) } else skb_get(fskb2); - SKB_FRAG_ASSERT(nskb); + BUG_ON(skb_shinfo(nskb)->frag_list); skb_shinfo(nskb)->frag_list = fskb2; } @@ -2780,7 +2796,6 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; int elt = 0; if (copy > 0) { @@ -2814,22 +2829,26 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) start = end; } - skb_walk_frags(skb, frag_iter) { - int end; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; - WARN_ON(start > offset + len); + for (; list; list = list->next) { + int end; - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start, - copy); - if ((len -= copy) == 0) - return elt; - offset += copy; + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + elt += __skb_to_sgvec(list, sg+elt, offset - start, + copy); + if ((len -= copy) == 0) + return elt; + offset += copy; + } + start = end; } - start = end; } BUG_ON(len); return elt; @@ -2877,7 +2896,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) return -ENOMEM; /* Easy case. Most of packets will go this way. */ - if (!skb_has_frags(skb)) { + if (!skb_shinfo(skb)->frag_list) { /* A little of trouble, not enough of space for trailer. * This should not happen, when stack is tuned to generate * good frames. OK, on miss we reallocate and reserve even more @@ -2912,7 +2931,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) if (skb1->next == NULL && tailbits) { if (skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1) || + skb_shinfo(skb1)->frag_list || skb_tailroom(skb1) < tailbits) ntail = tailbits + 128; } @@ -2921,7 +2940,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) skb_cloned(skb1) || ntail || skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1)) { + skb_shinfo(skb1)->frag_list) { struct sk_buff *skb2; /* Fuck, we are miserable poor guys... */ @@ -3007,12 +3026,12 @@ EXPORT_SYMBOL_GPL(skb_tstamp_tx); */ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off) { - if (unlikely(start > skb_headlen(skb)) || - unlikely((int)start + off > skb_headlen(skb) - 2)) { + if (unlikely(start > skb->len - 2) || + unlikely((int)start + off > skb->len - 2)) { if (net_ratelimit()) printk(KERN_WARNING "bad partial csum: csum=%u/%u len=%u\n", - start, off, skb_headlen(skb)); + start, off, skb->len); return false; } skb->ip_summed = CHECKSUM_PARTIAL; diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 06e26b77ad9e..58dec9dff99a 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -155,7 +155,6 @@ static const char *af_family_key_strings[AF_MAX+1] = { "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , - "sk_lock-AF_IEEE802154", "sk_lock-AF_MAX" }; static const char *af_family_slock_key_strings[AF_MAX+1] = { @@ -171,7 +170,6 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = { "slock-27" , "slock-28" , "slock-AF_CAN" , "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , - "slock-AF_IEEE802154", "slock-AF_MAX" }; static const char *af_family_clock_key_strings[AF_MAX+1] = { @@ -187,7 +185,6 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = { "clock-27" , "clock-28" , "clock-AF_CAN" , "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , - "clock-AF_IEEE802154", "clock-AF_MAX" }; @@ -1008,7 +1005,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, } EXPORT_SYMBOL(sk_alloc); -static void __sk_free(struct sock *sk) +void sk_free(struct sock *sk) { struct sk_filter *filter; @@ -1031,17 +1028,6 @@ static void __sk_free(struct sock *sk) put_net(sock_net(sk)); sk_prot_free(sk->sk_prot_creator, sk); } - -void sk_free(struct sock *sk) -{ - /* - * We substract one from sk_wmem_alloc and can know if - * some packets are still in some tx queue. - * If not null, sock_wfree() will call __sk_free(sk) later - */ - if (atomic_dec_and_test(&sk->sk_wmem_alloc)) - __sk_free(sk); -} EXPORT_SYMBOL(sk_free); /* @@ -1082,10 +1068,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; atomic_set(&newsk->sk_rmem_alloc, 0); - /* - * sk_wmem_alloc set to one (see sk_free() and sock_wfree()) - */ - atomic_set(&newsk->sk_wmem_alloc, 1); + atomic_set(&newsk->sk_wmem_alloc, 0); atomic_set(&newsk->sk_omem_alloc, 0); skb_queue_head_init(&newsk->sk_receive_queue); skb_queue_head_init(&newsk->sk_write_queue); @@ -1189,18 +1172,12 @@ void __init sk_init(void) void sock_wfree(struct sk_buff *skb) { struct sock *sk = skb->sk; - int res; /* In case it might be waiting for more memory. */ - res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); + atomic_sub(skb->truesize, &sk->sk_wmem_alloc); if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) sk->sk_write_space(sk); - /* - * if sk_wmem_alloc reached 0, we are last user and should - * free this sock, as sk_free() call could not do it. - */ - if (res == 0) - __sk_free(sk); + sock_put(sk); } EXPORT_SYMBOL(sock_wfree); @@ -1839,7 +1816,6 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_stamp = ktime_set(-1L, 0); atomic_set(&sk->sk_refcnt, 1); - atomic_set(&sk->sk_wmem_alloc, 1); atomic_set(&sk->sk_drops, 0); } EXPORT_SYMBOL(sock_init_data); diff --git a/trunk/net/core/user_dma.c b/trunk/net/core/user_dma.c index 25d717ebc92e..164b090d5ac3 100644 --- a/trunk/net/core/user_dma.c +++ b/trunk/net/core/user_dma.c @@ -51,7 +51,6 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; dma_cookie_t cookie = 0; /* Copy header. */ @@ -95,28 +94,31 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - copy = end - offset; - if (copy > 0) { - if (copy > len) - copy = len; - cookie = dma_skb_copy_datagram_iovec(chan, frag_iter, - offset - start, - to, copy, - pinned_list); - if (cookie < 0) - goto fault; - len -= copy; - if (len == 0) - goto end; - offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + copy = end - offset; + if (copy > 0) { + if (copy > len) + copy = len; + cookie = dma_skb_copy_datagram_iovec(chan, list, + offset - start, to, copy, + pinned_list); + if (cookie < 0) + goto fault; + len -= copy; + if (len == 0) + goto end; + offset += copy; + } + start = end; } - start = end; } end: diff --git a/trunk/net/ieee802154/Kconfig b/trunk/net/ieee802154/Kconfig deleted file mode 100644 index 1c1de97d264a..000000000000 --- a/trunk/net/ieee802154/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config IEEE802154 - tristate "IEEE Std 802.15.4 Low-Rate Wireless Personal Area Networks support (EXPERIMENTAL)" - depends on EXPERIMENTAL - ---help--- - IEEE Std 802.15.4 defines a low data rate, low power and low - complexity short range wireless personal area networks. It was - designed to organise networks of sensors, switches, etc automation - devices. Maximum allowed data rate is 250 kb/s and typical personal - operating space around 10m. - - Say Y here to compile LR-WPAN support into the kernel or say M to - compile it as modules. diff --git a/trunk/net/ieee802154/Makefile b/trunk/net/ieee802154/Makefile deleted file mode 100644 index f99338a26100..000000000000 --- a/trunk/net/ieee802154/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_IEEE802154) += nl802154.o af_802154.o -nl802154-y := netlink.o nl_policy.o -af_802154-y := af_ieee802154.o raw.o dgram.o - -ccflags-y += -Wall -DDEBUG diff --git a/trunk/net/ieee802154/af802154.h b/trunk/net/ieee802154/af802154.h deleted file mode 100644 index b1ec52537522..000000000000 --- a/trunk/net/ieee802154/af802154.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Internal interfaces for ieee 802.15.4 address family. - * - * Copyright 2007, 2008, 2009 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#ifndef AF802154_H -#define AF802154_H - -struct sk_buff; -struct net_devce; -extern struct proto ieee802154_raw_prot; -extern struct proto ieee802154_dgram_prot; -void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb); -int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb); -struct net_device *ieee802154_get_dev(struct net *net, - struct ieee802154_addr *addr); - -#endif diff --git a/trunk/net/ieee802154/af_ieee802154.c b/trunk/net/ieee802154/af_ieee802154.c deleted file mode 100644 index 882a927cefae..000000000000 --- a/trunk/net/ieee802154/af_ieee802154.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * IEEE802154.4 socket interface - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Maxim Gorbachyov - */ - -#include -#include -#include -#include -#include -#include /* For TIOCOUTQ/INQ */ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "af802154.h" - -#define DBG_DUMP(data, len) { \ - int i; \ - pr_debug("function: %s: data: len %d:\n", __func__, len); \ - for (i = 0; i < len; i++) {\ - pr_debug("%02x: %02x\n", i, (data)[i]); \ - } \ -} - -/* - * Utility function for families - */ -struct net_device *ieee802154_get_dev(struct net *net, - struct ieee802154_addr *addr) -{ - struct net_device *dev = NULL; - struct net_device *tmp; - u16 pan_id, short_addr; - - switch (addr->addr_type) { - case IEEE802154_ADDR_LONG: - rtnl_lock(); - dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr); - if (dev) - dev_hold(dev); - rtnl_unlock(); - break; - case IEEE802154_ADDR_SHORT: - if (addr->pan_id == 0xffff || - addr->short_addr == IEEE802154_ADDR_UNDEF || - addr->short_addr == 0xffff) - break; - - rtnl_lock(); - - for_each_netdev(net, tmp) { - if (tmp->type != ARPHRD_IEEE802154) - continue; - - pan_id = ieee802154_mlme_ops(tmp)->get_pan_id(tmp); - short_addr = - ieee802154_mlme_ops(tmp)->get_short_addr(tmp); - - if (pan_id == addr->pan_id && - short_addr == addr->short_addr) { - dev = tmp; - dev_hold(dev); - break; - } - } - - rtnl_unlock(); - break; - default: - pr_warning("Unsupported ieee802154 address type: %d\n", - addr->addr_type); - break; - } - - return dev; -} - -static int ieee802154_sock_release(struct socket *sock) -{ - struct sock *sk = sock->sk; - - if (sk) { - sock->sk = NULL; - sk->sk_prot->close(sk, 0); - } - return 0; -} -static int ieee802154_sock_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len) -{ - struct sock *sk = sock->sk; - - return sk->sk_prot->sendmsg(iocb, sk, msg, len); -} - -static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr, - int addr_len) -{ - struct sock *sk = sock->sk; - - if (sk->sk_prot->bind) - return sk->sk_prot->bind(sk, uaddr, addr_len); - - return sock_no_bind(sock, uaddr, addr_len); -} - -static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags) -{ - struct sock *sk = sock->sk; - - if (uaddr->sa_family == AF_UNSPEC) - return sk->sk_prot->disconnect(sk, flags); - - return sk->sk_prot->connect(sk, uaddr, addr_len); -} - -static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, - unsigned int cmd) -{ - struct ifreq ifr; - int ret = -EINVAL; - struct net_device *dev; - - if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) - return -EFAULT; - - ifr.ifr_name[IFNAMSIZ-1] = 0; - - dev_load(sock_net(sk), ifr.ifr_name); - dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); - if (dev->type == ARPHRD_IEEE802154 || - dev->type == ARPHRD_IEEE802154_PHY) - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); - - if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) - ret = -EFAULT; - dev_put(dev); - - return ret; -} - -static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd, - unsigned long arg) -{ - struct sock *sk = sock->sk; - - switch (cmd) { - case SIOCGSTAMP: - return sock_get_timestamp(sk, (struct timeval __user *)arg); - case SIOCGSTAMPNS: - return sock_get_timestampns(sk, (struct timespec __user *)arg); - case SIOCGIFADDR: - case SIOCSIFADDR: - return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg, - cmd); - default: - if (!sk->sk_prot->ioctl) - return -ENOIOCTLCMD; - return sk->sk_prot->ioctl(sk, cmd, arg); - } -} - -static const struct proto_ops ieee802154_raw_ops = { - .family = PF_IEEE802154, - .owner = THIS_MODULE, - .release = ieee802154_sock_release, - .bind = ieee802154_sock_bind, - .connect = ieee802154_sock_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = datagram_poll, - .ioctl = ieee802154_sock_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_common_setsockopt, - .getsockopt = sock_common_getsockopt, - .sendmsg = ieee802154_sock_sendmsg, - .recvmsg = sock_common_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -#ifdef CONFIG_COMPAT - .compat_setsockopt = compat_sock_common_setsockopt, - .compat_getsockopt = compat_sock_common_getsockopt, -#endif -}; - -static const struct proto_ops ieee802154_dgram_ops = { - .family = PF_IEEE802154, - .owner = THIS_MODULE, - .release = ieee802154_sock_release, - .bind = ieee802154_sock_bind, - .connect = ieee802154_sock_connect, - .socketpair = sock_no_socketpair, - .accept = sock_no_accept, - .getname = sock_no_getname, - .poll = datagram_poll, - .ioctl = ieee802154_sock_ioctl, - .listen = sock_no_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_common_setsockopt, - .getsockopt = sock_common_getsockopt, - .sendmsg = ieee802154_sock_sendmsg, - .recvmsg = sock_common_recvmsg, - .mmap = sock_no_mmap, - .sendpage = sock_no_sendpage, -#ifdef CONFIG_COMPAT - .compat_setsockopt = compat_sock_common_setsockopt, - .compat_getsockopt = compat_sock_common_getsockopt, -#endif -}; - - -/* - * Create a socket. Initialise the socket, blank the addresses - * set the state. - */ -static int ieee802154_create(struct net *net, struct socket *sock, - int protocol) -{ - struct sock *sk; - int rc; - struct proto *proto; - const struct proto_ops *ops; - - if (net != &init_net) - return -EAFNOSUPPORT; - - switch (sock->type) { - case SOCK_RAW: - proto = &ieee802154_raw_prot; - ops = &ieee802154_raw_ops; - break; - case SOCK_DGRAM: - proto = &ieee802154_dgram_prot; - ops = &ieee802154_dgram_ops; - break; - default: - rc = -ESOCKTNOSUPPORT; - goto out; - } - - rc = -ENOMEM; - sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto); - if (!sk) - goto out; - rc = 0; - - sock->ops = ops; - - sock_init_data(sock, sk); - /* FIXME: sk->sk_destruct */ - sk->sk_family = PF_IEEE802154; - - /* Checksums on by default */ - sock_set_flag(sk, SOCK_ZAPPED); - - if (sk->sk_prot->hash) - sk->sk_prot->hash(sk); - - if (sk->sk_prot->init) { - rc = sk->sk_prot->init(sk); - if (rc) - sk_common_release(sk); - } -out: - return rc; -} - -static struct net_proto_family ieee802154_family_ops = { - .family = PF_IEEE802154, - .create = ieee802154_create, - .owner = THIS_MODULE, -}; - -static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - DBG_DUMP(skb->data, skb->len); - if (!netif_running(dev)) - return -ENODEV; - pr_debug("got frame, type %d, dev %p\n", dev->type, dev); - - if (!net_eq(dev_net(dev), &init_net)) - goto drop; - - ieee802154_raw_deliver(dev, skb); - - if (dev->type != ARPHRD_IEEE802154) - goto drop; - - if (skb->pkt_type != PACKET_OTHERHOST) - return ieee802154_dgram_deliver(dev, skb); - -drop: - kfree_skb(skb); - return NET_RX_DROP; -} - - -static struct packet_type ieee802154_packet_type = { - .type = __constant_htons(ETH_P_IEEE802154), - .func = ieee802154_rcv, -}; - -static int __init af_ieee802154_init(void) -{ - int rc = -EINVAL; - - rc = proto_register(&ieee802154_raw_prot, 1); - if (rc) - goto out; - - rc = proto_register(&ieee802154_dgram_prot, 1); - if (rc) - goto err_dgram; - - /* Tell SOCKET that we are alive */ - rc = sock_register(&ieee802154_family_ops); - if (rc) - goto err_sock; - dev_add_pack(&ieee802154_packet_type); - - rc = 0; - goto out; - -err_sock: - proto_unregister(&ieee802154_dgram_prot); -err_dgram: - proto_unregister(&ieee802154_raw_prot); -out: - return rc; -} -static void __exit af_ieee802154_remove(void) -{ - dev_remove_pack(&ieee802154_packet_type); - sock_unregister(PF_IEEE802154); - proto_unregister(&ieee802154_dgram_prot); - proto_unregister(&ieee802154_raw_prot); -} - -module_init(af_ieee802154_init); -module_exit(af_ieee802154_remove); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_NETPROTO(PF_IEEE802154); diff --git a/trunk/net/ieee802154/dgram.c b/trunk/net/ieee802154/dgram.c deleted file mode 100644 index 1779677aed46..000000000000 --- a/trunk/net/ieee802154/dgram.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * ZigBee socket interface - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "af802154.h" - -static HLIST_HEAD(dgram_head); -static DEFINE_RWLOCK(dgram_lock); - -struct dgram_sock { - struct sock sk; - - int bound; - struct ieee802154_addr src_addr; - struct ieee802154_addr dst_addr; -}; - -static inline struct dgram_sock *dgram_sk(const struct sock *sk) -{ - return container_of(sk, struct dgram_sock, sk); -} - - -static void dgram_hash(struct sock *sk) -{ - write_lock_bh(&dgram_lock); - sk_add_node(sk, &dgram_head); - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); - write_unlock_bh(&dgram_lock); -} - -static void dgram_unhash(struct sock *sk) -{ - write_lock_bh(&dgram_lock); - if (sk_del_node_init(sk)) - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); - write_unlock_bh(&dgram_lock); -} - -static int dgram_init(struct sock *sk) -{ - struct dgram_sock *ro = dgram_sk(sk); - - ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; - ro->dst_addr.pan_id = 0xffff; - memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); - return 0; -} - -static void dgram_close(struct sock *sk, long timeout) -{ - sk_common_release(sk); -} - -static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len) -{ - struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; - struct dgram_sock *ro = dgram_sk(sk); - int err = 0; - struct net_device *dev; - - ro->bound = 0; - - if (len < sizeof(*addr)) - return -EINVAL; - - if (addr->family != AF_IEEE802154) - return -EINVAL; - - lock_sock(sk); - - dev = ieee802154_get_dev(sock_net(sk), &addr->addr); - if (!dev) { - err = -ENODEV; - goto out; - } - - if (dev->type != ARPHRD_IEEE802154) { - err = -ENODEV; - goto out_put; - } - - memcpy(&ro->src_addr, &addr->addr, sizeof(struct ieee802154_addr)); - - ro->bound = 1; -out_put: - dev_put(dev); -out: - release_sock(sk); - - return err; -} - -static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) -{ - switch (cmd) { - case SIOCOUTQ: - { - int amount = atomic_read(&sk->sk_wmem_alloc); - return put_user(amount, (int __user *)arg); - } - - case SIOCINQ: - { - struct sk_buff *skb; - unsigned long amount; - - amount = 0; - spin_lock_bh(&sk->sk_receive_queue.lock); - skb = skb_peek(&sk->sk_receive_queue); - if (skb != NULL) { - /* - * We will only return the amount - * of this packet since that is all - * that will be read. - */ - /* FIXME: parse the header for more correct value */ - amount = skb->len - (3+8+8); - } - spin_unlock_bh(&sk->sk_receive_queue.lock); - return put_user(amount, (int __user *)arg); - } - - } - return -ENOIOCTLCMD; -} - -/* FIXME: autobind */ -static int dgram_connect(struct sock *sk, struct sockaddr *uaddr, - int len) -{ - struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; - struct dgram_sock *ro = dgram_sk(sk); - int err = 0; - - if (len < sizeof(*addr)) - return -EINVAL; - - if (addr->family != AF_IEEE802154) - return -EINVAL; - - lock_sock(sk); - - if (!ro->bound) { - err = -ENETUNREACH; - goto out; - } - - memcpy(&ro->dst_addr, &addr->addr, sizeof(struct ieee802154_addr)); - -out: - release_sock(sk); - return err; -} - -static int dgram_disconnect(struct sock *sk, int flags) -{ - struct dgram_sock *ro = dgram_sk(sk); - - lock_sock(sk); - - ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; - memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); - - release_sock(sk); - - return 0; -} - -static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, - struct msghdr *msg, size_t size) -{ - struct net_device *dev; - unsigned mtu; - struct sk_buff *skb; - struct dgram_sock *ro = dgram_sk(sk); - int err; - - if (msg->msg_flags & MSG_OOB) { - pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); - return -EOPNOTSUPP; - } - - if (!ro->bound) - dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); - else - dev = ieee802154_get_dev(sock_net(sk), &ro->src_addr); - - if (!dev) { - pr_debug("no dev\n"); - err = -ENXIO; - goto out; - } - mtu = dev->mtu; - pr_debug("name = %s, mtu = %u\n", dev->name, mtu); - - skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, - msg->msg_flags & MSG_DONTWAIT, - &err); - if (!skb) - goto out_dev; - - skb_reserve(skb, LL_RESERVED_SPACE(dev)); - - skb_reset_network_header(skb); - - mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA | MAC_CB_FLAG_ACKREQ; - mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev); - err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr, - ro->bound ? &ro->src_addr : NULL, size); - if (err < 0) - goto out_skb; - - skb_reset_mac_header(skb); - - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); - if (err < 0) - goto out_skb; - - if (size > mtu) { - pr_debug("size = %Zu, mtu = %u\n", size, mtu); - err = -EINVAL; - goto out_skb; - } - - skb->dev = dev; - skb->sk = sk; - skb->protocol = htons(ETH_P_IEEE802154); - - dev_put(dev); - - err = dev_queue_xmit(skb); - if (err > 0) - err = net_xmit_errno(err); - - return err ?: size; - -out_skb: - kfree_skb(skb); -out_dev: - dev_put(dev); -out: - return err; -} - -static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk, - struct msghdr *msg, size_t len, int noblock, int flags, - int *addr_len) -{ - size_t copied = 0; - int err = -EOPNOTSUPP; - struct sk_buff *skb; - - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) - goto out; - - copied = skb->len; - if (len < copied) { - msg->msg_flags |= MSG_TRUNC; - copied = len; - } - - /* FIXME: skip headers if necessary ?! */ - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - if (err) - goto done; - - sock_recv_timestamp(msg, sk, skb); - - if (flags & MSG_TRUNC) - copied = skb->len; -done: - skb_free_datagram(sk, skb); -out: - if (err) - return err; - return copied; -} - -static int dgram_rcv_skb(struct sock *sk, struct sk_buff *skb) -{ - if (sock_queue_rcv_skb(sk, skb) < 0) { - atomic_inc(&sk->sk_drops); - kfree_skb(skb); - return NET_RX_DROP; - } - - return NET_RX_SUCCESS; -} - -static inline int ieee802154_match_sock(u8 *hw_addr, u16 pan_id, - u16 short_addr, struct dgram_sock *ro) -{ - if (!ro->bound) - return 1; - - if (ro->src_addr.addr_type == IEEE802154_ADDR_LONG && - !memcmp(ro->src_addr.hwaddr, hw_addr, IEEE802154_ADDR_LEN)) - return 1; - - if (ro->src_addr.addr_type == IEEE802154_ADDR_SHORT && - pan_id == ro->src_addr.pan_id && - short_addr == ro->src_addr.short_addr) - return 1; - - return 0; -} - -int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb) -{ - struct sock *sk, *prev = NULL; - struct hlist_node *node; - int ret = NET_RX_SUCCESS; - u16 pan_id, short_addr; - - /* Data frame processing */ - BUG_ON(dev->type != ARPHRD_IEEE802154); - - pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); - short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev); - - read_lock(&dgram_lock); - sk_for_each(sk, node, &dgram_head) { - if (ieee802154_match_sock(dev->dev_addr, pan_id, short_addr, - dgram_sk(sk))) { - if (prev) { - struct sk_buff *clone; - clone = skb_clone(skb, GFP_ATOMIC); - if (clone) - dgram_rcv_skb(prev, clone); - } - - prev = sk; - } - } - - if (prev) - dgram_rcv_skb(prev, skb); - else { - kfree_skb(skb); - ret = NET_RX_DROP; - } - read_unlock(&dgram_lock); - - return ret; -} - -struct proto ieee802154_dgram_prot = { - .name = "IEEE-802.15.4-MAC", - .owner = THIS_MODULE, - .obj_size = sizeof(struct dgram_sock), - .init = dgram_init, - .close = dgram_close, - .bind = dgram_bind, - .sendmsg = dgram_sendmsg, - .recvmsg = dgram_recvmsg, - .hash = dgram_hash, - .unhash = dgram_unhash, - .connect = dgram_connect, - .disconnect = dgram_disconnect, - .ioctl = dgram_ioctl, -}; - diff --git a/trunk/net/ieee802154/netlink.c b/trunk/net/ieee802154/netlink.c deleted file mode 100644 index 105ad10876af..000000000000 --- a/trunk/net/ieee802154/netlink.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Netlink inteface for IEEE 802.15.4 stack - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int ieee802154_seq_num; - -static struct genl_family ieee802154_coordinator_family = { - .id = GENL_ID_GENERATE, - .hdrsize = 0, - .name = IEEE802154_NL_NAME, - .version = 1, - .maxattr = IEEE802154_ATTR_MAX, -}; - -static struct genl_multicast_group ieee802154_coord_mcgrp = { - .name = IEEE802154_MCAST_COORD_NAME, -}; - -static struct genl_multicast_group ieee802154_beacon_mcgrp = { - .name = IEEE802154_MCAST_BEACON_NAME, -}; - -/* Requests to userspace */ -static struct sk_buff *ieee802154_nl_create(int flags, u8 req) -{ - void *hdr; - struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); - - if (!msg) - return NULL; - - hdr = genlmsg_put(msg, 0, ieee802154_seq_num++, - &ieee802154_coordinator_family, flags, req); - if (!hdr) { - nlmsg_free(msg); - return NULL; - } - - return msg; -} - -static int ieee802154_nl_finish(struct sk_buff *msg) -{ - /* XXX: nlh is right at the start of msg */ - void *hdr = genlmsg_data(NLMSG_DATA(msg->data)); - - if (!genlmsg_end(msg, hdr)) - goto out; - - return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id, - GFP_ATOMIC); -out: - nlmsg_free(msg); - return -ENOBUFS; -} - -int ieee802154_nl_assoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 cap) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - if (addr->addr_type != IEEE802154_ADDR_LONG) { - pr_err("%s: received non-long source address!\n", __func__); - return -EINVAL; - } - - msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_INDIC); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, - addr->hwaddr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_assoc_indic); - -int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr, - u8 status) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr); - NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_assoc_confirm); - -int ieee802154_nl_disassoc_indic(struct net_device *dev, - struct ieee802154_addr *addr, u8 reason) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - if (addr->addr_type == IEEE802154_ADDR_LONG) - NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, - addr->hwaddr); - else - NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR, - addr->short_addr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_disassoc_indic); - -int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_CONF); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm); - -int ieee802154_nl_beacon_indic(struct net_device *dev, - u16 panid, u16 coord_addr) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr); - NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_beacon_indic); - -int ieee802154_nl_scan_confirm(struct net_device *dev, - u8 status, u8 scan_type, u32 unscanned, - u8 *edl/* , struct list_head *pan_desc_list */) -{ - struct sk_buff *msg; - - pr_debug("%s\n", __func__); - - msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF); - if (!msg) - return -ENOBUFS; - - NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); - NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex); - NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, - dev->dev_addr); - - NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); - NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type); - NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned); - - if (edl) - NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl); - - return ieee802154_nl_finish(msg); - -nla_put_failure: - nlmsg_free(msg); - return -ENOBUFS; -} -EXPORT_SYMBOL(ieee802154_nl_scan_confirm); - -/* Requests from userspace */ -static struct net_device *ieee802154_nl_get_dev(struct genl_info *info) -{ - struct net_device *dev; - - if (info->attrs[IEEE802154_ATTR_DEV_NAME]) { - char name[IFNAMSIZ + 1]; - nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME], - sizeof(name)); - dev = dev_get_by_name(&init_net, name); - } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) - dev = dev_get_by_index(&init_net, - nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX])); - else - return NULL; - - if (dev->type != ARPHRD_IEEE802154) { - dev_put(dev); - return NULL; - } - - return dev; -} - -static int ieee802154_associate_req(struct sk_buff *skb, - struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - int ret = -EINVAL; - - if (!info->attrs[IEEE802154_ATTR_CHANNEL] || - !info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || - (!info->attrs[IEEE802154_ATTR_COORD_HW_ADDR] && - !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]) || - !info->attrs[IEEE802154_ATTR_CAPABILITY]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) { - addr.addr_type = IEEE802154_ADDR_LONG; - nla_memcpy(addr.hwaddr, - info->attrs[IEEE802154_ATTR_COORD_HW_ADDR], - IEEE802154_ADDR_LEN); - } else { - addr.addr_type = IEEE802154_ADDR_SHORT; - addr.short_addr = nla_get_u16( - info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); - } - addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); - - ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr, - nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]), - nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY])); - - dev_put(dev); - return ret; -} - -static int ieee802154_associate_resp(struct sk_buff *skb, - struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - int ret = -EINVAL; - - if (!info->attrs[IEEE802154_ATTR_STATUS] || - !info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] || - !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - addr.addr_type = IEEE802154_ADDR_LONG; - nla_memcpy(addr.hwaddr, info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], - IEEE802154_ADDR_LEN); - addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); - - - ret = ieee802154_mlme_ops(dev)->assoc_resp(dev, &addr, - nla_get_u16(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]), - nla_get_u8(info->attrs[IEEE802154_ATTR_STATUS])); - - dev_put(dev); - return ret; -} - -static int ieee802154_disassociate_req(struct sk_buff *skb, - struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - int ret = -EINVAL; - - if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] && - !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) || - !info->attrs[IEEE802154_ATTR_REASON]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) { - addr.addr_type = IEEE802154_ADDR_LONG; - nla_memcpy(addr.hwaddr, - info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], - IEEE802154_ADDR_LEN); - } else { - addr.addr_type = IEEE802154_ADDR_SHORT; - addr.short_addr = nla_get_u16( - info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]); - } - addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); - - ret = ieee802154_mlme_ops(dev)->disassoc_req(dev, &addr, - nla_get_u8(info->attrs[IEEE802154_ATTR_REASON])); - - dev_put(dev); - return ret; -} - -/* - * PANid, channel, beacon_order = 15, superframe_order = 15, - * PAN_coordinator, battery_life_extension = 0, - * coord_realignment = 0, security_enable = 0 -*/ -static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) -{ - struct net_device *dev; - struct ieee802154_addr addr; - - u8 channel, bcn_ord, sf_ord; - int pan_coord, blx, coord_realign; - int ret; - - if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] || - !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] || - !info->attrs[IEEE802154_ATTR_CHANNEL] || - !info->attrs[IEEE802154_ATTR_BCN_ORD] || - !info->attrs[IEEE802154_ATTR_SF_ORD] || - !info->attrs[IEEE802154_ATTR_PAN_COORD] || - !info->attrs[IEEE802154_ATTR_BAT_EXT] || - !info->attrs[IEEE802154_ATTR_COORD_REALIGN] - ) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - addr.addr_type = IEEE802154_ADDR_SHORT; - addr.short_addr = nla_get_u16( - info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); - addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); - - channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]); - bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]); - sf_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_SF_ORD]); - pan_coord = nla_get_u8(info->attrs[IEEE802154_ATTR_PAN_COORD]); - blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]); - coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]); - - ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, - bcn_ord, sf_ord, pan_coord, blx, coord_realign); - - dev_put(dev); - return ret; -} - -static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) -{ - struct net_device *dev; - int ret; - u8 type; - u32 channels; - u8 duration; - - if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] || - !info->attrs[IEEE802154_ATTR_CHANNELS] || - !info->attrs[IEEE802154_ATTR_DURATION]) - return -EINVAL; - - dev = ieee802154_nl_get_dev(info); - if (!dev) - return -ENODEV; - - type = nla_get_u8(info->attrs[IEEE802154_ATTR_SCAN_TYPE]); - channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]); - duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]); - - ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, - duration); - - dev_put(dev); - return ret; -} - -#define IEEE802154_OP(_cmd, _func) \ - { \ - .cmd = _cmd, \ - .policy = ieee802154_policy, \ - .doit = _func, \ - .dumpit = NULL, \ - .flags = GENL_ADMIN_PERM, \ - } - -static struct genl_ops ieee802154_coordinator_ops[] = { - IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req), - IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp), - IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req), - IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req), - IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req), -}; - -static int __init ieee802154_nl_init(void) -{ - int rc; - int i; - - rc = genl_register_family(&ieee802154_coordinator_family); - if (rc) - goto fail; - - rc = genl_register_mc_group(&ieee802154_coordinator_family, - &ieee802154_coord_mcgrp); - if (rc) - goto fail; - - rc = genl_register_mc_group(&ieee802154_coordinator_family, - &ieee802154_beacon_mcgrp); - if (rc) - goto fail; - - - for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) { - rc = genl_register_ops(&ieee802154_coordinator_family, - &ieee802154_coordinator_ops[i]); - if (rc) - goto fail; - } - - return 0; - -fail: - genl_unregister_family(&ieee802154_coordinator_family); - return rc; -} -module_init(ieee802154_nl_init); - -static void __exit ieee802154_nl_exit(void) -{ - genl_unregister_family(&ieee802154_coordinator_family); -} -module_exit(ieee802154_nl_exit); - diff --git a/trunk/net/ieee802154/nl_policy.c b/trunk/net/ieee802154/nl_policy.c deleted file mode 100644 index c7d71d1adcac..000000000000 --- a/trunk/net/ieee802154/nl_policy.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * nl802154.h - * - * Copyright (C) 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include -#include -#include - -#define NLA_HW_ADDR NLA_U64 - -struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { - [IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, }, - [IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, }, - - [IEEE802154_ATTR_STATUS] = { .type = NLA_U8, }, - [IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, - [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, - [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, - [IEEE802154_ATTR_SRC_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_SRC_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_SRC_PAN_ID] = { .type = NLA_U16, }, - [IEEE802154_ATTR_DEST_SHORT_ADDR] = { .type = NLA_U16, }, - [IEEE802154_ATTR_DEST_HW_ADDR] = { .type = NLA_HW_ADDR, }, - [IEEE802154_ATTR_DEST_PAN_ID] = { .type = NLA_U16, }, - - [IEEE802154_ATTR_CAPABILITY] = { .type = NLA_U8, }, - [IEEE802154_ATTR_REASON] = { .type = NLA_U8, }, - [IEEE802154_ATTR_SCAN_TYPE] = { .type = NLA_U8, }, - [IEEE802154_ATTR_CHANNELS] = { .type = NLA_U32, }, - [IEEE802154_ATTR_DURATION] = { .type = NLA_U8, }, - [IEEE802154_ATTR_ED_LIST] = { .len = 27 }, -}; diff --git a/trunk/net/ieee802154/raw.c b/trunk/net/ieee802154/raw.c deleted file mode 100644 index fca44d59f97e..000000000000 --- a/trunk/net/ieee802154/raw.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Raw IEEE 802.15.4 sockets - * - * Copyright 2007, 2008 Siemens AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Written by: - * Sergey Lapin - * Dmitry Eremin-Solenikov - */ - -#include -#include -#include -#include -#include -#include - -#include "af802154.h" - -static HLIST_HEAD(raw_head); -static DEFINE_RWLOCK(raw_lock); - -static void raw_hash(struct sock *sk) -{ - write_lock_bh(&raw_lock); - sk_add_node(sk, &raw_head); - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); - write_unlock_bh(&raw_lock); -} - -static void raw_unhash(struct sock *sk) -{ - write_lock_bh(&raw_lock); - if (sk_del_node_init(sk)) - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); - write_unlock_bh(&raw_lock); -} - -static void raw_close(struct sock *sk, long timeout) -{ - sk_common_release(sk); -} - -static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len) -{ - struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; - int err = 0; - struct net_device *dev = NULL; - - if (len < sizeof(*addr)) - return -EINVAL; - - if (addr->family != AF_IEEE802154) - return -EINVAL; - - lock_sock(sk); - - dev = ieee802154_get_dev(sock_net(sk), &addr->addr); - if (!dev) { - err = -ENODEV; - goto out; - } - - if (dev->type != ARPHRD_IEEE802154_PHY && - dev->type != ARPHRD_IEEE802154) { - err = -ENODEV; - goto out_put; - } - - sk->sk_bound_dev_if = dev->ifindex; - sk_dst_reset(sk); - -out_put: - dev_put(dev); -out: - release_sock(sk); - - return err; -} - -static int raw_connect(struct sock *sk, struct sockaddr *uaddr, - int addr_len) -{ - return -ENOTSUPP; -} - -static int raw_disconnect(struct sock *sk, int flags) -{ - return 0; -} - -static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, - size_t size) -{ - struct net_device *dev; - unsigned mtu; - struct sk_buff *skb; - int err; - - if (msg->msg_flags & MSG_OOB) { - pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags); - return -EOPNOTSUPP; - } - - lock_sock(sk); - if (!sk->sk_bound_dev_if) - dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154); - else - dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); - release_sock(sk); - - if (!dev) { - pr_debug("no dev\n"); - err = -ENXIO; - goto out; - } - - mtu = dev->mtu; - pr_debug("name = %s, mtu = %u\n", dev->name, mtu); - - if (size > mtu) { - pr_debug("size = %Zu, mtu = %u\n", size, mtu); - err = -EINVAL; - goto out_dev; - } - - skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size, - msg->msg_flags & MSG_DONTWAIT, &err); - if (!skb) - goto out_dev; - - skb_reserve(skb, LL_RESERVED_SPACE(dev)); - - skb_reset_mac_header(skb); - skb_reset_network_header(skb); - - err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); - if (err < 0) - goto out_skb; - - skb->dev = dev; - skb->sk = sk; - skb->protocol = htons(ETH_P_IEEE802154); - - dev_put(dev); - - err = dev_queue_xmit(skb); - if (err > 0) - err = net_xmit_errno(err); - - return err ?: size; - -out_skb: - kfree_skb(skb); -out_dev: - dev_put(dev); -out: - return err; -} - -static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, - size_t len, int noblock, int flags, int *addr_len) -{ - size_t copied = 0; - int err = -EOPNOTSUPP; - struct sk_buff *skb; - - skb = skb_recv_datagram(sk, flags, noblock, &err); - if (!skb) - goto out; - - copied = skb->len; - if (len < copied) { - msg->msg_flags |= MSG_TRUNC; - copied = len; - } - - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - if (err) - goto done; - - sock_recv_timestamp(msg, sk, skb); - - if (flags & MSG_TRUNC) - copied = skb->len; -done: - skb_free_datagram(sk, skb); -out: - if (err) - return err; - return copied; -} - -static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb) -{ - if (sock_queue_rcv_skb(sk, skb) < 0) { - atomic_inc(&sk->sk_drops); - kfree_skb(skb); - return NET_RX_DROP; - } - - return NET_RX_SUCCESS; -} - - -void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb) -{ - struct sock *sk; - struct hlist_node *node; - - read_lock(&raw_lock); - sk_for_each(sk, node, &raw_head) { - bh_lock_sock(sk); - if (!sk->sk_bound_dev_if || - sk->sk_bound_dev_if == dev->ifindex) { - - struct sk_buff *clone; - - clone = skb_clone(skb, GFP_ATOMIC); - if (clone) - raw_rcv_skb(sk, clone); - } - bh_unlock_sock(sk); - } - read_unlock(&raw_lock); -} - -struct proto ieee802154_raw_prot = { - .name = "IEEE-802.15.4-RAW", - .owner = THIS_MODULE, - .obj_size = sizeof(struct sock), - .close = raw_close, - .bind = raw_bind, - .sendmsg = raw_sendmsg, - .recvmsg = raw_recvmsg, - .hash = raw_hash, - .unhash = raw_unhash, - .connect = raw_connect, - .disconnect = raw_disconnect, -}; - diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 575f9bd51ccd..1f1b82475eaf 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -507,7 +507,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_shinfo(head)->frag_list) { struct sk_buff *clone; int i, plen = 0; @@ -516,7 +516,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, clone->next = head->next; head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); + skb_shinfo(head)->frag_list = NULL; for (i=0; inr_frags; i++) plen += skb_shinfo(head)->frags[i].size; clone->len = clone->data_len = head->data_len - plen; diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 247026282669..3d6167fb2d97 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -474,7 +474,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) * LATER: this step can be merged to real generation of fragments, * we can switch to copy when see the first bad fragment. */ - if (skb_has_frags(skb)) { + if (skb_shinfo(skb)->frag_list) { struct sk_buff *frag; int first_len = skb_pagelen(skb); int truesizes = 0; @@ -485,7 +485,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb_cloned(skb)) goto slow_path; - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* Correct geometry. */ if (frag->len > mtu || ((frag->len & 7) && frag->next) || @@ -498,6 +498,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) BUG_ON(frag->sk); if (skb->sk) { + sock_hold(skb->sk); frag->sk = skb->sk; frag->destructor = sock_wfree; truesizes += frag->truesize; @@ -509,7 +510,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) err = 0; offset = 0; frag = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; skb->data_len = first_len - skb_headlen(skb); skb->truesize -= truesizes; skb->len = first_len; diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c b/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c index 3fc598eeeb1a..65e470bc6123 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_sctp.c @@ -33,7 +33,6 @@ sctp_manip_pkt(struct sk_buff *skb, enum nf_nat_manip_type maniptype) { const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); - struct sk_buff *frag; sctp_sctphdr_t *hdr; unsigned int hdroff = iphdroff + iph->ihl*4; __be32 oldip, newip; @@ -58,8 +57,8 @@ sctp_manip_pkt(struct sk_buff *skb, } crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff); - skb_walk_frags(skb, frag) - crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag), + for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) + crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb), crc32); crc32 = sctp_end_cksum(crc32); hdr->checksum = crc32; diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 7c76e3d18215..c8dc8e5a822f 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -658,7 +658,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) } mtu -= hlen + sizeof(struct frag_hdr); - if (skb_has_frags(skb)) { + if (skb_shinfo(skb)->frag_list) { int first_len = skb_pagelen(skb); int truesizes = 0; @@ -667,7 +667,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) skb_cloned(skb)) goto slow_path; - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* Correct geometry. */ if (frag->len > mtu || ((frag->len & 7) && frag->next) || @@ -680,6 +680,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) BUG_ON(frag->sk); if (skb->sk) { + sock_hold(skb->sk); frag->sk = skb->sk; frag->destructor = sock_wfree; truesizes += frag->truesize; @@ -689,7 +690,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) err = 0; offset = 0; frag = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; /* BUILD HEADER */ *prevhdr = NEXTHDR_FRAGMENT; diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index f3aba255ad9f..058a5e4a60c3 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -409,7 +409,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_shinfo(head)->frag_list) { struct sk_buff *clone; int i, plen = 0; @@ -420,7 +420,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) clone->next = head->next; head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); + skb_shinfo(head)->frag_list = NULL; for (i=0; inr_frags; i++) plen += skb_shinfo(head)->frags[i].size; clone->len = clone->data_len = head->data_len - plen; diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index 2642a41a8535..54a387d31e1a 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -494,7 +494,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_shinfo(head)->frag_list) { struct sk_buff *clone; int i, plen = 0; @@ -503,7 +503,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, clone->next = head->next; head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; - skb_frag_list_init(head); + skb_shinfo(head)->frag_list = NULL; for (i=0; inr_frags; i++) plen += skb_shinfo(head)->frags[i].size; clone->len = clone->data_len = head->data_len - plen; diff --git a/trunk/net/mac80211/agg-tx.c b/trunk/net/mac80211/agg-tx.c index 9e5762ad307d..43d00ffd3988 100644 --- a/trunk/net/mac80211/agg-tx.c +++ b/trunk/net/mac80211/agg-tx.c @@ -132,9 +132,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, state = &sta->ampdu_mlme.tid_state_tx[tid]; - if (*state == HT_AGG_STATE_OPERATIONAL) - sta->ampdu_mlme.addba_req_num[tid] = 0; - *state = HT_AGG_STATE_REQ_STOP_BA_MSK | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); @@ -340,7 +337,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) sta->ampdu_mlme.tid_tx[tid]->dialog_token, sta->ampdu_mlme.tid_tx[tid]->ssn, 0x40, 5000); - sta->ampdu_mlme.addba_req_num[tid]++; /* activate the timer for the recipient's addBA response */ sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = jiffies + ADDBA_RESP_INTERVAL; @@ -610,6 +606,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) *state = HT_AGG_STATE_IDLE; /* from now on packets are no longer put onto sta->pending */ + sta->ampdu_mlme.addba_req_num[tid] = 0; kfree(sta->ampdu_mlme.tid_tx[tid]); sta->ampdu_mlme.tid_tx[tid] = NULL; @@ -692,6 +689,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, sta->ampdu_mlme.addba_req_num[tid] = 0; } else { + sta->ampdu_mlme.addba_req_num[tid]++; ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); } spin_unlock_bh(&sta->lock); diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 3f47276caeb8..a9211cc183cb 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -1122,8 +1122,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, p.txop = params->txop; if (drv_conf_tx(local, params->queue, &p)) { printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), params->queue); + "parameters for queue %d\n", local->mdev->name, + params->queue); return -EINVAL; } diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 4dbc28964196..c088c46704a3 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -589,7 +589,6 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_AGGREGATION, IEEE80211_QUEUE_STOP_REASON_SUSPEND, IEEE80211_QUEUE_STOP_REASON_PENDING, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD, }; struct ieee80211_master_priv { @@ -1122,10 +1121,6 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, enum queue_stop_reason reason); void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, enum queue_stop_reason reason); -void ieee80211_add_pending_skb(struct ieee80211_local *local, - struct sk_buff *skb); -int ieee80211_add_pending_skbs(struct ieee80211_local *local, - struct sk_buff_head *skbs); void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index 092a017b237e..2683df918073 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -369,12 +369,60 @@ static void ieee80211_tasklet_handler(unsigned long data) } } +/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to + * make a prepared TX frame (one that has been given to hw) to look like brand + * new IEEE 802.11 frame that is ready to go through TX processing again. + */ +static void ieee80211_remove_tx_extra(struct ieee80211_local *local, + struct ieee80211_key *key, + struct sk_buff *skb) +{ + unsigned int hdrlen, iv_len, mic_len; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + + if (!key) + goto no_key; + + switch (key->conf.alg) { + case ALG_WEP: + iv_len = WEP_IV_LEN; + mic_len = WEP_ICV_LEN; + break; + case ALG_TKIP: + iv_len = TKIP_IV_LEN; + mic_len = TKIP_ICV_LEN; + break; + case ALG_CCMP: + iv_len = CCMP_HDR_LEN; + mic_len = CCMP_MIC_LEN; + break; + default: + goto no_key; + } + + if (skb->len >= hdrlen + mic_len && + !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) + skb_trim(skb, skb->len - mic_len); + if (skb->len >= hdrlen + iv_len) { + memmove(skb->data + iv_len, skb->data, hdrlen); + hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len); + } + +no_key: + if (ieee80211_is_data_qos(hdr->frame_control)) { + hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data, + hdrlen - IEEE80211_QOS_CTL_LEN); + skb_pull(skb, IEEE80211_QOS_CTL_LEN); + } +} + static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, struct sta_info *sta, struct sk_buff *skb) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - sta->tx_filtered_count++; /* @@ -416,15 +464,16 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, */ if (test_sta_flags(sta, WLAN_STA_PS) && skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { + ieee80211_remove_tx_extra(local, sta->key, skb); skb_queue_tail(&sta->tx_filtered, skb); return; } - if (!test_sta_flags(sta, WLAN_STA_PS) && - !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { + if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { /* Software retry the packet once */ - info->flags |= IEEE80211_TX_INTFL_RETRIED; - ieee80211_add_pending_skb(local, skb); + skb->requeue = 1; + ieee80211_remove_tx_extra(local, sta->key, skb); + dev_queue_xmit(skb); return; } diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index d779c57a8220..509469cb9265 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -621,6 +621,9 @@ static void ieee80211_change_ps(struct ieee80211_local *local) struct ieee80211_conf *conf = &local->hw.conf; if (local->ps_sdata) { + if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) + return; + ieee80211_enable_ps(local, local->ps_sdata); } else if (conf->flags & IEEE80211_CONF_PS) { conf->flags &= ~IEEE80211_CONF_PS; @@ -650,9 +653,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) count++; } - if (count == 1 && found->u.mgd.powersave && - (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) && - !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { + if (count == 1 && found->u.mgd.powersave) { s32 beaconint_us; if (latency < 0) @@ -792,13 +793,13 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, #ifdef CONFIG_MAC80211_VERBOSE_DEBUG printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " "cWmin=%d cWmax=%d txop=%d\n", - wiphy_name(local->hw.wiphy), queue, aci, acm, - params.aifs, params.cw_min, params.cw_max, params.txop); + local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, + params.cw_max, params.txop); #endif if (drv_conf_tx(local, queue, ¶ms) && local->ops->conf_tx) printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), queue); + "parameters for queue %d\n", local->mdev->name, + queue); } } @@ -1321,11 +1322,6 @@ void ieee80211_beacon_loss_work(struct work_struct *work) #endif ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; - - mutex_lock(&sdata->local->iflist_mtx); - ieee80211_recalc_ps(sdata->local, -1); - mutex_unlock(&sdata->local->iflist_mtx); - ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, ifmgd->ssid_len, NULL, 0); @@ -1346,7 +1342,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; struct sta_info *sta; - unsigned long last_rx; bool disassoc = false; /* TODO: start monitoring current AP signal quality and number of @@ -1363,21 +1358,17 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", sdata->dev->name, ifmgd->bssid); disassoc = true; - rcu_read_unlock(); - goto out; + goto unlock; } - last_rx = sta->last_rx; - rcu_read_unlock(); - if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && - time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) { + time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) { printk(KERN_DEBUG "%s: no probe response from AP %pM " "- disassociating\n", sdata->dev->name, ifmgd->bssid); disassoc = true; ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; - goto out; + goto unlock; } /* @@ -1396,29 +1387,26 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) } #endif ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&local->iflist_mtx); - ieee80211_recalc_ps(local, -1); - mutex_unlock(&local->iflist_mtx); ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, ifmgd->ssid_len, NULL, 0); mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); - goto out; + goto unlock; } - if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) { + if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) { ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&local->iflist_mtx); - ieee80211_recalc_ps(local, -1); - mutex_unlock(&local->iflist_mtx); ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, ifmgd->ssid_len, NULL, 0); } - out: if (!disassoc) mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL); - else + + unlock: + rcu_read_unlock(); + + if (disassoc) ieee80211_set_disassoc(sdata, true, true, WLAN_REASON_PREV_AUTH_NOT_VALID); } @@ -1901,12 +1889,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ieee80211_authenticate(sdata); } - if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { + if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&sdata->local->iflist_mtx); - ieee80211_recalc_ps(sdata->local, -1); - mutex_unlock(&sdata->local->iflist_mtx); - } } /* @@ -1964,9 +1948,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } #endif ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; - mutex_lock(&local->iflist_mtx); - ieee80211_recalc_ps(local, -1); - mutex_unlock(&local->iflist_mtx); } ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); diff --git a/trunk/net/mac80211/rc80211_minstrel.c b/trunk/net/mac80211/rc80211_minstrel.c index b218b98fba7f..0a11515341ba 100644 --- a/trunk/net/mac80211/rc80211_minstrel.c +++ b/trunk/net/mac80211/rc80211_minstrel.c @@ -215,7 +215,7 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi) unsigned int sample_ndx; sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); mi->sample_idx++; - if ((int) mi->sample_idx > (mi->n_rates - 2)) { + if (mi->sample_idx > (mi->n_rates - 2)) { mi->sample_idx = 0; mi->sample_column++; if (mi->sample_column >= SAMPLE_COLUMNS) diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index de5bba7f910a..6a9b8e63a6bf 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -797,7 +797,8 @@ static int ap_sta_ps_end(struct sta_info *sta) { struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; - int sent, buffered; + struct sk_buff *skb; + int sent = 0; atomic_dec(&sdata->bss->num_sta_ps); @@ -813,16 +814,22 @@ static int ap_sta_ps_end(struct sta_info *sta) #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ /* Send all buffered frames to the station */ - sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); - buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); - sent += buffered; - local->total_ps_buffered -= buffered; - + while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { + sent++; + skb->requeue = 1; + dev_queue_xmit(skb); + } + while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { + local->total_ps_buffered--; + sent++; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " - "since STA not sleeping anymore\n", sdata->dev->name, - sta->sta.addr, sta->sta.aid, sent - buffered, buffered); + printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " + "since STA not sleeping anymore\n", sdata->dev->name, + sta->sta.addr, sta->sta.aid); #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ + skb->requeue = 1; + dev_queue_xmit(skb); + } return sent; } @@ -1328,7 +1335,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) * mac80211. That also explains the __skb_push() * below. */ - align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3; + align = (unsigned long)skb->data & 3; if (align) { if (WARN_ON(skb_headroom(skb) < 3)) { dev_kfree_skb(skb); diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 364222bfb10d..1436f747531a 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -400,7 +400,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) sta_info_set_tim_bit(sta); info->control.jiffies = jiffies; - info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; skb_queue_tail(&sta->ps_tx_buf, tx->skb); return TX_QUEUED; } @@ -421,7 +420,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) * frame filtering and keeps a station blacklist on its own * (e.g: p54), so that frames can be delivered unimpeded. * - * Note: It should be safe to disable the filter now. + * Note: It should be save to disable the filter now. * As, it is really unlikely that we still have any pending * frame for this station in the hw's buffers/fifos left, * that is not rejected with a unsuccessful tx_status yet. @@ -908,8 +907,9 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) * deal with packet injection down monitor interface * with Radiotap Header -- only called for monitor mode interface */ -static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, - struct sk_buff *skb) +static ieee80211_tx_result +__ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, + struct sk_buff *skb) { /* * this is the moment to interpret and discard the radiotap header that @@ -960,7 +960,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, * on transmission */ if (skb->len < (iterator.max_length + FCS_LEN)) - return false; + return TX_DROP; skb_trim(skb, skb->len - FCS_LEN); } @@ -982,7 +982,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, } if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ - return false; + return TX_DROP; /* * remove the radiotap header @@ -991,7 +991,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, */ skb_pull(skb, iterator.max_length); - return true; + return TX_CONTINUE; } /* @@ -1025,7 +1025,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, /* process and remove the injection radiotap header */ sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { - if (!__ieee80211_parse_tx_radiotap(tx, skb)) + if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) return TX_DROP; /* @@ -1415,8 +1415,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) } if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && - local->hw.conf.dynamic_ps_timeout > 0 && - !local->sw_scanning && !local->hw_scanning && local->ps_sdata) { + local->hw.conf.dynamic_ps_timeout > 0) { if (local->hw.conf.flags & IEEE80211_CONF_PS) { ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_QUEUE_STOP_REASON_PS); diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 66ce96a69f31..22f63815fb36 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -341,52 +341,6 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) } EXPORT_SYMBOL(ieee80211_stop_queue); -void ieee80211_add_pending_skb(struct ieee80211_local *local, - struct sk_buff *skb) -{ - struct ieee80211_hw *hw = &local->hw; - unsigned long flags; - int queue = skb_get_queue_mapping(skb); - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING); - skb_queue_tail(&local->pending[queue], skb); - __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -} - -int ieee80211_add_pending_skbs(struct ieee80211_local *local, - struct sk_buff_head *skbs) -{ - struct ieee80211_hw *hw = &local->hw; - struct sk_buff *skb; - unsigned long flags; - int queue, ret = 0, i; - - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - for (i = 0; i < hw->queues; i++) - __ieee80211_stop_queue(hw, i, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - - while ((skb = skb_dequeue(skbs))) { - ret++; - queue = skb_get_queue_mapping(skb); - skb_queue_tail(&local->pending[queue], skb); - } - - for (i = 0; i < hw->queues; i++) { - if (ret) - __ieee80211_stop_queue(hw, i, - IEEE80211_QUEUE_STOP_REASON_PENDING); - __ieee80211_wake_queue(hw, i, - IEEE80211_QUEUE_STOP_REASON_SKB_ADD); - } - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - - return ret; -} - void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, enum queue_stop_reason reason) { diff --git a/trunk/net/mac80211/wme.c b/trunk/net/mac80211/wme.c index 116a923b14d6..694343b9102b 100644 --- a/trunk/net/mac80211/wme.c +++ b/trunk/net/mac80211/wme.c @@ -101,7 +101,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) * Now we know the 1d priority, fill in the QoS header if * there is one (and we haven't done this before). */ - if (ieee80211_is_data_qos(hdr->frame_control)) { + if (!skb->requeue && ieee80211_is_data_qos(hdr->frame_control)) { u8 *p = ieee80211_get_qos_ctl(hdr); u8 ack_policy = 0; tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; diff --git a/trunk/net/netfilter/nfnetlink_queue.c b/trunk/net/netfilter/nfnetlink_queue.c index 71daa0934b6c..8c860112ce05 100644 --- a/trunk/net/netfilter/nfnetlink_queue.c +++ b/trunk/net/netfilter/nfnetlink_queue.c @@ -1,6 +1,6 @@ /* * This is a module which is used for queueing packets and communicating with - * userspace via nfnetlink. + * userspace via nfetlink. * * (C) 2005 by Harald Welte * (C) 2007 by Patrick McHardy @@ -932,8 +932,6 @@ static void __exit nfnetlink_queue_fini(void) #endif nfnetlink_subsys_unregister(&nfqnl_subsys); netlink_unregister_notifier(&nfqnl_rtnl_notifier); - - rcu_barrier(); /* Wait for completion of call_rcu()'s */ } MODULE_DESCRIPTION("netfilter packet queue handler"); diff --git a/trunk/net/phonet/pep-gprs.c b/trunk/net/phonet/pep-gprs.c index 480839dfc560..851f6a3f8ddd 100644 --- a/trunk/net/phonet/pep-gprs.c +++ b/trunk/net/phonet/pep-gprs.c @@ -115,10 +115,10 @@ static int gprs_recv(struct gprs_dev *gp, struct sk_buff *skb) rskb->truesize += rskb->len; /* Avoid nested fragments */ - skb_walk_frags(skb, fs) + for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next) flen += fs->len; skb->next = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; skb->len -= flen; skb->data_len -= flen; skb->truesize -= flen; diff --git a/trunk/net/phonet/pep.c b/trunk/net/phonet/pep.c index eef833ea6d7b..8ad2b5333881 100644 --- a/trunk/net/phonet/pep.c +++ b/trunk/net/phonet/pep.c @@ -940,10 +940,10 @@ int pep_write(struct sock *sk, struct sk_buff *skb) rskb->truesize += rskb->len; /* Avoid nested fragments */ - skb_walk_frags(skb, fs) + for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next) flen += fs->len; skb->next = skb_shinfo(skb)->frag_list; - skb_frag_list_init(skb); + skb_shinfo(skb)->frag_list = NULL; skb->len -= flen; skb->data_len -= flen; skb->truesize -= flen; diff --git a/trunk/net/rfkill/Kconfig b/trunk/net/rfkill/Kconfig index eaf765876458..fd7600d8ab14 100644 --- a/trunk/net/rfkill/Kconfig +++ b/trunk/net/rfkill/Kconfig @@ -18,7 +18,7 @@ config RFKILL_LEDS default y config RFKILL_INPUT - bool "RF switch input support" if EMBEDDED + bool "RF switch input support" depends on RFKILL depends on INPUT = y || RFKILL = INPUT default y if !EMBEDDED diff --git a/trunk/net/rfkill/core.c b/trunk/net/rfkill/core.c index 4e68ab439d5d..11b7314723df 100644 --- a/trunk/net/rfkill/core.c +++ b/trunk/net/rfkill/core.c @@ -57,7 +57,6 @@ struct rfkill { bool registered; bool suspended; - bool persistent; const struct rfkill_ops *ops; void *data; @@ -117,9 +116,11 @@ MODULE_PARM_DESC(default_state, "Default initial state for all radio types, 0 = radio off"); static struct { - bool cur, sav; + bool cur, def; } rfkill_global_states[NUM_RFKILL_TYPES]; +static unsigned long rfkill_states_default_locked; + static bool rfkill_epo_lock_active; @@ -391,7 +392,7 @@ void rfkill_epo(void) rfkill_set_block(rfkill, true); for (i = 0; i < NUM_RFKILL_TYPES; i++) { - rfkill_global_states[i].sav = rfkill_global_states[i].cur; + rfkill_global_states[i].def = rfkill_global_states[i].cur; rfkill_global_states[i].cur = true; } @@ -416,7 +417,7 @@ void rfkill_restore_states(void) rfkill_epo_lock_active = false; for (i = 0; i < NUM_RFKILL_TYPES; i++) - __rfkill_switch_all(i, rfkill_global_states[i].sav); + __rfkill_switch_all(i, rfkill_global_states[i].def); mutex_unlock(&rfkill_global_mutex); } @@ -463,6 +464,29 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type) } #endif +void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked) +{ + BUG_ON(type == RFKILL_TYPE_ALL); + + mutex_lock(&rfkill_global_mutex); + + /* don't allow unblock when epo */ + if (rfkill_epo_lock_active && !blocked) + goto out; + + /* too late */ + if (rfkill_states_default_locked & BIT(type)) + goto out; + + rfkill_states_default_locked |= BIT(type); + + rfkill_global_states[type].cur = blocked; + rfkill_global_states[type].def = blocked; + out: + mutex_unlock(&rfkill_global_mutex); +} +EXPORT_SYMBOL(rfkill_set_global_sw_state); + bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) { @@ -508,14 +532,13 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) blocked = blocked || hwblock; spin_unlock_irqrestore(&rfkill->lock, flags); - if (!rfkill->registered) { - rfkill->persistent = true; - } else { - if (prev != blocked && !hwblock) - schedule_work(&rfkill->uevent_work); + if (!rfkill->registered) + return blocked; - rfkill_led_trigger_event(rfkill); - } + if (prev != blocked && !hwblock) + schedule_work(&rfkill->uevent_work); + + rfkill_led_trigger_event(rfkill); return blocked; } @@ -540,14 +563,13 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) spin_unlock_irqrestore(&rfkill->lock, flags); - if (!rfkill->registered) { - rfkill->persistent = true; - } else { - if (swprev != sw || hwprev != hw) - schedule_work(&rfkill->uevent_work); + if (!rfkill->registered) + return; - rfkill_led_trigger_event(rfkill); - } + if (swprev != sw || hwprev != hw) + schedule_work(&rfkill->uevent_work); + + rfkill_led_trigger_event(rfkill); } EXPORT_SYMBOL(rfkill_set_states); @@ -728,11 +750,15 @@ static int rfkill_resume(struct device *dev) struct rfkill *rfkill = to_rfkill(dev); bool cur; - cur = !!(rfkill->state & RFKILL_BLOCK_SW); + mutex_lock(&rfkill_global_mutex); + cur = rfkill_global_states[rfkill->type].cur; rfkill_set_block(rfkill, cur); + mutex_unlock(&rfkill_global_mutex); rfkill->suspended = false; + schedule_work(&rfkill->uevent_work); + rfkill_resume_polling(rfkill); return 0; @@ -862,6 +888,15 @@ int __must_check rfkill_register(struct rfkill *rfkill) dev_set_name(dev, "rfkill%lu", rfkill_no); rfkill_no++; + if (!(rfkill_states_default_locked & BIT(rfkill->type))) { + /* first of its kind */ + BUILD_BUG_ON(NUM_RFKILL_TYPES > + sizeof(rfkill_states_default_locked) * 8); + rfkill_states_default_locked |= BIT(rfkill->type); + rfkill_global_states[rfkill->type].cur = + rfkill_global_states[rfkill->type].def; + } + list_add_tail(&rfkill->node, &rfkill_list); error = device_add(dev); @@ -881,17 +916,7 @@ int __must_check rfkill_register(struct rfkill *rfkill) if (rfkill->ops->poll) schedule_delayed_work(&rfkill->poll_work, round_jiffies_relative(POLL_INTERVAL)); - - if (!rfkill->persistent || rfkill_epo_lock_active) { - schedule_work(&rfkill->sync_work); - } else { -#ifdef CONFIG_RFKILL_INPUT - bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW); - - if (!atomic_read(&rfkill_input_disabled)) - __rfkill_switch_all(rfkill->type, soft_blocked); -#endif - } + schedule_work(&rfkill->sync_work); rfkill_send_events(rfkill, RFKILL_OP_ADD); @@ -1109,8 +1134,7 @@ static int rfkill_fop_release(struct inode *inode, struct file *file) #ifdef CONFIG_RFKILL_INPUT if (data->input_handler) - if (atomic_dec_return(&rfkill_input_disabled) == 0) - printk(KERN_DEBUG "rfkill: input handler enabled\n"); + atomic_dec(&rfkill_input_disabled); #endif kfree(data); @@ -1133,8 +1157,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, mutex_lock(&data->mtx); if (!data->input_handler) { - if (atomic_inc_return(&rfkill_input_disabled) == 1) - printk(KERN_DEBUG "rfkill: input handler disabled\n"); + atomic_inc(&rfkill_input_disabled); data->input_handler = true; } @@ -1168,7 +1191,7 @@ static int __init rfkill_init(void) int i; for (i = 0; i < NUM_RFKILL_TYPES; i++) - rfkill_global_states[i].cur = !rfkill_default_state; + rfkill_global_states[i].def = !rfkill_default_state; error = class_register(&rfkill_class); if (error) diff --git a/trunk/net/sched/sch_hfsc.c b/trunk/net/sched/sch_hfsc.c index 362c2811b2df..5022f9c1f34b 100644 --- a/trunk/net/sched/sch_hfsc.c +++ b/trunk/net/sched/sch_hfsc.c @@ -372,7 +372,7 @@ cftree_update(struct hfsc_class *cl) * ism: (psched_us/byte) << ISM_SHIFT * dx: psched_us * - * The clock source resolution with ktime and PSCHED_SHIFT 10 is 1.024us. + * The clock source resolution with ktime is 1.024us. * * sm and ism are scaled in order to keep effective digits. * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective @@ -383,11 +383,9 @@ cftree_update(struct hfsc_class *cl) * bytes/1.024us 12.8e-3 128e-3 1280e-3 12800e-3 128000e-3 * * 1.024us/byte 78.125 7.8125 0.78125 0.078125 0.0078125 - * - * So, for PSCHED_SHIFT 10 we need: SM_SHIFT 20, ISM_SHIFT 18. */ -#define SM_SHIFT (30 - PSCHED_SHIFT) -#define ISM_SHIFT (8 + PSCHED_SHIFT) +#define SM_SHIFT 20 +#define ISM_SHIFT 18 #define SM_MASK ((1ULL << SM_SHIFT) - 1) #define ISM_MASK ((1ULL << ISM_SHIFT) - 1) diff --git a/trunk/net/sctp/input.c b/trunk/net/sctp/input.c index c0c973e67add..d2e98803ffe3 100644 --- a/trunk/net/sctp/input.c +++ b/trunk/net/sctp/input.c @@ -81,13 +81,13 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb); /* Calculate the SCTP checksum of an SCTP packet. */ static inline int sctp_rcv_checksum(struct sk_buff *skb) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; struct sctphdr *sh = sctp_hdr(skb); __le32 cmp = sh->checksum; - struct sk_buff *list; __le32 val; __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); - skb_walk_frags(skb, list) + for (; list; list = list->next) tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), tmp); diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index 79cbd47f4df7..cb2c50dbd421 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -1370,8 +1370,6 @@ SCTP_STATIC __exit void sctp_exit(void) sctp_proc_exit(); cleanup_sctp_mibs(); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ - kmem_cache_destroy(sctp_chunk_cachep); kmem_cache_destroy(sctp_bucket_cachep); } diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 0f01e5d8a24f..7c3dfd2d9489 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -1881,7 +1881,7 @@ static int sctp_skb_pull(struct sk_buff *skb, int len) len -= skb_len; __skb_pull(skb, skb_len); - skb_walk_frags(skb, list) { + for (list = skb_shinfo(skb)->frag_list; list; list = list->next) { rlen = sctp_skb_pull(list, len); skb->len -= (len-rlen); skb->data_len -= (len-rlen); @@ -6660,7 +6660,7 @@ static void sctp_sock_rfree_frag(struct sk_buff *skb) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) sctp_sock_rfree_frag(frag); done: @@ -6675,7 +6675,7 @@ static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) sctp_skb_set_owner_r_frag(frag, sk); done: diff --git a/trunk/net/sctp/ulpevent.c b/trunk/net/sctp/ulpevent.c index 8b3560fd876d..5f186ca550d7 100644 --- a/trunk/net/sctp/ulpevent.c +++ b/trunk/net/sctp/ulpevent.c @@ -976,8 +976,9 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, * In general, the skb passed from IP can have only 1 level of * fragments. But we allow multiple levels of fragments. */ - skb_walk_frags(skb, frag) + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc); + } } /* Do accounting for bytes just read by user and release the references to @@ -1002,7 +1003,7 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* NOTE: skb_shinfos are recursive. Although IP returns * skb's with only 1 level of fragments, SCTP reassembly can * increase the levels. @@ -1025,7 +1026,7 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) goto done; /* Don't forget the fragments. */ - skb_walk_frags(skb, frag) { + for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { /* NOTE: skb_shinfos are recursive. Although IP returns * skb's with only 1 level of fragments, SCTP reassembly can * increase the levels. diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index 66d458fc6920..e630b38a6047 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -1548,7 +1548,6 @@ static void __exit exit_rpcsec_gss(void) { gss_svc_shutdown(); rpcauth_unregister(&authgss_ops); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ } MODULE_LICENSE("GPL"); diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index d5850292b3df..3b74b88e10a3 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -395,23 +395,21 @@ int wiphy_register(struct wiphy *wiphy) /* check and set up bitrates */ ieee80211_set_bitrate_flags(wiphy); + mutex_lock(&cfg80211_mutex); + + /* set up regulatory info */ + wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); + res = device_add(&drv->wiphy.dev); if (res) - return res; + goto out_unlock; res = rfkill_register(drv->rfkill); if (res) goto out_rm_dev; - mutex_lock(&cfg80211_mutex); - - /* set up regulatory info */ - wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); - list_add(&drv->list, &cfg80211_drv_list); - mutex_unlock(&cfg80211_mutex); - /* add to debugfs */ drv->wiphy.debugfsdir = debugfs_create_dir(wiphy_name(&drv->wiphy), @@ -432,10 +430,13 @@ int wiphy_register(struct wiphy *wiphy) cfg80211_debugfs_drv_add(drv); - return 0; + res = 0; + goto out_unlock; out_rm_dev: device_del(&drv->wiphy.dev); + out_unlock: + mutex_unlock(&cfg80211_mutex); return res; } EXPORT_SYMBOL(wiphy_register); diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index 5e14371cda70..ea4c299fbe3b 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -2129,12 +2129,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) * driver wanted to the wiphy to deal with conflicts */ - /* - * Userspace could have sent two replies with only - * one kernel request. - */ - if (request_wiphy->regd) - return -EALREADY; + BUG_ON(request_wiphy->regd); r = reg_copy_regd(&request_wiphy->regd, rd); if (r) diff --git a/trunk/net/xfrm/xfrm_algo.c b/trunk/net/xfrm/xfrm_algo.c index d31ccb487730..96036cf2216d 100644 --- a/trunk/net/xfrm/xfrm_algo.c +++ b/trunk/net/xfrm/xfrm_algo.c @@ -696,9 +696,8 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, { int start = skb_headlen(skb); int i, copy = start - offset; - struct sk_buff *frag_iter; - struct scatterlist sg; int err; + struct scatterlist sg; /* Checksum header. */ if (copy > 0) { @@ -743,24 +742,28 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, start = end; } - skb_walk_frags(skb, frag_iter) { - int end; - - WARN_ON(start > offset + len); - - end = start + frag_iter->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - err = skb_icv_walk(frag_iter, desc, offset-start, - copy, icv_update); - if (unlikely(err)) - return err; - if ((len -= copy) == 0) - return 0; - offset += copy; + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + err = skb_icv_walk(list, desc, offset-start, + copy, icv_update); + if (unlikely(err)) + return err; + if ((len -= copy) == 0) + return 0; + offset += copy; + } + start = end; } - start = end; } BUG_ON(len); return 0;